2.5 KiB
2.5 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Prefer Statically Analyzable Paths | HIGH | 避免意外打包大范围文件和文件追踪范围扩大 | bundle, nextjs, vite, webpack, rollup, esbuild, path |
优先使用可静态分析的路径
构建工具在构建时能明确识别导入路径和文件系统路径时效果最佳。如果实际路径隐藏在变量中,或者通过过于动态的方式拼接路径,构建工具要么被迫包含大量可能的文件,要么发出警告称无法分析该导入,要么扩大文件追踪范围以确保安全。
应优先使用显式的映射表或字面量路径,使可访问文件集合保持窄小且可预测。无论你是用 import() 选择模块,还是在服务器/构建代码中读取文件,这条规则同样适用。
当静态分析范围变得过大时,代价是实实在在的:
- 更大的服务端打包体积
- 更慢的构建速度
- 更差的冷启动性能
- 更多的内存占用
导入路径
错误做法(打包工具无法判断可能导入什么):
const PAGE_MODULES = {
home: './pages/home',
settings: './pages/settings',
} as const
const Page = await import(PAGE_MODULES[pageName])
正确做法(使用显式的允许模块映射表):
const PAGE_MODULES = {
home: () => import('./pages/home'),
settings: () => import('./pages/settings'),
} as const
const Page = await PAGE_MODULES[pageName]()
文件系统路径
错误做法(即使是 2 值的枚举,仍然将最终路径隐藏于静态分析之外):
const baseDir = path.join(process.cwd(), 'content/' + contentKind)
正确做法(在调用处让每条最终路径成为字面量):
const baseDir =
kind === ContentKind.Blog
? path.join(process.cwd(), 'content/blog')
: path.join(process.cwd(), 'content/docs')
在 Next.js 服务端代码中,这一点对输出文件追踪同样重要。path.join(process.cwd(), someVar) 可能会扩大追踪文件集合,因为 Next.js 会静态分析 import、require 和 fs 的用法。
参考链接:Next.js output、Next.js dynamic imports、Vite features、esbuild API、Rollup dynamic import vars、Webpack dependency management