本文会从介绍npm run的原理script字段作用node_modules/.bin文件夹是什么

一、什么是npm script

package.json里面定义的scripts字段就是,它的每一个属性都对于一段脚本。

{
  // ...
  "scripts": {
    "build": "node build.js"
  }
}

其中build命令对应的脚本就是node build.js,使用npm run命令,就可以执行。

$ npm run build
# 等同于执行
$ node build.js
1.1npm run的原理

我们在项目当中运行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 就认为这个脚本执行失败。
1.2bin文件夹

npm install或者我们装包之后,都会发现node_modules下的第一个文件夹就是.bin
binbinary的缩写,里面存放的是可执行的二进制文件。binlinux系统中表示存放标准系统实用程序的目录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字段的软链接执行文件。

1.3 #!/usr/bin/env xxx是什么?

我们需要将它拆成三部分来看:

#! 这一部分叫做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进行一个软链接,去自主执行我们的入口文件去运行整个代码。

二、为什么需要npm script

好处:

  • 编写单一职责的命令,提高代码的复用性
  • 不同项目的脚本,只要功能相同,就可以有相同的对外接口,提升可读性、降低项目的门槛
  • 通过连接多个命令,可以打造自动化的工作流

三、如何使用npm script

3.1执行多个命令

1、串行执行
&& 来连接多个命令,前面命令执行完成才再执行后面的

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

2、并行执行
& 来同时平行执行

$ npm run script1.js & npm run script2.js
3.2 生命周期钩子

npm script是具有生命周期机制的,具体来说就是pre和post

  • 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命令,如果有,就执行该命令

3.3 使用npm变量

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对象来读取就可以

3.4 添加注释

在执行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'"
  }
}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐