npm npm scripts and script and package.json package.json

Excerpt: https://www.cnblogs.com/tandaxia/p/12111226.html

npm script and package.json

 

1. What is the script npm

  When you create a project, such as node.js a vue project, or react a project, the project will generate a description file package.json.

For example npm allowed inside package.json file, field definitions using scripts script commands.

{
//...
"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "e2e": "node test/e2e/runner.js",
    "test": "npm run e2e",
    "lint": "eslint --ext .js,.vue src test/e2e/specs",
    "build": "node build/build.js"
  },
}

  The above code fragment package.json a file, which is an object field of scripts. Each of its properties, corresponds to a script. For example, the build script command corresponds to a node build.js.

  Use npm run command at the command line, you can execute this script.

$ npm run build

  The equivalent to:

$ node build/build.js

  Similarly, in the above period of scripts,   NPM RUN Test   equivalent  npm run e2e,  equivalent to node test / e2e / runner.js    

  These definitions package.json inside the script, the script called npm. Related script projects can be concentrated in one place; different projects script command, as long as the same function, you can have the same external interface. For example, users do not need to know how to test your project, just run  npm run dev  can

  View all current projects npm script commands can be used without any parameters   npm run   command.

$ npm run

 

2, npm principle

  Npm script principle is very simple. Whenever execution npm run, it will automatically create a shell script that executes the specified command in the shell script inside. Therefore, only if the shell (typically bash) that you can run, you can write a script npm inside.

  A special feature is, node_modules npm run this new shell, sets the current directory / .bin subdirectory in your PATH variable, after the execution, and then restored to their original PATH variable. Also it means that all scripts node_modules current directory / .bin subdirectories, you can directly call their feet, whose real name without having to add the path. For example, depending on the current project which has Mocha, just write directly mocha test it.

"test": "mocha test"

  Rather than written as follows.

"test": "./node_modules/.bin/mocha test"

  Since the only requirement is that npm script can be executed in the shell, so it is not necessarily Node script, any executable files can be written on the inside. npm script exit code, and keep the shell script rules. If the exit code is not 0, npm it considers the script execution failed.

 

3, wildcard

  Since npm script is a shell script, so you can use shell wildcards.

"lint": "jshint *.js"
"lint": "jshint **/*.js"

  The above code, * represents any file name, ** indicates any layer subdirectories. If you want to pass a wildcard original command, to prevent the escape shell, you want to escape the asterisk.

"test": "tap test/\*.js"

 

4, parameter passing

  Npm script to pass parameters to be used - mark.

"lint": "jshint **.js"

  The above  npm run lint   pass parameters command, must be written as follows.

$ npm run lint --  --reporter checkstyle > checkstyle.xml

  Which may be further packaged package.json a command.

"lint": "jshint **.js",
"lint:checkstyle": "npm run lint -- --reporter checkstyle > checkstyle.xml"

 

5, the order of execution

  If npm script which need to perform multiple tasks, you need to clear their execution order. If performed in parallel (i.e., simultaneous parallel execution), ampersand can be used.

$ npm run script1.js & npm run script2.js

  If it is secondary to the implementation of (a task that is only the first successful, in order to perform the next task), you can use the && symbol.

$ npm run script1.js && npm run script2.js

 

6, the default value

  In general, npm script provided by the user. However, npm two script provides a default value. That is to say, without defining these two scripts, it can be used directly.

"start": "node server.js",
"install": "node-gyp rebuild"

  The above code, the default value npm run start is the node server.js, provided there is server.js this script in the project root directory; the default value npm run install a node-gyp rebuild, provided there is a binding project root directory. gyp file.

 

7, the hook

  It has pre script npm post two hooks. For example, the hook is prebuild build script commands and postbuild.

"prebuild": "echo I run before the build script",
"build": "cross-env NODE_ENV=production webpack",
"postbuild": "echo I run after the build script"

  When the user performs npm run build is performed automatically in the following order.

npm run prebuild && npm run build && npm run postbuild

  Therefore, these two hooks inside, do some preparation and cleanup. Below is an example:

"clean": "rimraf ./dist && mkdir dist",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production webpack"

  npm default provides the following hooks:

prepublish,postpublish
preinstall,postinstall
preuninstall, postuninstall
preversion, postversion
pretest,posttest
crossing, poststop
prestart, record start
prerestart, postrestart

  Custom script commands can also add pre and post hook. For example, myscript this script commands, there premyscript and postmyscript hook. However, the pre and post double invalid, such as prepretest and postposttest is invalid.

  npm provide a npm_lifecycle_event variable returns the currently running script commands, such as pretest, test, posttest, and so on. So, you can use this variable, in which the same script file, write code for different npm scripts command. Consider the following example:

const TARGET = process.env.npm_lifecycle_event;

if (TARGET === 'test') {
  console.log(`Running the test task!`);
}

if (TARGET === 'pretest') {
  console.log(`Running the pretest task!`);
}

if (TARGET === 'posttest') {
  console.log(`Running the posttest task!`);
}

  Note, prepublish this hook will not run before npm publish command, the command will be run before the npm install (without any parameters). This behavior makes it easy for users confused, so npm 4 introduces a new hook prepare, behavior is equivalent to prepublish, and, prepublish will only begin to run from the npm 5 before npm publish command.

 

8, shorthand

  There are four commonly used shorthand script npm.

  • npm start   is   npm run start   shorthand
  • npm stop   is   npm run stop   shorthand
  • npm test    is   npm run test    shorthand
  • npm  restart 是 npm  run  stop  &&  npm  run  restart  &&  npm  run  start 的简写

  npm start, npm stop, npm restart are better understood, and npm restart command is a complex, three actually execute script commands: stop, restart, start. Particular order of execution is as follows:

  1. prerestart
  2. crossing
  3. stop
  4. mail stop
  5. restart
  6. prestart
  7. start
  8. mail start
  9. postrestart

 

9, variable

  npm script has a very powerful feature is the ability to use the internal variables npm.

First, npm_package_ prefix, npm script can get package.json inside the field. For example, here is a package.json.

{
  "name": "foo", 
  "version": "1.2.5",
  "scripts": {
    "view": "node view.js"
  }
}

So, variable npm_package_name return foo, the variable npm_package_version return 1.2.5.

// view.js
console.log(process.env.npm_package_name); // foo
console.log(process.env.npm_package_version); // 1.2.5

  In the above code, we process.env objects through the environment variable to get the field value package.json. If bash script can marry these two values ​​by $ npm_package_name and $ npm_package_version.

npm_package_ prefix also supports nested package.json field.

 "repository": {
    "type": "git",
    "url": "xxx"
  },
  scripts: {
    "view": "echo $npm_package_repository_type"
  }

  In the above code, attribute repository type fields, to be taken by npm_package_repository_type.

Here is another example:

"scripts": {
  "install": "foo.js"
}

  In the above code, the variable is equal to the value npm_package_scripts_install foo.js.

  Then, npm script can also npm_config_ prefix, get npm configuration variables, namely npm config get xxx command value returned. For example, the current label issuing module to be taken through npm_config_tag.

"view": "echo $npm_config_tag",

  Note, package.json inside the config object that can be covered environment variable.

{ 
  "name" : "foo",
  "config" : { "port" : "8080" },
  "scripts" : { "start" : "node server.js" }
}

  The above code, npm_package_config_port variable returns 8080. This value may be covered by the following methods.

$ npm config set foo:port 80

  Finally, env command lists all environment variables.

"env": "env"

 

10, commonly used script examples

// delete directory
"clean": "rimraf dist/*",

// set up a local HTTP service
"serve": "http-server -p 9090 dist/",

// Open the browser
"open:dev": "opener http://localhost:9090",

// refreshed in real time
 "livereload": "live-reload --port 9091 dist/",

// build HTML file
"build:html": "jade index.jade > dist/index.html",

// As long as there are changes in the CSS file, re-execute the building
"watch:css": "watch 'npm run build:css' assets/styles/",

// As long as there are changes in the HTML file, re-execute the building
"watch:html": "watch 'npm run build:html' assets/html",

// deploy to Amazon S3
"deploy:prod": "s3-cli sync ./dist/ s3://example-com/prod-site/",

// build favicon
"build:favicon": "node scripts/favicon.js",

 

11, package.json Other Item Description

  For dependencies and devDependencies some explanation:

  When using npm install dependencies, if dependent --save installed inside dependencies module will be written to;

  The use --save-dev dependencies installed, it will be written inside devDependencies module to; if nothing to write, the default installation dependencies to go inside.

  For example, we use some of the build tools such as glup, webpack these only in the development environment was used in the package, only need to write to devDependencies can be.

  For targeting two environments, the configuration file by  process.env.NODE_ENV = 'development'   or   process.env.NODE_ENV = 'production'   to specify is the development or production environment.

 

12, package.json the bin properties

  package.json the bin is mapped command names and local files. If the installation is global, the file will be mapped to the global bin inside, after installation, to open a terminal anywhere in the file using the command line;

If it is installed locally, it will map the file to ./node_modules/.bin file folder inside the project, after installation, use the command line to execute the file in the project directory.

  for example:

  1. Create a new folder, open a terminal and enter the folder, the command   npm init -y   create a package.json file.
  2. Index.js then create a new file in the same directory package.json file, together with the test data. Note that the head index.js file must have the   #! / Usr / bin / env  node  node.
  3. Increase in package.json bin property, set the mapping between the command name and index.js.
  4. Globally installed in the terminal the current directory:  NPM the install -g   
  5. After the installation is successful, the folder can be opened in any terminal, package.json execution command set in the bin, it will perform a corresponding index.js code. As shown below

 

 

  At the same time, we open the global bin folder, you can find the global bin just add the following command  tan-temp-bin 

  像我们一些常用vue、vue-cli、create-react-app等都是通过bin属性将命令映射到了全局上的

 

参考链接:

阮一峰--npm  scripts使用指南:http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html

 

版权声明


作者:TDX

出处:博客园TDX的技术博客--http://www.cnblogs.com/tandaxia

您的支持是对博主最大的鼓励,感谢您的认真阅读。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 

 
分类:  JS + HTML
 

1、什么是npm脚本

  在创建node.js项目如一个vue项目,或一个react项目时,项目都会生成一个描述文件package.json 。

比如npm允许在package.json文件里面,使用scripts字段定义脚本命令。

{
//...
"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "e2e": "node test/e2e/runner.js",
    "test": "npm run e2e",
    "lint": "eslint --ext .js,.vue src test/e2e/specs",
    "build": "node build/build.js"
  },
}

  上面代码是package.json文件的一个片段,里面的scripts字段是一个对象。它的每一个属性,对应一段脚本。比如,build命令对应的脚本是node  build.js 。

  命令行下使用npm  run 命令,就可以执行这段脚本。

$ npm run build

  等同于执行:

$ node build/build.js

  同理,上面的那段scripts中,  npm  run  test  等同于 npm  run  e2e   , 等同于  node test/e2e/runner.js  

  这些定义在package.json里面的脚本,就称为npm脚本。项目的相关脚本,可以集中在一个地方;不同项目的脚本命令,只要功能相同,就可以有同样的对外接口。比如用户不需要知道怎么测试你的项目,只要运行 npm  run  dev 即可

  查看当前项目的所有npm脚本命令,可以使用不带任何参数的  npm  run  命令。

$ npm run

 

2、npm原理

  npm脚本的原理非常简单。每当执行 npm  run ,就会自动创建一个shell脚本, 在这个shell里面执行指定的脚本命令。因此,只需要是shell (一般是bash) 可以运行的命令,就可以写在npm脚本里面。

  比较特别的是,npm  run  新建的这个shell, 会将当前目录的node_modules/.bin 子目录加入PATH 变量,执行结束后,再将PATH变量恢复原样。还意味着,当前目录的node_modules/.bin 子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有Mocha, 只要直接写 mocha  test 就可以了。

"test": "mocha test"

  而不用写成下面这样。

"test": "./node_modules/.bin/mocha test"

  由于npm脚本的唯一要求就是可以在shell中执行,因此它不一定是Node脚本,任何可执行文件都可以写在里面。npm脚本的退出码,也遵守shell脚本规则。如果退出码不是0,npm 就认为这个脚本执行失败。

 

3、通配符

  由于npm脚本就是shell脚本,因此可以使用shell通配符。

"lint": "jshint *.js"
"lint": "jshint **/*.js"

  上面代码中,* 表示任意文件名,**表示任意一层子目录。如果要将通配符传入原始命令,防止被shell转义,要将*号转义。

"test": "tap test/\*.js"

 

4、传参

  向npm脚本传入参数,要使用 -- 标明。

"lint": "jshint **.js"

  向上面的 npm  run  lint  命令传入参数,必须写成下面这样。

$ npm run lint --  --reporter checkstyle > checkstyle.xml

  也可以再package.json里面封装一个命令。

"lint": "jshint **.js",
"lint:checkstyle": "npm run lint -- --reporter checkstyle > checkstyle.xml"

 

5、执行顺序

  如果npm脚本里面需要执行多个任务,那么需要明确它们的执行顺序。如果是并行执行(即同时的平行执行),可以使用 & 符号。

$ npm run script1.js & npm run script2.js

  如果是继发执行(即只有前一个任务成功,才能执行下一个任务),可以使用 && 符号。

$ npm run script1.js && npm run script2.js

 

6、默认值

  一般来说,npm脚本由用户提供。但是,npm对两个脚本提供了默认值。也就是说,这两个脚本不用定义,就可以直接使用。

"start": "node server.js",
"install": "node-gyp rebuild"

  上面代码中,npm  run  start  的默认值是 node  server.js, 前提是项目根目录下有server.js这个脚本;npm  run  install 的默认值是node-gyp  rebuild, 前提是项目根目录下有binding.gyp文件。

 

7、钩子

  npm脚本有pre何post两个钩子。举例来说,build脚本命令的钩子就是prebuild和postbuild。

"prebuild": "echo I run before the build script",
"build": "cross-env NODE_ENV=production webpack",
"postbuild": "echo I run after the build script"

  用户执行npm  run  build的时候,会自动按照下面的顺序执行。

npm run prebuild && npm run build && npm run postbuild

  因此,可以在这两个钩子里面,完成一些准备工作和清理工作。下面是一个例子:

"clean": "rimraf ./dist && mkdir dist",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production webpack"

  npm默认提供下面的这些钩子:

prepublish,postpublish
preinstall,postinstall
preuninstall,postuninstall
preversion,postversion
pretest,posttest
prestop,poststop
prestart,poststart
prerestart,postrestart

  自定义的脚本命令也可以加上pre和post钩子。比如,myscript这个脚本命令,也有premyscript和postmyscript钩子。不过,双重的pre和post无效,比如prepretest和postposttest是无效的。

  npm提供一个npm_lifecycle_event变量,返回当前正在运行的脚本命令,比如pretest、test、posttest等等。所以,可以利用这个变量,在同一个脚本文件里面,为不同的npm  scripts命令编写代码。请看下面的例子:

const TARGET = process.env.npm_lifecycle_event;

if (TARGET === 'test') {
  console.log(`Running the test task!`);
}

if (TARGET === 'pretest') {
  console.log(`Running the pretest task!`);
}

if (TARGET === 'posttest') {
  console.log(`Running the posttest task!`);
}

  注意,prepublish这个钩子不仅会在npm  publish 命令之前运行,还会在npm  install (不带任何参数)命令之前运行。这种行为很容易让用户感到困惑,所以npm 4引入了一个新的钩子prepare, 行为等同于prepublish, 而从npm 5开始,prepublish  将只在npm  publish命令之前运行。

 

8、简写形式

  四个常用的npm脚本有简写形式。

  • npm  start  是  npm  run  start  的简写
  • npm  stop  是  npm  run  stop  的简写
  • npm  test   是  npm  run  test   的简写
  • npm  restart 是 npm  run  stop  &&  npm  run  restart  &&  npm  run  start 的简写

  npm  start 、npm  stop、npm  restart都比较好理解,而npm  restart 是一个复合命令,实际上会执行三个脚本命令:stop、restart、start 。具体的执行顺序如下:

  1. prerestart
  2. prestop
  3. stop
  4. poststop
  5. restart
  6. prestart
  7. start
  8. poststart
  9. postrestart

 

9、变量

  npm脚本有一个非常强大的功能,就是可以使用npm的内部变量。

首先,通过npm_package_  前缀,npm脚本可以拿到package.json里面的字段。比如,下面是一个package.json。

{
  "name": "foo", 
  "version": "1.2.5",
  "scripts": {
    "view": "node view.js"
  }
}

那么,变量npm_package_name返回foo,  变量npm_package_version返回  1.2.5 。

// view.js
console.log(process.env.npm_package_name); // foo
console.log(process.env.npm_package_version); // 1.2.5

  上面代码中,我们通过环境变量process.env 对象,拿到package.json 的字段值。如果是bash脚本,可以用$npm_package_name和$npm_package_version娶到这两个值。

npm_package_  前缀也支持嵌套的package.json字段。

 "repository": {
    "type": "git",
    "url": "xxx"
  },
  scripts: {
    "view": "echo $npm_package_repository_type"
  }

  上面代码中,repository字段的type属性,可以通过 npm_package_repository_type取到。

下面是另外一个例子:

"scripts": {
  "install": "foo.js"
}

  上面代码中,npm_package_scripts_install变量的值等于foo.js 。

  然后,npm 脚本还可以通过npm_config_ 前缀,拿到npm的配置变量,即npm  config  get  xxx  命令返回的值。比如,当前模块的发行标签,可以通过npm_config_tag取到。

"view": "echo $npm_config_tag",

  注意,package.json里面的config对象,可以被环境变量覆盖。

{ 
  "name" : "foo",
  "config" : { "port" : "8080" },
  "scripts" : { "start" : "node server.js" }
}

  上面代码中,npm_package_config_port 变量返回的是8080。这个值可以用下面的方法覆盖。

$ npm config set foo:port 80

  最后,env命令可以列出所有环境变量。

"env": "env"

 

10、常用脚本示例

// 删除目录
"clean": "rimraf dist/*",

// 本地搭建一个 HTTP 服务
"serve": "http-server -p 9090 dist/",

// 打开浏览器
"open:dev": "opener http://localhost:9090",

// 实时刷新
 "livereload": "live-reload --port 9091 dist/",

// 构建 HTML 文件
"build:html": "jade index.jade > dist/index.html",

// 只要 CSS 文件有变动,就重新执行构建
"watch:css": "watch 'npm run build:css' assets/styles/",

// 只要 HTML 文件有变动,就重新执行构建
"watch:html": "watch 'npm run build:html' assets/html",

// 部署到 Amazon S3
"deploy:prod": "s3-cli sync ./dist/ s3://example-com/prod-site/",

// 构建 favicon
"build:favicon": "node scripts/favicon.js",

 

11、package.json其他配置项说明

  对于dependencies和devDependencies的一些说明:

  使用npm安装依赖时,如果使用--save安装的依赖,会被写到dependencies模块里面去;

  而使用--save-dev安装的依赖,则会被写到devDependencies模块里面去;如果什么都不写,则默认安装到dependencies里面去。

  比如我们使用的一些构建工具例如glup、webpack这些只在开发环境中才用到的包,则只需要写到devDependencies中即可。

  对于两种环境的指定方式,则是通过配置文件中的 process.env.NODE_ENV = 'development'  或  process.env.NODE_ENV = 'production'  来指定是开发还是生产环境。

 

12、package.json中的bin属性

  package.json中的bin是命令名和本地文件的映射。如果是全局安装,则会把文件映射到全局的bin里面去,安装后,在任意地方打开终端使用命令行执行该文件;

如果是本地安装,则会把文件映射到本项目的./node_modules/.bin文件夹里面,安装后,在本工程目录里面使用命令行执行该文件。

  举例说明:

  1. 新建一个文件夹,打开终端,进入该文件夹,通过命令  npm init -y  创建一个package.json文件。
  2. 然后在package.json文件同级目录下新建一个index.js文件,加上测试数据。注意,index.js文件的头部必须有这个  #!/usr/bin/env node  节点。
  3. 在package.json中增加bin属性,设置命令名和index.js的映射关系。
  4. 在终端当前目录中进行全局安装: npm install -g   
  5. 安装成功后,则在电脑任意文件夹打开终端,执行package.json中bin中设置的命令,都会执行对应的index.js中的代码。 如下图

 

 

  同时,我们打开全局的bin文件夹,可以发现bin下面的刚刚添加的全局命令 tan-temp-bin 

  像我们一些常用vue、vue-cli、create-react-app等都是通过bin属性将命令映射到了全局上的

 

参考链接:

阮一峰--npm  scripts使用指南:http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html

 

Guess you like

Origin www.cnblogs.com/xichji/p/12118047.html