Using grunt, how do I run three blocking tasks concurrently? - node.js

I have succesfully combined grunt-contrib-watch with grunt-nodemon using grunt-concurrent to allow me to autostart my node.js instance whenever I edit and transpile my coffeescript files.
Here is the grunt-concurrent portion of the gruntfile that I use to achieve this:
gruntfile.coffee
concurrent:
dev:
tasks: [
'watch'
'nodemon'
]
options:
logConcurrentOutput: true
The watch and nodemon tasks are configured in the same file but have been removed for brevity. This work fine.
Now I want to add a grunt-node-inspector to the list of concurrent tasks. Like so:
concurrent:
dev:
tasks: [
'watch'
'nodemon'
'node-inspector'
]
options:
logConcurrentOutput: true
According to the grunt-nodemon help file at least, this should be possible as it is given as an example usage: Running Nodemon Concurrently
However this does not work for me. Instead only the first two tasks are started.
Experiments show that grunt-concurrent appears to be limited to running only two tasks concurrently. Any subsequent tasks are ignored. I have tried various options, for example:
concurrent:
dev1:[
'watch'
'nodemon'
]
dev2:[
'node-inspector'
]
options:
logConcurrentOutput: true
grunt.registerTask 'default', ['concurrent:dev1', 'concurrent:dev2']
I also have tried setting the limit option to 3. I had high hopes for this so maybe I have misunderstood how to apply the value correctly:
concurrent:
dev:
limit: 3
tasks: [
'watch'
'nodemon'
'node-inspector'
]
options:
logConcurrentOutput: true
But I cannot get my third blocking task to run.
Question
How can I get all three blocking tasks running at the same time?
Thanks.

Put the limit value in the option, like so:
concurrent: {
tasks: ['nodemon', 'watch', 'node-inspector'],
options: {
limit: 5,
logConcurrentOutput: true
}
}

I've been using grunt.util.spawn to run my tasks and include the 1 blocking call at the end.
http://gruntjs.com/api/grunt.util#grunt.util.spawn
http://nodejs.org/api/process.html#process_signal_events
This block kills the children.
var children = [];
process.on('SIGINT', function(){
children.forEach(function(child) {
console.log('killing child!');
child.kill('SIGINT');
});
});
module.exports = function (grunt) {
'use strict';
...
Then I register a task
grunt.registerTask('blocked', 'blocking calls', function() {
var path = require('path')
var bootstrapDir = path.resolve(process.cwd()) + '/bootstrap';
var curDir = path.resolve(process.cwd());
children.push(
grunt.util.spawn( {
cmd: 'grunt',
args: ['watch'],
opts: {
cwd: bootstrapDir,
stdio: 'inherit',
}
})
);
children.push(
grunt.util.spawn( {
cmd: 'grunt',
args: ['nodemon'],
opts: {
cwd: curDir,
stdio: 'inherit',
}
})
);
children.push(
grunt.util.spawn( {
cmd: 'grunt',
args: ['node-inspector'],
opts: {
cwd: curDir,
stdio: 'inherit',
}
})
);
grunt.task.run('watch');
});
In your case, you can change the current working dir to the gruntfile.js and run multiple instances.

Related

Re-run Jest when jest.config changes

I am working with a jests.config.js file:
// jest.config.js
module.exports = {
verbose: true,
setupFiles: ["./helpers/setup/environment.js"],
testMatch: ["**/__tests__/v2/tests.cloud.js"],
globals: {
_: true,
},
watchPathIgnorePatterns: ["./src/dataset", "./logs"],
};
I run Jest with watch:
jest --watch
In order to develop each test on its own I change the test file on testMatch every time I move on to the next test I am writing. Is there a way for the watch to reload the Jest config itself when the configuration file changes?
There are plenty other options
CLI [TestPathPattern]
if you run jest --help you'll see you can pass TestPathPattern to match test files
$ jest --help
Usage: jest.js [--config=<pathToConfigFile>] [TestPathPattern]
--onlyChanged, -o
Jest will attempt to run only tests related to the changed (in the current repository) files.
watch mode (p)
While in --watch mode you can press P and enter regex to select which file to run
Ended up writing a short NodeJS script:
const fs = require("fs");
const { spawn } = require("child_process");
const filename = "../jest.config.js";
let jest;
const run = () => {
if (jest) {
jest.kill();
}
jest = spawn("jest", ["--watch"], { stdio: "inherit" });
};
run();
fs.watch(filename, run);
process.on("SIGINT", function() {
console.log("Caught interrupt signal");
process.exit();
});

gulp build with browser sync and react not reloading page

I have a gulpfile with the following build task:
var gulp = require('gulp'),
source = require('vinyl-source-stream'),
buffer = require('vinyl-buffer'),
babelify = require('babelify'),
browserify = require('browserify'),
uglify = require('gulp-uglify'),
sourcemaps = require('gulp-sourcemaps'),
bs = require('browser-sync').create('BrowserSync');
gulp.task('build', function () {
return browserify({entries: './src/app.js', debug: true})
.transform("babelify", { presets: ['es2015','react'] })
.bundle()
.pipe(source('app.js'))
.pipe(buffer())
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(sourcemaps.write('./maps'))
.pipe(gulp.dest('./dist/js'))
.pipe(bs.reload({stream: true}));
});
The process builds my files perfectly, however my browser does not load. Why doesn't my browser reload? And how do I achieve the desired behavior? I feel like I am missing something about BrowserSync.
NOTE: I am fairly confident BrowserSync is working properly as I call bs.reload() in another task, and the page reloads perfectly. Happy to paste in more code however if needed.
Here is a snippet from a starter project that I started a while back that does what you are mentioning...
/*...*/
gulp.task('watchify', () => {
let args = merge(watchify.args, { debug: true })
let bundler = watchify(browserify('./src/js/app.js', args)).transform(babelify, { presets: ["es2015", "react"] })
bundle(bundler)
bundler.on('update', () => {
bundle(bundler)
})
})
function bundle(bundler) {
return bundler.bundle()
.on('error', map_error)
.pipe(source('app.js'))
.pipe(buffer())
.pipe(rename('app.min.js'))
.pipe(sourcemaps.init({ loadMaps: true }))
// capture sourcemaps from transforms
.pipe(uglify())
.pipe(sourcemaps.write('./maps'))
.pipe(gulp.dest('./dist/js'))
.pipe(sync.reload({
stream: true
}))
}
/*...*/
// watching multiple files with a task 'watch'
gulp.task('default', () => {
gulp.watch('src/js/**/*.js', ['watchify']);
});
The gulp task that started browsersync was run by gulp as it was triggered in the default task.
Then I ran gulp build manually from the terminal, and here was the issue. This manual command thus did not have access to the instance of browsersync that was created by the default gulp process.
So having gulp build run automatically with the instantiated version available did the trick.

unable to run a grunt command

I am using this in gruntfile.js.
module.exports = function(grunt){
grunt.initConfig({
pkg: grunt.file.readJSON('package.json')
sass: {
options: {
sourceMap: true
},
dist: {
files: {
'css': 'scss/*.scss'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass'); // Load tasks
grunt.registerTask('default', ['sass']); // Register Task as Default
}
But it is giving me an error when I run this command
Task "sass" not found
Please tell me where am i doing it wrong.
I think you are missing task registration in the beginning of gruntfile
require('load-grunt-tasks')(grunt);
The documentation for using grunt-sass can be found at https://github.com/sindresorhus/grunt-sass/blob/master/readme.md

Gulp imagemin not working for SVG images

Hi i have a little bit of a problem in my Gulp configuration for images, my gulp task is supposed to minify all images in the resources folder and then place the minified version in the public directory, however only the PNG images are being exported correctly...
gulp.task('images', function() {
gulp.src(assets + 'images/**')
.pipe(imagemin({
progressive: true,
optimizationLevel: 7,
svgoPlugins: [{removeViewBox: false}],
use: [pngquant()]
}))
.pipe(gulp.dest(public + 'images/'));
});
That is the task that i'm running, i am currently using imagemin version ^2.4.0
Got the same issue, here is my config:
let developmentAssets = "src",
productionAssets = "dist";
module.exports = {
optimize : {
images: {
src: developmentAssets + '/img/**/*.{jpg,jpeg,png,gif,svg}',
options: {
optimizationLevel: 3,
progessive: true,
interlaced: true
}
}
}
};
and then in your task
/*
This is my particular setting to have everything organized
read this amazing gulp tutorial: http://stefanimhoff.de/2014/gulp-tutorial-12-optimize-css-javascript-images-and-html/
*/
config = require('./gulp/config'),
configImg = config.optimize.images,
.pipe(imagemin(configImg.options))
Hope that it helps.

Gulp doesn't notice my file changes

I'm working on a project with a few others. While they get Gulp to work, it doesn't seem to work on my computer, even through our code is identical.
When I write the 'gulp' command, I get this:
[10:51:17] Starting 'browserify'...
[10:51:19] Finished 'browserify' after 2.37 s
[10:51:19] Starting 'default'...
[10:51:19] Finished 'default' after 17 μs
But when I save the changes in the files Gulp is suppose to be watching, the 'update' event doesnt seem to be triggered.
Here is the Gulp file
var gulp = require("gulp"),
jest = require("gulp-jest"),
source = require('vinyl-source-stream'),
browserify = require('browserify'),
watchify = require('watchify'),
reactify = require('reactify');
require("harmonize")();
var paths = {
scripts: "src/**/*.js",
tests: "__tests__"
};
gulp.task("jest", function () {
return gulp.src(paths.tests).pipe(jest({
scriptPreprocessor: "preprocessor.js",
unmockedModulePathPatterns: [
"../node_modules/react"
],
testPathIgnorePatterns: [
"node_modules",
"spec/support"
],
moduleFileExtensions: [
"js",
"json",
"react"
]
}));
});
gulp.task('browserify', function() {
var bundler = browserify({
entries: ['./src/js/TopLevel.js'],
transform: [reactify],
debug: true,
cache: {}, packageCache: {}, fullPaths: true
});
var watcher = watchify(bundler);
return watcher
.on('update', function () { // When any files update
var updateStart = Date.now();
console.log('Updating!');
watcher.bundle() // Create new bundle that uses the cache for high performance
.pipe(source('main.js'))
.pipe(gulp.dest('./public/assets/js'));
console.log('Updated!', (Date.now() - updateStart) + 'ms');
})
.bundle() // Create the initial bundle when starting the task
.pipe(source('main.js'))
.pipe(gulp.dest('./public/assets/js'));
});
gulp.task("watch", function() {
gulp.watch("src/**/*.js", ["jest"]);
gulp.watch("__tests__/*.js", ["jest"]);
});
gulp.task("default", ["browserify"]);
However, I don't think there is anything wrong with the code, as it works for my other team members.
Any help and comments are highly appreciated!
Try this:
gulp.task("watch", function() {
gulp.watch("./src/**/*.js", ["jest"]);
gulp.watch("./__tests__/*.js", ["jest"]);
});
If you are only running gulp in the command line the watch task will not trigger since the default task is only running browserify, just change your default task to this.
gulp.task("default", ["browserify", "watch"]);

Resources