Node.js Builder (@now/node)

Status: Stable

The @now/node Builder takes an entrypoint of a Node.js function, builds its dependencies (if any) and bundles them into a Lambda.

This Builder is the recommended way to introduce any Node.js-based dynamic request handling into your codebases.

It can be used directly (as a single file, like my-function.js), or you can define an index.js file inside a directory.

For this example, we will create a hello endpoint that we want to access as my-deployment.url/api/hello.

Let's create our project structure:

mkdir -p my-node-project/api/hellocd my-node-project/api/hello

Inside my-node-project > api > hello we will create an index.js file.

The index.js file exports a Node.js function that takes in the standard Node.js request and response objects:

const { parse } = require('url')

module.exports = (req, res) => {
  const { query } = parse(req.url, true)
  const { name = 'World' } = query
  res.end(`Hello ${name}!`)
}

An example serverless Node.js function.

The only step left is to define a build that will take this directory's entrypoint (index.js), build it and turn it into a lambda:

{
  "version": 2,
  "builds": [{ "src": "api/hello/index.js", "use": "@now/node" }]
}

An example now.json configuration using the @now/node builder.

Our resulting deployment is here: https://my-node-project-5gkn6kqfy.now.sh/

You can pass query parameters to make the name change:

The lambda using the name query parameter to change the text using Node.js.

You can upload static content along side your Node.js application by using [the @now/static builder].

For example, if you have a static directory and an index.js like the one from the example above, you can serve that directory statically by extending your now.json configuration:

{
  "version": 2,
  "builds": [
    { "src": "api/hello/index.js", "use": "@now/node" },
    { "src": "./static", "use": "@now/static" }
  ]
}

Deploying a serverless Node.js function along with static files.

For more information, read the documentation for @now/static:

The entrypoint of this Builder is always a JavaScript file that exposes a function. If you want to expose a server, look into @now/node-server, although that is not recommended.

Note: @now/node will automatically detect a `package.json` file to install dependencies at the entrypoint level or higher.

The installation algorithm of dependencies works as follows:

  • If a package-lock.json is present, npm install is used
  • Otherwise, yarn is used.

To install private npm modules, define NPM_TOKEN as a build environment variable in now.json.

You can run build tasks by creating a now-build script within a package.json file at the entrypoint's level or higher.

An example package.json with a now-build script:
{
  "scripts": {
    "now-build": "node ./build.js"
  }
}
An example build script, named build.js:
fs.writeFile(
  'built-time.js',
  `module.exports = "$$new Date()}"`,
  (err) => {
    if (err) throw err
    console.log('Build time file created successfully!')
  }
)
An example entrypoint file for the built lambda, index.js:
const BuiltTime = require('./built-time')

module.exports = (req, res) => {
  res.setHeader('content-type', 'text/plain');
  res.end(`
    This Lambda was built at ${new Date(BuiltTime)}.
    The current time is ${new Date()}
  `)
}
To tie it all together, a now.json file:
{
  "version": 2,
  "builds": [
    { "src": "index.js", "use": "@now/node" }
  ]
}

The resulting lambda contains both the build and current time: https://build-time-pq6g1255e.now.sh/

The Node.js version used is the latest in the 8 branch.

For each invocation of a Node.js lambda, two objects, request and response, are passed to the function. These objects are the standard HTTP request and response objects given and used by Node.js.

To help keep cold boot times low, the maximum output bundle size for a Node.js output lambda is, by default, 5mb. This limit is extendable up to 50mb.

Example maxLambdaSize configuration:
{
  "builds": [
    { "src": "*.js", "use": "@now/node", "config": { "maxLambdaSize": "10mb" } }
  ]
}