Reputation: 6805
I'm able to deploy my Next.js project to Firebase Functions successfully as per this post. However, when I try to visit my project in the browser, I get a Error: could not handle the request
error, and in the Functions log I see this error message:
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)
I'm not sure how to resolve this though... Adding below my config files:
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"
}]
}
}
I assume that, once deployed, Firebase Functions environment would run npm run build
and npm run start
scripts. Or is the workflow different? Perhaps my scripts are incorrect?
Upvotes: 0
Views: 1997
Reputation: 1
I was this error, my solution was:
First, in the packege.json file, in the section scripts, we must modify the property “build”: "next build && next export", and a new property "export": "next export"
Second, we must establish the component and data folders in the root of the project
Third: use the command: a)You must make log in, so type: 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
Upvotes: 0
Reputation: 26256
Similar to scripts in package.json
files, the predeploy
and postdeploy
lines are executed before and after a call to firebase deploy
when using the Firebase CLI (documented here).
When the Firebase CLI uploads your code to the Cloud Functions staging servers, it is expected to have already been compiled and only needs its runtime dependencies installed. Once an upload has completed, the staging server will execute npm install --production
and then prepare your function to handle requests (essentially performing a cold-start, without actually executing the function). If either step fails, you will be shown an error like you have. If both steps succeed, your code with the dependencies installed is persisted as an image and saved to Cloud Storage, ready to use when requests to be handled come in.
In your case, the error seems to be that your .next
folder is missing the compiled version of your application.
There are two possible causes of this, either your build prior to deployment is incomplete or when your files are uploaded, something in your ignore
list that is required by the deployed code is missing.
For the first part, you modified the predeploy
hook in my previous answer from:
{
"functions": {
"source": ".",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
},
...
}
incorrectly to:
{
"functions": {
"source": ".",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build:functions"
]
},
...
}
By changing this, you aren't building your next app prior to deploying the code to the staging server.
In regards to the second part, the deployed next application may be missing some of its dependencies - you can either fine tune the ignore
list or you can perform the next build
step on the server using a postinstall
script in your package.json
file:
{
"main": "server.js", // my next.js app init file
"scripts": {
...
"build:next": "next build",
...
"postinstall": "npm run build:next"
},
"dependencies": {
// including next
}
}
Note: If your main
file is just JavaScript, you no longer need the typescript compile step defined in npm run build:functions
and it can be removed.
Upvotes: 2