为什么要将node_modules移动到父目录

问题描述 投票:0回答:2

在 Visual Studio Code 的 Docker 扩展中,在 Node.js Dockerfile 模板中,node_modules 目录被移动到父目录,在这一行:

RUN npm install --production --silent && mv node_modules ../

mv node_modules ../
对我来说看起来没什么用。 有理由这么做吗?

visual-studio-code node-modules
2个回答
8
投票

更新:找到了“为什么”的很好解释。请参阅:处理节点模块部分。

TLDR; 让您可以在容器内外运行应用程序,而不必担心 node_modules 中特定于操作系统的项目无法在主机和容器之间工作。

原文(评论中指出错误)答案:

这是为了利用Docker中的缓存机制。通常,您的

Dockerfile
中会有以下内容:

1. RUN apt-get #bunch of stuff you want installed
2. COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
3. RUN npm install --silent && mv node_modules ../
4. COPY . .
5. CMD node index.js

Docker 在“层”中构建其镜像,您可以认为每层都是在执行

Dockerfile
中的每一行时添加的。

那么我们在上面的片段中所说的是:

  1. 运行
    apt-get
    并将图层提交到缓存
  2. 接下来,将
    package.json
    文件从主机复制到容器,提交该层
  3. 运行
    npm install
    ,然后将
    node_modules
    文件夹向上移动一个目录,
    npm
    将递归向上搜索,直到找到
    node_modules folder
    ,所以你的应用程序不会关心。提交这一层。
  4. 将当前文件夹中包含的源代码复制到容器中,提交这一层
  5. 最后,当容器运行时,使用命令
    node index.js

这个系统的美妙之处在于,Docker 只会从上次构建容器以来发生变化的点重新构建容器。因此,在我们的例子中,如果前一层发生了更改(例如更新的

npm install…
),它只会运行
package.json
。如果不是,则它不会执行
npm install
命令,即使
index.js
可能已更改。

当然,请记住,您应该在

node_modules
文件中列出
.dockerignore
,这样
COPY . .
就不会尝试选取它。


0
投票

没有记录这样做的原因,但您可以向上移动

node_modules
,这样当您创建绑定挂载时(例如开发容器),您不必再次
npm i
,例如在
postStartCommand
对于开发容器。我再说一次
npm i
,因为你已经在
Dockerfile
那里做到了,或者他们做到了。请注意,您不能通过绑定挂载在 Docker 容器内重用主机中的 node_modules,因为例如,如果您在主机上运行 Windows 而容器运行 Debian,则二进制文件不兼容。

但是,仅将其向上移动一个目录,在我看来没有多大意义,将其移动到

/
更有意义,因为例如开发容器位于
/workspaces
中,并且它不会看到
/usr/src/node_modules
在您链接的这种特殊情况下。

旁注:在开发容器的情况下,您还希望为

${containerWorkspaceFolder}/node_modules
创建命名或匿名卷,否则当您通过
npm
安装某些包时,由于绑定安装,您还会写入主机文件系统。

我希望这能让您更好地了解他们为什么这样做。

© www.soinside.com 2019 - 2024. All rights reserved.