4、Node.js npm离线安装:npm pack打包、npm cache离线利用、npm离线仓库verdaccio搭建
说实话,Node.js 的 npm 生态虽然方便,但一到内网环境就让人头疼。我经历过好几次——项目急着上线,结果服务器连不上外网,npm install 直接卡死。那种感觉,你懂的。
今天我就把几种靠谱的离线安装方案掰开揉碎了讲。从最简单的单包打包,到搭建企业级离线仓库,一条龙给你安排明白。
4.1 方案一:npm pack 打包——最直接的单包搬运
如果你只需要安装一两个包,npm pack 是最快的方式。说白了,就是把一个 npm 包压缩成 .tgz 文件,然后拿到内网去解压安装。
4.1.1 打包操作
在有网的机器上执行:
# 打包单个包
npm pack express
# 打包指定版本
npm pack express@4.18.2
# 打包后生成 express-4.18.2.tgz
嗯,这里要注意:npm pack 只会打包你指定的那个包,不会自动包含它的依赖。我刚开始用的时候就被坑过——把包拷到内网,一安装发现缺了一堆依赖。
npm pack 只打包当前包,依赖需要单独处理。
4.1.2 离线安装
把 .tgz 文件拷贝到内网机器,然后:
# 直接安装 tgz 文件
npm install ./express-4.18.2.tgz
# 或者解压后安装
tar -xzf express-4.18.2.tgz
cd package
npm install
我个人习惯用第一种方式,省事。但如果你要安装的包依赖很多,这个方法就不太合适了。
4.2 方案二:npm cache 离线利用——批量依赖的救星
当项目依赖几十上百个包时,一个个打包显然不现实。这时候,npm cache 就派上用场了。
4.2.1 缓存原理
npm 在安装包时,会把下载的包缓存到本地。默认路径是 ~/.npm 目录。你想想看,既然本地有缓存,那能不能直接把缓存搬到内网?
答案是:可以,但有技巧。
4.2.2 缓存导出与导入
在有网的机器上:
# 先安装项目依赖,生成缓存
npm install
# 查看缓存位置
npm cache ls
# 导出缓存(npm v6+)
npm cache ls --cache ./npm-cache-backup
# 或者直接打包 .npm 目录
tar -czf npm-cache.tar.gz ~/.npm
然后到内网机器:
# 解压缓存
tar -xzf npm-cache.tar.gz -C ~/
# 设置离线模式安装
npm install --prefer-offline --no-audit --no-fund
--prefer-offline 参数,npm 会优先使用缓存,只有缓存没有时才去网络下载。在内网环境,这个参数能避免很多超时问题。
4.2.3 缓存目录结构
npm 缓存的结构是这样的:
~/.npm/
├── _cacache/ # 主要缓存目录
│ ├── content-v2/ # 包内容
│ └── index-v5/ # 索引
└── _locks/ # 锁文件
我记得有一次,同事直接把整个 ~/.npm 目录拷贝到内网,结果 npm install 还是去联网。后来才发现,_cacache 目录的权限不对。嗯,拷贝时记得保持文件权限。
4.3 方案三:verdaccio 搭建离线仓库——企业级解决方案
如果你需要长期维护内网环境,或者团队多人协作,搭建一个私有 npm 仓库才是正道。我个人最推荐 verdaccio,轻量、好配、功能全。
4.3.1 verdaccio 是什么?
verdaccio 是一个轻量级的 npm 私有仓库。它支持:
- 缓存代理:第一次从外网下载,之后从缓存提供
- 私有包发布:团队内部包可以发布到本地
- 权限控制:可以设置谁可以发布、谁可以安装
- 离线可用:缓存过的包,断网也能安装
4.3.2 安装与配置
安装 verdaccio 很简单:
# 全局安装
npm install -g verdaccio
# 启动(默认端口 4873)
verdaccio
启动后,访问 http://localhost:4873 就能看到仓库界面。但默认配置只适合开发环境,生产环境需要调整。
配置文件一般在 ~/.config/verdaccio/config.yaml,我常用的配置:
# 存储路径
storage: ./storage
# 插件目录
plugins: ./plugins
# 上游 registry
uplinks:
npmjs:
url: https://registry.npmjs.org/
# 缓存超时时间(毫秒)
cache: true
max_fails: 10
timeout: 60s
# 包访问权限
packages:
'@*/*':
access: $all
publish: $authenticated
proxy: npmjs
'**':
access: $all
publish: $authenticated
proxy: npmjs
# 监听地址
listen:
- 0.0.0.0:4873
# 开启离线模式
offline: false
uplinks 里的 cache: true 一定要开。这样第一次从外网下载后,包会缓存到本地 storage 目录。之后即使断网,也能从缓存安装。
4.3.3 离线仓库的初始化
搭建好 verdaccio 后,需要先「预热」缓存。我的做法是:
# 1. 设置 npm 指向本地仓库
npm set registry http://内网IP:4873
# 2. 在有网环境下,安装项目依赖
npm install
# 3. 此时所有依赖都被缓存到 verdaccio 的 storage 目录
# 4. 把 storage 目录打包,拷贝到内网服务器
tar -czf verdaccio-storage.tar.gz ~/.config/verdaccio/storage
到了内网,解压 storage 目录,启动 verdaccio,团队就能直接离线安装了。
4.3.4 团队使用配置
团队成员只需要修改 npm 配置:
# 设置 registry
npm set registry http://内网IP:4873
# 或者使用 .npmrc 文件
echo "registry=http://内网IP:4873" > .npmrc
然后正常执行 npm install 即可。如果包已经在缓存中,安装速度会非常快。
config.yaml 里的 uplinks 部分注释掉,或者设置 offline: true。否则 verdaccio 会尝试连接外网 registry,导致超时。
4.4 三种方案对比
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| npm pack | 单包或少量包 | 简单直接,无需额外工具 | 依赖需单独处理,不适合大型项目 |
| npm cache | 单个项目批量依赖 | 利用现有缓存,无需搭建服务 | 缓存目录大,权限问题多 |
| verdaccio | 团队协作、长期维护 | 功能完善,支持私有包和权限控制 | 需要额外搭建和维护 |
4.5 核心流程总结
下面这张图,把三种方案的流程串起来了。你可以根据实际情况选择:
4.6 我的经验总结
做了这么多年运维,我踩过的坑不少。给你几个实在的建议:
- 先列依赖清单:用
npm ls --depth=0查看顶层依赖,再用npm ls --all看全量依赖。心里有数再动手。 - 版本锁死:内网环境一定要用
package-lock.json或npm-shrinkwrap.json。否则同样的包名,内外网版本不一致,够你查半天的。 - 测试验证:离线安装完成后,跑一遍
npm test或node -e "require('你的包')"。确保所有依赖都正常。 - 定期更新缓存:如果使用 verdaccio,建议每个月在有网环境更新一次缓存,把新版本的包同步进来。
好了,这三种方案够你应对大部分离线场景了。从单包到企业级,按需选择就行。