一篇 NPM 小记

Posted by Ray on 2018-03-07

常见问题

1.npm 的package.json中的~和^

  • ~会匹配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x版本,但是不包括1.3.0
  • ^会匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,包括1.3.0,但是不包括2.0.0

你也有可能会看见在 package.json 中模块的版本号前面既没有 ~ 也没有 ^ 就像下面那样:

1
"moment": "2.4.0"

上面的情况属于精确安装模块指定的版本号。通过命令参数-E,或者 --save-exact 来指定版本号安装的。上述模块对应的精确安装命令:npm install --save-exact [email protected]

2.npm outdate与第三方工具npm-check

npm outdate此命令会列出项目中所有已经过时的包,像下面一样:

推荐使用检查依赖包更强大的一个工具 npm-check,更强大分析包的能力以及可以通过加上参数提供交互式更新方式,详情请参考其文档说明。安装完成后npm-check检查项目依赖包,展示像下面一样:

3.dependencies or devDependencies or optionalDependencies

dependencies(生产环境的依赖的包目录)devDependencies(开发环境的依赖包目录)

在项目的 package.json 使用命令 npm install --save moduel安装的模块会注册到 dependencies 目录中去(npm 5 开始 通过npm install不加–save 和npm install –save一样 都是局部安装并会把模块自动写入package.json中的dependencies里。)

npm install --dev module 并会安装模块并自动写入package.json中的 devDependencies 里。

当你 clone 下来了一个新项目在项目根目录下执行npm install的时候是会同时安装 dependencies 和 devDependencies中的所有依赖。当你的项目需要在生产环境中只需要安装 dependencies 中的依赖时,执行的是npm install --production命令。(如果配置了NODE_ENV环境变量为production,那么执行npm install就只安装dependencies里面的包。安装完后可以用npm ls查看安装的包的情况。)

With the –production flag (or when the NODE_ENV environment variable is set to production), npm will not install modules listed in devDependencies.

此外,你还有可能看到形如:

1
2
3
"optionalDependencies": {
"gulp": "^3.9.1"
}

optionalDependencies 是你在使用npm install npm install --save-optional gulp是所注册在可选依赖里的模块包,在项目执行npm install --no-optional就可以跳过可选包安装。

Tips : 在存在 package-lock.json 时npm install --no-optional你可能会发现依旧装上了可选模块,(它的issue页讨论),此时你可能还要加上另外一个参数执行npm install --no-optional --no-package-lock才能如愿。

4.npm config

查看和管理npm的基础配置。npm config ls -l

可以通过npm config get proxy查看你是否设置了npm 的代理。
npm config set registry https://registry.npm.taobao.org改成更快的淘宝源,解决出现安装不了模块或者速度慢的问题。

5.npm cache

当你使用命令 npm config get cache命令时 你会得到你的本地 npm 缓存的完整路径,npm 缓存是什么呢,可以先从npm install的执行过程说起(此部分参考阮一峰老师的博客):

  1. 发出npm install命令
  2. npm 向 registry 查询模块压缩包的网址
  3. 下载压缩包,存放在~/.npm(本地NPM缓存路径)目录
  4. 解压压缩包到当前项目的node_modules目录

实际上说一个模块安装以后,本地其实保存了两份。一份是~/.npm目录下的压缩包,另一份是node_modules目录下解压后的代码。但是,运行npm install的时候,只会检查 node_modules 目录,而不会检查~/.npm目录。如果一个模块在~/.npm下有压缩包,但是没有安装在node_modules目录中,npm 依然会从远程仓库下载一次新的压缩包。

阮老师在当时文中提到的离线安装时所说的有很多弊端的npm install --cache-min命令已经在npm 5.0.0开始被 deprecated 了

–cache-min and –cache-max have been deprecated. (#15666)

我们想利用已经在缓存中之前已经备份的模块实现离线模块安装的的 cache 机制已经在V5的时候重写了,缓存将由 npm 来全局维护不再需要开发人员操心,离线安装时将不再尝试连接网络,而是降级尝试从缓存中读取,或直接失败。就是如果你 offline ,npm将无缝地使用您的缓存。以下新增参数命令翻译自npm v5.0.0的release

  • 一个新的--prefer-offline选项将使npm跳过任何有条件的请求(304检查)过时的缓存数据,并且只有在缓存中丢失了某些内容时才能访问网络
  • 一个新的--prefer-online选项,它将强制 npm 重新验证缓存数据(使用304次检查),忽略任何过时检查,并用重新验证的新数据刷新缓存。
  • 一个新的 --offline 选项将强制npm使用缓存或退出。如果试图安装的任何内容尚未存在于缓存中,它将报 ENOTCACHED错误。
  • 一个新的npm cache verify命令,它将对你的缓存进行辣鸡回收,减少不需要的东西占据的磁盘使用量,并且会对索引和内容进行全面的完整性验证。

6.package-lock.json 问题

项目中如果是用 npm V5 以上版本就会有这么一个详细记录安装模块的细节的文件。确定当前安装的包的依赖,以便后续重新安装的时候生成相同的依赖,而忽略项目开发过程中有些依赖已经发生的更新。

你可能会看到过“如果手动修改了 package.json 文件中已有模块的版本,直接执行npm install不会安装新指定的版本,只能通过npm install xxx@yy更新” ,不过这是 V5.0.0 的问题,现在V5.4.2版本后如果改了package.json,且package.json和lock文件不同,那么执行npm i时npm会根据package中的版本号以及语义含义去下载最新的包,并更新至lock。详见这个知乎回答

其余常见命令

  • npm ls 查看安装的模块
  • npm uninstall 卸载模块
  • npm update 更新模块
  • npm help 查看某条命令的详细帮助
  • npm version 查看模块版本
  • npm view 查看模块的注册信息
  • npm publish 发布模块
  • npm adduser 用户登录
  • npm init 初始化项目,并在项目文件夹中引导创建一个package.json文件
  • npm root 查看包的安装路径
本文为原创文章作为学习交流笔记,如有错误请您评论指教
转载请注明来源:https://isliulei.com/article/NPM小记/