Grunt - output 2 versions of web app - javascript

I'm learning Grunt and trying to sort out how I can create 2 versions of the same application. The difference between the two are configuration settings.
Ideally, I would like the process to output 2 versions. One with a boolean in one of the .js files set to false, the other left to true. I would also need to concat and minify then file.
Is there a recommended way to do this? Thanks in advance

You can specify 2 configurations in your grunt.initConfig
grunt.initConfig({
myTask: {
version1: { ... }
version2: { ... }
}
})
And then register your default task to run each of these versions
grunt.task.registerTask("default", ["myTask:version1", "myTask:version2"])
Or just some other task name, myTaskAllVersions instead of default
You could use this versioning to flip your .js boolean, per version 1 or 2.
A similar approach could be taken to minifying and concatting the files afterwards, i.e.
grunt.initConfig({
minify: {
version1: { ... }
version2: { ... }
}
})
and
grunt.task.registerTask("default", ["myTask:version1", "minify:version1"])

You could do all of this with the uglifyjs grunt task.
Here's an example of the config for your Gruntfile:
grunt.initConfig({
uglify: {
app1: {
files: {
'dist/app1.min.js': [
'src/app1.js',
'src/common.js'
]
}
},
app2: {
files: {
'dist/app2.min.js': [
'src/app2.js',
'src/common.js'
]
}
}
}
});

Related

Trigger grunt task after browserify/watchify run

I'm trying to build my JS-bundle via grunt/browserify. I also use grunt for scss compile. For that I use grunt-watch to trigger scss compile on changes.
I wanted the same behavior for JS-browserify. grunt-browserify comes with the "watch" option, which does the trick very well.
My only issue is: I want to get notified after a "re-browserify". For SCSS I use grunt-notify. But I do not find any way to trigger a grunt task after browserify-watch.
My gruntfile excerpt:
var gruntOptions = {
notify: {
browserify_node_modules: {
options: {
title: "Browserify",
message: "node_modules build"
}
}
},
browserify: {
node_modules: {
src: ["node_modules.js"],
dest: "trunk/js/lib/node_modules.js",
options: {
watch: true,
}
}
}
};
Best case scenario:
options: {
watch: true,
finishTask: "notify:browserify_node_modules"
}
Thanks!
You can check if the file generated by Browserify has been changed and then, trigger a task.
Install watch task in Grunt:
npm install grunt-contrib-watch --save-dev
Configure watch task within Gruntfile.js:
grunt.initConfig({
// other tasks
your_task: {
// ...
},
watch: {
dev: {
files: 'trunk/js/lib/node_modules.js', // file generated by Browserify
options: { spawn: false },
tasks: ['your_task']
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');

gulp-jshint package: How to send parameters (without .jshintrc file)?

I'm currently trying to migrate a grunt project to a gulp project. Actually, in the gruntfile I have (for the jshint task) something like this:
jshint: {
options: {
trailing:true,
evil:false,
indent:4,
undef:true,
unused:true,
node:false,
browser:false,
loopfunc:true,
devel:false
},
default: {
options: {
browser:true,
globals: {
define:true
}
},
src: [basePath + "js/**/*.js"]
}
}
So, when I write "grunt jshint" in the terminal it seems to work fine. However, in the gulpfile I wrote this:
gulp.task("jshint", function() {
return gulp.src( basePath + "js/**/*.js" )
.pipe( jshint( { "trailing": true,..., "globals": true } ) )
.pipe( jshint.reporter("default") );
});
But when I write "gulp jshint" in terminal, it crashes.
My question is: Is there a way to send jshint parameters without .jshintrc file with the gulp-jshint node package? (I've already read the documentation in the npm site, but I dont undestand the "lookup" option)
globals is an array, not true false, here is my example. lookup works just like you were thinking.
gulp.src(files.backend)
.pipe(jshint({ "lookup": false, /* other options */ "globals": ['$']}))
.pipe(jshint.reporter(stylish))
.on('error', gutil.log);

Using grunt as a service

I am trying to build custom themes for my users. They do so by changing some less variables. I then store these to do and grunt there theme into a css which is then uploaded to server.
My problem is with the less grunting. Here is my code:
Gruntfile.js
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-less');
};
In nodejs
module.exports.test = function(req,res){
grunt.initConfig({
globalConfig: {
id: req.insertId
},
less: {
default: {
options: {
modifyVars: req.body.less
},
'files': {
"/tmp/theme<%= globalConfig.id %>.css": "templates/app.less"
}
}
}
});
grunt.tasks(['less']);
});
The problem is that in my console
Running "less:default" (less) task File /tmp/theme26.css created: 0 B
→ 9.22 kB
Done, without errors.
worker undefined died. spawning a new process...
Why does grunt kill my process? How can I prevent this?

Assemble: How can I generate pages from json/yaml?

Is there a way to generate pages from json/yaml if you provide a layout? I thought this was possible, but can't find in docs.
This is currently being tracked here in GitHub: http://webb.li/QjTX
Since the options.pages feature has been implemented, you can add pages like this:
options: {
pages: {
"about": {
"data": {
"title": "About"
},
"content": "Content for {{title}}"
},
...
}
}
We aren't supporting automatic loading of a json/yml file, but you can do this inside your Gruntfile and add the object to options.pages that way...
module.exports = function(grunt) {
grunt.initConfig({
// package.json
pkg: grunt.file.readJSON('package.json'),
assemble: {
options: {
flatten: true,
layoutdir: 'src/layouts',
assets: 'dest/assets'
},
blog: {
options: {
engine: 'handlebars',
layout: 'post.hbs',
site: {
title: 'This is my Blog'
},
pages: grunt.file.readJSON('pages.json')
},
files: { 'dest/': ['src/index.hbs'] }
}
}
});
// Load npm plugins to provide necessary tasks.
grunt.loadNpmTasks('assemble');
// Default task.
grunt.registerTask('default', ['assemble']);
};
This example uses the post.hbs file as the layout for any pages defined in the pages.json file. It will also build a page for the index.hbs specified in the files src array. Right now, the files dest/src is required so Assemble knows where to write the files, but I think we'll add that to the options, or the page object so it can be run without the files object.

grunt.js - Multiple destinations when minifying files

My grunt.js has a typical minification task:
min: {
dist: {
src: ['dist/precook.js'],
dest: 'dist/precook.min.js'
}
}
What is the simplest way to have multiple dest files? I'd like to minify into:
dist/precook.min.js
example/js/vendor/precook.min.js
The built-in min task doesn't appear to support multiple destinations, so I assume this can be achieved via a simple "copy" task. Can someone please point me in the right direction?
I'd use grunt-contrib-copy plugin:
Install with npm:
npm install grunt-contrib-copy
Modify grunt.js (add copy task definition and load copy plugin):
...
copy: {
dist: {
files: {
'example/js/vendor/': 'dist/precook.min.js'
}
}
}
...
grunt.loadNpmTasks('grunt-contrib-copy');
Optionally register copy in to grunt's default task.
The added beauty here is that you can now perform all other copy tasks as well. Even patterns are supported, like copy all minified files ('dist/*.min.js').
concat: {
css: {
src: ['UI.controls/assets/css/*.css'],
dest: 'UI.controls/assets/css/min/production.css'
},
js: {
src: ['UI.controls/assets/js/*.js'],
dest: 'UI.controls/assets/js/min/production.js'
},
js2: {
src: ['UI.core/assets/js/*.js'],
dest: 'UI.core/assets/js/min/production.js'
}
},
cssmin: {
css: {
src: 'UI.controls/assets/css/min/production.css',
dest: 'UI.controls/assets/css/min/production.min.css'
}
},
uglify: {
js: {
src: 'UI.controls/assets/js/min/production.js',
dest: 'UI.controls/assets/js/min/production.min.js'
},
js2: {
src: 'UI.core/assets/js/min/production.js',
dest: 'UI.core/assets/js/min/production.min.js'
}
},
watch: {
css: {
files: ['UI.controls/assets/css/*.css'],
tasks: ['concat:css', 'cssmin:css']
},
js: {
files: ['UI.controls/assets/js/*.js'],
tasks: ['concat:js', 'uglify:js']
},
js2: {
files: ['UI.core/assets/js/*.js'],
tasks: ['concat:js', 'uglify:js']
}
}
This is an alternative approach (next to #jalonen's solution) which may to interesting to you, IF you are using requirejs to modularize your project, then you can use the requirejs optimizer to minify your modules.
First of all, you need to add grunt-contrib-requirejs to your project:
npm install grunt-contrib-requirejs --save-dev
Grunt configuration:
requirejs: {
production:{
options:{
// don't include libaries when concatenating/minifying
paths:{
angular:'empty:',
jquery:'empty:'
},
baseUrl:'path/to/src/js',
dir:'path/to/target/js',
// keeps only the combined files
removeCombined:true,
modules:[
{name:'app', exclude: ['moduleA', 'moduleB']},
{name:'moduleA'},
{name:'moduleB'}
]
}
}
}
...
grunt.loadNpmTasks('grunt-contrib-copy');
Explanation:
Let's say you have this dependency tree (-> means depends on):
app -> moduleA -> moduleA1
-> moduleA2
app -> moduleB -> moduleB1
-> moduleB2
After minifying you will have three files:
app (minified version of app)
moduleA (minified version of moduleA, moduleA1, and moduleA2)
moduleB (minified version of moduleB, moduleB1, and moduleB2)
Had a similar problem and created a grunt multi-task that runs a list of specified tasks on multiple directories
Usage for the exact case:
```
min: {
dist: {
src: ['dist/precook.js'],
dest: 'dist/precook.min.js'
}
},
multidest: {
minifiedFiles: {
tasks: ['min'],
dest: [
'dist/precook.min.js',
'example/js/vendor/precook.min.js'
]
}
}
```

Categories

Resources