• home > webfront > ECMAS > npm-node >

    彻底锁定项目环境:package-lock包依赖于nodejs环境/npm版本锁

    Author:zhoulujun Date:

    一些老项目对 node 版本是有要求的,往往使用默认的新版本包安装不上,scripts 也跑不起来。解决问题的根本方法是项目中要对 node 版

    一些老项目对 node 版本是有要求的,往往使用默认的新版本包安装不上,scripts 也跑不起来。

    解决问题的根本方法是项目中要对 node 版本进行提示或锁死,否则新人仍会踩坑。

    我们先来回顾一下 npm版本管理(《 package.json和bower.json dependencies依赖包中^符号和~符号前缀区别》)

    • 符号^:表示主版本固定的情况下,可更新最新版。例如:vuex: "^3.1.3",3.1.3及其以上的3.x.x都是满足的。

    • 符号~:表示次版本固定的情况下,可更新最新版。如:vuex: "~3.1.3",3.1.3及其以上的3.1.x都是满足的。

    • 无符号:无符号表示固定版本号,例如:vuex: "3.1.3",此时一定是安装3.1.3版本。

    没有版本锁定的情况下,在执行每次npm i的时候,对应的版本前都有个^符号。也就是未固定版本的依赖如果有了次版本更新或者修订版本更新,会自动安装对应的最新版。 在这种情况下,你再次install时安装的包的版本可能与前次不一样,具体的,你可以到package-lock.json中查看实际的包版本。 例如:A新建了一个项目,生成了上面这份package.json文件,但A安装依赖的时间比较早,此时packageA的最新版本是2.1.0,该版本与代码兼容,没有出现bug。后来B克隆了A的项目,在安装依赖时packageA的最新版本是2.2.0,那么根据语义npm会去安装2.2.0的版本,但2.2.0版本的API可能发生了改动,导致代码出现bug。

    package.json会带来的问题,同一份package.json在不同的时间和环境下安装会产生不同的结果。

    npm作为开源世界的一部分,也遵循一个发布原则:相同大版本号下的新版本应该兼容旧版本。即2.1.0升级到2.2.0时API不应该发生变化。但很多开源库的开发者并没有严格遵守这个发布原则,导致了上面的这个问题。

    为了在不同的环境下生成相同的node_modules,引入版本依赖锁定就尤为必要了。

    为了解决 npm install 的不确定性问题,在 npm 5.x 版本新增了 package-lock.json 文件,而安装方式还沿用了 npm 3.x 的扁平化的方式。

    package-lock.json文件与package.json两者有什么区别与关联?

    • 生成方式

      • package.json文件已不再自动生成,npm init ,根据命令行提示输入一些基本信息,可初始化生成package.json文件

      • 执行"npm install"时,node会重新生成package-lock.json文件,然后把node_modules中的模块信息全部记入package-lock.json文件

    • 两者的区别

      • package.json文件只记录通过npm install方式安装的模块信息,而这些模块所依赖的其他子模块的信息不会记录

      • package-lock.json文件锁定所有模块的版本号,包括主模块和所有依赖子模块

      包的下载流程规则

    npm包的下载流程规

    改动影响

    • 两个文件的模块信息不冲突时(如package.json中模块版本区间^1.1.0包含lock文件中已安装的版本^1.7.0)

      • 执行npm install,node从package.json文件读取模块名称,从package-lock.json文件中获取版本号,然后进行下载或者更新

    • 两个文件的模块信息冲突时(如package.json中模块版本区间^1.1.0不包含lock文件中已安装的版本^2.11.0)

      • 执行npm install,node从package.json文件读取模块名称和范围,按其规则下载包,并更新package-lock.json文件版本

    package-lock.json 保证node_modules 版本与目录结构

    package-lock.json 文件 和 node_modules 目录结构是一一对应的,即项目目录下存在 package-lock.json 可以让每次安装生成的依赖目录结构保持相同。

    package-lock.json 可以显著加速依赖安装时

    package-lock.json 中已经缓存了每个包的具体版本和下载链接,不需要再去远程仓库进行查询,然后直接进入文件完整性校验环节,减少了大量网络请求。

    开发系统应用时,建议把 package-lock.json 文件提交到代码版本仓库,从而保证所有团队开发者以及 CI 环节可以在执行 npm install 时安装的依赖版本都是一致的。

    在发布npm包是,所以我们不应该把package-lock.json 文件发布出去( npm 默认也不会把 package-lock.json 文件发布出去)


    解决包依赖的版本问题,但是npm 与nodejs 版本,还是没锁定。

    如何锁定npm与nodejs版本呢?

    .nvmrc

    在项目根目录添加 .nvmrc 文件可指定 nvm 默认的 node 版本。在项目根目录执行如下命令

    node -v > .nvmrc

    会在项目根目录生成.nvmrc 文件

    v14.19.0
    engine-strict = true//默认没有这一行

    在执行 nvm use, nvm install, nvm exec, nvm run 或 nvm which 这些命令时,都会从该文件读取版本信息。

    在新的环境下,clone 项目后通过 nvm install && nvm use 就可使用上与项目相匹配的 node 版本。

    engines

    通过在 package.json 中指定 engines 字段,可限定项目使用的 node 版本,甚至 npm 版本。

    {
      "name": "bk-vision",
      "version": "0.0.1",
      "engines": {
        "node": "^v14.19.0",
        "npm": "^6.14.16"
      }
    }

    不过,通常情况下,配置之后你会发现,该字段只对 yarn 生效:

    根据 npm 文档中关于 engines 的部分,发现要让 npm 识别 engines 字段,还需要配置 engine-strict: true

    创建 .npmrc 文件配置如下内容:

    engine-strict = true


    版本依赖锁定方案中,最基础的一条就是:不要使用cnpm/tnpm,因为cnpm/tnpm,是不支持依赖版本锁定的。

    也即是说,无论你的项目中有package-lock.json、npm-shrinkwrap.json还是yarn-lock.json文件,执行cnpm i安装依赖的时候他们都只是摆设,都只会根据package.json文件进行安装

    但是使用npm避不开的一个问题就是安装速度,实在太慢了。这里我们可以通过手动更换npm源和nrm的方式实现使用npm命令的同时,依然享受cnpm的安装速度。

    • 设置npm源: npm config set registry [url]

    • 查看确认: npm config get registry


    本地不同项目,nodejs与npm 版本不同,如何解决呢?

    具体参看《nvm使用详解——命令解析大全》、《npm包管理问题:安装nvm后如何管理各个版本间包


    参考文章:

    www.conardli.top/blog/article/前端工程化/前端工程化-剖析npm的包管理机制(完整版).html#导读

    锁定项目的 node 版本 https://www.cnblogs.com/Wayou/p/14724138.html

    请将你的npm依赖版本锁定 https://juejin.cn/post/6960928446826741796

    从package-lock看npm版本锁定相关知识 https://blog.csdn.net/cindy647/article/details/105228158



    转载本站文章《彻底锁定项目环境:package-lock包依赖于nodejs环境/npm版本锁》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/nodejs/8789.html