Files
2026-07-13 21:36:17 +08:00

64 lines
2.5 KiB
Markdown

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