我们为什么需要 lock 文件
前言
从 Yarn 横空出世推出 lock 文件以来,已经两年多时间了,npm 也在 5.0 版本加入了类似的功能,lock 文件越来越被开发者们接收和认可。本篇文章想从前端视角探讨一下我们为什么需要 lock 文件,以及它的一些成本与风险,当然其中一些观点对于后端也是适用的。
为什么需要 lock 文件
之所以需要 lock 文件,我觉得主要有 4 个原因:
确保各环境依赖版本的一致性
软件开发一般有着好几个环境,通常包括本地开发环境、集成测试环境、预发布环境以及线上环境。各环境依赖版本不一致通常是 bug 的一大来源,大家可能碰到过“在我的电脑上是好的”这种问题,也许就是依赖版本不一致导致的。这种问题通常很难定位,因为你很难确定到底是自己的问题还是依赖的问题。这也是 Yarn 推出 lock 文件的初衷之一,使用了 lock 文件,你在排查问题时至少可以排除依赖版本不一致这个因素。
语义化版本并不绝对可靠
一些开发者不愿意使用 lock 文件,一个主要原因是他们希望基于语义化版本号让依赖自动升级,认为只要选择的依赖可靠,大版本不变化就可以放心升级。在绝大多数情况下这么做不会有问题,但是也有意外情况,比如:
React 在 v16.4.0 对 getDerivedStateFromProps 的调用时机进行了调整。React 在 v16.3.0 引入了这个 API,最初只有在父组件引起的重渲染过程中会被调用,v16.4.0 调整为在所有渲染过程中都会被调用。如果你在不知情的情况下(自动)把 React 从 v16.3.0 升级到了 v16.4.0,那么极端情况下你的应用就会出问题。
虽然只有在很极端的情况下你才会碰到类似问题,但是这种问题本来就是不怕一万就怕万一。
可控的升级依赖
现在通过 webpack 把依赖单独提取为一个 vendor.js 是个很常见的做法,因为依赖变更相对来说没那么频繁,再配合上强缓存,可以做到即使发布了新版本,用户也可以使用缓存的 vendor.js 而不必重新下载。通常我们的应用不止一个依赖,这些依赖肯定也不是同一时间发布更新,如果不使用 lock 文件让其自由更新,可能会导致 vendor.js 缓存失效多次(每个依赖更新都会导致缓存失效)。如果使用 lock 文件就可以积累一段时间,让多个依赖集中更新,甚至跳过一些小版本更新,从而提高 vendor.js 的缓存命中率。
安全问题
几个月前 ESLint 发生了一个安全事故,一个攻击者窃取了 ESLint 维护者的 npm 账户,并发布了恶意版本的 eslint-scope 和 eslint-config-eslint(都是更新的小版本),其中前者是 babel-eslint 和 webpack 的依赖。如果没有使用 lock 文件,那么你就极有可能中招,ESLint 事后也建议开发者使用 lock 文件来避免自动安装新版本。
成本
使用 lock 文件自然会增加一点项目的维护成本,因为依赖不会再自动升级,所以需要项目维护者每隔一段时间手动进行升级。另外如果两个人同时修改了依赖,解决 lock 文件的冲突也是一件很麻烦的事。
但是手动升级依赖也有一些额外的好处,至少你升级每个依赖时都要去看一下它的 change log,这样可以对每一次升级做到心中有数,这也有助于你掌握依赖的发展趋势。比如前文提到的 React 的例子,只要你在升级时看一眼它的 change log,就很容易避开可能出现的问题。
风险
我唯一能想到的风险就是依赖版本固化问题,如果你使用了 lock 文件又没有花时间跟精力去维护它,那么你的项目就很容易陷入依赖版本固化的问题。如果太久没有升级依赖,你当前使用的版本跟最新版差别太大,升级就会很困难,考虑到现实成本问题,可能就永远不会升级了。
但是如果不使用 lock 文件就能完全避免这个问题吗,我想也不一定。不使用 lock 文件最多也只能在同一个大版本范围内自动升级,如果依赖升级了大版本,你没有花时间去升级,也会碰到同样的问题。只是相对于不使用 lock 文件,问题暴露的晚一些而已。
我们为什么需要 lock 文件的更多相关文章
- ArcGIS GDB 文件中的lock文件影响复制
复制或压缩gdb文件的时候,经常碰到有lock文件,解决方法是: 在catalog中停止相应的地图服务 如果用catalog预览过相应的地图,关闭catalog
- Android开发 ---SQLite数据库,lock文件,结果集游标,适配器,安全退出,给连接设置下划线,编辑器,投影,ContentValues存储,DbHelper,activity栈
目录截图: 1.activity_main.xml 主界面效果: <?xml version="1.0" encoding="utf-8"?> &l ...
- composer update的错误使用以及如何更新composer.lock文件
用composer update装包是错误的. 安装包标准的方法应该是 require ,或者手动写 compose.json 文件,然后 composer install .如果只是需要更新 com ...
- mongodb的mongod.lock文件及oplog文件
在mongodb的启动时,在数据目录下,会生成一个mongod.lock文件.如果在正常退出时,会清除这个mongod.lock文件,若要是异常退出,在下次启动的时候,会禁止启动,从而保留一份干净的一 ...
- composer.lock文件的作用
在使用composer后目录中会出现2个文件,composer.lock和composer.json,现在来说说这两个文件的作用. 1.composer.json composer.json文件中保存 ...
- mongodb mongod.lock文件及oplog文件
在mongodb的启动时,在数据目录下,会生成一个mongod.lock文件.如果在正常退出时,会清除这个mongod.lock文件,若要是异常退出,在下次启动的时候,会禁止启动,从而保留一份干净的一 ...
- Ubuntu:我不小心把/var/lock文件夹给删了
在一个风和日丽的下午,不正常关闭minicom导致了device 没有正常解锁,于是使用minicom的时候提示 device is locked: 根据网上看到的方法只要把/var/lock 里面的 ...
- 解决Visual Studio 2010/2012在调试时lock文件的方法
调试3dsmax插件,有一个避免每次修改插件代码都需要重启3dsmax的方法,就是将导出的核心代码写在一个独立的DLL中,然后在插件代码需要导出时LoadLibrary这个DLL,导出之后再FreeL ...
- Mongodb 启动时 lock文件访问没有权限处理
mongodb 第二次启动时候异常信息: lock file: /data/db/mongod.lock errno:13 Permission denied Is a mongod instance ...
随机推荐
- 15.4,redis不重启,切换RDB备份到AOF备份
确保redis版本在2.2以上 [root@pyyuc /data ::]#redis-server -v Redis server v= sha=: malloc=jemalloc- bits= ...
- Docker构建nginx+uwsgi+flask镜像(一)
前言 笔者之前是从事Java方面的工作,自从18年5月左右来到新的公司,接触到Python,被其简单优雅的语法风格深深吸引,同时,新公司也帮助笔者打开Docker世界的大门,让笔者体会到“一次打包,到 ...
- jsUnpacker
EVAL function executeEval(){ let evalCodeElt = document.getElementById("eval_code"); let e ...
- 10.bootstrap分页,点击哪个分页号,哪个分页号就active
1.分页,点击哪个分页号,哪个分页号就active <nav> <ul class="pagination"> <li><a href=& ...
- H2数据库使用
H2数据库使用 H2数据库介绍 H2的优势: 1.h2采用纯Java编写,因此不受平台的限制. 2.h2只有一个jar文件,十分适合作为嵌入式数据库试用. 3.性能和功能的优势 H2和各数据库特征比较 ...
- 【Remove Duplicates from Sorted List 】cpp
题目: 第一次刷的时候漏掉了这道题. Given a sorted linked list, delete all duplicates such that each element appear o ...
- 【Merge Intervals】cpp
题目: Given a collection of intervals, merge all overlapping intervals. For example,Given [1,3],[2,6], ...
- STL之heap使用简介
STL中并没有把heap作为一种容器组件,heap的实现亦需要更低一层的容器组件(诸如list,array,vector)作为其底层机制.Heap是一个类属算法,包含在algorithm头文件中.虽然 ...
- 【Python】- pytharm 中import时无法识别自己写的程序
右键点击自己的工作空间,找下面的Mark Directory as(将目录标记为) 选择Source Root,就可以解决上面的问题了,如图
- Java内存模型与线程_学习笔记
深入理解java虚拟机: 1.java内存模型 java虚拟机规范中试图定义一种Java内存模型.Java Memory Model(JMM) 1.1 主内存与工作内存 java内存模型规定所有的变量 ...