I'm wondering how I can output messages to the terminal when I run a gulp process and how I can set an environment to run tasks in specific ways.
I'm sure I've seen something like gulp scripts:dev before but don't know how to use, can anyone advice how I can do this?
How would you run the default task this way, gulp deafult:dev?
Is it possible to ask the user which environment they want to run the task for in the terminal when the execute the gulp command, if they don't specify it.
I've used the gulp-if plugin to achieve this but it works slightly differently, you need to set a node environment variable before running gulp i.e. NODE_ENV=dev gulp.
var gulp = require('gulp'),
sass = require('gulp-ruby-sass'),
gulpif = require('gulp-if'),
shell = require('gulp-shell');
var isDev = process.env.NODE_ENV === 'dev';
// gulp-shell task to output messages to terminal
gulp.task('info', shell.task([
'echo run in developer mode with this command: NODE_ENV=dev gulp'
]));
// Styles Task
// Uses gulp-if plugin to run task differently dependent on env.
gulp.task('styles', ['info'], function () { // eslint-disable-line strict
return sass('css/sass/*.scss', {
style: gulpif(!isDev,'compressed','expanded'),
cacheLocation: 'css/sass/.sass-cache',
sourcemap: isDev
})
[...code ommitted...]
});
gulp.task('default', ['h','styles']);
Also I've used gulp-shell above to output messages to the terminal, but it's pretty basic. Is there anyway I can do something similar with line breaks and colours with the message I output to the terminal.
Take a look at gulp-environments - you can set as many as you like but dev and prod are sufficient for most. You can define each in the gulpfile and set different events to occur from within each gulp script. So your styles script can contain a .pipe(dev(some dev only sourcemap code))and a .pipe(prod(some mini fixed build code)). You can run the script from git bash with an --env flag... gulp --env dev or gulp --env prod. And run two completely different build cycles from more or less the same script. You set your default gulp task to run all your page scripts and it will only execute the ones for each environment as it loops.
To output messages to the terminal you can require gulp-util node module.
Example code:
gulp.task('test', () => {
gutil.log(gutil.colors.yellow('=== Testing ==='));
});
Related
I have a simple JS file that runs parcel bundler:
const Bundler = require('parcel-bundler');
(async () => {
const bundler = new Bundler('./src/index.html', {}); // options omitted for simplicity
await bundler.bundle();
})();
I run it from CLI with:
node ./build.js
While bundler works fine and creates bundled files in the dist folder, the process never exits, but rather remains in the async loop.
I tried adding then callback or using return but none of it helped.
Using process.exit() would of course stop the process but would also limit me from chaining this command in the CI, which is the whole purpose.
What am I doing wrong?
You need to set watch: false in your options to let Parcel know it should not watch but just build it once.
The default option is watch: true, so whenever you change something in your files, Parcel will recognize the change and rebuild your application.
Background
I am having this gulp watch task to handle sass compilation:
import gulp from 'gulp';
import sass from 'gulp-sass';
import concat from 'gulp-concat';
gulp.task("compile-scss", () => {
return gulp.src("assets/scss/**/*.scss")
.pipe(sass({ outputStyle: 'compressed' })
.on("error", sass.logError))
.pipe(concat("style.css"))
.pipe(gulp.dest("dist/css"));
});
gulp.task("watch-scss", ['compile-scss'], () => {
gulp.watch("assets/scss/**/*.scss", ["compile-scss"]);
});
I am then running gulp watch-scss and the process correctly compiles my files and start watching for new changes.
The problem
When I want watching to stop I am pressing Ctrl+C in the terminal and everything looks ok.
But then I make a change in the .scss file and expect it not be handled by the gulp task (should be already stopped). Anyway this change gets handled by the watch task as it seems still running.
Looking at the terminal code you can see where I start gulp watch-scss, where I press Ctrl+C and where task continues executing on change.
Environment details
OS: OS X 10.11 (El Capitan)
gulp version: 3.9.1
node version: 6.2.2
babel-core version: 6.11.4
History
The problem could be related to Node itself. Going into that direction I tried several solutions like terminating the process from within gulp like so:
process.on('SIGINT', function() {
process.exit();
});
It didn't help.
Read lot of info on that topic, but nothing helped. Here are two related questions, which didn't help either:
Stop a gulp watch task?
Terminate gulp-watch task
I can provide more details if needed.
Close the terminal and the session will be terminated. Run gulp again and try if CTRL + C works.
In the root directory of a project, I'm trying to load Grunt tasks, and all the content of the file as well, from a remote Gruntfile.js, accessible through a network (web or internal network).
I've already tried several things (see below), first hosting the Gruntfile.js on a local Apache server for the tests.
Using the --gruntfile option
> /project/path> grunt --gruntfile=http://localhost/Gruntfile.js build
Reading "Gruntfile.js" Gruntfile...ERROR
Fatal error: Unable to find "/project/path/http://localhost/Gruntfile.js" Gruntfile.
Using the --base option
> /project/path> grunt --base=http://localhost/Gruntfile.js build
process.chdir(grunt.option('base') || path.dirname(gruntfile));
Error: ENOENT, no such file or directory
Creating a Gruntfile.js located at the root directory of my project, which contains only the following code :
module.exports = function (grunt) {
grunt.loadTasks( 'http://localhost/Gruntfile.js' );
};
The result was :
> /project/path> grunt build
>> Tasks directory "http://localhost/Gruntfile.js" not found.
Warning: Task "build" not found. Use --force to continue.
Aborted due to warnings.
Another try with the Gruntfile.js
module.exports = function (grunt) {
require( 'http://localhost/Gruntfile.js' )( grunt );
};
Gave me this :
> /project/path> grunt build
Loading "Gruntfile.js" tasks...ERROR
>> Error: Cannot find module 'http://localhost/Gruntfile.js'
Warning: Task "build" not found. Use --force to continue.
Aborted due to warnings.
Edit: It seems there is no way of loading tasks from a grunt file not located on the disk. I will find another solution.
I ran into the same problem and this is my solution. I hope it helps someone in the present/future:
Create a npm package to host the Gruntfile.js and upload it to a repository (I´am currently using Bitbucket) This is how my package.json looks like:
{
"name": "my-remote-gruntfile-package",
"private": true,
"version": "0.0.1"
}
Configure it in the package.json of your current project and install it using npm install or just run
npm install git+ssh://git#bitbucket.org:user/my-remote-gruntfile-package.git#0.0.1
Create a bash script (or windows bash equivalent) to cover the problem of changing Gruntfile.js location and setting current base path. This is to avoid passing --gruntfile and --base parameters on every execution (this step is not mandatory)
#!/bin/bash
grunt --base ./ --gruntfile ./node_modules/my-remote-gruntfile-package/GruntFile.js $1
Note: take care of relative paths used on your Gruntfile.js
Requiring a separate file should work, note that you shouldn't refer to it via localhost, but rather the location on disk, for example ./somedir/yourtask.js. Here's an example:
yourtask.js:
module.exports = {
// your task config goes here
};
Your Gruntfile.js:
module.exports = function(grunt) {
var externalFile = require('./somedir/yourtask.js');
grunt.initConfig({
// some random tasks go here
yourtask: externalFile
});
};
This should work but I'm not able to run it right now and you haven't posted what kind of info you have defined in your separate file. You can also have a function in there as well.
My WebStorm has stopped read and run gulp tasks.
It was working fine until last Friday.
This is an error that appears in console:
Failed to list gulp tasks in questionary/gulpfile.js: Failed to parse
JSON -> Unterminated array at line 1 column 5 path $[1] * Edit
settings
$ /usr/local/bin/node
/Users/rkon2006/Projects/My/questionary/node_modules/gulp/bin/gulp.js
--no-color --gulpfile /Users/rkon2006/Projects/My/questionary/gulpfile.js --tasks-json
[17:26:14] Using gulpfile ~/Projects/My/questionary/gulpfile.js
[17:26:14] Starting 'default'... Default task...
This is the code from my gulpfile.js (it doesn't start even with this code):
var gulp = require('gulp');
gulp.task('default', function () {
console.log('Default task...');
});
Process finished with exit code 0
I use gulp v4.0, node js 4.1.1 (tried defferent versions from 0.10.28 up to 4.1.1) and npm 2.14.4.
Do you have any ideas about this?
I have the same problem with webstorm after install a updated version of node.
The solution for me is the following:
In the block Gulp where webstorm show the list of task, click the cog icon and select gulp settings, in the section "Gulp package" add the path to the local gulp package(the gulp inside the node_modules in your project).
Example of path: yourproject\node_modules\gulp
Update node version and npm itself, that did the trick.
The problem is that some text is logged to standard output stream when evaluating gulpfile.js, but before running any gulp task (i.e. logging happens outside of gulp tasks);
possible workarounds:
Avoid logging anything to standard output stream outside of gulp
tasks.
Or
Don't log to standard output stream if it's started for listing
tasks, like:
if (!isListingTasks()) {
console.log('[my info]');
}
function isListingTasks() {
return process.argv[process.argv.length - 1] === '--tasks-json';
}
I was having same problem and it was fixed by selecting different Node Interpreter version e.g. in the below image I selected 8.9.2 and then clicked small refresh button in Gulp window and the issue was fixed.
Does someone used node-inspector with Grunt for application debugging? If not, Can you recommend a debugging tool for Grunt based apps?
I'm working with nodejs for a server side app and I have Grunt to use separated tasks (this is because users can execute tasks separately).
To run grunt in debug, you need to pass the grunt script to node explicitly:
node-debug $(which grunt) task
and put a debugger; line in your task. node-inspector will then open a browser with debugging tools.
Edit 28 Feb 2014
node-inspector has added the command node-debug, which launches node in a --debug state and opens the browser to the node-inspector page, stopping when it hits the first debugger line or set breakpoint.
Edit 30 January 2015
On Windows, things are a touch more complicated. See the answer from #e.gluhotorenko for instructions.
Windows solution
Run
node --debug-brk c:\Users\username\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt taskname
from cmd in the directory with your Gruntfile.js. Do not forget to put debugger; line in necessary places.
To debug, we have to modify the grunt file under bin. On my machine, grunt is installed globally, so I went to /usr/local/lib/node_modules/grunt/bin
I opened the file and modified:
#!/usr/bin/env node
To
#!/usr/bin/env node --debug-brk
--debug-brk will break on the first line of javascript ran.
Doing that alone isn't quite enough though, since you won't be able to find you're grunt task js file in the drop down in node inspector, so you have to modify the file you're interested in debugging by adding debugger; where you want the breakpoint to happen.
Now you can click continue after the first break, and you'll break on you're debugger; line
Pretty kludgy, but it's the only way I've found so far.
I recently created grunt-node-inspector to easily configure node-inspector with the rest of your grunt workflow, check it out: https://github.com/ChrisWren/grunt-node-inspector
Here is a section of a Gruntfile which illustrates how you can debug a grunt task using grunt-node-inspector, grunt-concurrent, and grunt-shell: https://github.com/CabinJS/Cabin/blob/master/Gruntfile.js#L44-L77
I have done a task to run my app and launch node-inspector.
It is far better than current proposition, you just have to add this task in gruntfile:
grunt.registerTask('debug', 'My debug task.', function() {
var done = this.async();
grunt.util.spawn({
cmd: 'node',
args: ['--debug', 'app.js'],
opts: {
//cwd: current workin directory
}
},
function (error, result, code) {
if (error) {
grunt.log.write (result);
grunt.fail.fatal(error);
}
done();
});
grunt.log.writeln ('node started');
grunt.util.spawn({
cmd: 'node-inspector',
args: ['&'],
opts: {
//cwd: current workin directory
}
},
function (error, result, code) {
if (error) {
grunt.log.write (result);
grunt.fail.fatal(error);
}
done();
});
grunt.log.writeln ('inspector started');
});
Great answers here. In 2017, now you can do
node --inspect --debug-brk $(which grunt) taskName
Which prints something like.
To start debugging, open the following URL in Chrome:
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/232652c3-f63c-4b00-8de9-17dfad5db471
Open that URL in chrome, and you're good to go!
I'm using Node 7.3.0 and I'm on Mac. You might have to follow some of the advice in other posts to get it going on Windows.
2019 update
If you want to launch the grunt task in debug mode and break at first line:
node --inspect-brk $(which grunt) taskName
If you want to launch the grunt task in debug mode at a specific port:
node --inspect-brk=8080 $(which grunt) taskName
if you want to attache VSCODE to the node process running the debugging session of grunt, use the following configuration in vscode:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach by port IP 5656",
"port": 8080
}
]
}