Next.js: Production Deploy to Firebase doesn't work correctly

Created on 18 Dec 2018  路  2Comments  路  Source: vercel/next.js

Examples bug report

Example name

  • with-firebase-hosting
  • with-firebase-hosting-*

Describe the bug

Unable to deploy an app with custom server to Firebase

To Reproduce

  1. modify src\functions\index.js
var dev = false
var app = next({ dev, conf: { distDir: 'next' } })
  1. run npm run deploy
  2. happen to Error
=== Deploying to 'func-example'...

i  deploying functions, hosting
i  functions: ensuring necessary APIs are enabled...
+  functions: all necessary APIs are enabled
i  functions: preparing dist/functions directory for uploading...

Error: Error occurred while parsing your function triggers.

Error: Could not find a valid build in the 'C:\dev\js\projects\next.js\examples\with-firebase-hosting\next' directory! Try building your app with 'next build' before starting the server.
    at Server.readBuildId (C:\dev\js\projects\next.js\examples\with-firebase-hosting\dist\functions\node_modules\next\dist\server\next-server.js:753:15)
    at new Server (C:\dev\js\projects\next.js\examples\with-firebase-hosting\dist\functions\node_modules\next\dist\server\next-server.js:80:25)
    at module.exports (C:\dev\js\projects\next.js\examples\with-firebase-hosting\dist\functions\node_modules\next\dist\server\next.js:6:10)
    at Object.<anonymous> (C:\dev\js\projects\next.js\examples\with-firebase-hosting\dist\functions\index.js:8:11)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)

This error message is bit strange.
Because next dir is in C:\dev\js\projects\next.js\examples\with-firebase-hosting\dist\functions.
But error message saids me Could not find a valid build in the 'C:\dev\js\projects\next.js\examples\with-firebase-hosting\next'.

Expected behavior

No error occurs

System information

  • OS: Windows10
  • Browser: Chrome
  • Version of Next.js: 7.0.2-canary.47

Additional context

This happens because firebase-tools attempts to read the Node's runtime version from package.json.
Last Log code is here.
Here's the code that will cause the error. src/prepareFunctionsUpload.js#L115

Workaround

modify src\functions\index.js

var dev = false
var dir = __dirname
var app = next({ dev, dir, conf: { distDir: 'next' } })

this code works fine. but I think this is not good.

Suggestion

How about moving the call of readBuildId method in Server's constructor into the prepare method?

example upstream

Most helpful comment

This seems to be some strange situation where firebase-tools runs code to identify the functions and running next() with dev=false causes it to to load a built version of next and tries to resolve it relative to the current working directory which will be in the root.

So basically during deploy, firebase will run the code from your current working directory. This will execute the code with a different cwd relative to the next directory. When running next() with dev=true this is fine, because next will not try to find a finished build. However running it with dev=false will make it try to find a complete build when bootstrapping the application, and since firebase executed the file, CWD is your current CWD, rather than inside dist/functions where next is.

One solution is like you said,

  • adding dir as a property to next() ensuring that the correct directory is used as root rather than CWD.

But you can actually also

  • leave the var dev = process.env.NODE_ENV !== 'production' code without any loss. Firebase Functions are run with NODE_ENV='production' by default and such your hosted server will use the production codepath. The dev codepath is only used when firebase-tools evaluates the code while deploying to identify the functions to be deployed.

I don't think next _could_ or _should_ use any other logic to try to identify distDir location other than using cwd.
However one could argue that it is unhelpfull by firebase/firebase-tools to run the code with a different CWD than when they are deployed.

I might create a PR to add dir: __dirname in the firebase-hosting examples just to ensure that next always finds the built application.

All 2 comments

This seems to be some strange situation where firebase-tools runs code to identify the functions and running next() with dev=false causes it to to load a built version of next and tries to resolve it relative to the current working directory which will be in the root.

So basically during deploy, firebase will run the code from your current working directory. This will execute the code with a different cwd relative to the next directory. When running next() with dev=true this is fine, because next will not try to find a finished build. However running it with dev=false will make it try to find a complete build when bootstrapping the application, and since firebase executed the file, CWD is your current CWD, rather than inside dist/functions where next is.

One solution is like you said,

  • adding dir as a property to next() ensuring that the correct directory is used as root rather than CWD.

But you can actually also

  • leave the var dev = process.env.NODE_ENV !== 'production' code without any loss. Firebase Functions are run with NODE_ENV='production' by default and such your hosted server will use the production codepath. The dev codepath is only used when firebase-tools evaluates the code while deploying to identify the functions to be deployed.

I don't think next _could_ or _should_ use any other logic to try to identify distDir location other than using cwd.
However one could argue that it is unhelpfull by firebase/firebase-tools to run the code with a different CWD than when they are deployed.

I might create a PR to add dir: __dirname in the firebase-hosting examples just to ensure that next always finds the built application.

This error still happens to me when trying to get the next firebase function example to work. I've messed around with it a bit and had these two errors while trying to upload:

i  deploying functions                                                                                                  
i  functions: ensuring necessary APIs are enabled...                                                                    
+  functions: all necessary APIs are enabled                                                                            
i  functions: preparing src/functions directory for uploading...                                                        
i  functions: packaged src/functions (1.55 MB) for uploading                                                            
+  functions: src/functions folder uploaded successfully                                                                
i  functions: updating Node.js 8 function next(us-central1)...                                                          
!  functions[next(us-central1)]: Deployment error.                                                                      

Function failed on loading user code. Error message: Code in file index.js can't be loaded.                             
Is there a syntax error in your code?                                                                                   
Detailed stack trace: Error: Could not find a valid build in the '/srv/next' directory! Try building your app with 'next build' before starting the server.                                                                                         
at Server.readBuildId (/srv/node_modules/next-server/dist/server/next-server.js:271:23)                                 
at new Server (/srv/node_modules/next-server/dist/server/next-server.js:38:29)                                          
at module.exports (/srv/node_modules/next-server/index.js:4:10)                                                         
at module.exports (/srv/node_modules/next/dist/server/next.js:9:12)                                                     
at Object.<anonymous> (/srv/index.js:23:13)                                                                             
at Module._compile (module.js:653:30)                                                                                   
at Object.Module._extensions..js (module.js:664:10)                                                                     
at Module.load (module.js:566:32)                                                                                       
at tryModuleLoad (module.js:506:12)                                                                                     
at Function.Module._load (module.js:498:3) 

And this one:

i  deploying functions, hosting                                                                                         
i  functions: ensuring necessary APIs are enabled...                                                                    
+  functions: all necessary APIs are enabled                                                                            
i  functions: preparing src/functions directory for uploading...                                                                                                                                                                                
Error: Error occurred while parsing your function triggers.                                                                                                                                                                                     
Error: Could not find a valid build in the 'C:\Users\Robbert Olierook\github\functions-samples\nextjs-with-firebase-hosting\src\functions\next' directory! Try building your app with 'next build' before starting the server.                      
at Server.readBuildId (C:\Users\Robbert Olierook\github\functions-samples\nextjs-with-firebase-hosting\src\functions\node_modules\next-server\dist\server\next-server.js:271:23)                                                                
at new Server (C:\Users\Robbert Olierook\github\functions-samples\nextjs-with-firebase-hosting\src\functions\node_modules\next-server\dist\server\next-server.js:38:29)                                                                         
at module.exports (C:\Users\Robbert Olierook\github\functions-samples\nextjs-with-firebase-hosting\src\functions\node_modules\next-server\index.js:4:10)                                                                                        
at module.exports (C:\Users\Robbert Olierook\github\functions-samples\nextjs-with-firebase-hosting\src\functions\node_modules\next\dist\server\next.js:9:12)                                                                                    
at Object.<anonymous> (C:\Users\Robbert Olierook\github\functions-samples\nextjs-with-firebase-hosting\src\functions\index.js:24:13)                                                                                                            
at Module._compile (module.js:635:30)                                                                                   
at Object.Module._extensions..js (module.js:646:10)                                                                     
at Module.load (module.js:554:32)                                                                                       
at tryModuleLoad (module.js:497:12)                                                                                     
at Function.Module._load (module.js:489:3)

My code looks like this:

// const dev = process.env.NODE_ENV !== "production";
const dev = false; //(To be sure)
const dir = __dirname;
const app = next({ dev, dir, conf: { distDir: "next" } });

What can I do?

Was this page helpful?
0 / 5 - 0 ratings