Run npm script on termination from console "CTRL+C" - npm-scripts

I want to run yarn dev to start pm2 and webpack in watch mode for development. Problem is that I need to kill pm2 instance (run yarn pm2:del) when I terminate manually pressing "CTRL+C". How can it be done?
package.json:
"scripts": {
"dev": "yarn pm2:del && yarn pm2:dev && yarn wp:dev",
"pm2:dev": "pm2 start ecosystem.config.js --only dev",
"pm2:del": "pm2 delete all || exit 0",
"wp:dev": "webpack --mode=development --watch"
}

I made some research and found this: how to close server on ctrl+c when in no-daemon
pm2 kill && pm2 start ecosystem.json --only dev --no-daemon
It works if you run pm2 alone but you are running 2 programs together, so give it a try below script:
{
"scripts": {
"dev": "yarn pm2:del && yarn pm2:dev && yarn wp:dev && yarn pm2:del"
}
}
How does it work?
first, kill all pm2 daemons
start a pm2 daemon
start webpack
finally, kill all pm2 daemons again, it will run when you press CTRL + C

I've created dev.sh script:
#!/bin/bash
yarn pm2:del
yarn pm2:dev
yarn wp:dev
yarn pm2:del
And run it using yarn dev:
"scripts": {
"dev": "sh ./scripts/dev.sh",
"pm2:dev": "pm2 start ecosystem.config.js --only dev",
"pm2:del": "pm2 delete all || exit 0",
"wp:dev": "webpack --mode=development --watch"
}

Related

Yarn can't run any script

When I run yarn start or any other following scripts:
"scripts": {
"start": "webpack-dev-server --config scripts/webpack.dev.js",
"clean": "rimraf build",
"build": "yarn run clean && yarn run compile",
"compile": "webpack --config scripts/webpack.prod.js",
"compile-for-test": "webpack --config scripts/webpack.test.prod.js",
"build-for-test": "yarn run clean && yarn run compile-for-test",
"test": "jest -c scripts/jest.config.js --testPathIgnorePatterns=\"services/contract-tests\"",
"test-ci": "node scripts/test-shell-commands.js unitTestCI",
"test-contract": "node scripts/test-shell-commands.js testLocal",
"test-contract-ci": "node scripts/test-shell-commands.js testCI",
"coverage": "node scripts/test-shell-commands.js unitTestCoverage",
"lint": "./node_modules/.bin/eslint --max-warnings=0 \"src/**\"",
"start-backend": "bash -l ./scripts/start-backend-container.sh",
"stop-backend": "bash -l ./scripts/stop-backend-container.sh",
"start-stub": "bash -l ./scripts/start-backend-stub-container.sh",
"stop-stub": "bash -l ./scripts/stop-backend-stub-container.sh",
"prettier": "prettier --write **/*{ts,tsx}"
},
I get the following error:
# yarn start
$ webpack-dev-server --config scripts/webpack.dev.js
error Couldn't find the binary webpack-dev-server --config scripts/webpack.dev.js
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
# yarn test
$ jest -c scripts/jest.config.js --testPathIgnorePatterns="services/contract-tests"
error Couldn't find the binary jest -c scripts/jest.config.js --testPathIgnorePatterns="services/contract-tests"
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
This applies to all scripts (its not spesific to webpack etc). However, when I use it npm run start, it works. yarn add or yarn commands alone also work. Just I can't run any script with yarn.
Does anyone encountered this before?
My yarn version is: 1.22.10
I have uninstalled and installed a few times but the problem continues. OS: Windows
This might be an issue with node trying to spawn a command on windows when specifying bash as the shell since Yarn uses node's child_process.spawn.
The shell-script specified in .yarnrc, passes that shell as the shell option to spawn, and when a shell is specified and process.platform evaluates to win32, ['/d', '/s', '/c' will be tacked in the arguments (see below source of spawn()).
if (options.shell) {
const command = [file].concat(args).join(' ');
if (process.platform === 'win32') {
if (typeof options.shell === 'string')
file = options.shell;
else
file = process.env.comspec || 'cmd.exe';
args = ['/d', '/s', '/c', `"${command}"`];
options.windowsVerbatimArguments = true;
Please check your yarn configuration via yarn config get script-shell in order to verify the settings of the bash-path.
See child_process.spawn for more info..

How can I unset env variable when run npm script?

I have some npm scripts. Some of them use env variables. For example (just example):
"scripts": {
"start": "webpack --watch --env.noSourceMaps",
},
So, for now, when I call npm start env.noSourceMaps = true
But, how can I unset that variable when run npm start?
If I run npm run -- --env.noSourceMaps=false I got env.noSourceMaps = [true, 'false']
If I run npm run -- --env.noSourceMaps I got env.noSourceMaps = [true, true]
If I run npm run -- --env.noSourceMaps= I got env.noSourceMaps = [true, '']
But I want env.noSourceMaps = false or undefined
And I do not want to reverse logic (I mean, i don't want to use it as "start": "webpack --watch" and call it as npm start or npm start -- --env.noSouceMaps or "start": "webpack --watch", "start:noMaps": "webpack --watch --env.noSourceMaps")

Is this safe to use postinstall in npm packages?

I want to use npm postinstall hook in my package to achieve my requirement. is this safe to use, I mean will it create security issues?
I am using like below:
"scripts": {
"postinstall" : "node ./tagchange.js",
"scripts": "gulp schematics-tasks && gulp schematics-remove && gulp adding-externals && npm run packagr",
"bundle": "rollup -c rollup.config.js"
},

How add variable npm run build in package.json

I have 6 projects in an Angular workspace and I have to build each. Instead of write six lines in my package.json for each projet, for example :
"build_a":" npm run build a"
"buiild_b": "npm run build b"
I would like to create only one line like this :
"build_app": "npm run build name="aaa""
How I can do it ?
you could rely on environment variables in order to discover such names.
however it depends on which operating system you're using on how to define env variables.
"scripts":{
"build:a":"cross-env NAME=a npm run build",
"build:b":"cross-env NAME=b npm run build",
"build:c":"cross-env NAME=c npm run build",
"build":"browserify src/main.js -o build.js"
}
You would end up with a script section more or less like this.
Finally I found the solution using a node.js script: build-subproject.js.
const { exec } = require('child_process');
const args = process.argv.slice(2).join(' ');
console.log(`RUNNING build with args: ${args}`);
exec(
`ng build ${args} && cd dist/${args} && npm pack `,
(error, stdout) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.info(`stdout: ${stdout}`);
}
);
In package.json,
"build-subproject": "node ./build-subproject.js",
Then run , npm run build-subproject my-project-name

Use ng build watch & gulp watch on the same console

I would like to use ng build --watch & gulp watch:ng on the same console
Here's my task code
gulp.task('watch:ng', function () {
gulp.watch('ng/dist/ng/*', gulp.series('copy-ng'));
});
I want to copy/merge the scripts to another location when angular rebuild the project
I found a solution using npm-run-all
npm install npm-run-all --save-dev
"scripts": {
"build:watch": "ng build --deleteOutputPath=false --watch",
"gulp:watch": "gulp watch:ng",
"rebuild": "run-p build:watch gulp:watch",
}
npm run rebuild