【问题标题】:Firebase Functions do not build Next.js project when deployedFirebase 函数在部署时不构建 Next.js 项目
【发布时间】:2021-10-13 03:15:09
【问题描述】:

我能够按照this post 将我的 Next.js 项目成功部署到 Firebase Functions。但是,当我尝试在浏览器中访问我的项目时,我收到了 Error: could not handle the request 错误,并且在函数日志中我看到了以下错误消息:

Error: Could not find a production build in the '/workspace/.next' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id
    at Server.readBuildId (/workspace/node_modules/next/dist/next-server/server/next-server.js:151:355)
    at new Server (/workspace/node_modules/next/dist/next-server/server/next-server.js:3:120)
    at NextServer.createServer (/workspace/node_modules/next/dist/server/next.js:1:2935)
    at process._tickCallback (internal/process/next_tick.js:68:7)

我不确定如何解决这个问题...在我的配置文件下面添加:

package.json

{
  "main": "server.js", // my next.js app init file
  "scripts": {
    "dev": "FIREBASE_AUTH_EMULATOR_HOST=localhost:9099 next dev",
    "start": "next start",
    "build": "next build",
    "build:functions": "tsc",
    "lint": "npm run lint:next && npm run lint:functions",
    "lint:functions": "eslint --ext .js",
    "lint:next": "next lint",
    "deploy": "firebase deploy --only database,hosting,functions:nextServer",
    "emulate": "firebase emulators:start --import=./emulator-data --export-on-exit",
    "test": "jest --runInBand --detectOpenHandles",
    "cypress": "cypress open"
  },
  "dependencies": {
    // including next
  }
}

firebase.json

{
  "functions": {
    "source": ".",
    "runtime": "nodejs10",
    "ignore": [
      "**/.next/cache/**",
      "**/__tests__/**",
      "**/components/**",
      "**/cypress/**",
      "**/emulator-data/**",
      "**/functions/**",
      "**/layouts/**",
      "**/node_modules/**",
      "**/pages/**",
      "**/public/**",
      "**/utils/**",
      "**/.*",
      "**/*.log",
      "**/cypress.json",
      "**/database.rules.json",
      "**/firebase.json"
    ],
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint",
      "npm --prefix \"$RESOURCE_DIR\" run build:functions"
    ]
  },
  "hosting": {
    "target": "my_app",
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [{
      "source": "**",
      "function": "nextServer"
    }]
  }
}

我假设一旦部署,Firebase Functions 环境将运行 npm run buildnpm run start 脚本。还是工作流程不同?也许我的脚本不正确?

【问题讨论】:

  • 您不应该在predeploy 中调用npm --prefix \"$RESOURCE_DIR\" run build 来构建应用程序吗?
  • 感谢您的建议。我尝试将其更改为run build,唉,同样的结果......那么,predeploy 脚本是在部署后在云功能服务器上运行的脚本吗?如果是这样,命名会很混乱,最好在部署后命名或类似的东西......
  • 为了完整起见,您应该将当前形式的 server.js 添加到此问题中,而不是依赖查看 previous question 的人。
  • 我实际上已将我的问题缩小到firebase.jsonignore 部分。问题是当我包含**/pages/** 时,它不仅忽略了顶级页面文件夹,还忽略了.next/server/pages,使我的部署不完整。由于某种原因,仅忽略 /pages/** 也不起作用...

标签: firebase google-cloud-functions next.js


【解决方案1】:

我是这个错误,我的解决方法是:

首先,在packege.json文件的section scripts中,我们必须修改属性“build”:“next build && next export”,以及一个新属性“export”:“next export”

其次,我们要在项目根目录下建立组件和数据文件夹

第三:使用命令: a)你必须登录,所以输入:firebase login

  b)select de option "Configure files for Firebase Hosting and (optionally) set 
                      up GitHub Action deploys"
  c)in the question:  if you have a build process 
                      for your assets, use your build's output directory?
                      What do you want to use as your public directory?
     
     You must type:   out  (really important, it's a folder output) 
  d) You must type:   npm run build
  f) last step: type: firebase deploy

package.json out folder

【讨论】:

    【解决方案2】:

    类似于package.json 文件中的scriptspredeploypostdeploy 行在使用 Firebase CLI (documented here) 时在调用 firebase deploy 之前和之后执行。

    当 Firebase CLI 将您的代码上传到 Cloud Functions 暂存服务器时,它应该已经编译并且只需要安装其运行时依赖项。上传完成后,登台服务器将执行npm install --production,然后准备您的函数来处理请求(本质上是执行冷启动,而不实际执行函数)。如果任一步骤失败,您将看到与您一样的错误。如果这两个步骤都成功,则安装了依赖项的代码将作为图像保存并保存到 Cloud Storage,以便在需要处理的请求到来时使用。

    在您的情况下,错误似乎是您的 .next 文件夹缺少应用程序的编译版本。

    这有两个可能的原因,要么是您在部署之前的构建不完整,要么是在您上传文件时,您的 ignore 列表中缺少已部署代码所需的内容。

    对于第一部分,您修改了我的 previous answer 中的 predeploy 钩子来自:

    {
      "functions": {
        "source": ".",
        "predeploy": [
          "npm --prefix \"$RESOURCE_DIR\" run lint",
          "npm --prefix \"$RESOURCE_DIR\" run build"
        ]
      },
      ...
    }
    

    错误地:

    {
      "functions": {
        "source": ".",
        "predeploy": [
          "npm --prefix \"$RESOURCE_DIR\" run lint",
          "npm --prefix \"$RESOURCE_DIR\" run build:functions"
        ]
      },
      ...
    }
    

    通过更改此设置,您无需在将代码部署到临时服务器之前构建下一个应用程序。

    关于第二部分,部署的下一个应用程序可能缺少一些依赖项 - 您可以微调ignore 列表,也可以使用postinstall 脚本在服务器上执行next build 步骤在您的package.json 文件中:

    {
      "main": "server.js", // my next.js app init file
      "scripts": {
        ...
        "build:next": "next build",
        ...
        "postinstall": "npm run build:next"
      },
      "dependencies": {
        // including next
      }
    }
    

    注意:如果您的 main 文件只是 JavaScript,则您不再需要 npm run build:functions 中定义的 typescript 编译步骤,可以将其删除。

    【讨论】:

    • 问题确实出在我的ignoreconfiguration 上。我在原始帖子中编写它的方式也是从.next 目录中删除pagesdirectories,因此最终部署了一个不完整的构建目录。
    猜你喜欢
    • 2018-06-09
    • 2021-07-20
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 2021-12-27
    • 2018-12-31
    • 2020-03-13
    相关资源
    最近更新 更多