Next.js: Production configuration

Created on 14 Apr 2017  路  11Comments  路  Source: vercel/next.js

I was very excited when v2.1.0 dropped with support for distDir configuration (#1513). I restructured my app in a way that I'm very pleased with, except for the fact that it doesn't work the way I had assumed it would :/

My filesystem post-build is like so:

src/
  server/
    server.js
  client/
    pages/
    next.config.js  (distDir: ../../dist/client)
dist/
  server/
    server.js
  client/
    bundles/
    app.js
    etc...

I'm using Koa to serve Next via next({ dir: '../client' }) so in development it runs Next out of src/client and in production out of dist/client. It turns out that this does not work and Next must be run out of src/client even in production.

I would very much prefer to only deploy my dist directory to production, but as it stands I'm forced to include src as well. The reason appears to be that there is a runtime dependency on next.config.js within the Next Server (server/index.js). Within the Server's constructor is this line, this.config = getConfig(this.dir), and since the dist directory does not contain next.config.js it uses the default configuration, which in turn attempts to read build-stats.json from config.distDir, which by default is .next which of course does not exist because it is not the actual dist directory.

The two questions that this has lead me to are:

  1. Will next.config.js ever store runtime configuration values? As far as I can tell there are none right now, and if the plan is to never allow them in there then Server should not depend on it and anything it's currently reading from the config should be passed in separately.
  2. If next.config.js will eventually contain runtime values then it will need to be copied to the dist directory on build. But the problem there is that any of the non-runtime configuration values, such as distDir, will not be needed and may not even make sense (for example distDir being a path relative to the source directory, etc). This doesn't feel like the right option to me.

In any case, I guess my big question is if running directly from the dist directory is even a goal. I absolutely think it should be, but I'd love to have a clear yes/no from a core team member before looking any more deeply into it.

Most helpful comment

I'm with @dizlexik here, I did hit this wall once and feeling the same way. I guess this happen for custom server (express in my case) only. Please consider reopen this.

All 11 comments

Frankly we've not sure about this yet.
For now, you should keep things as they mentioned on the docs.

Is there any discussion I could review regarding this? I'd like to see where this goes because it seems like the sort of thing that should be addressed sooner rather than later to avoid a lot of rework once a decision is finally made.

For now I guess I'll do as you're suggesting and deploy both the source and dist directories to production. It just feels very wrong/unnecessary to require source in production...

I'm with @dizlexik here, I did hit this wall once and feeling the same way. I guess this happen for custom server (express in my case) only. Please consider reopen this.

I totally have to agree with @dizlexik & @katopz. Never mix up runtime conf. with build conf.. I think the proposed project structure of @dizlexik is a quite obvious structure for big projects. This applies, in particular, to projects which have to implement certain kind of backend logic. It took me a while to understand why my code was not working. Quick and dirty fix... just copy the next.config.js during your build task to dist/server and change the path in server.js to next({ dir: './dist/sever' }). This def. not a good solution. So i have to say as well, please consider to reopen this.

any news on this matter?

PR #3909 looks to be related to this. @timneutkens maybe you could weigh in on this discussion.

In short, yes it's going to hold runtime config from now on.
To solve your issue however, you can drop next.config.js fully and hold the configuration inside of your server. As you can see here: https://github.com/zeit/next.js/blob/canary/server/config.js#L24

https://github.com/zeit/next.js#custom-server-and-routing

The conf key can be set inside the server constructor. Eliminating the need for next.config.js 馃憤

@dizlexik, it's been few months, did you finally find a way to set up the project structure you described above?
I plan to have a very similar structure in my project (client and server separate directories) and I would be very interested in finding out the solution you came up with.

@6r3al, I haven't revisited this since @timneutkens's comment, but his recommendation seems like the way to go now.

My workaround at the time was to not rely on distDir at all since it's broken, but instead to build my server and client separately and then copy client/.next into my dist directory to end up with this:

src/
  server/
    server.js - next({ dir: '../client' })
  client/
    pages/
dist/
  server/
    server.js
  client/
    .next/
      bundles/
      app.js

I hope that helps! The site I did that on is running an older version of Next, but I imagine that same approach would still work with the current generation.

Figured I'd leave my solution here for any forth-comers. Looks to be running well in both dev and build.

Directory

client/
  pages/
server/
  server.js
next.config.js

next.config.js

module.exports = {
  distDir: process.env.NODE_ENV === 'production' ? `../build` : '.next',
}

server.js
```js
// ...

const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({ dev, dir: dev ? ${__dirname}/../client : ${__dirname}/../build });

// ...
````

My solution for distDir path issue:

const app = next({
  dev,
  conf: { distDir: `${path.relative(process.cwd(), __dirname)}/../next` },
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

renatorib picture renatorib  路  3Comments

timneutkens picture timneutkens  路  3Comments

olifante picture olifante  路  3Comments

jesselee34 picture jesselee34  路  3Comments

havefive picture havefive  路  3Comments