- Notifications
You must be signed in to change notification settings - Fork0
Grunt plugin for building RequireJS-based applications with optimizing js, css and Handlebars templates
License
croc-code/grunt-croc-requirejs
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Build RequireJS-based applications optimizing js, css and Handlebars templates.
If you haven't usedGrunt before, be sure to check out theGetting Started guide, as it explains how to create aGruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
npm install grunt-croc-requirejs --save-dev
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of #"auto" data-snippet-clipboard-copy-content="grunt.loadNpmTasks('grunt-croc-requirejs');">
grunt.loadNpmTasks('grunt-croc-requirejs');
Or just usematchdep module.
Why do we need another Grunt task for merging RequireJS modules if there'replenty of them? There is a major difference - this task generates alayered application, i.e. all js scripts are not just combined into a single file but instead they are combined into several files - "layers". Here's motivation for such an approach.
Usually a front-end application consists of a bunch of scripts. Some of them belongs to the application but other ones are some 3rd-party libraries. When an application is being developed app scripts are usually changed often but 3rd-party scripts much more rarely. So if we combine all scripts into a single one "mega" script then end-users of the application will have to redownload that script on every change.
This task allows to split scripts intolayers so end-users will redownload only changed part of the application.
Also the plugin provides some usefull optimization tools which allows you to:
- combine all CSS files imported by AMD modules into a single CSS-script ("generic.css")
- precompile Handlebars-templates imported by modules
xcss plugin allows a module to import its CSS dependencies as regular AMD-modules.
Usage example:
define(["jquery","xcss!lib/ui/styles/jquery.blocked.css"],function($){});
Here we imported a CSS-file (jquery.blocked.css) as AMD-module.
In run-timexcss plugin requests the CSS-file via XHR and adds its content intoSTYLE tag (underHEAD). So in a development environment CSS-script are fetched and added into page'sSTYLE. The nice thing is that modules control their CSS-files on their own.
NOTE: All imports of CSS-files in all modules use a singleSTYLE tag to be IE-friendly.
In build-timexcss plugin writes down content of CSS-files into a single file (by default it's 'generic.css', but can be controlled bygenericCssUrl option). So at the end we'll have a single CSS-file with content of all CSS-scripts imported viaxcss plugin. Obviously that script should be loaded vialink:
<linkrel='stylesheet'href='/client/content/generic.css'type='text/css'>
But it's not enough. In run-time for optimized (or built) applicationxcss plugin will do nothing. It becomes just a stub. So in runtime there is no any overhead for componentization.
For loading CSS-files the plugin uses standard RJS's plugintext. It should be registered with alias "text".
xhtmpl plugin allows a module to import its Handlebars dependencies as regular AMD-modules.
Usage example:
define(["xhtmpl!lib/ui/Dialog/template.hbs"],function(template){});
Here we imported a hbs-file (lib/ui/Dialog/template.hbs) as AMD-mobule. hbs-files are Handlebars templates. Actual files extension doesn't matter much. But it's usefull to name them as '*.hbs' due to HB-templates support in WebStorm and Visual Studio.
In runtime the plugin fetches specified template and compiles it viaHandlebars. Handlebars compiles templates into js code (functions).
In build-time the plugin emits template's compiled js code as an AMD-module (the module returns template's function). In runtime for optimized (built) applicationxhtmlp plugin just returns already compiled function. So there is no compilation (i.e. overhead) in runtime for optimized applications.
For loading templates (*.hbs) the plugin uses standard RJS's plugintext. It should be registered with alias "text".
In your project's Gruntfile, add a section namedrjs to the data object passed intogrunt.initConfig().
grunt.initConfig({rjs:{options:{// Task-specific options go here.},your_target:{// Target-specific file lists and/or options go here.},},})
Type:String
Default value:make.config.json
Required: no
Build config file name. If the file exists then task will read its configuration from it. So if you createmake.config.json besideGruntfile.js then it will be used as task's config.
Please note that parameters values fromGruntfile.js will overwrite values from external config file.
Type:String
Required: yes
Input directory. It should point to a directory with root modules.
Type:String
Required: no
Output directory. If an output directory isn't specified then optimized files will be placed into input directory replacing its content.
Type:String
Default value:.make_build/
Required: no
Temporary directory for build.
Type:String
Default value:.make_tmp/
Required: no
Temporary directory for intermediate result (should be discarded)
Type:Boolean
Default value:false
Required: no
Do not remove buildDir and tempDir after build completes.
Type:Array ofString
Required: no
Directories under input dir with standalone scripts (not referenced by app modules, usually injected on server) to optimize.
Type:String
Default value:require.config.json
Required: no
RequireJS config file name (relative to input dir).
Type:Object
Default value:undefined
Required: no
RequireJS config JSON object. It will override config from 'requireConfigFile' option.
Type:Object
Default value:undefined
Required: no
RequireJS config JSON for output optimized application (will override all other configs).
Type:Array
Default value:undefined
Required: no
Array of main modules names. If empty then all *.js files directly under input directory will be used.
Type:Array
Default value:undefined
Required: no
Array of modules names to ignore. They will not be included into layers modules
Type:String
Default value:none
Required: no
Optimization method of *.js files in terms of RJS:none,uglify.
Type:String
Default value:none
Required: no
Optimization method of *.css files in terms of RJS:none,standard,standard.keepLines.
Type:Boolean
Default value:undefined
Required: no
r.js option: If the minifier specified in the "optimize" option supports generating source maps for the minified code, then generate them.
Type:Boolean
Default value:false
Required: no
r.js option: this option will turn off the auto-preservation of licence comments.
Type:String
Default value:content/generic.css
Required: no
Path to generic.css - css file for combining all css imported via xcss.js.
Type:String
Default value:undefined
Required: no
A locale to bundle - i.e. resources imported viai18n rjs plugin will be included into optimized js-modules and all other resources will be left unchanged.
The value will be used aslocale option for r.js.
Type:Object
Default value:undefined
Required: no
An object-map with a mapping of layer name to folder or array of folders.
By default (if no option specified) task will use:
{"lib-layer": ["lib","modules"],"vendor-layer":"vendor"}That means that scripts from "lib" and "modules" folders will be combined into "lib-layer" script, and scripts from "vendor" folder - into "vendor-layer".
An example of override:
{"lib-layer":"lib","modules":"modules","vendor-layer":"vendor"},Type:Object
Required: no
An object-map with options overrides for particilar layers.
For example you want to minify/uglify all modules except main and report-main:
{"optimizeJs":"uglify2","layerOverrides": {"main": {"optimizeJs":"none"},"report-main": {"optimizeJs":"none"}}}The plugin assumes that client-side of a project has the following structure:
- all client stuff is inside a single folder (let's call itclient root);
- client root containsroot modules - usually these are scripts which are loaded by RequireJS directly (e.g. via
data-mainattribute) - i.e.mainscripts in terms of RequireJS; - client root contains subfolders which are treated as
layers. Usually we haveapp,libandvendorfolders (the app can also have any other folders). Scripts (*.js) which are in these layer-folders will be bundled together.
RequireJS provides rjs optimizer for building optimized version of apps. rjs is a script to be run under node.js. It has pletly of options - seethe doc.This plugin grunt-croc-requirejs is just a wrapper around rjs optimizer.
modules option can specifies a bunch of files which will be treated asroot modules. Ifmodules options isn't specified then all *.js underinputDir will be treated as root modules.rjs optimizer has two modes: optimizing directory and optimizing files. The plugin uses the latter mode. Files for rjs optimizer are specified inmodules option. So these files we're callign asroot modules.
By default if you supply a main script to rjs optimizer it'll combine all depedency tree into a single minified script. rjs does support layers and shared scripts for multi-page applications -see this official sample. But it requires to do a lot of configuration.This plugin supports splitting scripts onto layers depending on folder structure. For example let's consider an application has the following structure:
───Server ├───client │ ├───app │ │ ├───templates │ │ └───ui │ │ └───styles │ ├───boot │ ├───content │ │ ├───fonts │ │ └───images │ ├───lib │ │ └───... │ ├───modules │ │ └───... │ ├───shim │ ├───vendor │ │ └───... │ └───main.jsHere all client code is placed underclient folder (client root). Under client root we can seeapp,lib,vendor and some other folders. They will layers names. After optimization we'll get:
- main.js - all scripts imported from main.js except those which included into lib/vendor layers
- lib-layer.js - all scripts from "lib" and "modules" folders (which are used by other scripts starting from main.js)
- vendor-layer.js - all scripts from "vendor" folder
grunt.initConfig({rjs:{dist:{options:{input:'dist/dev',output:'dist/prod',requireConfigFile:'require.config.json',requireConfigOutput:{paths:{handlebars:"vendor/handlebars/handlebars.runtime"}},genericCssUrl:'content/generic.css',optimizeJs:'uglify',optimizeCss:'standard',generateSourceMaps:true,bundledLocale:'ru'}}}})
IfoptimizeJs option specified asuglify then output files will be processed withUglifyJS. It also has different options which you'd want to override.For example, by default UglifyJS removes quotes for keys if they are not reserved words. This behavior can lead to runtime errors in IE8.
Here's example how to pass options into UglifyJS via Grunt task's options:
rjs:{dist:{options:{optimizeJs:'uglify',requireConfig:{uglify:{output:{quote_keys:true}}},}}}
- 2017-12-01 v0.3.0 Added
layersoption to override folder-layer mapping - 2017-08-28v0.2.0Support multiple folders for a layer (by default modules from "lib" and "modules" folders go to "lib-layer").
OptionlayerOverridesfor overriding options for particular layers. - 2016-12-26v0.1.5Updated README, updated dev-dependencies
- 2015-12-07v0.1.3fix for NPM3 support
- 2015-09-01v0.1.0 Updated README
- 2013-12-03v0.1.0Task submitted
- 2013-08-27v0.0.0Work started
Task submitted bySergei Dorogin
(c) Copyright CROC Inc. 2013-2017
About
Grunt plugin for building RequireJS-based applications with optimizing js, css and Handlebars templates
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Uh oh!
There was an error while loading.Please reload this page.
