Javascript:npm模块安装机制简介
正因为有了npm,我们只要一行命令,就能安装别人写好的模块 。
$ npm install
- 1
本文介绍 npm 模块安装机制的细节,以及如何解决安装速度慢的问题。
一、从 npm install
说起
npm install 命令用来安装模块到node_modules目录。
$ npm install <packageName>
- 1
安装之前,npm install
会先检查,node_modules
目录之中是否已经存在指定模块。如果存在,就不再重新安装了,即使远程仓库已经有了一个新版本,也是如此。
如果你希望,一个模块不管是否安装过,npm 都要强制重新安装,可以使用-f或–force参数。
$ npm install <packageName> --force
- 1
二、npm update
如果想更新已安装模块,就要用到npm update命令。
$ npm update <packageName>
- 1
它会先到远程仓库查询最新版本,然后查询本地版本。如果本地版本不存在,或者远程版本较新,就会安装。
三、registry npm update
命令怎么知道每个模块的最新版本呢?
答案是 npm 模块仓库提供了一个查询服务,叫做 registry 。以 npmjs.org 为例,它的查询服务网址是 https://registry.npmjs.org/
。
这个网址后面跟上模块名,就会得到一个 JSON 对象,里面是该模块所有版本的信息。比如,访问 https://registry.npmjs.org/react
,就会看到 react 模块所有版本的信息。
它跟下面命令的效果是一样的。
$ npm view react # npm view 的别名 $ npm info react $ npm show react $ npm v react
- 1
- 2
- 3
- 4
- 5
registry 网址的模块名后面,还可以跟上版本号或者标签,用来查询某个具体版本的信息。比如, 访问 https://registry.npmjs.org/react/v0.14.6
,就可以看到 React 的 0.14.6 版。
返回的 JSON 对象里面,有一个dist.tarball属性,是该版本压缩包的网址。
dist: { shasum: '2a57c2cf8747b483759ad8de0fa47fb0c5cf5c6a', tarball: 'http://registry.npmjs.org/react/-/react-0.14.6.tgz' },
- 1
- 2
- 3
- 4
到这个网址下载压缩包,在本地解压,就得到了模块的源码。npm install
和npm update
命令,都是通过这种方式安装模块的。
四、缓存目录 npm install
或npm update
命令,从 registry 下载压缩包之后,都存放在本地的缓存目录。
这个缓存目录,在 Linux 或 Mac 默认是用户主目录下的.npm
目录,在 Windows 默认是%AppData%/npm-cache
。通过配置命令,可以查看这个目录的具体位置。
$ npm config get cache $HOME/.npm
- 1
- 2
你最好浏览一下这个目录。
$ ls ~/.npm # 或者 $ npm cache ls
- 1
- 2
- 3
你会看到里面存放着大量的模块,储存结构是{cache}/{name}/{version}
。
$ npm cache ls react ~/.npm/react/react/0.14.6/ ~/.npm/react/react/0.14.6/package.tgz ~/.npm/react/react/0.14.6/package/ ~/.npm/react/react/0.14.6/package/package.json
- 1
- 2
- 3
- 4
- 5
每个模块的每个版本,都有一个自己的子目录,里面是代码的压缩包package.tgz
文件,以及一个描述文件package/package.json
。
除此之外,还会生成一个{cache}/{hostname}/{path}/.cache.json
文件。比如,从 npm 官方仓库下载 react 模块的时候,就会生成registry.npmjs.org/react/.cache.json
文件。
这个文件保存的是,所有版本的信息,以及该模块最近修改的时间和最新一次请求时服务器返回的 ETag 。
{ "time":{ "modified":"2016-01-06T23:52:45.571Z", // ... }, "_etag":"\"7S37I0775YLURCFIO8N85FO0F\"" }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
对于一些不是很关键的操作(比如npm search
或npm view
),npm会先查看.cache.json
里面的模块最近更新时间,跟当前时间的差距,是不是在可接受的范围之内。如果是的,就不再向远程仓库发出请求,而是直接返回.cache.json
的数据。
.npm
目录保存着大量文件,清空它的命令如下。
$ rm -rf ~/.npm/* # 或者 $ npm cache clean
- 1
- 2
- 3
五、模块的安装过程
总结一下,Node模块的安装过程是这样的。
- 发出npm install命令
- npm 向 registry 查询模块压缩包的网址
- 下载压缩包,存放在~/.npm目录
- 解压压缩包到当前项目的node_modules目录
注意,一个模块安装以后,本地其实保存了两份。一份是~/.npm
目录下的压缩包,另一份是node_modules
目录下解压后的代码。
但是,运行npm install
的时候,只会检查node_modules
目录,而不会检查~/.npm
目录。也就是说,如果一个模块在~/.npm
下有压缩包,但是没有安装在node_modules
目录中,npm 依然会从远程仓库下载一次新的压缩包。
这种行为固然可以保证总是取得最新的代码,但有时并不是我们想要的。最大的问题是,它会极大地影响安装速度。即使某个模块的压缩包就在缓存目录中,也要去远程仓库下载,这怎么可能不慢呢?
另外,有些场合没有网络(比如飞机上),但是你想安装的模块,明明就在缓存目录之中,这时也无法安装。
六、–cache-min 参数
为了解决这些问题,npm 提供了一个--cache-min
参数,用于从缓存目录安装模块。
--cache-min
参数指定一个时间(单位为分钟),只有超过这个时间的模块,才会从 registry 下载。
$ npm install --cache-min 9999999 <package-name>
- 1
上面命令指定,只有超过999999分钟的模块,才从 registry 下载。实际上就是指定,所有模块都从缓存安装,这样就大大加快了下载速度。
它还有另一种写法。
$ npm install --cache-min Infinity <package-name>
- 1
但是,这并不等于离线模式,这时仍然需要网络连接。因为现在的--cache-min
实现有一些问题。
(1)如果指定模块不在缓存目录,那么 npm 会连接 registry,下载最新版本。这没有问题,但是如果指定模块在缓存目录之中,npm 也会连接 registry,发出指定模块的 etag ,服务器返回状态码304,表示不需要重新下载压缩包。 (2)如果某个模块已经在缓存之中,但是版本低于要求,npm会直接报错,而不是去 registry 下载最新版本。
- 1
- 2
- 3
npm 团队知道存在这些问题,正在重写 cache。并且,将来会提供一个--offline
参数,使得 npm 可以在离线情况下使用。
不过,这些改进没有日程表。所以,当前使用--cache-min
改进安装速度,是有问题的。
七、离线安装的解决方案
社区已经为npm的离线使用,提出了几种解决方案。它们可以大大加快模块安装的速度。
解决方案大致分成三类。
第一类,Registry 代理。
npm-proxy-cache local-npm(用法) npm-lazy
- 1
- 2
- 3
上面三个模块的用法很类似,都是在本机起一个 Registry 服务,所有npm install
命令都要通过这个服务代理。
# npm-proxy-cache $ npm --proxy http://localhost:8080 \ --https-proxy http://localhost:8080 \ --strict-ssl false \ install # local-npm $ npm set registry http://127.0.0.1:5080 # npm-lazy $ npm --registry http://localhost:8080/ install socket.io
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
有了本机的Registry服务,就能完全实现缓存安装,可以实现离线使用。
第二类,npm install
替代。
如果能够改变npm install
的行为,就能实现缓存安装。npm-cache
工具就是这个思路。凡是使用npm install
的地方,都可以使用npm-cache
替代。
$ npm-cache install
- 1
第三类,node_modules
作为缓存目录。
这个方案的思路是,不使用.npm
缓存,而是使用项目的node_modules
目录作为缓存。
Freight
npmbox
上面两个工具,都能将项目的node_modules
目录打成一个压缩包,以后安装的时候,就从这个压缩包之中取出文件。
原文发布时间:2018-6-19
原文作者: 阮一峰
本文来源csdn博客如需转载请紧急联系作者

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JavaScript 异步编程--Generator函数、async、await
JavaScript 异步编程–Generator函数 Generator(生成器)是ES6标准引入的新的数据类型,其最大的特点就是可以交出函数的执行的控制权,即:通过yield关键字标明需要暂停的语句,执行时遇到yield语句则返回该语句执行结果,等到调用next函数时(也就是说可以通过控制调用next函数的时机达到控制generator执行的目的)重新回到暂停的地方往下执行,直至generator执行结束。 基本结构 以下是一个典型的generator函数的示例,以”*”标明为generator。 function* gen(x){ var y = yield x + 2; console.log(y); // undefine var yy = yield x + 3; console.log(yy); // 6 return y; // 没啥用 } var g = gen(1); var r1 = g.next(); console.log(r1); // { value: 3, done: false } var r2 = g.next(); console.log(r2);...
- 下一篇
JavaScript弹出对话框的三种方式
javascript的三种对话框是通过调用window对象的三个方法alert(),confirm()和prompt()来获得,可以利用这些对话框来完成js的输入和输出,实现与用户能进行交互的js代码。 今天小编就来简单介绍一下js中的三种弹出对话框,小编先单独对这几个方法进行详细讲解,接着,将这几个方法进行对比,好了,开始我们的js之旅吧`(*∩_∩*)′...... 第一种:alert()方法 alert()方法是这三种对话框中最容易使用的一种,她可以用来简单而明了地将alert()括号内的文本信息显示在对话框中,我们将它称为警示对话框,要显示的信息放置在括号内,该对话框上包含一个“确认”按钮,用户阅读完所显示的信息后,只需单击该按钮就可以关闭对话框。下面来看一个使用alert()方法的例子,代码如下所示: ? 1 2 3 4 5 6 7 8 9 <html> <head> <title>编写html页面</title> <script language= "javascript" > //JavaScript脚本标注 a...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7设置SWAP分区,小内存服务器的救世主
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS关闭SELinux安全模块