npm包离线安装方法(npm 离线包)
有时候,你可能会想在离线状态下安装npm包。这可能是由于糟糕的网络、或者你在飞机上、再或者是你正在开会。我已经梦想能离线安装npm很久了!
有人说人应该追随梦想,除非时间太过久远或者是梦想不可能实现。幸运的是,现在已经有一些方法让我们能够离线安装npm包了。
--cache-min
首先,这是一个npm内置的选项(但是并不完美)。理论上,当你想 强制从npm的缓存安装npm包时,你可以使用--cache-min这个参数,并给它配上一个很高的数值。比如:
或者,使用npm --cache-min Infinity。每次都手动输入这么复杂的命令实在让人感到无趣,所以不妨在你的配置文件(dotfiles)里为它赋上一个别名。我就在我的bash配置文件里这么做了:
在理想状态下,npm应该将这个命令命名为--offline才对。So,为什么这就不能在npm3中成为一个默认设置呢?
我们需要一条命令,但不是现在
上面的--cache-min hack会带来许多不必要的麻烦。
当我们使用这个命令时,如果我们的package有一些不在缓存中的依赖的话,npm仍然会通过网络与仓库通信。并且,如果你的package中依赖的包的版本比曾经安装过的要新,这条命令也会失败。
npm团队已经开始考虑推出一个原生的offline参数了,因为大部分用户都对npm cache实现的细节不够了解。从我了解到的情况看,他们愿意最终推出对npm离线使用的全部支持。但是现在,我们还是来看看一些第三方提供的权宜之计吧。
local-npm
相对于--cache-min,一个更强大的解决方案是Nolan Lawson的“离线优先”的local-npm(我非常喜欢它!)。这本质上是一个Node服务器,就像一个本地的npm镜像一样(但是不需要复制整个npm仓库)。
使用local-npm时,你安装的package会从仓库中获取,并且随后,模块和它们的依赖都会被存在一个本地的PouchDB数据库中。这样随后的npm install命令就可以通过本地缓存而不是网络去安装package了。local npm也考虑到了要保持模块的版本更新。它通过监听远程仓库的变化来实时更新模块版本,所以你不用担心它会造成模块的版本落后。
安装local-npm , 运行:
npm是基于CouchDB的。local-npm复制了这个数据库的skimdb部分,成为了一个本地的PouchDB实例。运行:
将会开始这个复制的过程。你不需要等待一个完整的skimdb的下载。因为当一个库没有被复制时,local-npm会自动会回落到用网络下载的方式。就像之前提到的那样,local-npm是“离线优先”的。它会在你第一次安装某个版本的package时预下载元数据和压缩包。
为了完全的安装好,你还需要将npm指向这个本地的服务器local-npm。运行以下代码:
哈哈,你现在应该可以打开一个新的终端并且使用npm install,用缓存安装任何依赖任何依赖包了。
一个成功的离线npm install看起来应该像这样:
为了更清楚的理解这个过程,我新创建了一个标签,运行了local-npm,并且我们可以看到,它成功的代理了bluebird和lodash模块的请求
为了检查是否所有东西都像预期那样顺利工作:
- 检查你的网络开启了没
- 运行npm install去获取一个包或者dependencies中的依赖。例如lodash.
- 这时候,local-npm会将这些模块存为一个缓存版本
- 清除npm的缓存,使用npm cache clean或者直接在node_modules目录中删除模块
- 关掉你的WIFI或者有线网
- 尝试再次使用npm install。在没有网络的情况下,一切都应该被local-npm正确的安装。
local-npm安装时的一个方便额外选项是——网页界面。它可以让你在浏览器中浏览和搜索本地模块。你可以通过这个地址访问它:
http://localhost:5080/_browse。
从local-npm发布npm包不需要对仓库的设置进行任何额外的改变。你只需要确保网络通畅并且其其余一切正常工作
提醒一下,如果你需要切换到主仓库或者是你因为某些原因更喜欢镜像仓库,你只需要再用一次npm set命令:
虽然local-npm非常好,但是我们目前仍不明确npm团队想往哪个 方向为npm提供离线支持。不管怎样,local-npm现在仍然是一个非常好的权宜之计,所以我非常建议你去尝试尝试它。
在发布这篇文章的时候,Nolan已经分享了一些local-npm和普通npm的速度测试。总之,普通的npm在你第一次npm install一个包的时候会更快,但是之后local npm会更胜一筹。
配合其他工具使用local npm
我尝试了使用local-npm配合Yeoman和雅虎的generator-fluxible,仅仅把npm当做包管理程序。就像你在下面看到的所有事情(包括对依赖的安装)都很顺利,并且,我可以顺利地预览从缓存安装的输出结果(此处翻译存疑,建议阅读原文)。
npm_lazy
另一个流行的npm惰性缓存代理是npm_lazy。类似于local-npm,一旦你安装了任何不在本地缓存中的模块,npm lazy就会把它缓存起来。
在npm_lazy中,唯一被缓存的东西是包的索引元数据(index metadata)和包的tarfile。几乎所有的请求都会被代理。这意味着从缓存中npm install包都可以工作,但是如果主仓库或者镜像仓库(它们相当于没有npm lazy时的替代品)挂掉的话,更多的外部端点(endpoints)将不能工作。
安装:
开启服务,运行:
类似于local npm,仓库可以被设置为本地服务,运行下面的命令:
npm_lazy的配置设计的非常好,它允许你定制缓存的生周期,设置最大请求数,HTTP超时时间以及要不要检查HTTPS请求与Node的发布机构列表是否冲突。
替代品
有许多npm包致力于为npm提供缓存代理服务(例如Sinopia)。但是我致力于保持这个清单足够短,以避免选择恐惧症。
打包
这篇文章中我们已经了解了npm包离线安装,但是你可能还对离线的打包感兴趣。你往往希望可以将一个包和它的依赖打包在一起,放在一个单一归档(single archive)中,这样就可以通过一个离线的系统去分享。这种情况在工作环境中十分常见。
npm开源项目上有一个开放的issue,致力于通过npm pack和bundledDependencies改善打包功能。在这成为现实之前,我建议你使用一下方案之一:
- Freight - 不管是npm还是bower包,都能将包和其依赖打包在一起成为一个单一归档(single archive)
- npmbox - 支持在一个单一归档(single archive)中创建和安装依赖创建
- bundle-dependencies - 深层的打包所有的模块依赖到一个巨大的npm包中,可以在之后发布到npm上