package-lock.json 的作用

今天遇到一个很坑的问题,本地看怎么都没问题,线上之前也没问题。但就把master的代码重新发布了一遍,线上页面就挂掉了。找了半天才发现原因是react有个小版本更新了,导致了页面报错。具体原因是一个全局接口的loading文件是这样写的

const Loading = {
  show: () => {
    // console.log('show');
    const content = React.createElement('div', null, LoadSpin({ loading: true }));
    ReactDOM.render(
      content,
      document.querySelector('#root'),
    );
  },
  hide: () => {
    // console.log('hide');
    ReactDOM.render(
      LoadSpin({ loading: false }),
      document.querySelector('#root'),
    );
  },
};

将loading挂载到了root节点下面,之前并没有报错,但是在react这个小版本更新过后,提示就是root也会挂载别的组件,卸载的时候出了问题。解决办法也简单,那就是在document文件里面增加一个Dom去挂载这个loading节点。

  // document
<body>
    <div id="root"></div>
    <div id="root-loading"></div>
  </body>

//loading.js

const Loading = {
  show: () => {
    // console.log('show');
    const content = React.createElement('div', null, LoadSpin({ loading: true }));
    ReactDOM.render(
      content,
      document.querySelector('#root-loading'),
    );
  },
  hide: () => {
    // console.log('hide');
    ReactDOM.render(
      LoadSpin({ loading: false }),
      document.querySelector('#root-loading'),
    );
  },
};

那问题来了,为什么本地跑没事,线上却有问题,什么导致了本地和线上环境的不一致,下面就要说这个package-lock.json了。package-lock.json作用就是固定版本使用的。(需注意下自己的npm版本,下文有介绍)

要知道在package.json里面,我们的依赖如antd": "^4.4.0", ^这种形式,是只能固定大版本的,他是会向后升级小版本的,如果小版本升级了,就导致我们安装时的依赖发生了改变。为了防止这样问题的出现,所以有了package-lock.json这个文件去锁定到某个固定的版本。这个文件的存在能保障我们安装版本的一致性。

坑就坑在了,我本地的package-lock因为在.gitignore 里面被忽略了,所以线上被没有这个lock去锁定文件,导致了线上版本是更新后的一个小版本,而我本地却是锁定的。所以本地没有任何问题,但线上却一直出错。

然后针对这个问题特意查了下资料,如下:

https://www.zhihu.com/question/264560841

作者:贺师俊
链接:https://www.zhihu.com/question/264560841/answer/286682428
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

先给出回答:

package-lock.json 不应写进 .gitignore。这点无论你是否使用 lock 都是一样的。

具体来说:

如果你使用 lock 机制,则应该将 package-lock.json 提交到 repo 中。比如 Vue 采取了该策略。

如果你不使用 lock 机制,则应该加入 .npmrc 文件,内容为 package-lock=false ,并提交到 repo 中。比如 ESLint 采取了该策略。

例外是,如果你使用 yarn 并且不打算使用 npm,则可以把 package-lock.json 列入 .gitignore(比如 Babel);反之如果你使用 npm 并且不打算使用 yarn,则可以把 yarn.lock 列入 .gitignore (比如 TypeScript)。

如果你不按照上述方式做,请确定你清楚自己在干什么。比如 jQuery 为什么把 package-lock.json 写入 .gitignore 可以看其 commit message:Build: Remove package-lock.json, add it to .gitignore · jquery/jquery@7037fac 。简单说就是 optional 依赖包会导致不同平台上的 package-lock.json 发生变更。jQuery 的人认为这有问题,所以暂时性 ignore 了它。先不管是不是有更好的方式或者其他 workaround,最新的 npm 5.6.0 其实已经解决了这个问题。(想混个 jQuery contributor 的同学可以赶紧去提交 PR 了,成功之后可以给我发个红包当谢礼。)

有一些不使用 lock 机制的库,已经使用了 .npmrc ,但也把 package-lock.json 列入了 .gitignore,这是没有必要的。

至于到底要不要 lock,是另一个话题了。尽管题主也许想问的实际上就是要不要 lock,不过我还是按照题面作答。如果想讨论要不要 lock,建议移步已有的 透过 js-beautify@1.7.0 的 Bug 来看,npm 默认的 lock 机制是否重要? 问题。

作者:知乎用户
链接:https://www.zhihu.com/question/264560841/answer/282759714
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 

npm 5.x 发布以来到现在的5.6.0 lock的作用变更过好多次,现在网上很多小白文都是停留在以前的文档翻译。

从npm3.x更新到了npm5,但是发现执行 `npm i ` 时的现象跟网络上的科普文不太一致。

有提到不管怎么修改package.json文件,重复执行npm i,npm都会根据lock文件描述的版本信息进行下载。

也有提到重复npm i时,npm会不顾lock的信息,根据package.json中的包Semantic versioning 版本信息下载更新模块(lock貌似没啥用了)。

**查阅资料得知,自npm 5.0版本发布以来,npm i的规则发生了三次变化。**

1、npm 5.0.x 版本,不管package.json怎么变,npm i 时都会根据lock文件下载

package-lock.json file not updated after package.json file is changed · Issue #16866 · npm/npm

这个 issue 控诉了这个问题,明明手动改了package.json,为啥不给我升级包!然后就导致了5.1.0的问题...

2、5.1.0版本后 npm install 会无视lock文件 去下载最新的npm

然后有人提了这个issue why is package-lock being ignored? · Issue #17979 · npm/npm

控诉这个问题,最后演变成5.4.2版本后的规则。

3、5.4.2版本后 why is package-lock being ignored? · Issue #17979 · npm/npm

大致意思是,如果改了package.json,且package.json和lock文件不兼容(注意是兼容,比如package里"antd": "^4.6.3", ^表示固定大版本吗,那么lock里面可以是"antd": "4.6.4"的),那么执行`npm i`时npm会根据package中的版本号以及语义含义去下载最新的包,并更新至lock。

如果两者是同一状态,那么执行`npm i `都会根据lock下载,不会理会package实际包的版本是否有新

2021.8.24更新

发现 cnpm 好像不会默认按照package-lock.json去安装,而npm是会的。难道是依赖package-lock.json去安装这一步也是需要各个镜像源自己单独设置的吗?

目前zanpm也会忽略package-lock.json 按package.json去安装。

iybnpm 目前则会按照package-lock.json去安装。

2021.8.26更新

上述原因找到了,如果是 类似这样 

在mac 根目录的.bash_profile添加的配置

alias iybnpm="npm --registry=https://npm.baoyun.ltd \ --cache=$HOME/.npm/.cache/iybnpm \ --disturl=https://npm.baoyun.ltd/dist \ --userconfig=$HOME/.iybnpmrc"

那么只是设置了个别名,本质走的还是npm那一套。所以按照npm的机制,iybnpm 的package-lock.json是生效的。

如果是下面这样安装

npm install -g zanpm --registry=http://npm.zhonganonline.com  

那么执行zanpm时候就会走zanpm node_modules包里封装的那一套逻辑,有没有按本地的package-lock.json去安装就看他自己里面的逻辑了。目前来看cnpm和zanpm都没有去实现按package-lock.json去安装这一套。

如果以上两个命令都安装了,按测试结果来看,是优先走的第一种方案,可以通过zanpm -v 和

npm -v来看下 当前指向的到底是哪个版本。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在配置.gitignore文件中忽略package-lock.json时,可以选择两种做法。首先,你可以将package-lock.json一直包含在仓库中,不将其忽略。这样做的好处是,其他开发人员在clone项目后,可以确保他们使用的是与你相同的依赖版本。但是在执行npm publish命令时,package-lock.json应该被忽略,不应该被发布出去。另一种做法是,在.gitignore文件中添加对package-lock.json的忽略规则。这样,package-lock.json文件将不会被Git跟踪和提交到仓库中。如果你选择这种做法,请确保在运行npm install之前删除package-lock.json文件,以便安装所有最新版本的依赖并重新生成package-lock.json。此外,你还可以在项目的根目录下添加.gitattributes文件,并在其中写入需要忽略的文件名,包括package-lock.json。使用merge=ours来指定合并冲突时选择保留当前版本。这样,即使其他开发人员在合并代码时修改了package-lock.json,也不会影响你的本地版本。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [详解package.jsonpackage-lock.json](https://blog.csdn.net/weixin_38664300/article/details/127495039)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [git merge时忽略某文件合并来避免冲突(以忽略package-lock.json文件冲突为例)](https://blog.csdn.net/m0_50181189/article/details/124912806)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值