本文会从介绍npm run的原理
、script字段作用
、node_modules/.bin文件夹是什么
在package.json
里面定义的scripts
字段就是,它的每一个属性都对于一段脚本。
{
// ...
"scripts": {
"build": "node build.js"
}
}
其中build
命令对应的脚本就是node build.js
,使用npm run
命令,就可以执行。
$ npm run build
# 等同于执行
$ node build.js
我们在项目当中运行npm run xxx
,主要分为以下几步:
1、从package.json
当中读取scrips
对象。
2、以传给npm run
命令的第一个参数作为键
,在scripts
对象当中找到对应的值
作为接下来要执行的命令,没有找到会报错。
3、执行npm run
,就会立马自动创建一个shell
,其中只要是shell
可以运行的命令,就可以写在npm script
当中。
4、将当前目录下的node_modules/.bin
这个子目录加入PATH变量
(这就意味着,当前目录的node_modules/.bin
子目录里的所有脚本,都可以直接用脚本名调用,而不需要加路径)
"test": "mocha test"
// 而不用写成这样
"test": "./node_modules/.bin/mocha test"
5、在这个shell上执行上述命令
npm 脚本的唯一要求就是可以在 Shell 执行,因此它不一定是 Node 脚本,任何可执行文件都可以写在里面。 npm 脚本的退出码,也遵守 Shell 脚本规则。如果退出码不是0,npm 就认为这个脚本执行失败。npm install
或者我们装包之后,都会发现node_modules
下的第一个文件夹就是.bin
。
bin
是binary
的缩写,里面存放的是可执行的二进制文件。bin
在linux
系统中表示存放标准系统实用程序的目录
,sbin
表示存放标准系统管理文件
。
在项目当中node_modules/.bin
文件夹下,一个就有三个同名的可执行文件。
没有后缀名的文件
: 这个文件通常是一个符号链接(symlink)
或者是一个脚本文件
,它起到在命令行中执行对应包内可执行文件的作用。这个文件在不同的操作系统下可能表现为不同的文件类型。后缀名为.cmd的文件
: 这是一个Windows系统下的命令脚本文件
。它是为了在Windows命令行中执行对应包内可执行文件而存在的。后缀名为.ps1的文件
: 这是一个PowerShell脚本文件
,通常用于在Windows PowerShell环境中执行对应包内可执行文件。这些文件的作用是为了让项目中安装的Node.js包内的可执行文件能够在不同的操作系统和命令行环境中被正确执行。在使用·npm install·安装包的时候,npm会根据你的操作系统和命令行环境在.bin文件夹中创建相应的文件。这样,你就可以通过在命令行中运行这些文件来调用项目中依赖包的可执行文件。实质上都是用node执行一个js文件。
在package.json
文件中有一个bin
字段,当我们使用npm安装一个依赖包的时候,如果该包使用了这个bin
字段,那么将会自动在我们项目当中的node_modules/.bin
目录里面生成指向依赖包bin
字段的软链接执行文件。
我们需要将它拆成三部分来看:
#!
这一部分叫做shebang
,这个符号通常在Unix系统的基本中第一行开头中出现,用于指明这个脚本文件的解释程序。
/usr/bin/env
这一部分是路径,指明系统去那个目录下查找到脚本解释器,而/usr/bin/env
就是告诉系统去PATH
目录中查找,/usr/bin
是系统中的一个二进制目录,其中存放了许多系统级别的可执行文件,/usr/bin/env
实际上是一个用于寻找系统环境变量中指定的可执行程序的工具,而env
是一个寻找环境变量中指定程序的工具。
xxx
这一部分是指定解释器,这里node就是在使用环境当中找到node.js解释环境,这里我们可以指定我们想要用的解释器。
例如:
这个就是指定powershell
解释器
!# usr/bin/env node
的意思是让系统动态的去查找node,可以解决不同机器不同用户设置不一致的问题。
关于这个的具体细节大家可以在stackoverfolw
当中去详细阅读:
阅读1、阅读2
它的主要用途:
有时候我们会自主分装一些库
或者脚手架
,就可以通过这个命令同时配合package.json
文件中的bin
字段让node_modules/.bin
进行一个软链接,去自主执行我们的入口文件去运行整个代码。
好处:
1、串行执行
用&&
来连接多个命令,前面命令执行完成才再执行后面的
$ npm run script1.js && npm run script2.js
2、并行执行
用 &
来同时平行执行
$ npm run script1.js & npm run script2.js
npm script是具有生命周期机制的,具体来说就是pre和post
npm默认提供以下钩子
prepublish,postpublish
preinstall,postinstall
preuninstall,postuninstall
preversion,postversion
pretest,posttest
prestop,poststop
prestart,poststart
prerestart,postrestart
执行npm run build时,会分3个阶段串行执行
1、检查是否存在prebuild命令,如果有,就执行该命令,否则进入第2阶段
2、检查是否存在build命令,如果有,就执行运行build命令,若执行成功则进入第3阶段,否则就会报错
3、检查是否存在postbuild命令,如果有,就执行该命令
1、自定义变量
使用 “config” 字段:
你可以在 package.json 文件中的 “config” 字段下定义自己的变量,然后在脚本中使用。
"config": {
"myVariable": "custom-value"
},
"scripts": {
"example": "echo $npm_package_config_myVariable"
}
这里定义了一个名为 “myVariable” 的自定义变量,然后在脚本中使用 $npm_package_config_myVariable 引用它。
2、预定义变量
npm当中内置了很多变量,可以通过执行npm run env
来查看完整的预定义变量列表
在js
读取变量,通过process.env
对象来读取就可以
在执行npm script的时候会产生一些日志输出,我们也可以添加一些自己的注释。
添加的方法就是直接在命令前面添加:
在 unix
系统上,可以使用 #
注释:
{
"scripts": {
"start": "echo 'Start script'",
"build": "echo 'Build script'",
"custom-comment": "# This is a custom comment\n echo 'This is a custom comment'"
}
}
在windows
系统上,可以使用 REM
注释:
{
"scripts": {
"start": "echo 'Start script'",
"build": "echo 'Build script'",
"custom-comment": "REM This is a custom comment\n echo 'This is a custom comment'"
}
}