output
在构建过程中,Next.js 会自动追踪每个页面及其依赖项,以确定部署生产版本应用所需的所有文件。
该特性能显著减小部署体积。以往使用 Docker 部署时,您需要安装包中 dependencies 的所有文件才能运行 next start。从 Next.js 12 开始,您可以利用 .next/ 目录中的输出文件追踪功能,仅包含必要文件。
此外,这消除了对已弃用的 serverless 目标的需求,该目标可能导致各种问题并造成不必要的重复。
工作原理
在 next build 过程中,Next.js 会使用 @vercel/nft 静态分析 import、require 和 fs 的使用情况,以确定页面可能加载的所有文件。
Next.js 生产服务器也会被追踪其所需文件,并输出到 .next/next-server.js.nft.json 以便在生产环境中使用。
要利用输出到 .next 目录的 .nft.json 文件,您可以读取每个追踪中相对于 .nft.json 文件的文件列表,然后将它们复制到部署位置。
自动复制追踪文件
Next.js 可以自动创建 standalone 文件夹,仅复制生产部署所需的文件(包括 node_modules 中的选定文件)。
要启用此自动复制功能,可在 next.config.js 中配置:
module.exports = {
output: 'standalone',
}这将在 .next/standalone 创建文件夹,无需安装 node_modules 即可独立部署。
此外,还会输出一个精简的 server.js 文件,可用于替代 next start。默认情况下,该精简服务器不会复制 public 或 .next/static 文件夹(这些文件最好由 CDN 处理),但您可以手动将这些文件夹复制到 standalone/public 和 standalone/.next/static 目录,之后 server.js 将自动提供这些文件。
须知:
next.config.js会在next build期间被读取并序列化到server.js输出文件中。如果使用了旧版serverRuntimeConfig或publicRuntimeConfig配置,其值将固定为构建时的值。- 如果项目需要监听特定端口或主机名,可在运行
server.js前定义PORT或HOSTNAME环境变量。例如执行PORT=8080 HOSTNAME=0.0.0.0 node server.js将在http://0.0.0.0:8080启动服务。- 如果项目使用默认
loader的 图片优化 功能,必须安装sharp依赖:
npm i sharpyarn add sharppnpm add sharpbun add sharp注意事项
- 在 monorepo 环境中进行追踪时,默认使用项目目录作为追踪根目录。对于
next build packages/web-app,packages/web-app将成为追踪根目录,该文件夹外的文件不会被包含。要包含外部文件,可在next.config.js中设置experimental.outputFileTracingRoot。
module.exports = {
experimental: {
// 这将包含来自 monorepo 根目录(上两级目录)的文件
outputFileTracingRoot: path.join(__dirname, '../../'),
},
}- 某些情况下 Next.js 可能无法包含必要文件,或错误包含未使用的文件。此时可通过
next.config.js中的experimental.outputFileTracingExcludes和experimental.outputFileTracingIncludes分别处理。这两个配置接受包含 minimatch 通配符 的对象作为键(用于匹配特定页面),值则是相对于项目根目录的通配符数组(用于包含或排除追踪内容)。
module.exports = {
experimental: {
outputFileTracingExcludes: {
'/api/hello': ['./un-necessary-folder/**/*'],
},
outputFileTracingIncludes: {
'/api/another': ['./necessary-folder/**/*'],
},
},
}- 目前 Next.js 不会对生成的
.nft.json文件进行任何操作。这些文件需要由您的部署平台(例如 Vercel)读取以创建最小化部署。未来版本计划新增命令来利用这些.nft.json文件。
实验性 turbotrace
依赖追踪可能较慢,因为它需要非常复杂的计算和分析。我们用 Rust 开发了 turbotrace 作为 JavaScript 实现的更快更智能替代方案。
要启用该功能,可在 next.config.js 中添加以下配置:
module.exports = {
experimental: {
turbotrace: {
// 控制 turbotrace 的日志级别,默认为 `error`
logLevel?:
| 'bug'
| 'fatal'
| 'error'
| 'warning'
| 'hint'
| 'note'
| 'suggestions'
| 'info',
// 控制 turbotrace 日志是否包含分析详情,默认为 `false`
logDetail?: boolean
// 显示所有日志信息(无限制)
// turbotrace 默认每个类别仅显示 1 条日志
logAll?: boolean
// 控制 turbotrace 的上下文目录
// 上下文目录外的文件不会被追踪
// 设置 `experimental.outputFileTracingRoot` 有相同效果
// 如果同时设置两者,将优先使用 `experimental.turbotrace.contextDirectory`
contextDirectory?: string
// 如果代码中有 `process.cwd()` 表达式,可通过此选项告知 turbotrace 追踪时的 `process.cwd()` 值
// 例如 require(process.cwd() + '/package.json') 将被追踪为 require('/path/to/cwd/package.json')
processCwd?: string
// 控制 turbotrace 的最大内存使用量(单位 MB),默认为 `6000`
memoryLimit?: number
},
},
}