After we get a project, how to look at the entry file, how to run the project, we’ll find the script in package.json. Even after we’ve been working on a project for a long time, we write our own scripts to improve development, but you know what NPM scripts can do? Do you know how to pass an argument to a script? Do you know how to execute a script file? In this article, I’ll share how I got the most out of NPM scripts.

introduce

NPM scripts are a set of built-in and custom scripts defined in package.json. Their goal was to provide an easy way to perform repetitive tasks, such as:

  • Start the project
  • Packaging project
  • Perform unit tests, generate test reports, and so on

So how do you define an NPM script? All you need to do is set its name and write the script in the script property of the package.json file as follows:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
}
Copy the code

It is worth noting that all dependencies on node_modules bin in NPM can be accessed directly in the script, just as they are referenced in the path. Such as:

{" scripts ": {" lint" : ", / node_modules/bin/eslint. ",}} / / this spelled the same as the above effect {" scripts ": {" lint" : "eslint."}}Copy the code

The command

Now we can run the NPM run test script from the terminal as follows:

➜  xxx npm run test

> xx@1.0. 0 test /Users/beidan/Desktop/xxx
> echo "Error: no test specified" && exit 1

Error: no test specified
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! xx@1.0. 0 test: `echo "Error: no test specified" && exit 1`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the xx@1.0. 0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/beidan/.npm/_logs/2021-02-19T06_40_42_472Z-debug.log
Copy the code

You can get the same result if you execute NPM test directly on the terminal

➜  xxx npm test

> xx@1.0. 0 test /Users/beidan/Desktop/xxx
> echo "Error: no test specified" && exit 1

Error: no test specified
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! xx@1.0. 0 test: `echo "Error: no test specified" && exit 1`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the xx@1.0. 0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/beidan/.npm/_logs/2021-02-19T06_40_42_472Z-debug.log
Copy the code

This is because some scripts are built in and can be executed using shorter commands and are easier to remember. For example, all of the following commands have the same effect:

npm run-script test
npm run test
npm test
npm t
Copy the code

The same is true for NPM start

npm run-script start
npm run start
npm start
Copy the code

Execute multiple scripts

We might want to combine some scripts and run them together. For this, we can use && or &

  • To run multiple scripts in sequence, use &&, for example:
npm run lint && npm test
Copy the code
  • To run multiple scripts in parallel, use & for example:
NPM run lint&npm testCopy the code

Note: This is only for Unix environments. In Windows, it will run sequentially.

Therefore, in a real project, we could create a script that combines two scripts to simplify our operations, as follows:

{
    "scripts": {
        "lint": "eslint ."."test": "echo \"Error: no test specified\" && exit 1"."ci": "npm run lint && npm test"  // NPM run ci will run NPM run lint and NPM run test in sequence}}Copy the code

pre & post

We can create “pre” and “post” scripts for any script, and NPM will automatically run them in sequence. The only requirement is that the name of the script (followed by a prefix of “pre” or “post”) matches the main script. Such as:

{
    "scripts": {
        "prehello": "echo \"--Pre \""."hello": "echo \"Hello World\""."posthello": "echo \"--post\""}}Copy the code

If we run NPM run Hello, NPM executes the script in the following order :prehello, Hello, posthello. The output is as follows:

➜ XXX NPM run hello > [email protected] prehello/Users/beidan/Desktop/XXX > echo "- Pre - Pre > [email protected] hello / Users/beidan/Desktop/XXX > echo "Hello World" Hello World > [email protected] posthello/Users/beidan/Desktop/XXX > echo "--post" --postCopy the code

error

When the script ends with a non-zero exit code, it means that an error occurred while the script was running and execution was terminated. Such as:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
}
Copy the code

When the script throws an error, we will get some other details, such as the error number and the code. The specific error log path can be obtained at the terminal, as follows:

➜  xxx npm run test

> xx@1.0. 0 test /Users/beidan/Desktop/xxx
> echo "Error: no test specified" && exit 1

Error: no test specified
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! xx@1.0. 0 test: `echo "Error: no test specified" && exit 1`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the xx@1.0. 0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/beidan/.npm/_logs/2021-02-19T06_48_18_141Z-debug.log
Copy the code

The silent message

If you want to reduce error logging rather than prevent scripts from throwing errors, you can use the following command for “silent” processing (such as in CI, where you want the pipeline to continue running even if the test command fails)

npm run <script> --silent
/ / or
npm run <script> -s
Copy the code

If the script name does not exist, you can use –if-present, for example, NPM run

The log level

We can use — Silent to reduce the log, but how do we get more detailed logs? Or is it somewhere in between?

There are different log levels:

"silent", "error", "warn", "notice", "http", "timing", "info", "verbose", "silly".
Copy the code

The default value is notice. Log levels determine which logs will be displayed in the output. Any logs at a higher level than currently defined are displayed.

We can use –loglevel to explicitly define the loglevel to use when running commands.

Now, if we want to get more detailed logs, we need to use a higher level than the default level (” notice “). Such as:

--loglevel <info>
Copy the code

We can also use some shorter versions to simplify the command:

-s, --silent, --loglevel silent
-q, --quiet, --loglevel warn
-d, --loglevel info
-dd, --verbose, --loglevel verbose
-ddd, --loglevel silly
Copy the code

Therefore, to obtain the highest level of detail, we can use the following command

NPM run <script> -ddd // or NPM run <script> --loglevel sillyCopy the code

References a path from a file

If the script is complex, maintaining it in package.json is obviously getting longer and harder to maintain, so complex scripts are often written in files and executed from files. As follows:

{
    "scripts": {
        "hello:js": "node scripts/helloworld.js"."hello:bash": "bash scripts/helloworld.sh"."hello:cmd": "cd scripts && helloworld.cmd"}}Copy the code

We use node <path.js> to execute js files and bash <path.sh> to execute bash files

Note that if it is a CMD or bat file, you need to navigate to the corresponding folder first. Do not execute it directly like sh or js files. Otherwise, an error will be reported.

Accessing environment variables

NPM provides a set of environment variables that we can use when executing NPM scripts. We can use

Npm_config_ < val > or npm_package_ < val >Copy the code

Such as:

{
    "scripts": {
        "config:loglevel": "echo \"Loglevel: $npm_config_loglevel\"",
    }
}
Copy the code

The terminal output is as follows:

➜ XXX NPM run config: loglevel > [email protected] config: loglevel/Users/beidan/Desktop/XXX > echo "loglevel: $npm_config_loglevel" Loglevel: noticeCopy the code

Configuration parameters are put into the environment using the NpM_config_ prefix. Here are some examples:

We can get config using the following command

npm config ls -l
Copy the code

Passing parameters

In some cases, you may need to pass some parameters to the script. You can do this using the — at the end of the command. Anything added to the script — is converted to an environment variable with the NPM configuration prefix. Such as:

npm run <script>---<argument>="value"
Copy the code

Example:

{
    "scripts": {
        "ttt": "echo \"ttt $npm_config_firstname!\""
    }
}
Copy the code
➜ XXX NPM run TTT -- firstname = 234 / / incoming > [email protected] TTT/Users/beidan/Desktop/XXX > echo "TTT $npm_config_firstname!" ttt 234! // The output valueCopy the code

Naming rules

The prefix

In some open source projects, we can see that script scripts are prefixed. This is also a good naming convention, using: dev, : prod to distinguish the environment, as follows: dev, : prod

{ "scripts": { "build:dev": "..." // Development environment "build:prod": "..." // Production environment}}Copy the code

Technical communication

Welcome to add my wechat communication: Sky42 –