Next.js: Executing app.prepare() only once when exporting app instead of running a server (express)

Created on 10 Mar 2018  路  6Comments  路  Source: vercel/next.js

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior

My app runs an infinite loop of webpack compilation, every action is therefore hyper slow.

Context

I'm running a Next.js app on top of Express, which is itself on top of serverless-offline, which is used to simulate the AWS lambda behavior.

Express is used by aws-serverless-express, which is a bridge between express and the Serverless framework. I therefore don't run an instance of express myself, but rather just configure the app and export it, as a module. This module is then used internally of aws-serverless-express to run the express server.

In this situation, I don't see how I can use app.prepare, which is async, because if I run it inside my lambda then it gets called at every call, including the HMR heartbeats.

Most helpful comment

since v6.0.0 it moves defineRoutes into app.prepare. How do we avoid to call app.prepare?

All 6 comments

App.prepare() seems to be only necessary for develop mode (eg. HMR etc all), atleast with <=5.0.0.
So I avoided that problem in lambda with this:

#lambda.js
const serverless = require("serverless-http");

process.env.IN_LAMBDA = true;
process.env.NODE_ENV = "production";

...

const appServer = require("./server");

const handler = serverless(appServer);

exports.handler = (evt, ctx, callback) => handler(evt, ctx, callback);
#server.js
const express = require("express");
const next = require("next");
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

function createServer() {
    const server = express();
    server.get("*", (req, res) => handle(req, res));
    return server;
}

if (process.env.IN_LAMBDA) {
    module.exports = createServer();
} else {
    app.prepare().then(() => {
        const server = createServer();
        server.listen(port);
    });
}

So app.prepare() is not called at all when running app in lambda.
Full source code here: https://github.com/TomiTakussaari/serverless-nextjs

Actually, my issue is somehow reversed @TomiTakussaari

My app works fine in production, but is "failing" in development. (local machine)

I don't run app.prepare either on AWS, using a similar trick to yours ;)

But I don't run app.prepare in dev mode either, because if I do then the app becomes completely unstable and keeps recompiling everything. I don't know what's the cause of this neither how to track/debug it.

I therefore have 2 servers running, one using Next directly, and another one using express. But the express one doesn't run app.prepare and doesn't get HMR (which is sad)

https://github.com/Vadorequest/serverless-with-next

Ah I see.

At first I also attempted to use serverless-offline for dev mode too, but because serverless-offline seems to recreate lambda instance for every request (similar to how AWS Lambda could work in worst case), it would also start webpack process for every request, because app.prepare() is called for every request.

I could not see easy way out of this, so decided not to use serverless-offline in development mode, but just start my own custom server.js (expressjs) which calls app.prepare().

Yeah, that's exactly what I'm facing.

I think I need to split both, one part with Next + express for dev/local environment and one part with serverless-offline + bundle Next, for local testing

Or, get rid of serverless-offline, which wouldn't be a big issue for me since I only have one lambda in that case.

since v6.0.0 it moves defineRoutes into app.prepare. How do we avoid to call app.prepare?

Solved in #5927

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wagerfield picture wagerfield  路  3Comments

swrdfish picture swrdfish  路  3Comments

flybayer picture flybayer  路  3Comments

pie6k picture pie6k  路  3Comments

havefive picture havefive  路  3Comments