2022-15 | package与package-lock的区别 | npm ci and install | lerna bootstrap --hoist --ci

node.js

package.json与package-lock.json的区别

参考文档 https://nodejs.dev/learn/the-package-lock-json-file

package-lock.json是为了弥补package.json的一些不足之处。

package.json中记录的包依赖版本信息遵循如下语法:

  • 如果package.json中记录的版本信息格式为~0.13.0,则表示仅允许更新补丁版本(0.13.1),不允许更新小版本(0.14.0)
  • 如果package.json中记录的版本信息格式为^0.13.0,则表示除了最靠近左边的非0版本号不可以更新(如果主版本非0,则可以更新小版本和补丁版本;如果主版本为0,小版本不为0,那么只允许更新补丁版本)

项目进行版本管理时,node_modules中安装的包我们不会提交到远端仓库,我们只会把package.json纳入版本管理,那么当其他开发者在本地拉取项目,执行npm install命令后会发生如下行为:

  1. npm遵循package.json的包版本要求在本地安装依赖包

此时可能会安装包最新的小版本或者补丁版本,导致的结果会是每个开发者初始化后的项目不一致,还有可能会因为安装依赖包的小版本中引入bug。

package-lock.json就是解决上述的问题,其他开发者可以严格遵循package-lock.json中的版本下载依赖包(通过执行npm ci命令),这样便能确保每个开发者初始化项目后环境一致。

什么情况下package-lock.json中的版本信息会更改

参考文档:https://nodejs.dev/learn/update-all-the-nodejs-dependencies-to-their-latest-version

  • 执行npm update命令会更新package-lock.json中依赖版本
  • 当执行npm install命令时,会发生如下行为:
    1. 检查package-lock.json中的包版本是否符合package.json中的范围
    2. 如果满足,按照package-lock.json安装最新的可用包被安装到node_modules路径,包对应的版本信息被添加到package.json和package-lock.json(package.json是大概版本,package-lock.json中是确切的版本)
    3. 如果不满足,则更新包最新的版本

npm

版本语法

参考文档 https://nodejs.dev/learn/semantic-versioning-using-npm

版本采用三个数字来标识,x.y.z

  • x表示主版本
  • y表示小版本
  • z表示补丁版本

package.json中记录的版本前会增加一些符号,这些符号在执行npm update是会起作用,具体规则查看参考文档

命令选项

ci
  • 如果package-lock.json中的版本与package.json中不符合,则报错,ci命令退出
  • 执行ci不会更新package.json
  • ci执行更快,常用于自动化环境,比如测试平台,持续集成,持续部署
install

安装一个或者多个依赖的包,如果包有package-lock,则npm install会遵循package-lock.json

lerna

lerna是一个多项目开发下的包管理工具

命令选项

clean

清除非根路径下的node_modules

bootstrap

处理本地包关联,然后安装包

–hoist选项把子模块的共用模块提升至根路径

–ci选项指通过npm ci安装依赖包,通过npm ci安装要求必须要有package-lock.json

-hoist和–ci冲突,当添加–hoist选项时,默认执行npm i,但是不会更新package-lock.json

相关issue https://github.com/lerna/lerna/issues/2047

//源代码
if (hoist) {
 let hoisting;

 if (hoist === true) {
     // lerna.json `hoist: true`
     hoisting = ["**"];
 } else {
     // `--hoist ...` or lerna.json `hoist: [...]`
     hoisting = [].concat(hoist);
 }

 if (nohoist) {
     if (!Array.isArray(nohoist)) {
         // `--nohoist` single
         hoisting = hoisting.concat(`!${nohoist}`);
     } else {
         // `--nohoist` multiple or lerna.json `nohoist: [...]`
         hoisting = hoisting.concat(nohoist.map((str) => `!${str}`));
     }
 }

 this.logger.verbose("hoist", "using globs %j", hoisting);
 this.hoisting = hoisting;
}
if (npmClient === "npm" && this.options.ci && hasNpmVersion(">=5.7.0")) {
 // never `npm ci` when hoisting
 this.npmConfig.subCommand = this.hoisting ? "install" : "ci";

 if (this.hoisting) {
 // don't mutate lockfiles in CI
 this.npmConfig.npmClientArgs.unshift("--no-save");
 }
}

执行lerna bootstap --hoist --ci --loglevel verbose输出

lerna notice cli v4.0.0
lerna info ci enabled
lerna verb hoist using globs ["**"]
lerna info Bootstrapping 4 packages
lerna verb lifecycle preinstall

npm ci与npm i主要有以下的区别。

  • npm i依赖package.json,而npm ci依赖package-lock.json。
  • 当package-lock.json中的依赖于package.json不一致时,npm ci退出但不会修改package-lock.json。
  • npm ci只可以一次性的安装整个项目依赖,但无法添加单个依赖项。
  • npm ci安装包之前,会删除掉node_modules文件夹,因此他不需要去校验已下载文件版本与控制版本的关系,也不用校验是否存在最新版本的库,所以下载的速度更快。
  • npm安装时,不会修改package.json与package-lock.json

打印更多日志

lerna --loglevel 日志级别

比如打印verbose日志
lerna --loglevel verbose

你可能感兴趣的:(后端,node.js,npm)