代码之家  ›  专栏  ›  技术社区  ›  Viper Bailey

为什么“npm install”重写package-lock.json?

  •  856
  • Viper Bailey  · 技术社区  · 7 年前

    我最近刚升级到 npm@5 package-lock.json 从中归档所有内容 .我希望在我跑步的时候 npm install 将从锁文件中提取依赖项版本,以确定应在我的 node_模块 文件

    例如,锁文件的typescript指定为at版本 2.1.6 .然后 npm安装 命令,版本更改为 2.4.1

    我错过了什么?如何让npm真正尊重我的锁文件?

    12 回复  |  直到 4 年前
        1
  •  574
  •   Ben Scheirman    5 年前

    更新3: 正如其他答案所指出的那样 npm ci 命令在npm 5.7.0中引入,作为在CI上下文中实现快速和可复制构建的额外方式。请参阅 documentation npm blog 了解更多信息。


    更新和澄清文件的问题是 GitHub issue #18103 .


    GitHub issue #17979 .


    原始答案: package-lock.json 已在中更改 npm 5.1.0 issue #16866 .您观察到的行为显然是npm从5.1.0版开始的意图。

    这意味着 package.json 可以覆盖 每当在中找到依赖项的更新版本时 包.json 1.2.0 而不是 ~1.2.0 ^1.2.0 .然后结合 package-lock.json 将产生可复制的构建。需要明确的是: package-lock.json

    issue #17979 lock 不再适用。)

    还有一点需要注意:对于不支持不可变包的注册表也有限制,例如直接从GitHub而不是npmjs.org拉取包 this documentation of package locks

        2
  •  228
  •   Community CDub    4 年前

    我发现将有一个新版本的npm 5.7.1 使用新命令 npm ci package-lock.json 只有

    新的npm ci命令仅从锁定文件安装。如果你的包裹。json和锁定文件不同步,那么它将报告错误。

    除了保证只获取锁文件中的内容外,它还快得多(2x-10x!)当您不从node_模块开始时,安装npm。

    正如您可能从名称中看到的那样,我们希望它对持续集成环境是一大福音。我们还预计,使用git标签进行生产部署的人员将获得重大收益。

        3
  •  144
  •   ATOMP VonC    4 年前

    简短回答:

    • npm install
    • 如果不满足这些要求,则更新包;包锁被覆盖。
    • 如果希望安装失败,而不是在发生这种情况时覆盖包锁,请使用 npm ci .

    下面是一个可能解释事情的场景(通过NPM 6.3.0验证)

    在包中声明依赖项。类似json:

    "depA": "^1.0.0"
    

    然后你会的, npm安装 这将生成包锁。json与:

    "depA": "1.0.0"
    

    几天后,一个较新的“depA”次要版本发布,比如“1.1.0”,然后以下内容成立:

    npm ci       # respects only package-lock.json and installs 1.0.0
    
    npm install  # also, respects the package-lock version and keeps 1.0.0 installed 
                 # (i.e. when package-lock.json exists, it overrules package.json)
    

    接下来,手动更新包。json收件人:

    "depA": "^1.1.0"
    

    然后重新运行:

    npm ci      # will try to honor package-lock which says 1.0.0
                # but that does not satisfy package.json requirement of "^1.1.0" 
                # so it would throw an error 
    
    npm install # installs "1.1.0" (as required by the updated package.json)
                # also rewrites package-lock.json version to "1.1.0"
                # (i.e. when package.json is modified, it overrules the package-lock.json)
    
        4
  •  116
  •   Gal Margalit    6 年前

    npm ci
    

    npm ci承诺为大型团队带来最大利益。让开发人员能够签署包锁,可以促进大型团队之间更高效的协作,并且能够准确地安装锁文件中的内容,有可能每月节省数十个甚至数百个开发人员小时,让团队有更多的时间来构建和发布惊人的东西。

    Introducing npm ci for faster, more reliable builds

        5
  •  32
  •   Daniel Tonon    3 年前

    使用 npm ci 命令而不是 npm install .

    它将基于包锁安装项目依赖项。json文件,而不是lenient包。json文件依赖项。

    你可以在这篇博文中了解更多信息: https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable

        6
  •  10
  •   Daniel Tonon    6 年前

    https://github.com/npm/npm/issues/17979

    使现代化

    实际上已在5.6.0中修复。5.4.2中存在一个跨平台错误,导致问题仍然存在。

    https://github.com/npm/npm/issues/18712

    请看我的答案: https://stackoverflow.com/a/53680257/1611058

    npm ci 是您现在安装现有项目时应该使用的命令。

        7
  •  9
  •   Timothy Higinbottom    7 年前

    将来,您将能够使用 --from-lock-file (或类似)安装标志 package-lock.json 无需修改。

    https://github.com/npm/npm/issues/18286 用于跟踪特征。

        8
  •  7
  •   Sengottaian Karthik    5 年前

    也许你应该用这样的东西

    npm ci
    

    而不是使用 npm install

    npm ci 安装项目所需的依赖项。

    主要区别在于, 安装软件包是否需要 packge.json 作为参考。在这种情况下 npm ci ,它确实安装了以下软件包: package-lock.json

        9
  •  6
  •   Matt    7 年前

    您可能有以下情况:

    "typescript":"~2.1.6"
    

    在你的 package.json 2.4.1

    编辑:来自OP的问题

    无论semver值如何,它仍应使用相同的2.1.6 版本

    答案:

    typescript v2.4.1 要求 widget ~v1.0.0 。当您安装它时 抓取 widget v1.0.0 。稍后,您的开发伙伴(或CI构建) npm是否安装并获取 但是 widget 已经 widget v1.0.1 。现在您的节点模块不同步。这 package-lock.json 防止。

    或者更一般地说:

    例如,考虑

    A包:

    {“name”:“A”,“version”:“0.1.0”,“dependencies”:{

    B包:

    {“name”:“B”,“version”:“0.0.1”,“dependencies”:{

    和包装C:

    {“name”:“C”,“version”:“0.0.1”}

    如果只有这些版本 A、B和C在注册表中可用,然后正常的npm安装A

    A@0.1.0 -- B@0.0.1

    然而,如果B@0.0.2发布后,新的npm安装a将安装:

    -- C@0.0.1假设新版本没有修改B的依赖关系。当然,新版本的B可以包括一个新的 C版本和任意数量的新依赖项。如果此类变更是 A的作者没有办法说他或她不想插手


    依赖项,但仍然依赖于package.json的模糊匹配 确定顶级依存关系。这准确吗?

    答:没有。包锁锁定整个包树,包括 如果 typescript 已锁定 2.4.1 在你的 package-lock.json ,它应该保持这种方式,直到它是 发布版本 2.4.2 . npm install ,npm将尊重 2.4.1 .

    package-lock.json :

    此文件旨在提交到源存储库中,并用于各种用途:

    为用户提供一种工具,使其能够“时间旅行”到node_模块的以前状态,而无需提交目录本身。

    通过可读的源代码管理差异,提高树更改的可见性。

    并通过允许npm跳过以前安装的包的重复元数据解析来优化安装过程。

    https://docs.npmjs.com/files/package-lock.json

        10
  •  3
  •   Bernardo Dal Corno    6 年前

    编辑:“锁”这个名字很复杂,它的NPM试图赶上Yarn。它不是一个被锁定的文件。 package.json 是一个用户固定文件,一旦“安装”,将生成node\u模块文件夹树,然后将该树写入 package-lock.json 包.json package-lock.json package-tree.json

    (在这么多人投了反对票后,希望这能让我的回答更清楚)


    包.json package-lock.json 是“一个精确且更重要的是可复制的node_模块树”(摘自 npm docs itself ).

        11
  •  0
  •   hrdwdmrbl    7 年前

    在他们的github页面上有一个公开问题: https://github.com/npm/npm/issues/18712

    当开发人员使用不同的操作系统时,这个问题最为严重。

        12
  •  -3
  •   obul    3 年前

    Npm安装检测对包所做的任何更改。json文件来相应地反映依赖项列表。

    例如,如果用户添加或删除了新的依赖项,则生成将下载或删除本地计算机中的依赖项。我们可以将其与java中的.m2存储库进行比较,maven在其中跟踪pom。xml文件不断更新依赖项。

    包裹锁。json是包的副本。内部进程在运行时使用json,唯一的区别是包锁。json对用户是只读的。