package.json: what is the difference between & and &&? - node.js

Title pretty much says it all, but I'd also like to know if these commands work or behave differently depending upon the OS.
example1:
"scripts": {
"build": "babel -d serverbuild ./server",
"exe": "node ./serverbuild/index.js",
"start": "npm run build && npm run exe"
}
example2:
"scripts": {
"build": "babel -d serverbuild ./server",
"exe": "node ./serverbuild/index.js",
"start": "npm run build & npm run exe"
}
Given these examples portions of a package.json, what would be the difference between npm run start?

When using &&, the first command will run, and if it does not error, the second command will run. It's like a logical AND.
Using &, however, will run a command in the background. So in your second package.json, npm run build will start running in the background and then npm run exe will run as well regardless of what happens to the first command.

Related

Concatenating command line arguments and flags in NPM package.json scripts

I am looking for a way to do something like this:
package.json
[...]
"scripts": {
"test": "cd ./apps/my-awesome-app && npx cypress run",
"test:watch": "npm run test && --headed",
[...]
so then at the command line, running
npm run test:watch
will result in the following commands being executed:
cd ./apps/my-awesome-app
npx cypress run --headed
However, this is not working as expected. Is there a way to achieve this without repeating the whole "test"-string?

In package.json scripts key: npm run or not?

In an online tutorial, the package.json said (simplified):
"scripts": {
"dev": "npm run webpack -- --mode development"
},
I usually write, and it works:
"scripts": {
"dev": "webpack --mode development"
},
Is the first version in any way preferable? I understand the meaning of --, but I do not know whether encapsulating the command in another npm run call provides any benefits.
The first call allows you to change the webpack command used, or add additional arguments, or even run an entirely different command at all.
For example, npm run tsc on my repos runs npm run delDist && tsc.

`package.json` sequential start script only execute one of the script

I have the following scripts property in package.json:
"scripts": {
"start": "webpack -w && nodemon server.js",
"watch:server": "nodemon server.js",
"watch:build": "webpack -w",
},
When I run npm run start it only starts the webpack -w command but not the nodemon server.js command. I thought having && will run the scripts sequentially but it is definitely not the case for me. I have seen many people chaining execution with && and it works fine.
Why is mine not working?
If webpack -w is not finishing successfully, your second command nodemon server.js won't run. Using a single & should allow the second one to run even if the first one fails.

Syntax (windows and linux) for multiple commands using Node cross-env

I'm taking a look at a project that has this line in it's package.json to run Karma tests
"scripts": {
"test": "NODE_ENV=test karma start karma.conf.js",
This doesn't work in Windows when I try "npm test".
I gather this is because this is a *nix syntax. And, in fact, if I change it to
"scripts": {
"test": "set NODE_ENV=test && karma start karma.conf.js",
the tests start when I run npm test.
Looking around, the optimal solution appears to be to use the cross-env package and rewrite it like
"scripts": {
"test": "cross-env NODE_ENV=test && karma start karma.conf.js",
So I get the cross-env will take care of the "set NODE_ENV" part to work on multiple OSes, but it's the "&&" part I'm questioning.
Do I leave the "&&" between the commands when using cross-env? Will that work in windows and linux?
Your cross-env example won't work, it should just be:
"scripts": {
"test": "cross-env NODE_ENV=test karma start karma.conf.js",
without the &&. The command to run comes immediately after you're done setting the variables.
I found your question by searching for how to set multiple variables with cross-env and also how to run multiple scripts/commands with cross-env. So to address the "multiple commands" part of your question:
Given these 2 test scripts:
a.js
console.log('a', process.env.TEST_VAR, process.env.TEST_VAR_2);
b.js
console.log('b', process.env.TEST_VAR, process.env.TEST_VAR_2);
You'll find if you have an && in the script in your package.json the subsequent scripts don't receive the variables. For example:
"scripts": {
"check": "cross-env TEST_VAR=hello TEST_VAR_2=world node a.js && node b.js",
Running npm run check gives:
a hello world
b undefined undefined
You can solve this by having an extra script which runs the multiple commands and running that with cross-env:
"scripts": {
"check": "cross-env TEST_VAR=hello TEST_VAR_2=world npm run check-real",
"check-real": "node a.js && node b.js",
Now npm run check gives:
a hello world
b hello world

How do I execute typescript watch and running server at the same time?

I was developing my project in nodejs. I found if I need to code and test api, I will run two console, one is to execute typescript watch, another is to execute server.
I think it's so troublesome. I find other developers on github have written scripts in package.json. It's easy to call any commands. It attracts how to write the scripts and simply my development workflow.
In short, the comand of typescript watch is tsc -w and the comand of running server is node app.js. My idea is merge the commands as tsc -w & node app.js but I can't work the two commands at the same time. How do I do? Thanks.
My idea is merge the commands as tsc -w & node app.js but I can't work the two commands at the same time. How do I do
You have a few options. Simplest is to use ts-node-dev : https://github.com/whitecolor/ts-node-dev
Option 1
Step 1
install concurrently, use npm, pnpm or yarn
pnpm i concurrently -D
Step 2
create a script with this command
"scripts": {
"run": "tsc && concurrently \"tsc -w\" \"nodemon dist/app.js\"",
}
Option 2
without install anything (mac or Linux)
"scripts": {
"run": "tsc -w & nodemon dist/app.js",
}
run tsc first so that your directory has something at the time of running node
And with that you will have running your Typescript application 🚀
Another option can be to use nodemon:
tsc -w & nodemon app.js
Since Typescript 3.4 the compilation is faster because you can use the incremental compiler option and they keep improving (including interesting changes for large projects in 3.8).
Update:
I also moved to use concurrently as HerberthObregon says in his answer
TLDR, If you like nodemon this is a straight forward way to get file watch, compilation and execution:
nodemon --ext ts --exec 'tsc && node dist/index.js'
Optionally replace tsc with babel for faster compilation.
Here is a more complete example, in package.json (with source maps):
"scripts": {
"develop": "nodemon --ext ts --exec 'yarn build --incremental && yarn serve'",
"build": "tsc",
"serve": "node --require source-map-support/register dist/index.js",
...
},
Install source-map-support as a dependency if you want, ahem... source map support! Otherwise, remove --require source-map-support/register from the serve script above.
tsconfig.json
{
"compilerOptions": {
...
"sourceMap": true,
"outDir": "dist",
}
}
Building on herberthObregon's answer
Step 1: Install packages
npm install concurrently typescript nodemon --save-dev
Step 2: Create these scripts in package.json
"scripts": {
"build": "tsc",
"build:watch": "tsc -w",
"dev": "npm run build && concurrently \"npm run build:watch\" \"npm run serve:watch\"",
"serve": "node dist/index.js",
"serve:watch": "nodemon dist/index.js"
},
build runs a standard typescript build
build:watch runs typescript build in watch mode
serve serves up your node project (assuming your tsconfig outputs to dest/index/js)
serve:watch uses nodemon to restart the node server whenever the js output changes
dev puts them all together
Just going to throw my hat in here, here's a solution using ts-node-dev and concurrently, similar to the one provided by #HerberthObregon but using ts-node-dev instead of nodemon:
"scripts": {
"start": "npm run build && concurrently \"npm run build:watch\" \"npm run dev\"",
"dev": "tsnd --respawn src/main.ts",
"build": "tsc -p tsconfig.release.json",
"build:watch": "tsc -w -p tsconfig.release.json"
}
Bonus: If you need help with your figuring out tscand your tsconfig.json, I use the sensible defaults from this node typescript starter.
Here's a solution that works for me
1. Install ts-node and nodemon as dev dependencies
2. Create a script : "dev" : "nodemon app.ts"

Resources