前端Web框架SSR前端构建插件系统微前端跨平台【免费下载链接】ice ice.js: The Progressive App Framework Based On React基于 React 的渐进式应用框架项目地址https://gitcode.com/gh_mirrors/ice1/ice点击查看免费下载ice.js基于 React 的渐进式应用框架将几乎所有构建行为收敛到单一配置文件ice.config.mts中。本文以官方「构建配置」文档为核心完整讲解从路径别名、环境变量替换、产物分包、代码压缩、polyfill 策略到 SSR/SSG 服务端产物、路由定制等全量配置项并结合仓库源码packages/ice/src/config.ts、packages/webpack-config/src/index.ts剖析每个配置项背后的实现机制与默认值来源读完即可掌握 ice.js 工程的构建调优与疑难排查能力。配置文件与基础写法构建配置文件ice.config.mtsice.js 支持常用的构建配置项所有配置项均在ice.config.mts中设置。为了获得良好的类型提示推荐使用ice.config.mtsESM 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 与 devPublicPathpublicPath类型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.publicPathpackages/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/barcleanUrl/index.html/foo.html/foo/bar.htmlcompat/index.html/foo/index.html/foo/bar/index.htmlcleanUrl生成的文件路径与路由一致通常用于支持自动省略.html后缀的现代服务器compat生成兼容模式的路径文件通常用于只能省略index.html的服务器。该类型定义位于 packages/ice/src/types/userConfig.ts。模块解析与外部依赖alias类型Recordstring, 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类型Recordstring, 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 langen body Main / script crossOrigin srchttps://unpkg.com/react18/umd/react.production.min.js/script script crossOrigin srchttps://unpkg.com/react-dom18/umd/react-dom.production.min.js/script Scripts / /body /html ); } export default Document;externals 配置会直接透传给 webpack 的output.externalspackages/webpack-config/src/index.ts适合对 react 等体积大、更新频率低的三方库做 CDN 化处理。crossOriginLoading类型false | anonymous | use-credentials默认值false指定 webpack 启用 cross-origin 方式加载 chunkimport { defineConfig } from ice/app; export default defineConfig(() ({ crossOriginLoading: anonymous }));该值会被合并到 webpack 的output.crossOriginLoadingpackages/ice/src/config.ts在资源部署到 CDN 且需要跨域携带 Cookie 或凭证时很有用。编译期变量替换define类型Recordstring, 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.rendererclient/server与import.meta.target等运行时变量packages/ice/src/bundler/webpack/getWebpackConfig.ts。对于运行时变量ice.js 更推荐通过环境变量的方式注入。代码优化与产物控制minify类型boolean默认值true压缩产物目前默认仅在 build 阶段生效。源码中minify支持boolean | swc | MinifyOptionspackages/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.tstrue对应compress.drop_console: true数组会映射为compress.pure_funcs中的console.xxx列表字符串会按等级表trace:0, debug:1, log:1, info:2, warn:3, error:4取所有小于等于该等级的 console 方法。若传入非法字符串会打印警告。codeSplitting 与 splitChunks已废弃splitChunksdeprecated不再建议使用能力由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.tschunks策略将react、react-dom、react-router等框架依赖整体打入frameworkchunkpriority 40并将node_modules中体积大于 160000 字节的模块按内容 hash 拆分libchunk同时限制maxInitialRequests: 25、minSize: 20000vendors/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 体积。默认情况下classNamecustom-head-tab-wrap会被构建为classcustom-head-tab-wrap--rAEgGaqM自定义后精简为classrAEgGaqMimport { 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直接设为trueimport { 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, Recordstring, 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.tsmodule.exports { plugins: [ [ postcss-preset-env, // 修改 postcss-preset-env 的选项 { stage: 2, } ] ], }内置postcss-preset-env使用 Stage 3 特性并关闭了custom-propertiesCSS 变量交给原生支持同时默认启用 rpx2vw 转换enableRpx2Vwpackages/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 }默认值undefinedice.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构建时渲染在构建时就提前生成内容 HTMLice.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类型PluginListConfig, 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默认值trueice.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-mappackages/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 的渐进式应用框架项目地址https://gitcode.com/gh_mirrors/ice1/ice点击查看免费下载相关推荐如何高效配置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上一篇解决Elasticsearch大整数精度丢失elasticsearch-dump的big.js集成方案下一篇TypeScript 泛型完全指南从 Queue 到便利泛型设计模式typescript-book 实践篇创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
