Skip to content

serverless functions not standalone as claimed #26297

@fast-reflexes

Description

@fast-reflexes

What version of Next.js are you using?

11.0.0

What version of Node.js are you using?

12.16.1

What browser are you using?

Chrome

What operating system are you using?

MacOS

How are you deploying your application?

Serverless with Node

Describe the Bug

NextJS supports the serverless target but fails to document it well, and the only brief documentation about this feature that I can find is on https://nextjs.org/blog/next-8#serverless-nextjs. This documentation lacks details and omit important parts, such as how to handle api routes. Nonetheless, it claims explicitly that

The serverless target will output a single lambda per page. This file is completely standalone and does not require any 
dependencies to run

It also claims

The signature of the Next.js Serverless function is similar to the Node.js HTTP server callback

This makes me think that I would be able to build targetting serverless, and then copy items from .next/serverless/pages and run as standalone files with a Node server like the following:

const http = require('http');
const index = require("./index.js")

const app = http.createServer((req, rej) => index.render(req, rej))

app.listen(3000, '127.0.0.1');

However, this does not work as expected ...

Problems:

  • No matter if we talk about lambdas from .next/serverless/pages or .next/serverless/pages/api, if .next/serverless/chunks is not present, the server fails to start with the error message Error: Cannot find module '../chunks/569.js'. This looks like a dependency to me.
  • When the chunks folder is present, using a lambda from the pages directory works but it causes the browser to load a bunch of other files as well (main-####.js, -webpack-####.js, index-####.js, framework-####.js and ####.css). I assume these could be considered static assets that could be hosted as part of the static website, but if this is the expected behaviour, there is a certain ambiguity to The serverless function has 0 dependencies (they are included in the function bundle) that could be clarified.
  • When the chunks folder is present, using a lambda from the pages/api directory works well, however, it has to be used with default like:
const http = require('http');
const hello = require("./hello.js")

const app = http.createServer((req, rej) => hello.default(req, rej))

app.listen(3000, '127.0.0.1');

... which is neither documented nor conforms to the Node.js HTTP server callback.

Expected Behavior

  • More documentation in general with examples of this feature.
  • That all files in .next/serverless/pages (including files in api) could be used as standalone lambdas with a signature similar to the Node.js HTTP server callback, OR that it is better documented what kind of dependencies to expect or what steps to take, should there be something more that has to be done in order to accomplish this goal.

I understand that most deployments of serverless NextJS applications uses the Serverless framework (or similar) or Vercel but I think that some people, myself included, would like to make it work in a simple hands-on situation first to get an understanding of what goes on behind the curtains with these plugins.

Apart from that, thanks for a great framework which is very pleasant to use! 🏅

To Reproduce

  • Start a new NextJS project with npx create-next-app
  • Add target: "serverless" to next.config.js
  • Change the contents of index.js to to activate server-side rendering:
export async function getServerSideProps(ctx) {

  const user = "test";
  return {props: {user}}
}

export default function Home({user}) {

  return (
      <div>
        <p>{user}</p>
      </div>
  );
}

  • Run next build
  • Copy
    1. Only ./next/serverless/pages/index.js
    2. Only ./next/serverless/pages/api/hello.js
    3. ./next/serverless folder

... to a new place and run the files with the above Node script to observe
i. Missing dependencies
ii. Missing dependencies
iii. index.js resulting in extra downloads in the browser and hello.js having to be executed with default function name.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssue was opened via the bug report template.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions