前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >锁定NodeJS项目的依赖库

锁定NodeJS项目的依赖库

作者头像
jeremyxu
发布2018-05-10 12:04:59
1.3K0
发布2018-05-10 12:04:59
举报

今天一上班,顺手点了一次构建整个项目,结果发现项目中的javascript编译报错,而且报的错莫名其秒。

1

undefined is not iterable!

搜遍互联网才在babel的twitter上找到了这个问题的说明。

If you are getting anundefined is not iterable!error, pleasenpm install babel-types(to use v6.8.1). If necessary, clear node_modules

看情况应该是babel相关的依赖自动升级导致的错误,这里鄙视一下NodeJS生态里的npmjs.com上的库,质量真的是参差不齐,明明安装的是兼容的版本,可实际上很有可能由于某个依赖的升级导致整个项目编译失败。

实际上我之前已发现了这个问题,当时的方案是在package.json里将所有依赖的包指定一个确定的版本号,如下如示:

代码语言:javascript
复制
"dependencies": {
  "babel-polyfill": "6.3.14",
  "before-unload": "2.0.0",
  "bootstrap": "3.3.4",
  "bowser": "1.0.0",
  "browser-audio": "1.0.2",
  "classnames": "2.1.2",
  "cropper": "0.11.0",
  "extend": "3.0.0",
  "fancybox": "3.0.0",
  "favicon-notification": "0.1.4",
  "flux": "2.0.3",
  "fullscreen": "1.0.0",
  "immutable": "3.7.5",
  "inherits": "2.0.1",
  "jquery": "1.11.3",
  "jquery-textrange": "1.3.3",
  "jwt-decode": "1.4.0",
  "keymirror": "0.1.1",
  ...
}

原以为这样依赖的版本号就固定了。但实际上在NodeJS生态里大量第三方库其package.json文件是这样的:

代码语言:javascript
复制
"dependencies": {
    "acorn": "^3.0.0",
    "async": "^1.3.0",
    "clone": "^1.0.2",
    "enhanced-resolve": "^2.2.0",
    "interpret": "^1.0.0",
    "loader-runner": "^2.1.0",
    "loader-utils": "^0.2.11",
    "memory-fs": "~0.3.0",
    "mkdirp": "~0.5.0",
    "node-libs-browser": "^1.0.0",
    "object-assign": "^4.0.1",
    "source-map": "^0.5.3",
    "supports-color": "^3.1.0",
    "tapable": "~0.2.3",
    "uglify-js": "~2.6.0",
    "watchpack": "^1.0.0",
    "webpack-sources": "^0.1.0",
    "yargs": "^3.31.0"
  }

可以看到~表示该依赖可能会自动更新至最近的minor版本,^表示该依赖可能会自动更新至最近的major版本。

这样就存在问题了,这里我用示例简单说明一下。

最开始项目是这样的,其中A使用^依赖于B

代码语言:javascript
复制
proj 1.0.0
   A 1.1.0
      B 1.2.0

某一天B的维护者发布了一个新的版本1.3.0,但他并没有经过完备的测试来保证一定是与1.2.0版本是兼容的。项目的维护者又手贱地执行了下npm installnpm install C,执行后,依赖树就变成下面这样了。

代码语言:javascript
复制
proj 1.0.0
   A 1.1.0
      B 1.3.0

然后项目编译时就失败了,或者编译成功,但在浏览器中运行出错了,悲剧。

怎么办?还好查到了npmjs.com官方针对这个问题的说明,详见这里

npm shrinkwrap的作用就是以项目为根,将项目依赖树上所有第三方库版本固定。 使用上还是比较简单的,就是执行npm shrinkwrap命令,就会在package.json旁边上一个npm-shrinkwrap.json,以后再执行npm install,就会安装npm-shrinkwrap.json里描述的确切版本。

不过这里还有一个小坑,官方文档里说明如下:

1

Since npm shrinkwrap is intended to lock down your dependencies for production use, devDependencies will not be included unless you explicitly set the --dev flag when you run npm shrinkwrap.

也就是默认不会锁定devDependencies的版本,除非执行npm shrinkwrap带上--dev参数。我建议执行npm shrinkwrap还是带上--dev参数,否则很有可能某天一个开发依赖库版本小升个版本号,你的项目又悲剧了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档