npm模块安装机制
npm 是 Node 的模块管理器,功能极其强大。它是 Node 获得成功的重要原因之一。正因为有了npm,我们只要一行命令:npm install,就能安装别人写好的模块 。
一、从 npm install 说起
npm install 命令用来安装模块到node_modules目录。
$ npm install <packageName>
安装之前,npm install会先检查,node_modules目录之中是否已经存在指定模块。如果存在,就不再重新安装了,即使远程仓库已经有了一个新版本,也是如此。
如果你希望,一个模块不管是否安装过,npm 都要强制重新安装,可以使用 -f 或 --force 参数。
$ npm install <packageName> --force
二、npm update
如果想更新已安装模块,就要用到npm update命令。
$ npm update <packageName>
它会先到远程仓库查询最新版本,然后查询本地版本。如果本地版本不存在,或者远程版本较新,就会安装。
三、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
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'
},
到这个网址下载压缩包,在本地解压,就得到了模块的源码。npm install和npm update命令,都是通过这种方式安装模块的。
四、缓存目录
npm install或npm update命令,从 registry 下载压缩包之后,都存放在本地的缓存目录。
这个缓存目录,在 Linux 或 Mac 默认是用户主目录下的.npm目录,在 Windows 默认是%AppData%/npm-cache。通过配置命令,可以查看这个目录的具体位置。
$ npm config get cache
$HOME/.npm
你最好浏览一下这个目录。
$ ls ~/.npm
# 或者
$ npm cache ls
你会看到里面存放着大量的模块,储存结构是{cache}/{name}/{version}。
$ npm cache ls react
~/.npm/react/react/0.14./
~/.npm/react/react/0.14./package.tgz
~/.npm/react/react/0.14./package/
~/.npm/react/react/0.14./package/package.json
每个模块的每个版本,都有一个自己的子目录,里面是代码的压缩包package.tgz文件,以及一个描述文件package/package.json。
除此之外,还会生成一个{cache}/{hostname}/{path}/.cache.json文件。比如,从 npm 官方仓库下载 react 模块的时候,就会生成registry.npmjs.org/react/.cache.json文件。这个文件保存的是,所有版本的信息,以及该模块最近修改的时间和最新一次请求时服务器返回的 ETag 。
$ rm -rf ~/.npm/*
# 或者
$ npm cache clean
五、模块的安装过程
总结一下,Node模块的安装过程是这样的。
1、发出npm install命令
2、npm 向 registry 查询模块压缩包的网址
3、下载压缩包,存放在~/.npm目录
4、解压压缩包到当前项目的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 <package-name>
上面命令指定,只有超过999999分钟的模块,才从 registry 下载。实际上就是指定,所有模块都从缓存安装,这样就大大加快了下载速度。它还有另一种写法。
$ npm install --cache-min Infinity <package-name>
但是,这并不等于离线模式,这时仍然需要网络连接。因为现在的--cache-min实现有一些问题。
(1)如果指定模块不在缓存目录,那么 npm 会连接 registry,下载最新版本。这没有问题,但是如果指定模块在缓存目录之中,npm 也会连接 registry,发出指定模块的 etag ,服务器返回状态码304,表示不需要重新下载压缩包。
(2)如果某个模块已经在缓存之中,但是版本低于要求,npm会直接报错,而不是去 registry 下载最新版本。npm 团队知道存在这些问题,正在重写 cache。并且,将来会提供一个--offline参数,使得 npm 可以在离线情况下使用。不过,这些改进没有日程表。所以,当前使用--cache-min改进安装速度,是有问题的。
七、离线安装的解决方案
社区已经为npm的离线使用,提出了几种解决方案。它们可以大大加快模块安装的速度。解决方案大致分成三类。
第一类,Registry 代理。
npm-proxy-cache
local-npm(用法)
npm-lazy
上面三个模块的用法很类似,都是在本机起一个 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
有了本机的Registry服务,就能完全实现缓存安装,可以实现离线使用。
第二类,npm install替代。
如果能够改变npm install的行为,就能实现缓存安装。npm-cache 工具就是这个思路。凡是使用npm install的地方,都可以使用npm-cache替代。
$ npm-cache install
第三类,node_modules作为缓存目录。
这个方案的思路是,不使用.npm缓存,而是使用项目的node_modules目录作为缓存。
Freight
npmbox
上面两个工具,都能将项目的node_modules目录打成一个压缩包,以后安装的时候,就从这个压缩包之中取出文件。
npm模块安装机制的更多相关文章
- [转] npm 模块安装机制简介
npm 是 Node 的模块管理器,功能极其强大.它是 Node 获得成功的重要原因之一. 正因为有了npm,我们只要一行命令,就能安装别人写好的模块 . $ npm install 本文介绍 npm ...
- npm 模块安装机制简介
npm 是 Node 的模块管理器,功能极其强大.它是 Node 获得成功的重要原因之一. 正因为有了npm,我们只要一行命令,就能安装别人写好的模块 . $ npm install 本文介绍 npm ...
- npm模块安装机制简介
npm是node的模块管理器,功能及其强大,它是node获得成功的重要原因之一. 正因为有了nom,我们只要一行命令,就能安装别人写好的模块. $ npm install 本文介绍npm模块安装机制的 ...
- 介绍下 npm 模块安装机制,为什么输入 npm install 就可以自动安装对应的模块?
1. npm 模块安装机制: 发出npm install命令 查询node_modules目录之中是否已经存在指定模块 若存在,不再重新安装 若不存在 npm 向 registry 查询模块压缩包的网 ...
- 详解npm的模块安装机制 --社会我npm哥,好用话不多
依赖树表面的逻辑结构与依赖树真实的物理结构 依赖树表面的逻辑结构与依赖树真实的物理结构并不一定相同! 这里要先提到两个命令:tree -d(linux)和npm ls(npm) 在一个npm项目下 ...
- 【npm】详解npm的模块安装机制
依赖树表面的逻辑结构与依赖树真实的物理结构 依赖树表面的逻辑结构与依赖树真实的物理结构并不一定相同! 这里要先提到两个命令:tree -d(linux)和npm ls(npm) 在一个npm项目下 ...
- 详解npm的模块安装机制
详解npm的模块安装机制 依赖树表面的逻辑结构与依赖树真实的物理结构 依赖树表面的逻辑结构与依赖树真实的物理结构并不一定相同! 这里要先提到两个命令:tree -d(linux)和npm ls(npm ...
- 4.npm模块安装和使用(axios异步请求,lodash工具库)
建立package.json npm init 下载包 npm install axios npm install lodash 下载包,并加到package里面 npm install axios ...
- 在Windows平台上安装Node.js及NPM模块管理
1. 下载Node.js官方Windows版程序:http://nodejs.org/#download 从0.6.1开始,Node.js在Windows平台上提供了两种安装方式,一是.MSI安 ...
随机推荐
- [Leetcode Week9]Minimum Path Sum
Minimum Path Sum 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/minimum-path-sum/description/ Descr ...
- 【C语言】一次内存泄露的分析的记录
今天运行一个程序,程序刚启动时占用内存很小,在运行过程中发现占用的内存会一直增大. 用cat /proc/pid/statm的方式查看发现也确实在一直增大. 而且这个程序移植到另外一个平台后,会直接无 ...
- Image.FromStream与Image.FromFile使用区别
将一个图片加载并显示在picturebox上,一般情况下得到预期的结果,然而对于同一个filepath, 若连续两次调用下面的语句系统将会报错(如用户多次选择加载同一张图片使用Image.FromFi ...
- selenium java 读取xml (数据驱动)
selenium 数据驱动 (xml解析) getElementByTagName()可以通过标签名获取某个标签.它所获取的对象是以数组形式存放.如“caption”和“item”标签在info.xm ...
- python高阶函数,map,filter,reduce,ord,以及lambda表达式
为什么我突然扯出这么几个函数,是因为我今天在看流畅的python这本书的时候,里面有一部分内容看的有点懵逼. >>> symbols = '$¢£¥€¤' >>> ...
- [BZOJ2005][Noi2010]能量采集 容斥+数论
2005: [Noi2010]能量采集 Time Limit: 10 Sec Memory Limit: 552 MBSubmit: 4394 Solved: 2624[Submit][Statu ...
- linux下IPTABLES配置详解 (防火墙命令)
linux下IPTABLES配置详解 -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 24000 -j ACCEPT ...
- [BZOJ1790][AHOI2008]Rectangle 矩形藏宝地(四维偏序,CDQ+线段树)
1790: [Ahoi2008]Rectangle 矩形藏宝地 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 553 Solved: 193[Subm ...
- 【枚举】【贪心】 Codeforces Round #398 (Div. 2) B. The Queue
卡题意……妈的智障 一个人的服务时间完整包含在整个工作时间以内. 显然,如果有空档的时间,并且能再下班之前完结,那么直接输出即可,显然取最左侧的空档最优. 如果没有的话,就要考虑“挤掉”某个人,就是在 ...
- 【最大权闭合子图/最小割】BZOJ3438-小M的作物【待填】
[题目大意] 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号),现在,第i种作物种植在A中种植 ...