run node js scripts from gulp task - javascript

I have many js scripts in one folder (scripts/*.js).
How to execute them all from the gulp task (instead of using 'node script.js' many times)?
something like
gulp.task('exec_all_scripts', function () {
gulp.src(path.join(__dirname, './scripts/*.js'))
})

Gulp is a task runner, meaning it's meant to automate sequences of commands; not run entire scripts. Instead, you can use NPM for that. I don't think there's a way to glob scripts and run them all at once, but you can set each file as its own npm script and use npm-run-all to run them:
{
"name": "sample",
"version": "0.0.1",
"scripts": {
"script:foo": "node foo.js",
"script:bar": "node bar.js",
"script:baz": "node baz.js",
"start": "npm-run-all --parallel script:*",
},
"dependencies": {
"npm-run-all": "^4.0.2"
}
}
Then you can use npm start to run all your scripts at once.
If you really need to use gulp to run the scripts, you can use the same strategy, and then use gulp-run to run the npm script with gulp.
var run = require('gulp-run');
// use gulp-run to start a pipeline
gulp.task('exec_all_scripts', function() {
return run('npm start').exec() // run "npm start".
.pipe(gulp.dest('output')); // writes results to output/echo.
})

you can export functions in your scripts/*.js and import them in gulpfile.js and call the functions in 'exec_all_scripts' task, it's easy

You could concatinate all of the scripts into a single script and then execute it from the same task, a different task, or using a different process. See the following NPM package: https://www.npmjs.com/package/gulp-concat
Here is an example:
var concat = require('gulp-concat'); // include package
gulp.task('exec_all_scripts', function() {
return gulp.src(path.join(__dirname, './scripts/*.js')
.pipe(concat('all_scripts.js'))
.pipe(gulp.dest('./dist/')); // assuming you had a dist folder but this could be anything
});

Related

Configure vscode task to copy a file after parcel watch

EDIT: I don't want to use grunt or gulp for this, and neither do I want to configure a parcel-bundler. I have used all of those before,
and I would like to try using vscode tasks for this.
I have a working parcel watch npm task to build my files into a dist folder. Due to some reasons I need to copy a file from the dist folder to another folder after every build. I have configured another npm task for that, called "copy".
I am now trying to configure a vscode task to run this "copy" task after every build from the watch task.
I have already configured a watch task for this, however, it only runs the "copy" task when I terminate the watch task with ctrl-c.
{
"version": "2.0.0",
"tasks": [
{
"label": "copy",
"type": "npm",
"script": "windows-build",
"path": "frontend/",
"problemMatcher": []
},
{
"label": "watch",
"type": "npm",
"script": "watch",
"path": "frontend/",
"isBackground": true,
"problemMatcher": {
"background": {
"activeOnStart": true,
"beginsPattern": "> parcel watch \\.\\/src\\/index\\.html --public-url \\/public\\/dist -d \\.\\.\\/public\\/dist",
"endsPattern": "√ Built in \\d+\\.\\d+s\\."
}
}
},
{
"label": "build",
"dependsOrder": "sequence",
"dependsOn":["watch","copy"]
}
]
}
I get this error message in the "output" tab
Error: the description can't be converted into a problem matcher:
{
"background": {
"activeOnStart": true,
"beginsPattern": "> parcel watch \\.\\/src\\/index\\.html --public-url \\/public\\/dist -d \\.\\.\\/public\\/dist",
"endsPattern": "√ Built in \\d+\\.\\d+s\\."
}
}
Not sure why. Thanks for any help in advance.
My guess is:
You have defined your watch and copy tasks as a sequence. So copy will only execute, if watch has finished. Problem is: parcel watch is an endless process, as it watches for file changes, until you abort it manually. So copy will never start until watch exits.
Solution : Drop "dependsOrder": "sequence" from your task, so VS Code executes both tasks in parallel. First task watch starts Parcel in watch mode. The second task copy (npm run windows-build) should start another watcher, which watches your dist folder and copys your specific files from dist to another folder. E.g. that could be nodemon:
"scripts": {
"windows-build":"nodemon --watch dist -x \"cp x y\""
}
Alternative: Use of buildEnd hook of the Parcel API
...would save you a watcher, if you wanna give it a try.
const bundler = new Bundler(...);
bundler.on('buildEnd', () => {
// start your copy task on each rebuild,
// e.g. with node childprocess spawn
});
// Call this to start bundling
bundler.bundle();
On my side i use concurrently
"start-nw": "npm run copy && concurrently --kill-others \"npm start\" \"npm run nw\"",
"start": "parcel src/index.html --no-autoinstall",
"nw": "nw ./dist --remote-debugging-port=9222",
"copy": "node tasks/copy.js -nwp plugins -d",

Bazel: How do i use nodeJS_binary rule to do "npm run start"

How do i use the nodejs_binary rule to do a standard npm run start. I am able to run a typical node project using this rule. However i want to run a the start script in package.json. So far i have the following below in my build file
load("#build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
nodejs_binary(
name = "app",
data = [":app_files"],
node="#nodejs//:bin/npm",
entry_point = "workspace_name/src/server.js",
node_modules = "#npm_deps//:node_modules",
args=["start"]
)
This does not start the server..somehow npm command is not running properly. it indicates usage of the command in incomplete.
I am currently able to do this within the WORKSPACE
bazel run #nodejs//:bin/yarn (runs yarn install and installs all node-modulse)
bazel run #nodejs//:bin/npm start (this starts the server)
In my package.json i have
{
"scripts": {
"start": "babel-node src/server.js",
...
}
...
}
I do i get this to work with nodejs_binary rule and subsequently node_image
I changed from using npm to using yarn..workspace_name/src/server.js.. is called now but Then i had different set of problems, babel-node was not found.
I modified the rule a bit. After careful study...I realise that there is a dependency on babel-node that is not satisfied at the time yarn run start is called. The following worked after i had run bazel run #nodejs//:bin/yarn before running the rule.
nodejs_binary(
name = "app",
args = ["start"],
data = [
":app_files",
"#//:node_modules",
],
entry_point = "workspace_name/src/server.js",
node = "#nodejs//:bin/yarn",
node_modules = "#npm_deps//:node_modules",
)
It appears that "#//:node_modules" solves the babel-node dependency issue. So the rule above does not work on its own...it needs me to do bazel run #nodejs//:bin/yarn (more like npm/yarn install to make the node_modules, which contain babel-node dependecy available when npm/yarn start is run)
So my problem is that I do not want to have to manually run bazel run #nodejs//:bin/yarn before executing my rule. how do i do this.
I suppose it would work if i stopped depending on babel-node...but then i would have to change my code to not use es6 syntax (that is a hustle). Is there a way i can do this with a genrule? or something...
What I ended up doing was that i made a babel nodejs_binary rule. Then used that to compile my source files in a gen rule
# Make babel binary
nodejs_binary(
name = "babel",
entry_point = "npm_deps/node_modules/babel-cli/bin/babel",
install_source_map_support = False,
node_modules = "#npm_deps//:node_modules",
)
# Compile source files with babel
genrule(
name = "compiled_src",
srcs = [
":src_files",
],
outs = ["src"],
cmd = "$(location babel) src --out-dir $#",
tools = [":babel"],
)
Note that in this case src in cmd = "$(location babel) src --out-dir $#" is a folder in the :src_files filegroup.
filegroup(
name = "src_files",
srcs = glob([
"src/**/*",
...
]),
)
After this it was unnecessary to use npm start, just used default node. I could just do
nodejs_binary(
name = "app",
data = [":compiled_src"],
entry_point = "workspace_name/src/server.js",
node_modules = "#npm_deps//:node_modules",
)

npm script pass parameters/arguments to node script using yargs

Is it possible to call out to retrieve a key from yargs when using as a npm script argument?
User types in the OSX terminal:
npm run scaffold --name=blah
which executes in package.json:
"scaffold" : "node ./scaffold/index.js -- "
This results in
const yargs = require('yargs').argv
if (yargs) {
console.log(yargs);
console.log(yargs.name);
process.exit(1)
}
...
result:
{ _: [], '$0': 'scaffold/index.js' }
undefined
This only works if I hard code in package.json "scaffold" : "node scaffold/index.js --name=blah", but I need this to be configurable.
As I stated I am using args, as it appears to make it easy to retrieve keys by name ( as opposed to an array ). Open to suggestions.
What am I missing?
update 11-07-2017
Related: Sending command line arguments to npm script
However, passing in the commandline 1: npm run scaffold name=hello
OR 2: npm run scaffold --name=hello yields:
1: { _: [], '$0': 'scaffold/index.js' }
2: { _: [ 'name=hello' ], '$0': 'scaffold/index.js' }
Still can't see a way to retrieve the yargs.name property. Still undefined.
Update 13-07-2017
For the time being, I have given up. It just seem impossible. I run the script manually in the terminal.
E.g.
node ./scaffold/index.js --name=blah
Image below shows executing of a node script directly as opposed to running through npm scripts. I have added https://www.npmjs.com/package/nopt node module to see if it helps ( it doesn't ). process.argv.name is still undefined when running through npm scripts.
Update 18-07-2017
Added github example: https://github.com/sidouglas/stackoverflow-node-arguments
Update 24-07-2017
Adding the variables before the start of the command works
myvar="hello npm run scaffold as opposed to npm run scaffold myvar="hello world"
As of npm#2.0.0, you can use custom arguments when executing scripts. The special option -- is used by getopt to delimit the end of the options. npm will pass all the arguments after the -- directly to your script:
npm run test -- --grep="pattern"
https://docs.npmjs.com/cli/run-script
I'm not sure that it matters where the variables are added on the command line, and if this is of no concern to you, then this works:
//package.json
{
"name": "npm-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {},
"devDependencies": {},
"scripts": {
"start": "node index.js"
},
"author": "",
"license": "ISC"
}
Your JS file:
//index.js
console.log('myvar', process.env.myvar);
And your command line command:
myvar="hello world" npm run start
So in the end, just prefix your npm script command with your argument list.
For me the following works on Node 10, 12, 14
npm run yourscript -- -- --name=bla
I do need to use -- --
and
"yourscript": "node bla.js"

Using wildcard to run multiple scripts for npm run test

I my package.json I have
"scripts": {
"test": "node tests/*-test.js"
}
And I have a-test.js and b-test.js in the tests folder, which I can verify by running ls tests/*-test.js.
However, npm run test is only executing a-test.js. How can I execute all *-test.js scripts? Explicitly listing them is not an option, since I will have more than 2 to run in the future.
You could use a task manager such as grunt or gulp, or a simple script that execute those scripts:
test.js:
require('./test/a-test.js')
require('./test/b-test.js')
package.json
"scripts": {
"test": "node test.js"
}
You could also use the include-all module for automating these for you https://www.npmjs.com/package/include-all
Example using includeAll:
const path = require('path');
const includeAll = require('include-all');
const controller = includeAll({
dirname: path.join(__dirname, 'test'),
filter: /(.+test)\.js$/,
});

How to start Gulp watch task when I type npm start

I have a gulp.js file that includes:
gulp.task('default', ['watch']);
Which starts up the watch task
gulp.task('watch', function(){
gulp.watch(productionScripts, ['autoConcat']);
});
Then on any saved changes to files in productionScripts, the watch task will concat the files.
What I would like to do, is in my package.json, I would like to spool up this watch when I type npm start (this already starts my node server).
package.json
"start": "node server.js",
UPDATE--------
Ben(b3nj4m.com), I tried what you stated. The watch and server start up. However, everything runs twice (probably due to the editor, not related), but I do lose my server log when I start it up with gulp.
[15:31:18] Starting 'autoConcat'...
[15:31:18] Finished 'autoConcat' after 147 ms
[15:31:19] Starting 'autoConcat'...
[15:31:19] Finished 'autoConcat' after 138 ms
[15:31:20] Starting 'autoConcat'...
[15:31:20] Finished 'autoConcat' after 127 ms
[15:31:23] Starting 'autoConcat'...
It's like there is a loop between the server restarting on a change, and the concatenated file changing.
You could run your server from your gulpfile:
var child = require('child_process');
var fs = require('fs');
gulp.task('default', ['server', 'watch']);
gulp.task('server', function() {
var server = child.spawn('node', ['server.js']);
var log = fs.createWriteStream('server.log', {flags: 'a'});
server.stdout.pipe(log);
server.stderr.pipe(log);
});
gulp.task('watch', function(){
gulp.watch(productionScripts, ['autoConcat']);
});
Then change your npm start definition to look like:
"scripts": {
"start": "gulp"
}
You could concatenate multiple tasks in your start in package.json using the package concurrently as such:
{
"start": "concurrent \"node server.js\" \"gulp\" "
}
And run npm start from your terminal. This would execute all statements within start.
For references: https://www.npmjs.com/package/concurrently
EDIT:
As pointed out by #Josh in the comments, the CLI name now matches the package name. Hence, you could write the script as:
{
"start": "concurrently \"node server.js\" \"gulp\" "
}
I have something like this in one of my projects. Note that it will background both processes - you can use ps to get the ID and stop it with kill <pid>.
"scripts": {
"start": "{ gulp watch & node server.js & }"
}
To disable logging, too:
"scripts": {
"start": "{ gulp watch --silent & node server.js & }"
}
One best practice to consider is to use nodemon and gulp-nodemon and then like the accepted answer, trigger the gulp script from npm with npm start. It's blazing fast and you get the node server restarted on file changes. For example:
gulpfile.js
var gulp = require('gulp');
var nodemon = require('gulp-nodemon');
...
var nodemonOptions = {
script: 'bin/www.js',
ext: 'js',
env: { 'NODE_ENV': 'development' },
verbose: false,
ignore: [],
watch: ['bin/*', 'routes/*', 'app.js']
};
gulp.task('start', function () {
nodemon(nodemonOptions)
.on('restart', function () {
console.log('restarted!')
});
});
package.json
{
...
"scripts": {
"start": "gulp start"
},
"devDependencies": {
"gulp": "^3.9.0",
"gulp-nodemon": "^2.0.4"
}
}

Categories

Resources