环宇的Blog

NPM小技巧

package.json里描述依赖时候一般版本声明是前面带 ‘^’ 的形式,意味着安装依赖时npm会自动尝试去安装声明版本的最新patch,多人合作一个项目时就可能出现大家依赖不一致的问题,出现问题后的复现与调试会比较麻烦,容易出现仅在某台电脑上可以复现的情况。

前言

npm是JS世界的包管理工具,因为其和node捆绑安装,应该是全世界最多人使用的包管理工具。

目前的前端开发普遍离不开构建/依赖管理,大部分项目其实都是一个npm包形式进行的,拥有自己的package.json来管理项目依赖,使用npm script来提供开发/构建/测试等命令。

npm的依赖管理设计得和其他包管理工具差异非常大的一点是,项目依赖默认是本地安装的,全局安装是需要额外声明的。就是说使用npm来安装一个依赖,默认会安装到当前项目路径下的node_modules文件夹里。

这样做缺点是浪费空间,npm包的依赖关系可能比想象中复杂得多,node_modules的体积占用非常大。但也不是没有好处。

比如,版本隔离,每个项目有自己的依赖,各用各的互不干扰。以及第三方库的代码触手可及,便于学习理解,出问题后也便于调试。

安装依赖

通过npm install可以安装依赖,简写npm i。npm6以后,安装依赖后还会生成一个package-lock.json,前面提到过,由于声明依赖时带 ‘^’ ,npm i时候会自动安装package.json里声明的版本所对应的最新patch版本。

那么如果有人不遵守版本规范,恶意在patch版本里做breaking change,这样安装依赖就极有可能出问题。

而且还会影响帮助他人解决问题和云端构建的稳定性。

为了解决这个问题,可以使用npm ci来进行依赖安装。

ci指令的官方文档在这里:https://docs.npmjs.com/cli-commands/ci.html

描述里提到ci这个指令的用处是:Install a project with a clean slate,为项目干净稳定地安装依赖。

表现出来的行为和npm i的区别主要有以下几点:

  1. 会删除现有的node_modules文件夹里的东西再开始安装(干净)

  2. 会严格按照lock文件记录的版本号进行安装(稳定)

  3. 安装速度更快,不更新lock文件

所以,通过ci指令,我们就可以在任何一台电脑上完全复现git中某次提交时候的现场。

不过这个也不是万金油,也不建议抛弃npm i只使用npm ci,正常开发场景下,npm i还是更好地选择,patch版本一般都是为了修复一些bug所发布的,跟随使用最新的patch是好事。

总结就是 npm ci 可以用来干净稳定地复现现场,用于帮助他人debug和CI/CD流程等场景下的安装依赖。