npm shrinkwrap

我们使用node开发时,经常需要依赖一些模块来完成功能需求,而我们所依赖的模块也必然会依赖其他模块,就这样一级一级的依赖,而且这些依赖模块并不为我们所控制。一个产品或项目的开发周期,少则几个周,多则几个月几年。开发人员往往在一开始时下载了依赖包发现能够正常工作后,便一直在依赖包的当前版本上工作,然而在线上服务器布属时往往是根据依赖配置文件,重新下载依赖包。可这个时候依赖链中的包的开发者很可能已经将某个模块升级了,而且并不能保证这些新的依赖包没有bug。一旦依赖链上的某个包出现bug,可能对产品造成严重影响,而且这个时候往往无法找回开发时所用的正确依赖,以及依赖的依赖的版本。

我们来看一个经典的例子:

假设有包A依赖包B,包B依赖包C:

//包A
{
"name": "A",
"version": "0.1.0",
"dependencies": {
"B": "<0.1.0"
}
}
//包B
{
"name": "B",
"version": "0.0.1",
"dependencies": {
"C": "<0.1.0"
}
}
//包C
{
"name": "C",
"version": "0.0.1"
}

假设在开发时,我们运行npm install A得到以下的依赖链:

A@0.1.0
`-- B@0.0.1
`-- C@0.0.1

而在项目需要部署上线时,我们不可能把所有node_modules放到线上服务器中,所以将项目代码放到服务器时,我们便会运行npm install A,而恰恰这阶段,包B的版本更新到了0.0.8,所以我们在服务器上得到的依赖链就是:

A@0.1.0
`-- B@0.0.8
`-- C@0.0.1

如果B的新版本有问题,这时就会对产品造成难以预估的损失。

所以我们推荐当开发环境中,所有依赖模块都能正常工作时,便在部署到服务器之前将依赖包的版本锁住,这时候就运行这个命令:

npm shrinkwrap

我们会得到一个npm-shrinkwrap.json的文件,这个文件保存了所有当前使用的依赖模块的版本:

{
"name": "A",
"version": "0.1.0",
"dependencies": {
"B": {
"version": "0.0.1",
"from": "B@^0.0.1",
"resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
"dependencies": {
"C": {
"version": "0.0.1",
"from": "org/C#v0.0.1",
"resolved": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4"
}
}
}
}
}

将这个文件连同项目源码一同部署到服务器上,然后运行npm install这时候,npm会首先检查有没有npm-shrinkwrap.json文件,有的话会根据该文件中依赖包的版本以及resolve字段下载依赖包,这样就能够保证线上环境与开发环境一致。

from 与 resolve

这个文件时根据我们当前项目中的node_modules中的模块的当前版本生成的。version代表当前模块版本,from表示的是package.json中对该依赖模块的版本描述,resolve代表当前模块的实际来源。

比如当你的package.json中对于某个依赖模块有如下描述:

"dependencies": {
"acorn": "^3.0.0",
....................................
}

acorn模块安装后,它的package.json文件中会出现如下字段:

  "_from": "acorn@>=3.0.0 <4.0.0",
"_resolved": "https://registry.npmjs.org/acorn/-/acorn-3.2.0.tgz",

这时候运行npm shrinkwrap便会出现:

  "dependencies": {
"acorn": {
"version": "3.2.0",
"from": "acorn@>=3.0.0 <4.0.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-3.2.0.tgz"
},

对于npm-shrinkwrap.json来说,这其中最重要的就是resolve字段。

使用npm shrinkwrap的注意事项

  • 如果要安装新的依赖模块,一定要使用npm install --save 模块,这样保证package.json与npm-shrinkwrap.json文件同步更新。
  • node_modules中的模块必须能够包含package.json中的依赖模块,如果node_modules中不存在package.json中指定的依赖模块,运行npm shrinkwrap会报错;如果node_modules中包含有package.json中未指定的模块,根据官方说法是也会报错,但根据我的实验(windows7系统)并没有报错,npm-shrinkwrap.json会包含所有在node_modules中的模块。
  • npm-shrinkwrap.json中并不会包含devDependencies字段中的模块。

参考文章:

npm-shrinkwrap-Lock down dependency versions

node应用线上部署时锁定包的依赖版本的更多相关文章

  1. Node+mongodb线上部署到阿里云

    Node+mongodb线上部署到阿里云 部署使用的主要工具是pm2+nginx,使用码云的私有仓库,自动部署到服务器,私有仓库和服务器要事先设置好免密码登录.使用DNSPOD进行域名解析.事先准备好 ...

  2. skiasharp在阿里云Windows server 2016上部署时提示The type initializer for 'SkiaSharp.SKAbstractManagedStream' threw an exception. 错误

    应用环境及问题描述: Windows Server 2016,.Net core 2.1, Skiasharp作为跨平台的图像处理组件在生成缩略图时出错,本地测试都是正常的,部署到服务器无法生成缩略图 ...

  3. vue-router+webpack线上部署时单页项目路由,刷新页面出现404问题

    使用vue项目,线上部署的时候,访问首页以及通过路由打开二级页面没有问题,但是一刷新就出现404现象 因为刷新页面时访问的资源在服务端找不到,因为vue-router设置的路由不是真实存在的路径. 解 ...

  4. 价值100W的经验分享: 基于JSPatch的iOS应用线上Bug的即时修复方案,附源码.

    限于iOS AppStore的审核机制,一些新的功能的添加或者bug的修复,想做些节日专属的活动等,几乎都是不太可能的.从已有的经验来看,也是有了一些比较常用的解决方案.本文先是会简单说明对比大部分方 ...

  5. React/Vue 项目在 GitHub Pages 上部署时资源的路径问题

    GitHub Pages 常被用来部署个人博客,而无论是大名鼎鼎的 Jekyll,还是 Hugo 或者 Hexo,他们都是将我们的文章嵌入模板,发布为静态页面,也就是说,GitHub Pages (G ...

  6. 关于使用dotnetbar开发winform程序在用户电脑上部署时问题

    1.首先要安装两个软件

  7. node vue 开发环境部署时,外部访问页面出现: Invalid Host header 服务器域名访问出现的问题

    这是新版本 webpack-dev-server  出于安全考虑, 默认检查 hostname,如果hostname不是配置内的,将中断访问.顾仅存在于开发环境: npm run dev,打包之后不会 ...

  8. java应用线上CPU过高问题排查

    1.top 命令,查看占用CPU最高的PID.ps aux|grep PID 进一步确定tomcat进程出现问题.2.ps -mp pid -o THREAD,tid,time显示线程列表3.prin ...

  9. Django项目在Linux服务器上部署和躺过的坑

    引言 在各方的推荐下,领导让我在测试环境部署之前开发的测试数据预报平台.那么问题来了,既然要在服务器上部署, 就需要准备: 1.linux服务器配置 2.linux安装python环境搭建与配置 3. ...

随机推荐

  1. 【声明】前方不设坑位,不收费!~ 我为NET狂官方学习计划

    发个通知,过段时间学习计划相关的东西就出来了,上次写了篇指引文章后有些好奇心颇重的人跟我说:“发现最近群知识库和技能库更新的频率有点大,这是要放大招的节奏啊!” 很多想学习却不知道如何规划的人想要一个 ...

  2. .Net多线程编程—任务Task

    1 System.Threading.Tasks.Task简介 一个Task表示一个异步操作,Task的创建和执行是独立的. 只读属性: 返回值 名称 说明 object AsyncState 表示在 ...

  3. Python的单元测试(二)

    title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...

  4. 神经网络、logistic回归等分类算法简单实现

    最近在github上看到一个很有趣的项目,通过文本训练可以让计算机写出特定风格的文章,有人就专门写了一个小项目生成汪峰风格的歌词.看完后有一些自己的小想法,也想做一个玩儿一玩儿.用到的原理是深度学习里 ...

  5. 运用php做投票题,例题

    要求大概是这样的,有一个题目,题目下面是复选框,要求点完复选框提交后会变成进度条,各选项的进度条百分比,和投票数量 首先还是要在数据库建两张表,如下: 要完成这个题目,需要建两个页面 <!DOC ...

  6. webapi - 模型验证

    本次要和大家分享的是webapi的模型验证,讲解的内容可能不单单是做验证,但都是围绕模型来说明的:首先来吐槽下,今天下午老板为自己买了套新办公家具,看起来挺好说明老板有钱,不好的是我们干技术的又成了搬 ...

  7. Mac OS、Ubuntu 安装及使用 Consul

    Consul 概念(摘录): Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,比如 Airbnb 的 SmartStac ...

  8. PHP 获取 特定时间范围 类

    目录  前序 用途 功能及事项 使用方法 代码及注释 前序: 总体来说,我更应该是一个 android 移动开发者,而不是一个 phper,如果说只做移动端的 APP ,我也不会学这么多,这 2年来, ...

  9. 舍弃Nunit拥抱Xunit

    前言 今天与同事在讨论.Net下测试框架的时候,说到NUnit等大多数测试框架的SetUp以及TearDown方法并不是显得那么完美,所以在公司内部的项目中采用了Xunit框架.那么究竟是什么样的原因 ...

  10. 提升网速的路由器优化方法(UPnP、QoS、MTU、交换机模式、无线中继)

    在上一篇<为什么房间的 Wi-Fi 信号这么差>中,猫哥从微波炉.相对论.人存原理出发,介绍了影响 Wi-Fi 信号强弱的几大因素,接下来猫哥再给大家介绍几种不用升级带宽套餐也能提升网速的 ...