diff --git a/packages/serverless-nextjs-component/README.md b/packages/serverless-nextjs-component/README.md index ebb0cc01fa..b764bb96a1 100644 --- a/packages/serverless-nextjs-component/README.md +++ b/packages/serverless-nextjs-component/README.md @@ -76,6 +76,16 @@ AWS_ACCESS_KEY_ID=accesskey AWS_SECRET_ACCESS_KEY=sshhh ``` +Set next.js build target to `serverless`: + +```js +// next.config.js + +module.exports = { + target: "serverless" +}; +``` + And simply deploy: ```bash @@ -124,6 +134,7 @@ myNextApplication: Make sure you add CloudWatch log permissions to your custom policy. ### Lambda memory + Both **default** and **api** lambdas will be assigned 512mb of memory by default. This value can be altered by assigning a number to the `memory` input ```yml @@ -170,13 +181,19 @@ The fourth cache behaviour handles next API requests `api/*`. ### Inputs -| Name | Type | Default Value | Description | -| ------------- | --------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| domain | `Array` | `null` | For example `['admin', 'portal.com']`. | -| bucketName | `string` | `null` | Custom bucket name where static assets are stored. By default is autogenerated. | -| nextConfigDir | `string` | `.` | Directory where your application `next.config.js` file is. This input is useful when the `serverless.yml` is not in the same directory as the next app. | -| build | `boolean` | `true` | When true builds and deploys app, when false assume the app has been built and uses the .next .serverless_nextjs directories in nextConfigDir to deploy | -| memory | `number` or `object` | `512` | When assigned a number, both the default and api lambdas will assigned memory of that value. When assigned to an object, values for the default and api lambdas can be separately defined | +| Name | Type | Default Value | Description | +| ------------- | --------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| domain | `Array` | `null` | For example `['admin', 'portal.com']`. | +| bucketName | `string` | `null` | Custom bucket name where static assets are stored. By default is autogenerated. | +| nextConfigDir | `string` | `./` | Directory where your application `next.config.js` file is. This input is useful when the `serverless.yml` is not in the same directory as the next app.
**Note:** `nextConfigDir` should be set if `next.config.js` `distDir` is used. | +| nextStaticDir | `string` | `./` | If your `static` or `public` directory is not a direct child of `nextConfigDir` this is needed. | +| memory | `number` or `object` | `512` | When assigned a number, both the default and api lambdas will assigned memory of that value. When assigned to an object, values for the default and api lambdas can be separately defined | | +| build | `boolean` or `Object` | `true` | When true builds and deploys app, when false assume the app has been built and uses the `.next` `.serverless_nextjs` directories in `nextConfigDir` to deploy. If an object is passed `build` allows for overriding what script gets called and with what arguments. | +| build.cmd | `string` | `node_modules/.bin/next` | Build command | +| build.args | `Array|string` | `['build']` | Arguments to pass to the build | +| build.cwd | `string` | `./` | Override the current working directory | +| build.enabled | `boolean` | `true` | Same as passing `build:false` but from within the config. | +| build.env | `Object` | `{}` | Add additional environment variables to the script. | Custom inputs can be configured like this: @@ -245,6 +262,22 @@ The serverless team is currently working on remote state storage so this won't b Serverless next.js is _regionless_. By design, `serverless-next.js` applications will be deployed across the globe to every CloudFront edge location. The lambda might look like is only deployed to `us-east-1` but behind the scenes, it is replicated to every other region. +#### I require passing additional information into my build + +See the sample below for an advanced `build` setup that includes passing additional arguments and environment variables to the build. + +```yml +# serverless.yml +myDatabase: + component: MY_DATABASE_COMPNENT +myNextApp: + component: serverless-next.js + build: + args: ["build", "custom/path/to/pages"] + env: + DATABASE_URL: ${myDatabase.databaseUrl} +``` + ## Contributing Please see the [contributing](./CONTRIBUTING.md) guide. diff --git a/packages/serverless-nextjs-component/serverless.js b/packages/serverless-nextjs-component/serverless.js index b263dfbb74..93da4e75e6 100644 --- a/packages/serverless-nextjs-component/serverless.js +++ b/packages/serverless-nextjs-component/serverless.js @@ -237,9 +237,24 @@ class NextjsComponent extends Component { ? path.resolve(inputs.nextConfigDir) : process.cwd(); - await execa("node_modules/.bin/next", ["build"], { - cwd: nextConfigPath - }); + const buildConfig = { + enabled: inputs.build && inputs.build.enabled !== false, + cmd: "node_modules/.bin/next", + args: ["build"], + ...(typeof inputs.build === "object" ? inputs.build : {}), + cwd: + inputs.build && inputs.build.cwd + ? path.resolve(inputs.build.cwd) + : nextConfigPath + }; + + if (buildConfig.enabled) { + let { cmd, args, cwd, env } = buildConfig; + await execa(cmd, args, { + cwd, + env + }); + } await this.emptyBuildDirectory(nextConfigPath); @@ -263,6 +278,8 @@ class NextjsComponent extends Component { const nextConfigPath = inputs.nextConfigDir ? path.resolve(inputs.nextConfigDir) : process.cwd(); + const nextStaticPath = inputs.nextStaticDir || ""; + const staticPath = nextStaticPath || nextConfigPath; const [defaultBuildManifest, apiBuildManifest] = await Promise.all([ this.readDefaultBuildManifest(nextConfigPath), @@ -312,14 +329,14 @@ class NextjsComponent extends Component { ]; const [publicDirExists, staticDirExists] = await Promise.all([ - fse.exists(join(nextConfigPath, "public")), - fse.exists(join(nextConfigPath, "static")) + fse.exists(join(staticPath, "public")), + fse.exists(join(staticPath, "static")) ]); if (publicDirExists) { assetsUpload.push( bucket.upload({ - dir: join(nextConfigPath, "public"), + dir: join(staticPath, "public"), keyPrefix: "public" }) ); @@ -328,7 +345,7 @@ class NextjsComponent extends Component { if (staticDirExists) { assetsUpload.push( bucket.upload({ - dir: join(nextConfigPath, "static"), + dir: join(staticPath, "static"), keyPrefix: "static" }) );