如何强制应用引擎上传node_modules

时间:2016-05-18 21:17:22

标签: node.js google-app-engine

在我的项目中,我们使用带有打字稿的nodejs进行谷歌云应用引擎应用开发。我们有自己的构建机制来将ts文件编译成javascript,然后将它们收集到一个完整的可运行包中,这样我们就不希望在google云上进行中继来安装依赖项,而是希望将node_modules中的所有节点包上传到谷歌云。

但似乎google cloud将始终忽略node_modules文件夹并在部署期间运行npm install。即使我试图从app.yaml删除'skip_files: - ^ node_modules $',它也不起作用,谷歌云将始终自行安装包。

有没有人对node_modules的部署节点应用程序有这个想法?谢谢。

3 个答案:

答案 0 :(得分:3)

我发现了同样的问题。

我的解决方法是在部署之前将node_modules/重命名为node_modules_hack/。这可以防止AppEngine将其删除。

我在安装时将其恢复为原始名称,并使用以下(部分)package.json文件:

  "__comments": [
    "TODO: Remove node_modules_hack once AppEngine stops stripping node_modules/"
  ],
  "scripts": {
    "install": "mv -fn node_modules_hack node_modules",
    "start": "node server.js"
  },

您可以通过查看它生成的Docker镜像来确认AppEngine剥离了您的node_modules/。你可以在Images page找到它。它们为您提供了一个命令行,您可以在云控制台上运行该命令行来获取它。然后,您可以运行docker run <image_name> ls来查看目录结构。该图片是在npm install之后创建的,因此一旦您使用上述解决方法,您就会在那里看到node_modules/

答案 1 :(得分:1)

最新的解决方案是允许node_modules中的.gcloudignore

下面是默认的.gcloudignore(如果您还没有gcloud app deploy的初始执行,则会产生该初始更改),并带有所需的更改:

# This file specifies files that are *not* uploaded to Google Cloud Platform
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
#   $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:
.git
.gitignore

# Node.js dependencies:
# node_modules/ # COMMENT OR REMOVE THIS LINE

答案 2 :(得分:0)

node_modules 中允许 .gcloudignore 不再有效。

自 2020 年 10 月/11 月以来,App Engine 部署为 switched to buildpacks。由它触发的 Cloud Build 步骤将始终删除上传的 node_modules 文件夹并使用 yarn 或 npm 重新安装依赖项。

这是相关的构建包代码: https://github.com/GoogleCloudPlatform/buildpacks/blob/89f4a6ba669437a47b482f4928f974d8b3ee666d/cmd/nodejs/yarn/main.go#L60

这是一种理想的行为,因为上传的 node_modules 可能来自不同的平台,并且可能会破坏与用于在 App Engine 环境中运行您的应用的 Linux 运行器的兼容性。

因此,为了跳过 Cloud Build 中的 npm/yarn 依赖项安装,我建议:

  • 使用与您在 App Engine 环境中使用的 Node 版本相同的 Linux runner CI。

  • 使用您的 node_modules 创建 tar 存档,以免在每个 gcloud app deploy 上上传大量文件。

  • node_modules 中忽略 .gcloudignore 目录。

  • node_modules.tar.gz 脚本中解压 preinstall 档案。不要忘记保持向后兼容性,以防 tar 存档丢失(本地开发等):

{
  "scripts": {
    "preinstall": "test -f node_modules.tar.gz && tar -xzf node_modules.tar.gz && rm -f node_modules.tar.gz || true"
  }
}

注意 ... || true 的事情。这将确保预安装脚本无论如何都返回零退出代码,并且 yarn/npm 安装将继续。

用于打包和上传 App Engine 部署依赖项的 Github Actions 工作流程可能如下所示:

  deploy-gae:
    name: App Engine Deployment
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      # Preferable to use the same version as in GAE environment
      - name: Set Node.js version
        uses: actions/setup-node@v2
        with:
          node-version: '14.15.4'    

      - name: Save prod dependencies for GAE upload
        run: |
          yarn install --production=true --frozen-lockfile --non-interactive
          tar -czf node_modules.tar.gz node_modules
          ls -lah node_modules.tar.gz | awk '{print $5,$9}'

      - name: Deploy
        run: |
          gcloud --quiet app deploy app.yaml --no-promote --version "${GITHUB_ACTOR//[\[\]]/}-${GITHUB_SHA:0:7}"

这只是 initially suggested hack 的扩展版本。

注意:如果您的 gcp-build 中有 package.json 脚本,您将需要创建两个存档(一个用于生产依赖项,一个用于开发)并修改预安装脚本以解压当前需要的一个(取决于 buildpack 设置的 NODE_ENV)。