Skip to Content

配置

@utoo/pack 支持通过 utoopack.jsonutoopack.config.mjs 和 Node API 进行配置。

配置文件

utoopack.json
{ "$schema": "@utoo/pack/config_schema.json", "mode": "production", "entry": [ { "import": "./src/index.ts", "html": { "template": "./index.html" } } ], "output": { "path": "./dist", "filename": "[name].[contenthash:8].js", "chunkFilename": "[name].[contenthash:8].js", "clean": true } }

如果配置完全可 JSON 序列化,推荐使用 utoopack.json。如果需要类型提示,或者要在 JS 里组合配置,推荐使用 utoopack.config.*。配置文件形式还可以承载 UserConfig 里的运行时字段,例如 processEnvwatchdevbuildIdtracingpackPathprojectPathrootPath

顶层选项

选项描述
mode构建模式:developmentproduction
target目标运行环境
entry入口、HTML 生成和库输出
output输出目录、文件名模板、资源复制
resolvealias 和扩展名解析
define构建时常量替换
provider自动注入模块,类似 Webpack ProvidePlugin
externals将依赖排除出 bundle
module自定义模块规则和 loader
stylesCSS Modules、Less、Sass、PostCSS、Emotion、styled-components、styled-jsx
images图片内联行为
reactJSX runtime 和 React transform 相关配置
mdxRust MDX transform 配置
reactCompilerRust React Compiler 配置
optimization压缩、tree shaking、split chunks、import 转换
devServerhost、port、HTTPS、HMR、proxy
server服务端入口、Server Functions 和服务端输出
sourceMaps是否生成 source map
stats是否输出构建统计信息
persistentCaching是否跨次构建复用缓存
turbopackMemoryEviction持久缓存的内存回收模式
nodePolyfill浏览器构建时是否补齐 Node.js 内置能力
swcPlugins自定义 SWC 插件
pluginRuntimeStrategyloader / plugin 的运行进程模型
experimentalreactCompilerswcPlugins 的兼容配置入口

核心配置

mode 和 target

mode 会影响默认优化策略,target 用来指定输出运行环境。

{ "mode": "production", "target": "browser" }
描述
development更快构建,更好调试,启用 HMR
production优化输出,压缩,tree shaking

entry

定义应用入口、HTML 生成和库输出。

{ "entry": [ { "name": "main", "import": "./src/index.ts", "library": { "name": "MyBundle", "export": ["default"] }, "html": { "template": "./index.html", "filename": "index.html", "title": "My App", "inject": "body", "scriptLoading": "module" } } ] }

output

配置输出目录、文件命名、静态资源复制和运行时资源路径。

{ "output": { "path": "./dist", "type": "standalone", "filename": "[name].[contenthash:8].js", "chunkFilename": "[name].[contenthash:8].js", "cssFilename": "[name].[contenthash:8].css", "cssChunkFilename": "[name].[contenthash:8].css", "assetModuleFilename": "assets/[name].[contenthash:8][ext]", "publicPath": "/", "crossOriginLoading": "anonymous", "copy": ["./public"], "chunkLoadingGlobal": "TURBOPACK", "clean": true, "entryRootExport": "AppExports" } }
选项描述
path输出目录
type输出类型:standaloneexport
filename入口 chunk 文件名模板
chunkFilename非入口 chunk 文件名模板
cssFilename主 CSS 文件名模板
cssChunkFilenameCSS chunk 文件名模板
assetModuleFilename资源文件名模板
publicPath资源的公共 URL 前缀;也支持 runtimeauto
crossOriginLoading懒加载 chunk 的 crossorigin 配置
copy将静态文件复制到输出目录
chunkLoadingGlobal运行时加载 chunk 使用的全局变量名
clean构建前清理输出目录
entryRootExport将入口导出挂到 window / globalThis

publicPath: "runtime" 会从 globalThis.publicPath 读取运行时前缀;publicPath: "auto" 会根据当前加载的脚本地址自动推断前缀。

define

构建时变量替换。

{ "define": { "process.env.NODE_ENV": "\"production\"", "__VERSION__": "\"1.0.0\"" } }

provider

自动注入模块,作用类似 Webpack 的 ProvidePlugin

{ "provider": { "$": "jquery", "Buffer": ["buffer", "Buffer"] } }

externals

从打包中排除依赖。

{ "externals": { "react": "React", "react-dom": "ReactDOM", "lodash-es": { "root": "_", "type": "global" } } }

externals 支持简单字符串全局变量,也支持 scriptcommonjsesmglobalpromise 形式以及更复杂的子路径配置。

resolve

配置模块解析。resolve.alias 会在模块解析前,把导入请求改写到另一个模块或路径,规则采用 Turbopack 风格的 alias 行为 

{ "resolve": { "alias": { "react": "preact/compat", "@/*": "./src/*", "legacy/": "./src/legacy/", "runtime/*": ["./src/runtime/*", "./fallback/runtime/*"] }, "extensions": [".ts", ".tsx", ".js", ".jsx"] } }

resolve.alias 支持以下结构:

type ResolveAlias = Record<string, string | string[] | Record<string, string | string[]>>

匹配规则:

Alias会匹配不会匹配
"foo": "./src/foo"import "foo"import "foo/bar"
"foo/*": "./src/foo/*"import "foo/bar" 以及更深的子路径import "foo"
"foo/": "./src/foo/"等价于 "foo/*": "./src/foo/*"import "foo"

如果需要把匹配到的子路径带入替换结果,使用 ** 可以跨路径分隔符,因此 "@/*": "./src/*" 可以解析 @/components/Button 这样的导入。

alias value 支持以下形式:

Value行为
string改写到单个包或路径
string[]按顺序尝试多个候选路径
条件对象按条件选择 value,常用条件是 browser,不满足时使用 default

相对路径 value 会从项目根目录解析,例如 "./src/foo"。项目内的绝对路径会被规范化为项目相对路径。不要配置指向项目目录之外的 alias。

utoopack.config.mjs
import { defineConfig } from '@utoo/pack'; export default defineConfig({ resolve: { alias: { // 精确替换 lodash: 'lodash-es', // 子路径替换 '@/*': './src/*', // 目录简写 'components/': './src/components/', // 多候选 'runtime/*': ['./src/runtime/*', './fallback/runtime/*'], // 条件 alias env: { browser: './src/env.browser.ts', default: './src/env.node.ts', }, }, extensions: ['.ts', '.tsx', '.js', '.jsx'], }, });

从 Webpack alias 迁移

最容易踩坑的差异是子路径匹配。Webpack 中常见的 foo: path.resolve(__dirname, 'src/foo') 通常可以同时覆盖 foofoo/bar。在 Utoopack 中,普通 key 是精确匹配;如果要覆盖子路径,需要显式加 /*,或者使用以 / 结尾的目录简写。

WebpackUtoopack
foo: path.resolve(__dirname, 'src/foo'),用于 import "foo""foo": "./src/foo"
foo: path.resolve(__dirname, 'src/foo'),用于 import "foo/bar""foo/*": "./src/foo/*""foo/": "./src/foo/"
'@': path.resolve(__dirname, 'src'),用于 import "@/Button""@/*": "./src/*"
react: 'preact/compat'"react": "preact/compat"

Webpack 通过 $ 后缀表示精确匹配,例如 foo$: './src/foo'。Utoopack 不需要这个后缀,因为精确匹配就是默认行为:

{ "resolve": { "alias": { "foo": "./src/foo" } } }

这只会影响:

import "foo"

不会影响:

import "foo/bar"

如果需要覆盖子路径,应该写成:

{ "resolve": { "alias": { "foo/*": "./src/foo/*" } } }

或使用目录简写:

{ "resolve": { "alias": { "foo/": "./src/foo/" } } }

module

定义基于 loader 的模块规则。规则对象支持 loadersconditiontype 等字段。

{ "module": { "rules": { "*.md": ["raw-loader"], "*.svg": [ { "loaders": [ { "loader": "@svgr/webpack", "options": { "icon": true } } ] } ] } } }

styles

配置内置样式处理能力。

{ "styles": { "autoCssModules": true, "cssModules": { "localIdentName": "[local]__[hash:base64:6]" }, "postcss": {}, "less": { "loader": "less-loader", "implementation": "less" }, "sass": { "implementation": "sass" }, "inlineCss": { "injectType": "styleTag" }, "emotion": { "autoLabel": "dev-only" }, "styledComponents": { "displayName": true, "ssr": true }, "styledJsx": { "useLightningcss": true } } }

styles.cssModules.localIdentName 用于自定义 CSS Modules 类名模板。styles.less.loader 用于指定自定义 Less loader;implementation 指定实际使用的 Less 实现,其他字段会继续传给 loader。

images

配置图片内联行为。

{ "images": { "inlineLimit": 8192 } }

react

React transform 相关配置。

{ "react": { "runtime": "automatic", "importSource": "react", "absoluteSourceFilename": false } }

mdx

mdx 启用 Rust MDX transform。可以直接传布尔值,也可以传对象配置编译模式、JSX runtime 和 MDX 语法模式。

{ "mdx": { "development": false, "jsx": false, "jsxRuntime": "automatic", "jsxImportSource": "react", "providerImportSource": "@mdx-js/react", "mdxType": "gfm" } }

mdxType 支持 commonmarkgfm。使用默认配置时可以简写为 "mdx": true

React Compiler 和 SWC 插件

reactCompiler 可以是布尔值,也可以通过 compilationModetarget 配置 Rust React Compiler。compilationMode 支持 inferannotationalltarget 支持 React 1819

{ "reactCompiler": { "compilationMode": "infer", "target": "19" }, "swcPlugins": [ ["swc-plugin-name", {}] ] }

experimental.reactCompilerexperimental.swcPlugins 仍然可用。顶层 reactCompiler 优先于 experimental.reactCompiler;顶层和 experimental 中的 swcPlugins 会合并执行。

optimization

{ "optimization": { "minify": true, "extractComments": true, "treeShaking": true, "moduleIds": "deterministic", "splitChunks": { "js": { "minChunkSize": 50000, "maxChunkCountPerGroup": 40, "maxMergeChunkSize": 200000 } }, "cssChunking": "graph", "modularizeImports": { "lodash": { "transform": "lodash/{{member}}", "preventFullImport": true } }, "packageImports": ["package-name"], "transpilePackages": ["shared-ui"], "removeConsole": { "exclude": ["error"] }, "concatenateModules": true, "removeUnusedExports": true, "removeUnusedImports": true } }
选项类型描述
moduleIdsnamed | deterministic模块 ID 生成策略
noManglingboolean压缩时保留变量、函数等局部名称
compressboolean | object控制压缩优化;对象支持 passessequenceskeepClassnameskeepFnames
minifyboolean压缩输出代码
extractCommentsboolean库构建压缩时将 legal comments 提取到 [file].LICENSE.txt
treeShakingboolean移除未使用代码
splitChunksobject分别配置 js / css chunk 的尺寸和数量限制
cssChunkingboolean | string | objectCSS chunk 分组算法
modularizeImportsobject按模板转换包导入,类似 babel-plugin-import
packageImportsstring[]优化具有大量导出的包入口
transpilePackagesstring[]转译指定依赖包
removeConsoleboolean | object移除 console 调用,可通过 exclude 保留方法
concatenateModulesboolean合并模块以减少 chunk 数量
removeUnusedExportsboolean移除未使用导出;开发环境默认关闭,生产环境默认开启
removeUnusedImportsboolean移除未使用导入;开发环境默认关闭,生产环境默认开启
nestedAsyncChunkingboolean启用嵌套异步 chunk
wasmAsAssetboolean将 WASM 内联到 bundle;默认关闭并作为静态资源输出

optimization.packageImports

optimization.packageImports 用于优化导出大量模块的包的具名导入。将包名加入配置后,业务代码仍可从包的根入口导入,Utoopack 只加载实际使用的模块,从而减少开发和生产构建中的模块解析与编译开销。该选项的类型为 string[],用法类似 Next.js 的 optimizePackageImports

utoopack.json
{ "optimization": { "packageImports": ["package-name"] } }

Utoopack 的内置列表参考 Next.js 维护,但以 DEFAULT_OPTIMIZE_PACKAGE_IMPORTS 的实现为准。当前共包含 74 个包或包子路径:

[ "lucide-react", "date-fns", "lodash-es", "ramda", "react-bootstrap", "ahooks", "@ant-design/icons", "@headlessui/react", "@headlessui-float/react", "@heroicons/react/20/solid", "@heroicons/react/24/solid", "@heroicons/react/24/outline", "@visx/visx", "@tremor/react", "rxjs", "@mui/material", "@mui/icons-material", "recharts", "react-use", "effect", "@effect/schema", "@effect/platform", "@effect/platform-node", "@effect/platform-browser", "@effect/platform-bun", "@effect/sql", "@effect/sql-mssql", "@effect/sql-mysql2", "@effect/sql-pg", "@effect/sql-sqlite-node", "@effect/sql-sqlite-bun", "@effect/sql-sqlite-wasm", "@effect/sql-sqlite-react-native", "@effect/rpc", "@effect/rpc-http", "@effect/typeclass", "@effect/experimental", "@effect/opentelemetry", "@material-ui/core", "@material-ui/icons", "@tabler/icons-react", "mui-core", "react-icons/ai", "react-icons/bi", "react-icons/bs", "react-icons/cg", "react-icons/ci", "react-icons/di", "react-icons/fa", "react-icons/fa6", "react-icons/fc", "react-icons/fi", "react-icons/gi", "react-icons/go", "react-icons/gr", "react-icons/hi", "react-icons/hi2", "react-icons/im", "react-icons/io", "react-icons/io5", "react-icons/lia", "react-icons/lib", "react-icons/lu", "react-icons/md", "react-icons/pi", "react-icons/ri", "react-icons/rx", "react-icons/si", "react-icons/sl", "react-icons/tb", "react-icons/tfi", "react-icons/ti", "react-icons/vsc", "react-icons/wi" ]

通过 optimization.packageImports 配置的包会与这份内置列表合并并去重。

optimization.cssChunking

optimization.cssChunking 支持 trueloosegraphloose(以及 true)使用默认分组算法;graph 使用基于图的算法,也可以通过对象调整额外请求的估算成本和权重分布。

utoopack.json
{ "optimization": { "cssChunking": { "type": "graph", "requestCost": 100000, "weightDistribution": 0.1 } } }

falsestrict{ "type": "strict" } 当前不受 Utoopack 支持,使用时构建会报错。

devServer

本地仓库当前支持的字段包括 hotdynamicHmrChunkListshostporthttpsproxy

{ "devServer": { "hot": true, "dynamicHmrChunkLists": true, "host": "0.0.0.0", "port": 3000, "https": false, "proxy": [ { "context": ["/api"], "target": "http://localhost:7001", "changeOrigin": true, "pathRewrite": { "^/api": "" } } ] } }

dynamicHmrChunkLists 开启后,运行时会随着动态 chunk 加载注册对应的 HMR chunk list。

server

server 配置服务端入口、Server Functions 边界和服务端 chunk 输出。entry 可以是单个入口字符串,也可以是具名入口数组;数组中的第一个入口是主服务端运行时,并接收 Server Functions。

utoopack.json
{ "server": { "entry": [ { "name": "server", "import": "./src/server.ts" }, { "name": "admin-server", "import": "./src/admin.server.ts" } ], "function": { "clientProxy": "./src/transport.ts", "serverRegister": "./src/register.ts" }, "output": { "path": "./dist/server", "filename": "[name].[contenthash:8].js", "chunkFilename": "chunks/[name].[contenthash:8].js" } } }

单入口可以简写为 "entry": "./src/server.ts"clientProxy 模块需要导出 createServerReference(actionId, name)serverRegister 模块需要导出 registerServerReference(action, actionId, name)

高级选项

选项类型描述
sourceMapsboolean启用 source map
statsboolean启用构建统计输出
nodePolyfillboolean为浏览器补齐 Node.js 内置模块
persistentCachingboolean启用持久化构建缓存,默认开启
turbopackMemoryEvictionboolean | auto | full持久缓存的内存回收模式,默认 autofalse 关闭,true 等价于 full
swcPlugins[string, any][]自定义 SWC 插件及其选项
pluginRuntimeStrategyworkerThreads | childProcessesloader / plugin 使用 worker thread 或子进程运行
experimentalobjectreactCompilerswcPlugins 的兼容配置入口

配置文件运行时字段

这些字段属于 UserConfig,可在 utoopack.config.* 中控制构建运行过程。

选项类型描述
processEnvRecord<string, string>编译时使用的环境变量
watchobject文件监听配置
devboolean是否以开发模式运行
buildIdstring当前构建 ID
tracingboolean是否启用默认 tracing 日志,默认开启
packPathstring@utoo/pack 的绝对路径
projectPathstring项目路径
rootPathstring根路径,monorepo 中可与项目路径不同

watch 支持 enablepollIntervalMsignorednodeModulesRegexes。默认忽略 node_modulesignored 中的 !node_modules/<regex>nodeModulesRegexes 中的包名正则可以重新纳入需要监听的依赖。

utoopack.config.mjs
import { defineConfig } from '@utoo/pack'; export default defineConfig({ entry: [{ import: './src/index.ts' }], watch: { enable: true, pollIntervalMs: 500, ignored: ['node_modules'], nodeModulesRegexes: ['rc-.*', '@rc-component/.*'], }, });

编程 API

const { build } = require('@utoo/pack'); await build({ config: { mode: "production", entry: [{ import: "./src/index.ts" }], output: { path: "./dist" } } });

完整配置 schema 见 config_schema.json 

Last updated on