专栏首页jeremy的技术点滴锁定NodeJS项目的依赖库

锁定NodeJS项目的依赖库

今天一上班,顺手点了一次构建整个项目,结果发现项目中的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里将所有依赖的包指定一个确定的版本号,如下如示:

"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文件是这样的:

"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

proj 1.0.0
   A 1.1.0
      B 1.2.0

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

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参数,否则很有可能某天一个开发依赖库版本小升个版本号,你的项目又悲剧了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 分发JavaWeb项目之docker方案

    jeremyxu
  • 优化nginx-ingress-controller并发性能

    这两天遇到一个很有意思的应用场景:有一个业务应用部署在kubernetes容器中,如果将该应用以Kubernetes Service NodePort暴露出来,...

    jeremyxu
  • kubernetes中部署mysql高可用集群

    很多软件后端使用的存储都是mysql,当这些软件系统在生产环境部署时,都会面临一个严峻问题,需要在生产环境中部署一个高可用的mysql集群服务。刚好在最近一周的...

    jeremyxu
  • 云鼎实验室 | 最新招募岗位发布啦~

    ? 快来加入我们吧~

    云鼎实验室
  • OpenStack环境搭建2(先电版)

    适用主机:controller控制节点 运行命令:iaas-install-mysql.sh

    Weiyang
  • https原理

      先来说下对称加密和非对称加密,对称加密就是当在对信息进行加密和解密时使用的秘钥是同一个秘钥,对称加密的优点是效率高但是相对不安全;非对称加密秘钥分为公钥和私...

    码缘
  • 业界时评 | Twitter如何使用Redis提高可伸缩性

    最近,Twitter Cache团队的工程师Yu Yao在Youtube发表了一段演讲,介绍了Twitter如何使用Redis提高系统可伸缩性。High Sca...

    张逸
  • 嵌入向量能否理解数字?BERT竟不如ELMo?

    理解和处理数字(识数)的能力对于很多复杂的推理任务而言非常关键。目前,大部分自然语言处理模型对文本中数字的处理方式与其他 token 相同:将数字看作分布式向量...

    机器之心
  • 使用gunicorn 部署django项目

    openssl req -new -x509 -nodes -sha1 -days 365 -key stunnel.key > stunnel.cert

    超级大猪
  • 超详细 Pycharm 部署项目视频教程

    大家好,我是猫哥,今天分享的是一篇超详细的教程。这篇教程手把手教你购买云主机、安装 Python3.7、使用 Pycharm 部署项目,详细到想学不会都难。

    Python猫

扫码关注云+社区

领取腾讯云代金券