Configure vscode task to copy a file after parcel watch - javascript

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",

Related

Why won't my breakpoints get hit in Visual Studio Code

I'm trying the get the Visual Studio Code debugger working in my angular/typescript application but it's not working.
Here's what I have:
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug node",
"port": 9229,
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"localRoot": "${workspaceFolder}\\.dist",
"remoteRoot": "/usr/src/api/.dist",
"type": "node"
}
]
}
scripts/local-entry-point.sh
#!/usr/bin/env sh
set -e
echo "STARTING local-entry-point.sh"
FOLDER=/tmp/.dist
if [ ! -d "$FOLDER" ]; then
mkdir /tmp/.dist
fi
false | cp -ir ${FOLDER} /usr/src/api/ 2>/dev/null
rm -rf ${FOLDER}
cd scripts
npm run watch
scripts/package.json
{
"private": true,
"devDependencies": {
"#effect-ts/core": "^0.11.1"
},
"scripts": {
"watch": "nodemon --watch '/usr/src/api/.dist/**/*' -e ts,json,js -x npm run debug",
"debug": "node --inspect=0.0.0.0:9229 /usr/src/api/.dist/start.js"
}
}
docker-compose.yml
...
ports:
- 4002:8800
- 9229:9229
...
I put breakpoints in both my Typescript and the compiled Javascript in the .dist folder (on the corresponding line):
I start my application (npm run docker), start the debugger in vscode, go through the steps to run the code, but the breakpoints don't get hit.
Seems like you are using Typescript. AFAIK VSCode debugger needs a sourcemap to put breakpoints on ts projects. I think this doc might help https://code.visualstudio.com/docs/typescript/typescript-debugging

run node js scripts from gulp task

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
});

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