diff --git a/README.md b/README.md index 24ac90a7ce..af74ab1e46 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,11 @@ publish = ".next" package = "@netlify/plugin-nextjs" ``` -If you previously set `target: "serverless"`, `node_bundler` or `external_node_modules` in your `next.config.js` these are no longer needed and can be removed. +If you previously set `target: "serverless"` or a custom `distDir` in your `next.config.js`, or set `node_bundler` or `external_node_modules` in your `netlify.toml` these are no longer needed and can be removed. + +If you are using a monorepo you will need to change `publish` to point to the full path to the built `.next` directory, which may be in a subdirectory. If you have changed your `distDir` then it will need to match that. + +If you are using Nx, then you will need to point `publish` to the folder inside `dist`, e.g. `dist/apps/myapp/.next`. ## Beta feedback diff --git a/docs/large-functions.md b/docs/large-functions.md new file mode 100644 index 0000000000..c4e95b8966 --- /dev/null +++ b/docs/large-functions.md @@ -0,0 +1,16 @@ +## Troubleshooting large functions + +You may see an error about generated functions being too large. This is because when deploying your site it is packaged into a zipfile, which is limited by AWS to 50MB in size. +There are two possible causes for this, each with its own solution. The list of largest files shown in the build logs will help you see what the cause is. + +- **Large dependencies** + This is the most common cause of the problem. Some node modules are very large, mostly those that include native modules. Examples include `electron` and `chromium`. The function bundler is usually able to find out which modules are actually used by your code, but sometimes it will incorrectly include unneeded modules. If this is the case, you can either remove the module from your dependencies if you installed it yourself, or exclude it manually by adding something like this to your `netlify.toml`, changing the value according to the problematic module: + + ```toml + [functions] + excluded_files = "node_modules/electron/**/*" + ``` + If you do need large modules (e.g. if you are running Puppeteer in a Next API route), consider changing to a Netlify function. + +- **Large numbers of pre-rendered pages** +If you have a very large number of pre-rendered pages, these can take up a lot of space in the function. There are two approaches to fixing this. One is to consider deferring the building of the pages. If you set `fallback = "blocking"`, the rendering will be deferred until the first user requests the page. This is a good choice for low-traffic pages. It reduces build and deploy time, and can make your bundle a lot smaller. The other option is to enable an experimental feature that moves static files out of the function bundle. To do this, set the environment variable `EXPERIMENTAL_MOVE_STATIC_PAGES` to true. diff --git a/src/helpers/verification.js b/src/helpers/verification.js index ef9538289b..79deec9bd4 100644 --- a/src/helpers/verification.js +++ b/src/helpers/verification.js @@ -59,13 +59,13 @@ exports.checkForRootPublish = ({ publish, failBuild }) => { // 50MB, which is the documented max, though the hard max seems to be higher const LAMBDA_MAX_SIZE = 1024 * 1024 * 50 -exports.checkZipSize = async (file) => { +exports.checkZipSize = async (file, maxSize = LAMBDA_MAX_SIZE) => { if (!existsSync(file)) { console.warn(`Could not check zip size because ${file} does not exist`) return } const size = await promises.stat(file).then(({ size }) => size) - if (size < LAMBDA_MAX_SIZE) { + if (size < maxSize) { return } // We don't fail the build, because the actual hard max size is larger so it might still succeed @@ -74,7 +74,7 @@ exports.checkZipSize = async (file) => { The function zip ${yellowBright(relative(process.cwd(), file))} size is ${prettyBytes( size, - )}, which is larger than the maximum supported size of ${prettyBytes(LAMBDA_MAX_SIZE)}. + )}, which is larger than the maximum supported size of ${prettyBytes(maxSize)}. There are a few reasons this could happen. You may have accidentally bundled a large dependency, or you might have a large number of pre-rendered pages included. @@ -85,7 +85,7 @@ exports.checkZipSize = async (file) => { const sortedFiles = Object.values(await zip.entries()).sort((a, b) => b.size - a.size) const largest = {} - for (let i = 0; i < 10; i++) { + for (let i = 0; i < 10 && i < sortedFiles.length; i++) { largest[`${i + 1}`] = { File: sortedFiles[i].name, 'Compressed Size': prettyBytes(sortedFiles[i].compressedSize), @@ -94,6 +94,9 @@ exports.checkZipSize = async (file) => { } console.log(yellowBright`\n\nThese are the largest files in the zip:`) console.table(largest) + console.log( + greenBright`\n\nFor more information on fixing this, see ${blueBright`https://ntl.fyi/large-next-functions`}`, + ) } exports.logBetaMessage = () => @@ -101,7 +104,7 @@ exports.logBetaMessage = () => greenBright( outdent` Thank you for trying the Essential Next.js beta plugin. - Please share feedback at ${blueBright`https://ntl.fyi/next-beta-feedback`} + Please share feedback (both good and bad) at ${blueBright`https://ntl.fyi/next-beta-feedback`} `, ), )