How to use a package script under a different platform? - npm

I have to have this line package.json
"scripts": {
"default_linux": "export NODE_ENV=default&& export NODE_MINIFIED=false&& webpack",
"default_windows": "set NODE_ENV=default&& set NODE_MINIFIED=false&& webpack",
"default_linux_min": "export NODE_ENV=default&& export NODE_MINIFIED=true&& webpack",
"default_windows_min": "set NODE_ENV=default&& set NODE_MINIFIED=true&& webpack",
},
But to run a not very nice to think about each version separately and so as to correctly configure scripts for different platforms to make it as a team, not ..?
$ npm run default_linux # frontend assembly under linux

You can use the cross-env package on npm. It allows you to use unix style scripts, and handles all the cross-platform issues. It works for linux and windows, but I haven't tested it for Mac. Also, there's no need for export.
After you install cross-env, you can replace your scripts field with this:
"scripts": {
"build": "cross-env NODE_ENV=default NODE_MINIFIED=false webpack",
"build-min": "cross-env NODE_ENV=default NODE_MINIFIED=true webpack",
},

Related

How to run shell scripts cross-platform, using npm

I have nestJS project with that line in package.json:
"scripts": {
...
"test": "sh scripts/test.sh",
...
},
And on my windows machine, it can't run.
How to rewrite it, to run cross-platform? May be example using cross-env-shell or add some package in dependencies?

How does npm run build work with npm pack?

I'm working on a project that requires using the npm pack command. Is running build on the library/package required before creating the installable tar file? Or can I just pack and then install it into the app?
Yes, but for totally different reasons.
npm run build can do anything: it just executes the value for build inside the scripts object in your package.json, for example on an Angular project it'll look like this,
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
npm pack basically "create a tarball from a package", but here is the deal: the "package" that it creates a tarball from has to exist. So, in order to create the "package" that npm pack targets in ./dist
you frequently have to run npm build. This is because many JavaScript projects are written in TypeScript (in which case "build" usually runs npx tsc) or use a build system that will transpile their code to produce JavaScript (like babel). If your project is very rudimentary, there is a good chance you won't have to "build anything": you can see this if you create an empty directory and run npm init, but seldom are useful packages created this way.
The result of npm pack is a .tgz file. This is basically a compressed copy of a target directory. You can install this with npm i ./file.tgz. On the consuming machine that you wish to install the package on, you do not have to build anything. Building is what you do as a developer and a package maintainer. For example, you build TypeScript producing JavaScript. The consumer just downloads the result and installs the dependencies. It doesn't even have to know that you write your code with TypeScript (or better, Rust.)

Use Verbose when building with Webpack and NPM

I have the following package.json file and I am building using webpack:
{
"name": "web",
"private": true,
"scripts": {
"build": "webpack --config webpack.config.js --mode development"
},
"devDependencies": {
"webpack": "4.21.0",
"webpack-cli": "3.1.2"
},
"dependencies": {
"jquery": "3.4.1"
}
}
How can I pass a parameter when using npm run build to use verbose so I can see build errors?
Try the following:
npm run build --verbose
(you can pass any parameter via npm run <command> after --).
To be more clear with regards to the first answer, using npm run build --verbose does increase the log level of the npm process, as noted here https://docs.npmjs.com/cli/v8/using-npm/logging. This does not necessarily bump any log level in the Webpack process itself.
The first answer would incur additional logging for the npm process. The parenthetical note is slightly misleading -- if you want to pass a parameter to an npm script to pass to the underlying scripts, you need to add a primary "--". So, while that answer does increase npm logging, it doesn't necessarily alter the webpack logging verbosity.
For example, if you have a linter scripts in npm:
"jest-preview": "jest-preview",
"lint": "eslint ./src",
"build": "webpack --config webpack.config.js --mode development"
If you want to utilize the "--fix" parameter to pass to eslint, you would run this npm script as:
npm run lint -- --fix
As can be seen on https://webpack.js.org/api/cli/, there is no --verbose option for build in webpack-cli. There are some facilities for log output verbosity configuration for the loaders and plugins that can be implemented in the webpack config. I would check that documentation for further information.

Setting argv in the package.json and running a different script

I have two versions of my application, for one I set --extended, and for the other not, like this
"scripts": {
"build": "webpack --mode production",
"extended": "webpack --mode production --extended",
// ...
}
Now, in my webpack, I access the extended like this
module.exports = (_env,argv)=> {
argv.extended
}
I am trying to improve this in a cross platform way to do something like
"scripts": {
"build": "webpack --mode production",
"extended": "--extended npm run build"
}
as to run the build script from extended but still access the --extended variable.
I there a way to achieve this? Thank you
I read this whole question How to set environment variables from within package.json but can't find a way
Change the scripts section of your package.json to the following:
"scripts": {
"build": "webpack --mode production",
"extended": "npm run build -- --extended"
}
Explanation:
As stated in the npm-run-script documentation which can be found here:
... 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:
So, essentially when you run the following command via your CLI:
$ npm run extended
npm invokes the extended script, which then runs the build script and passes the --extended argument to the end of it (i.e. it passes --extended to the end of the build script).
Is there another way?
Yes, you could also consider simplifying the scripts section of your package.json further by deleting your extended script completely.
For instance:
"scripts": {
"build": "webpack --mode production"
}
Then you can do either of the following:
Run the following command via your CLI:
$ npm run build
This will to invoke your build script without the --extended argument/option.
Or run the following command via your CLI instead:
$ npm run build -- --extended
This will invoke your build script with the --extended argument/option.

Using environment variables in npm scripts across platforms

I am building a package.json and use "npm run" to run some scripts, to be exactly, https://docs.npmjs.com/misc/scripts.
My script would need to expand some environment variables and I want to make it cross platform compatible. For example, my script would say
"scripts": {
"build": "md %npm_package_version%\helloworld"
}
But it's currently running on Windows because the expansion of environment variables. Linux would use md $npm_package_version\helloworld.
Does npm comes with a mechanism to convert environment variables expansion so that it works across platforms?
To make it cross-platform, use cross-var:
"scripts": {
"build": "cross-var md %npm_package_version%\helloworld"
}
npm doesn't appear to have a cross platform way to expand environment variables, but you do have node at your disposal, so I'd recommend implementing all your scripts as node scripts, then you can access process.env and cross-platform filesystem functions, like mkdirSync.
package.json
"scripts": {
"build": "node utils/mdkir.js"
}
utils/mkdir.js
'use strict';
var fs = require('fs');
fs.mkdirSync(process.env.npm_package_version + '/helloworld');