Specify one normal task and one watching task with Grunt Browserify - gruntjs

I use Watchify (via grunt-browserify) for fast compilation during local dev:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
browserify: {
app: {
src: './src/app.js',
dest: 'build/js/app.js'
},
options: {
// next two lines for watchify + watch instead of browserify
watch: true,
keepAlive: true,
transform: ['node-lessify', 'node-underscorify'],
debug: true,
browserifyOptions: {
debug:true // include source maps. currently only available with browserify
}
}
}
}
grunt.loadNpmTasks('grunt-browserify');
Running grunt browserify enters a while true loop that continuously watches for changes. When it comes to build a production-ready bundle, I want it to run through once and not watch.
I have tried this configuration but the browserify:dev task never watches:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
browserify: {
dev: {
src: './src/app.js',
dest: 'build/js/app.js',
// next two lines for watchify + watch instead of browserify
watch: true,
keepAlive: true
},
package: {
src: './src/app.js',
dest: 'build/js/app.js'
},
options: {
transform: ['node-lessify', 'node-underscorify'],
browserifyOptions: {
debug:true // include source maps. currently only available with browserify
}
}
}
});
How can I specify one Browserify task that watches with Watchify, and one task that builds the whole package and exits?

I had my configuration wrong. Note that keepAlive: false is in the options namespace of the browserify:package job:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
browserify: {
dev: {
src: './src/app.js',
dest: 'build/js/app.js'
},
package: {
src: './src/app.js',
dest: 'build/js/app.js',
options: {
keepAlive: false
}
},
options: {
watch: true,
keepAlive: true,
transform: ['node-lessify', 'node-underscorify'],
browserifyOptions: {
debug:true // include source maps. currently only available with browserify
}
}
}
});

Related

How to use array variable properly in gruntfile.js

Trying to use a predefined array inside of a grunt file, thought using this.js_paths would work, but doesn't seem to work as I'm getting the error, "Cannot read property IndexOf of undefined" when it comes to trying to uglify the scripts. How can I link the js_paths variable to the files src property properly instead of copying the array into the files. Would like to define it separately at the top. Is this possible?
module.exports = function(grunt) {
// loadNpmTasks from package.json file for all devDependencies that start with grunt-
require("matchdep").filterDev("grunt-*", './package.json').forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
js_paths: [
'inc/header1/js/*.js',
'!inc/header1/js/*.min.js',
'inc/header2/js/*.js',
'inc/header2/js/*.js',
'!inc/header2/js/*.min.js',
'js/*.js',
'!js/*.min.js'
],
uglify: {
options: {
mangle: true
},
build: {
files: [{
expand: true,
src: this.js_paths,
rename: function(dst, src) {
return src.replace('.js', '.min.js');
}
}]
}
},
watch: {
scripts: {
files: ['inc/header1/js/*.js', 'inc/header2/js/*.js', 'js/*.js'],
tasks: ['uglify'],
options: {
spawn: false,
}
}
}
});
grunt.registerTask('default', ['uglify', 'watch']);
};
Preferrably would like to use the same array js_paths in the watch files (since it's required there), if that makes sense? Still kinda new to using gruntfile.js
Utilize the Templates syntax. It's described in the docs as following:
Templates
Templates specified using <% %> delimiters will be automatically expanded when tasks read them from the config. Templates are expanded recursively until no more remain.
Essentially, change this.js_paths to '<%= js_paths %>' in your uglify task.
For instance:
// ...
uglify: {
options: {
mangle: true
},
build: {
files: [{
expand: true,
src: '<%= js_paths %>', // <-----
rename: function(dst, src) {
return src.replace('.js', '.min.js');
}
}]
}
},
// ...
Likewise for your watch task too.
For instance:
watch: {
scripts: {
files: '<%= js_paths %>', // <-----
tasks: ['uglify'],
options: {
spawn: false,
}
}
}

Create two configurations for a grunt plug-in that is not multi-taskable

I use a grunt package called grunt-preprocess, Obviously, it doesn't support multi-tasks.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
preprocess: {
options: {
context: {
ENV: grunt.option('env') || 'prod'
},
},
all_from_dir: {
src: '*.*',
cwd: 'src/',
dest: 'src',
expand: true
}
},
})
Now I want to execute preprocess twice, once from the src directory, and once from the dist directory. How should I configure this package to achieve that?
I have tried this configuration;
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
preprocess: {
first: {
options: {
context: {
ENV: grunt.option('env') || 'prod'
},
},
all_from_dir: {
src: '*.*',
cwd: 'src/',
dest: 'src',
expand: true
}
},
second: {
options: {
context: {
ENV: grunt.option('env') || 'prod'
},
},
all_from_dir: {
src: '*.*',
cwd: 'dist/',
dest: 'dist',
expand: true
}
}
}
})
and then execute grunt preprocess:first. However it does not work:
PS D:\workspace\environment-compile> grunt preprocess:first
Running "preprocess:first" (preprocess) task
Done.
Yes, you're right preprocess is single Task only, therefore doesn't allow multiple targets to be defined.
You'll need to create another custom task that dynamically configures the preprocess Task and then runs it.
For example:
Gruntfile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-preprocess');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
preprocess: {
options: {
context: {
ENV: grunt.option('env') || 'prod'
},
},
all_from_dir: {
src: '*.*',
cwd: 'src/',
dest: 'src',
expand: true
}
},
// ...
});
// Custom task dynamically configures the `preprocess` Task and runs it.
grunt.registerTask('preprocess_dist', function() {
grunt.config.set('preprocess.all_from_dir.cwd', 'dist/');
grunt.config.set('preprocess.all_from_dir.dest', 'dist');
grunt.task.run(['preprocess']);
});
grunt.registerTask('preprocessBoth', [ 'preprocess', 'preprocess_dist' ]);
};
Running:
Via your CLI run the following single command to execute the preprocess task twice, once from the src directory, once from the dist directory:
grunt preprocessBoth
Explanation:
The custom Task named preprocess_dist dynamically configures the values for the cwd and dest properties, setting them to 'dist/' and 'dist' respectively. This is done via the grunt.config.set method
Then the task is run via the grunt.task.run method.
The last line of code that reads:
grunt.registerTask('preprocessBoth', [ 'preprocess', 'preprocess_dist' ]);
creates a task named preprocessBoth and adds the following two tasks to to the taskList:
preprocess
preprocess_dist
Essentially what happens when you run grunt preprocessBoth is:
The preprocess task runs using files from the src directory.
Then the custom preprocess_dist task runs using files from the dist directory.
If you prefer, you can also run each task independently via CLI, i.e:
grunt preprocess
and
grunt preprocess_dist

How to run two different Grunt task in one command?

I am using 'cssmin' and 'sass' grunt task separately, Is it possible to run them one after other automatically, when I can anything in my file.
cssmin: {
target: {
files: [{
cwd: srcCss,
src: ['**/*.css', '*.css'],
dest: buildCss
}]
}
},
sass: {
target: {
files: [{
cwd: srcScss,
src: ['**/*.scss', '*.scss'],
dest: srcCss
}]
}
}
This can be done easily: You need to use watch plugin,
npm install grunt-contrib-watch
grunt.loadNpmTasks('grunt-contrib-watch');
3.
grunt.initConfig({
watch: {
scripts: {
files: ['lib/*.js'],
tasks: ['jshint'],
options: {
spawn: false,
},
},
},
jshint: {
all: {
src: ['lib/*.js'],
},
},
});
// Default task(s).
grunt.registerTask('default', 'watch');
Now Just run grunt in cmd.

Grunt Watch LiveReload on site on server

I am developing a WordPress site on a server (not local). I want to refresh the page in my browser whenever I modify a sass file. I've got some grunt tasks listed, but right now I just want it to refresh on any sass modification. Right now, it catches whenever a file is modified, but it does not refresh the page.
Gruntfile:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
scripts: {
options: { livereload: true },
files: ['**/*.scss'],
//tasks: ['criticalcss:front', 'criticalcss:page', 'cssmin', 'postcss'],
}
},
postcss: {
options: {
processors: [
require('autoprefixer')({browsers: 'last 6 versions'}), // add vendor prefixes
//require('cssnano')() // minify the result
]
},
dist: {
src: 'style.css',
dest: 'style.css'
}
},
criticalcss: {
front : {
options: {
url: "https://grandeurflooring.ca/grand_dev/",
minify: true,
width: 1500,
height: 900,
outputfile: "critical_css/critical-front.css",
filename: "style.css",
buffer: 800*1024,
ignoreConsole: true
}
},
page : {
options: {
url: "https://grandeurflooring.ca/grand_dev/sample-page/",
minify: true,
width: 1500,
height: 900,
outputfile: "critical_css/critical-page.css",
filename: "style.css",
buffer: 800*1024,
ignoreConsole: true
}
}
},
cssmin: {
target: {
files: [{
expand: true,
cwd: 'critical_css',
src: ['*.css', '!*.min.css'],
dest: 'critical_css',
ext: '.min.css'
}]
}
}
});
// Load the plugin that provides the "critical" task.
grunt.loadNpmTasks('grunt-criticalcss');
// Load the plugin that provides the "cssmin" task.
grunt.loadNpmTasks('grunt-contrib-cssmin');
// Load the plugin that provides the "watch" task.
grunt.loadNpmTasks('grunt-contrib-watch');
// Load the plugin that provides the "PostCSS" task.
grunt.loadNpmTasks('grunt-postcss');
// Critical task.
grunt.registerTask('critical', ['criticalcss:front']);
};
In footer.php, before wp_footer(), I put the script:
<script src="http://localhost:35729/livereload.js"></script>
You can configure Grunt to watch the compiled css file in your dist directory, which would be updated every time the Sass is recompiled.
Here is my watch configuration which is achieving what you want:
watch: {
options: {
livereload: true,
},
html: {
files: ['index.html'],
},
js: {
files: ['js/**/*.js'],
tasks: ['jshint'],
},
sass: {
options: {
livereload: false
},
files: ['css/scss/**/*.scss'],
tasks: ['sass'],
},
css: {
files: ['dist/css/master.css'],
tasks: []
}
}
You might need to change spawn: false to spawn: true depending on your setup as well.
EDIT: Additionally, you can use the grunt-contrib-watch plugin which allows you to:
Run predefined tasks whenever watched file patterns are added, changed or deleted
This plugin contains numerous additional options for live-reloading, watching, etc. which you may find useful.

Get Grunt to upload files after watch is triggered

I am working on a site that uses SCSS. We have grunt watching those files to convert them to css but each time we make a change we have to tab over to the css file and upload. Maybe not a big deal but over time on different projects it adds up.
I would like the watch process to run ftpush once it see's a change but the only times I've got it to work it stays on ftpush which means we have to exit grunt then run it again. It would be helpful if after the upload os complete(or a specific time passes) it resumes the watch task.
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
options: {
loadPath: ['bower_components/foundation/scss'],
sourceMap: true
},
dist: {
options: {
style: 'expanded'
},
files: {
'assets/css/app.css': 'assets/scss/app.scss'
}
}
},
ftpush: {
build: {
auth: {
host: 'OUR HOST',
port: 21,
authKey: 'key1'
},
src: '../vhc-master',
dest: '/var/www/html/vhc/dev/wp-content-themes/vhc-master'
}
},
watch: {
scripts: {
files: ['Gruntfile.js'],
tasks: ['ftpush'],
options: {
interrupt: true,
reload: true
}
},
sass: {
files: 'assets/scss/*.scss',
tasks: ['sass']
}
}
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-ftpush');
grunt.registerTask('build', ['sass']);
grunt.registerTask('deploy', ['ftpush']);
grunt.registerTask('default', ['build','watch']);
}

Resources