包管理

77 阅读3分钟

版本号

semver 约定一个包的版本号必须包含3个数字,格式必须为 MAJOR.MINOR.PATCH, 意为 主版本号.次版本号.修订版本号.

MAJOR 主版本号,对应大的版本号迭代,做了不兼容旧版的修改时要更新 MAJOR 版本号
MINOR 次版本号,对应小版本迭代,发生兼容旧版API的修改或功能更新时,更新MINOR版本号
PATCH 修订号,对应修订版本号,一般针对修复 BUG 的版本号

~,^

~,^ 的表述需要结合具体的包管理工具和版本号规则来确定,但是对于一般使用记住如下原则:
    ^ 是确保版本兼容性时,默认对次版本号的限定约束
    ~ 是确保版本兼容性时,默认对补丁号的约束

npm install流程

  • 检查 .npmrc 文件:优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的 .npmrc 文件
  • 检查项目中有无 lock 文件。
  • 无 lock 文件:
    • 从 npm 远程仓库获取包信息
    • 根据 package.json 构建依赖树,构建过程:
      • 构建依赖树时,不管其是直接依赖还是子依赖的依赖,优先将其放置在 node_modules 根目录。
      • 当遇到相同模块时,判断已放置在依赖树的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 node_modules 下放置该模块。
      • 注意这一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包
    • 在缓存中依次查找依赖树中的每个包
      • 不存在缓存:
        • 从 npm 远程仓库下载包
        • 校验包的完整性
        • 校验不通过:
          • 重新下载
        • 校验通过:
          • 将下载的包复制到 npm 缓存目录
          • 将下载的包按照依赖结构解压到 node_modules
      • 存在缓存:将缓存按照依赖结构解压到 node_modules
    • 将包解压到 node_modules
    • 生成 lock 文件
  • 有 lock 文件:
    • 检查 package.json 中的依赖版本是否和 package-lock.json 中的依赖有冲突。
    • 如果没有冲突,直接跳过获取包信息、构建依赖树过程,开始在缓存中查找包信息,后续过程相同

image.png

package.json

image.png

npm脚本

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

比较特别的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样。

这意味着,当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。

运行多个 npm script

`&&` npm script 串行
`&`  npm script 并行

npm script 传递参数

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

"lint:js:fix": "npm run lint:js -- --fix"

npm script 钩子

为了方便开发者自定义,npm script 的设计者为命令的执行增加了类似生命周期的机制,具体来说就是 pre 和 post 钩子脚本。这种特性在某些操作前需要做检查、某些操作后需要做清理的情况下非常有用。

举例来说,运行 npm run test 的时候,分 3 个阶段:

  1. 检查 scripts 对象中是否存在 pretest 命令,如果有,先执行该命令;
  2. 检查是否有 test 命令,有的话运行 test 命令,没有的话报错;
  3. 检查是否存在 posttest 命令,如果有,执行 posttest 命令;