- 前端
- Web框架
- SSR
- 前端构建
- 插件系统
- 微前端
- 跨平台
【免费下载链接】ice
🚀 ice.js: The Progressive App Framework Based On React(基于 React 的渐进式应用框架)
ice.js(基于 React 的渐进式应用框架)将几乎所有构建行为收敛到单一配置文件ice.config.mts中。本文以官方「构建配置」文档为核心,完整讲解从路径别名、环境变量替换、产物分包、代码压缩、polyfill 策略到 SSR/SSG 服务端产物、路由定制等全量配置项,并结合仓库源码(packages/ice/src/config.ts、packages/webpack-config/src/index.ts)剖析每个配置项背后的实现机制与默认值来源,读完即可掌握 ice.js 工程的构建调优与疑难排查能力。
配置文件与基础写法
构建配置文件ice.config.mts
ice.js 支持常用的构建配置项,所有配置项均在ice.config.mts中设置。为了获得良好的类型提示,推荐使用ice.config.mts(ESM + TypeScript)作为配置文件:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ publicPath: '/', }));defineConfig支持函数或对象两种入参,定义在 packages/ice/src/config.ts:当传入函数时先执行函数得到配置对象,再原样返回(空配置时返回{}),因此函数形式便于在配置内部读取process.env等环境信息做分支判断。仓库中的 examples/basic-project/ice.config.mts 即展示了函数式写法 + 环境变量分支(如process.env.ICE_ENV === 'common' ? 'warn' : 'error')。
所有配置项都会经过userConfig注册表(packages/ice/src/config.ts)进行validation校验和默认值注入,非法类型会在启动阶段被拦截。
兼容性配置.browserslistrc
构建的浏览器兼容性推荐配置在.browserslistrc文件中:
chrome 55该文件会被getSupportedBrowsers读取,用于生成 PostCSS 的 autoprefixer、browserslist 目标,并参与 webpack 文件系统缓存的版本指纹计算(packages/webpack-config/src/index.ts 中以 browsers 列表的 MD5 作为缓存 key 的一部分)。更多规则可参考 browserslist 文档。
路径与产物配置
publicPath 与 devPublicPath
publicPath:类型string,默认值/,配置 Webpack 的output.publicPath,仅在执行build命令时生效;devPublicPath:类型string,默认值/,与publicPath同理,仅在执行start命令时生效。
源码中两者的setConfig分别判断context.command === 'build'与context.command === 'start'才将值合并进最终配置(packages/ice/src/config.ts),因此生产环境与开发服务器可以各自指定不同的资源前缀。publicPath最终会写入 webpack 的output.publicPath并同时用于 devServer 的devMiddleware.publicPath(packages/webpack-config/src/index.ts)。
outputDir
- 类型:
string - 默认值:
build
构建产物输出目录,默认为项目根目录下的build目录。源码中当配置值不是绝对路径时会以rootDir为基准拼接(packages/webpack-config/src/index.ts)。
hash
- 类型:
boolean | string - 默认值:
false
如果希望构建后的资源带 hash 版本,可将hash设为true,也可以设为contenthash按文件内容生成 hash 值:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ hash: 'contenthash', }));源码中hash === true会被归一为hash:8,作为输出文件名模板js/[name]-[hash:8].js的组成部分(packages/webpack-config/src/index.ts)。注意:设置为contenthash这类字符串时,webpack 会按文件内容生成 hash,未变化的文件在多次构建间保持相同文件名,从而最大化浏览器缓存命中率。
htmlGenerating
- 类型:
boolean | object - 默认值:
true
如果产物不想生成 html,可以设置为false;注意在 SSG 开启的情况下,强制关闭 html 生成将导致 SSG 失效。传入true与传入{}效果一致。
htmlGenerating.mode
- 类型:
'cleanUrl' | 'compat' - 默认值:
'cleanUrl'
配置 HTML 生成文件的规则,避免某些服务器下非首页内容刷新后 404。两种模式的差别如下表:
| Route | / | /foo | /foo/bar |
|---|---|---|---|
cleanUrl | /index.html | /foo.html | /foo/bar.html |
compat | /index.html | /foo/index.html | /foo/bar/index.html |
cleanUrl:生成的文件路径与路由一致,通常用于支持自动省略.html后缀的现代服务器;compat:生成兼容模式的路径文件,通常用于只能省略index.html的服务器。
该类型定义位于 packages/ice/src/types/userConfig.ts。
模块解析与外部依赖
alias
- 类型:
Record<string, string | false> - 默认值:
{ "@": "./src/" }
ice.js 默认内置常用 alias 规则,项目大多数时候不需要配置即可更简单地导入模块:
-import CustomTips from '../../../components/CustomTips'; +import CustomTips from '@/components/CustomTips';如需配置别名对 import 路径进行映射:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ alias: { pages: './src/pages', }, }));源码实现中,以.开头的相对别名值会被自动拼接为相对项目根目录的绝对路径(packages/shared-config/src/getAlias.ts),因此上面pages: './src/pages'等价于根目录下的src/pages。同时 alias 支持false值,可用于显式禁用内置别名。
externals
- 类型:
Record<string, string> - 默认值:
{}
设置哪些模块不打包,转而通过<script>或其他方式引入:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ externals: { react: 'React', 'react-dom': 'ReactDOM', }, }));对应需要在document.ts或页面模板中添加 CDN 文件:
import { Main, Scripts } from 'ice'; function Document() { return ( <html lang="en"> <body> <Main /> + <script crossOrigin="" src="https://unpkg.com/react@18/umd/react.production.min.js"></script> + <script crossOrigin="" src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <Scripts /> </body> </html> ); } export default Document;externals 配置会直接透传给 webpack 的output.externals(packages/webpack-config/src/index.ts),适合对 react 等体积大、更新频率低的三方库做 CDN 化处理。
crossOriginLoading
- 类型:
false | 'anonymous' | 'use-credentials' - 默认值:
false
指定 webpack 启用 cross-origin 方式加载 chunk:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ crossOriginLoading: 'anonymous' }));该值会被合并到 webpack 的output.crossOriginLoading(packages/ice/src/config.ts),在资源部署到 CDN 且需要跨域携带 Cookie 或凭证时很有用。
编译期变量替换:define
- 类型:
Record<string, string | boolean> - 默认值:内置
{ 'process.env.NODE_ENV': 'development' | 'production'; 'import.meta.renderer': 'client' | 'server'; 'import.meta.target': string; }
define在编译时将代码中的全局变量替换成其他值或表达式,一般用于区分不同环境以执行不同代码逻辑:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ define: { ASSETS_VERSION: JSON.stringify('0.1.0'), AGE: '11', }, }));在代码中直接使用对应变量:
console.log(ASSETS_VERSION); // 最终会被编译成: // console.log('0.1.0'); console.log(AGE); // 最终会被编译成: // console.log(11);注意:编译时框架会对define的替换值进行类似字符串拼接的方式生成新代码,因此:
- 对于引用数据类型(
function和object),必须使用JSON.stringify()处理; - 当要替换的全局变量是字符串时,也必须使用
JSON.stringify()或手动多添加一对引号(如"'hello world'"),否则替换结果会是一个标识符而非字符串字面量,与预期不符。
在构建时这些变量通过 webpackDefinePlugin注入(packages/webpack-config/src/index.ts),同时框架默认注入import.meta.renderer(client/server)与import.meta.target等运行时变量(packages/ice/src/bundler/webpack/getWebpackConfig.ts)。对于运行时变量,ice.js 更推荐通过环境变量的方式注入。
代码优化与产物控制
minify
- 类型:
boolean - 默认值:
true
压缩产物,目前默认仅在 build 阶段生效。源码中minify支持boolean | 'swc' | MinifyOptions(packages/ice/src/types/userConfig.ts),未显式配置时按context.command === 'build'决定是否压缩(packages/ice/src/config.ts);压缩由 TerserPlugin 承担,且支持通过minify: 'swc'切换到更快的 swc 压缩(packages/webpack-config/src/index.ts)。
dropLogLevel
- 类型:
boolean | DropType[] | DropType,其中DropType为'trace' | 'debug' | 'log' | 'info' | 'warn' | 'error' - 默认值:
false,不移除任何 console 代码
压缩代码时移除console.*相关代码。配置为true时移除所有console.*;只想移除部分(如console.log与console.error)时:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ dropLogLevel: ['error', 'log'], }));也可以按 console 等级批量移除:
// console 等级为 trace < debug < log < info < warn < error // 例如想要移除 trace、debug、log 时可以像下面这样配置 import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ dropLogLevel: 'log', }));源码中实现了完整的等级换算(packages/ice/src/config.ts):true对应compress.drop_console: true;数组会映射为compress.pure_funcs中的console.xxx列表;字符串会按等级表(trace:0, debug:1, log:1, info:2, warn:3, error:4)取所有小于等于该等级的 console 方法。若传入非法字符串会打印警告。
codeSplitting 与 splitChunks(已废弃)
splitChunks(@deprecated):不再建议使用,能力由codeSplitting替代。默认会根据模块体积自动拆分 chunks,可能产生多个 bundle;若不希望产物出现过多 bundle 可设为false。codeSplitting:类型boolean | 'vendors' | 'page' | 'chunks' | 'page-vendors',默认值true。
框架内置三种分包策略:
vendors:将异步 chunks 里的三方依赖统一打入vendor.js,避免重复、在依赖不变时有效利用缓存;缺陷是项目过大时单文件尺寸偏大;page:所有路由级别组件按需加载,若需保留原splitChunks: false的效果可配置该策略;page-vendors:在page策略基础上,将异步 chunks 里的三方依赖统一打入vendor.js,兼顾按需加载与缓存;chunks:在路由级组件按需加载基础上,按模块体积自动拆分 chunks,为默认推荐策略。
若存在特殊场景需要关闭分包能力,可设为false。源码中策略的实际实现位于 packages/webpack-config/src/config/splitChunks.ts:chunks策略将react、react-dom、react-router等框架依赖整体打入frameworkchunk(priority 40),并将node_modules中体积大于 160000 字节的模块按内容 hash 拆分libchunk,同时限制maxInitialRequests: 25、minSize: 20000;vendors/page-vendors通过 cacheGroups 统一聚合三方依赖。另外,同时配置splitChunks与codeSplitting时会打印弃用警告,且codeSplitting优先(packages/ice/src/config.ts)。更完整的分包策略可参考代码分割进阶文档。
cssModules
- 类型:
{ localIdentName: string } - 默认值:
{}
构建 CSS Modules 时定制 class 名称的生成规则(与 css-loader 的localIdentName一致)。例如配置'[hash:8]'只保留 hash 值,以精简 HTML 与 CSS 体积。默认情况下className="custom-head-tab-wrap"会被构建为class="custom-head-tab-wrap--rAEgGaqM",自定义后精简为class="rAEgGaqM":
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ cssModules: { localIdentName: '[hash:8]' }, }));编译范围与转译配置
compileDependencies
- 类型:
array | boolean - 默认值:
[](实际默认行为见下)
默认情况下,为保证 dev 阶段体验,node_modules下的文件不会进行编译;而 build 阶段为追求代码体积的极致优化与兼容性保证,会对node_modules内容也进行编译(源码中默认值即process.env.NODE_ENV !== 'development',见 packages/ice/src/config.ts)。
如果 dev 阶段需要额外编译一些依赖,而 build 阶段仍保持全量编译,可通过正则结合环境判断:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ compileDependencies: process.env.NODE_ENV === 'development' ? [/@alifd\/next/, /need-compile/] : true, }));:::caution 如果 build 阶段仍然需要全量编译,请务必增加环境判断,避免误关 build 的依赖编译。 :::
如果希望 dev 和 build 阶段均编译node_modules,直接设为true:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ compileDependencies: true, }));如果明确知道哪些依赖需要编译,也可以通过正则设置(对 dev 和 build 同时生效):
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ compileDependencies: [/@alifd\/next/, /need-compile/], }));源码中字符串类型的依赖会自动加上node_modules前缀构成匹配正则;需注意在--speedup加速模式下不支持 RegExp 形式的配置(会直接报错),且 dev 阶段会通过config.compileIncludes传入编译 loader 的include规则。
postcss
- 类型:
ProcessOptions & { plugins?: (string | [string, Record<string, any>?])[] } - 默认值:
{}
用于添加 postcss 自定义配置:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ postcss: { plugins: [ 'postcss-px-to-viewport-8-plugin', { // ... }, ], syntax: 'sugarss', } }));ice.js 内置的 postcss 配置为:
{ "plugins": [ ["postcss-nested"], ["postcss-preset-env", { "stage": 3, "autoprefixer": { "flexbox": "no-2009", }, "features": { "custom-properties": false, }, }], ["postcss-plugin-rpx2vw"], ], }如果需要完全重写 postcss 配置或修改内置配置,需要在项目根目录新增postcss.config.js,工程会检测到该文件后清空内置 postcss 配置(packages/shared-config/src/getPostcssOpts.ts):
module.exports = { plugins: [ [ 'postcss-preset-env', // 修改 postcss-preset-env 的选项 { stage: 2, } ] ], }内置postcss-preset-env使用 Stage 3 特性并关闭了custom-properties(CSS 变量交给原生支持),同时默认启用 rpx2vw 转换(enableRpx2Vw,packages/webpack-config/src/index.ts);用户配置会与内置插件列表做数组合并而非整体覆盖。
polyfill
- 类型:
'usage' | 'entry' | false - 默认值:
false
框架提供多种 polyfill 方式,可按实际情况选择:
usage:按开发者实际使用的语法自动引入对应 polyfill,适用于node_modules也参与编译的场景(一定程度上影响编译效率,且可能因三方依赖二次编译造成代码冗余);entry:自动引入浏览器需要兼容的 polyfill,适用于node_modules依赖不参与编译的场景(可能引入大量未被使用的 polyfill)。
如果面向现代浏览器开发,大量 ES 语法无需 polyfill,推荐不开启
polyfill配置。如果代码或三方依赖要求兼容到 IE 11 等浏览器,可以选择主动引入指定语法的 polyfill,或开启polyfill配置。
polyfill 生效依赖.browserslistrc声明的浏览器目标(packages/ice/src/types/userConfig.ts),与兼容性配置一节相互配合。
transform
- 类型:
(code: string, id: string) => string | { code: string; map?: SourceMap | null } - 默认值:
undefined
通过transform配置实现代码转化:
import { defineConfig } from '@ice/app'; import { transformSync } from '@babel/core'; export default defineConfig(() => ({ transform: (originalCode, id) => { if (!id.includes('node_modules')) { // 借助 babel 编译 const { code, map } = transformSync(originalCode, { plugins: ['transform-decorators-legacy'], }); return { code, map }; } }, }));ice.js 内置通过
swc提升编译体验,如果在transform上过多依赖 babel 等工具,可能造成编译性能瓶颈。
源码中多次调用transform会被收集为数组逐个执行(packages/ice/src/config.ts),并在 webpack 中通过编译 loader 接入(packages/webpack-config/src/index.ts)。
syntaxFeatures
- 类型:
{ exportDefaultFrom: boolean; functionBind: boolean } - 默认值:
undefined
ice.js 内置了大量 ES 语法支持。对于proposal-export-default-from和proposal-bind-operator这类提案进度较慢的语法并不推荐直接使用,如确需支持可显式开启:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ syntaxFeatures: { exportDefaultFrom: true, functionBind: true, }, }));源码中开启后会注入 swc 编译器的 parser 选项(packages/ice/src/config.ts),且注释明确标注这两个语法不被 esbuild 支持(packages/ice/src/types/userConfig.ts)。
tsChecker
- 类型:
boolean - 默认值:
false
默认关闭 TypeScript 类型检测,如需开启配置为true即可:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ tsChecker: true, }));开启后底层通过 ForkTsCheckerPlugin 在独立进程做类型检查(packages/webpack-config/src/index.ts),默认只检测src目录下的源码(**/src/**/*,packages/ice/src/config.ts)。
eslint
- 类型:
boolean | object - 默认值:
undefined
配置说明:
false:不检测 eslint 错误;true:将 eslint 错误展示在预览页面上;object:仅 Webpack 模式支持,表现等同于true,同时支持配置 eslint-webpack-plugin 的更多参数。
源码中的实现细节(packages/ice/src/config.ts):开启前会校验 eslint 主版本必须大于 7.0.0;默认检测js/ts/jsx/tsx扩展名;build 阶段failOnError: false(不因 lint 错误阻断构建),dev 阶段只 lint 变更文件(lintDirtyModulesOnly: true),从而兼顾体验与效率。
开发体验配置
proxy
- 类型:
object - 默认值:
{}
配置 dev 开发阶段的代理功能,配置项与 webpackdevServer.proxy保持一致:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ proxy: { '/api': { target: 'http://jsonplaceholder.typicode.com/', changeOrigin: true, pathRewrite: { '^/api' : '' }, }, }, }));该配置直接合并进 devServer 配置(packages/webpack-config/src/index.ts),仅在start命令下生效。
mock
- 类型:
{ exclude: string[] } - 默认值:
{}
配置忽略 mock 的文件:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ mock: { // 忽略 mock 目录中 custom 目录下的文件以及 api.ts 文件 exclude: ["custom/**", "api.ts"] }, }));配合默认的mock/目录约定(参考 examples/basic-project/mock 下的示例)与start命令的--mock参数一起使用。
渲染模式:SSR / SSG / Server 产物
ssr
- 类型:
boolean - 默认值:
false
是否开启 SSR 能力。SSR(服务端渲染)在服务端运行 Node.js 程序动态生成 HTML,受设备性能与网络影响更小,可带来更好的性能与 SEO 体验;与 SSG 不同,ice.js 中 SSR 不是默认开启的,需要手动在ice.config.mts中设置ssr: true。更完整的配置与dataLoader/serverDataLoader的协作方式参考 SSR 文档。
ssg
- 类型:
boolean - 默认值:
true
是否开启 SSG 能力。SSG(构建时渲染)在构建时就提前生成内容 HTML,ice.js 默认开启,不仅适用于静态站点,也适用于为普通 CSR 应用提前生成静态内容(如将不依赖数据的组件内容直接输出到 HTML)。更多细节(含staticDataLoader兜底数据)参考 SSG 文档。
server
- 类型:
{ format: 'esm' | 'cjs'; bundle: boolean; ignores: IgnorePattern[]; externals: string[]; onDemand: boolean } - 默认值:
{ format: 'esm', bundle: false, ignores: [], externals: [], onDemand: false }
SSR / SSG 产物标准,推荐以 ESM 标准执行;如果想打包成一个 cjs 模块:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ server: { format: 'cjs', bundle: true, }, }));注意源码中format: 'esm'与bundle: true组合不被支持,会直接报错并退出(packages/ice/src/config.ts)。
通过ignores参数为 SSR / SSG 产物过滤指定文件:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ server: { ignores: [{ resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/, }] }, }));其中:
resourceRegExp:对应文件的匹配路径;contextRegExp(可选):对应文件内容的匹配规则。
通过externals参数在构建 Server 端产物时 external 指定内容:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ server: { externals: ['react', 'react-dom'] }, }));通过onDemand参数,在执行 Server 端产物时按需构建所需模块,并提供体验良好的模块热更新服务:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ server: { onDemand: true, format: 'esm', }, }));类型定义中还包含bundler: 'webpack' | 'esbuild'(默认 esbuild)与webpackConfig等扩展字段(packages/ice/src/types/userConfig.ts),说明服务端产物既支持 webpack 也支持更轻量的 esbuild 打包链路。
dataLoader
- 类型:
boolean | { fetcher: { packageName: string; method: string } } - 默认值:
true
是否启用内置的数据预加载能力以及自定义发送者(fetcher)。开启后构建产物会为数据请求生成额外资源,源码中通过DataLoaderPlugin在 webpack 编译阶段收集路由组件的dataLoader导出并生成数据加载模块(packages/ice/src/bundler/webpack/getWebpackConfig.ts)。关闭方式:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ dataLoader: false, }));完整的 dataLoader API 与 SSR/CSR 协作方式参考数据预加载文档(可对比 examples/with-data-loader 示例工程)。
路由定制:routes
- 类型:
{ ignoreFiles: string[]; defineRoutes: (route: DefineRouteFunction) => void; config?: RouteItem[] } - 默认值:
{}
ignoreFiles
用于忽略src/pages下被处理成路由模块的文件,使用 glob 表达式(minimatch)对文件路径匹配:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ routes: { // 忽略 src/pages 下所有 components 目录 ignoreFiles: ['**/components/**'], }, }));defineRoutes
对约定式路由不满足的场景,可通过该 API 自定义路由地址:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ routes: { defineRoutes: (route) => { // 将 /about-me 路由访问内容指定为 about.tsx // 第一个参数是路由地址 // 第二个参数是页面组件的相对地址(前面不能带 `/`),相对于 `src/pages` 目录 route('/about-me', 'about.tsx'); // 嵌套路由的场景需要使用第三个 callback 参数来定义嵌套路由 route('/', 'layout.tsx', () => { route('/product', 'products.tsx'); }); }, }, }));:::caution 同一个路由组件只能分配一条路由规则,即同时执行以下语句时,仅生效后执行的逻辑:
route('/about-me', 'about.tsx'); route('/about-you', 'about.tsx');:::
config
对于大量自定义或原配置式路由升级的项目,支持以config字段直接声明路由信息:
import { defineConfig } from '@ice/app'; export default defineConfig({ routes: { config: [ { path: 'rewrite', // 从 src/pages 开始计算路径,并且需要写后缀。 component: 'sales/layout.tsx', children: [ { path: '/favorites', component: 'sales/favorites.tsx', }, { path: 'overview', component: 'sales/overview.tsx', }, { path: 'recommends', component: 'sales/recommends.tsx', }, ], }, { path: '/', component: 'index.tsx', }, ], }, });config中component路径从src/pages开始计算且必须带文件后缀。约定式路由与配置式路由的完整对比可参考路由文档与 examples/routes-config、examples/routes-generate 示例工程。
插件与底层扩展
plugins
- 类型:
PluginList<Config, OverwritePluginAPI> - 默认值:
[]
添加插件:
import { defineConfig } from '@ice/app'; import customPlugin from './custom-plugin'; import myPlugin from '@ice/my-plugin'; export default defineConfig(() => ({ plugins: [ customPlugin(), myPlugin(), ], }));ice.js 的插件体系基于build-scripts的PluginList类型(packages/ice/src/types/userConfig.ts),支持通过插件改写框架配置。仓库的 packages/plugin-* 目录下提供了 request、store、auth、i18n、icestark 等官方插件的完整实现,可作为编写自定义插件的参照;examples/basic-project/plugin.ts 展示了项目内自定义插件的接入方式。
webpack
:::tip ice.js 对 webpack 构建配置进行了定制,并借助 esbuild 等工具提升用户开发体验,直接修改 webpack 配置的方式并不推荐。 :::
- 类型:
(config: WebpackConfig, taskConfig: TaskConfig) => WebpackConfig - 默认值:
true
ice.js 默认基于 webpack 5 构建,在上述构建配置无法满足需求时,可以定制 webpack 配置:
import { defineConfig } from '@ice/app'; import SpeedMeasurePlugin from 'speed-measure-webpack-plugin'; export default defineConfig(() => ({ webpack: (webpackConfig) => { if (process.env.NODE_ENV !== 'test') { // 添加 webpack 插件 webpackConfig.plugins?.push(new SpeedMeasurePlugin()); } return webpackConfig; }, }));源码中每次调用webpack函数都会打印「不推荐直接配置 webpack」的警告(packages/ice/src/config.ts),随后将函数追加到configureWebpack管道中,最终与内置的 css/assets 配置一起按顺序执行(packages/webpack-config/src/index.ts)。
其他常用配置
sourceMap
- 类型:
boolean | string - 默认值:
development模式下为'cheap-module-source-map'(支持通过false关闭,不支持设置为其他枚举值);production模式下默认false。
源码中getDevtoolValue将false映射为关闭 devtool,字符串原样透传,未配置时返回'source-map'(packages/shared-config/src/utils/getDevtool.ts)。
optimization
- 类型:
{ disableRouter: boolean; optimizePackageImport: boolean | string[] } - 默认值:
{}
框架提供内置的优化能力:
disableRouter:默认false,如希望关闭路由能力可设为true,主要应用于不存在路由依赖的场景(如没有 SPA 页面跳转);optimizePackageImport:默认false,开启后框架对已知三方依赖进行按需加载,进一步提升构建体验,内置三方依赖列表定义在 packages/ice/src/config.ts,包含@alifd/next、antd、lodash-es、ramda、date-fns、ahooks、@mui/material、recharts以及全部react-icons/*等主流库。
参考配置:
import { defineConfig } from '@ice/app'; export default defineConfig(() => ({ optimization: { disableRouter: true, // optimizePackageImport 配置为 true 则使用内置的三方依赖列表,如果配置为数组则会在内置列表基础上追加 optimizePackageImport: ['@ice/components'], }, }));需注意:optimizePackageImport仅在--speedup加速模式下生效,源码在非加速模式下会打印提示(packages/ice/src/config.ts);加速模式下不支持 RegExp 形式的compileDependencies。
总结:配置优先级与生效命令
综合源码中的配置注册表(packages/ice/src/config.ts),可以归纳出 ice.js 构建配置的几个关键规律:
- 命令隔离:
publicPath仅在build生效、devPublicPath仅在start生效,proxy/mock属 dev 能力,minify默认只在 build 开启; - 默认值即工程最佳实践:
ssg默认开启、ssr默认关闭、codeSplitting默认采用chunks策略、build 默认全量编译node_modules保证兼容性; - 覆盖链路清晰:配置项 →
userConfig注册表校验与归一 →Config中间对象 → webpack/编译插件执行。用户可通过 webpack 回调与 plugins 在最后一层接管,但官方明确不推荐直接改 webpack。
实际工程中可对照 examples/basic-project/ice.config.mts 查看一套包含 SSR、polyfill、alias、define、cssModules、eslint 等的完整生产配置,其余能力可在 examples 目录下的对应示例工程(如 examples/with-data-loader、examples/with-ssg、examples/with-suspense-ssr)中直接运行验证。
- 前端
- Web框架
- SSR
- 前端构建
- 插件系统
- 微前端
- 跨平台
【免费下载链接】ice
🚀 ice.js: The Progressive App Framework Based On React(基于 React 的渐进式应用框架)
相关推荐
如何高效配置ICE.js:掌握ice.config.mts核心技巧的完整指南
如何高效配置ICE.js:掌握ice.config.mts核心技巧的完整指南 ICE.js作为基于React的渐进式应用框架,其配置文件ice.config.m
前端Web框架SSR前端构建插件系统微前端跨平台Snowpack 配置完全指南:从 snowpack.config.js 到源码级原理
Snowpack 配置完全指南:从 snowpack.config.js 到源码级原理 本文是 Snowpack 配置体系( snowpack.config.j
前端开发工具前端构建pnpm 构建策略引擎 @pnpm/building.policy 完全指南:从 allowBuilds 配置到源码级决策原理
pnpm 构建策略引擎 @pnpm/building.policy 完全指南:从 allowBuilds 配置到源码级决策原理 @pnpm/building.p
包管理器开发工具CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考