2023-01-05 15:45:42 +08:00
|
|
|
|
---
|
|
|
|
|
title: 从 ice.js 2.x 升级
|
2023-03-17 11:03:19 +08:00
|
|
|
|
order: 0902
|
2023-01-05 15:45:42 +08:00
|
|
|
|
---
|
|
|
|
|
# 从 ice.js 2.x 升级
|
|
|
|
|
|
|
|
|
|
## 前言
|
|
|
|
|
|
2023-03-17 11:03:19 +08:00
|
|
|
|
升级 ice.js 3.x 可以带来构建速度和页面性能的提升,并且带来更多移动端功能,比如开箱即用的 PHA、Weex 和小程序方案等。
|
2023-01-05 15:45:42 +08:00
|
|
|
|
|
|
|
|
|
## 升级指南
|
|
|
|
|
|
|
|
|
|
### 依赖修改
|
|
|
|
|
|
|
|
|
|
```diff
|
|
|
|
|
{
|
|
|
|
|
"devDependencies": {
|
|
|
|
|
- "ice.js": "^2.0.0",
|
|
|
|
|
+ "@ice/app": "^3.0.0",
|
|
|
|
|
+ "@ice/runtime": "^1.0.0",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
对应插件能力:
|
|
|
|
|
- @ali/build-plugin-ice-def -> @ali/ice-plugin-def
|
|
|
|
|
- build-plugin-moment-locales -> @ice/plugin-moment-locales
|
|
|
|
|
- build-plugin-fusion -> @ice/plugin-fusion (多主题能力暂不支持)
|
|
|
|
|
- build-plugin-antd -> @ice/plugin-antd
|
|
|
|
|
- build-plugin-css-assets-local -> @ice/plugin-css-assets-local
|
|
|
|
|
- build-plugin-jsx-plus -> @ice/plugin-jsx-plus [文档](../advanced/jsx-plus.md)
|
|
|
|
|
- build-plugin-keep-alive 不再支持,有 ice.js 3.0 的 [keep alive 方案](../advanced/keep-alive.md)替代
|
|
|
|
|
|
|
|
|
|
插件使用方式变更为函数调用:
|
|
|
|
|
|
|
|
|
|
```ts title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import jsxPlus from '@ice/plugin-jsx-plus';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
plugins: [
|
|
|
|
|
jsxPlus(),
|
|
|
|
|
],
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
> 完成依赖升级后推荐重新安装依赖,即执行 npm update
|
|
|
|
|
|
|
|
|
|
### 工程配置文件升级
|
|
|
|
|
|
|
|
|
|
为了获取更好的类型提示,ice 新版本中推荐使用 ts 文件进行配置,即在项目目录下新增 `ice.config.mts` 文件,原 json 中的能力支持情况如下:
|
|
|
|
|
|
|
|
|
|
| ice 2.x | ice 3.0 | 备注 |
|
|
|
|
|
| ---- | ---- | ---- |
|
|
|
|
|
| --port | ✅ | - |
|
|
|
|
|
| --host | ✅ | - |
|
|
|
|
|
| --config | ✅ | - |
|
|
|
|
|
| --disable-open | ✅ | - |
|
|
|
|
|
| plugins | ✅ | - |
|
|
|
|
|
| alias | ✅ | - |
|
|
|
|
|
| publicPath | ✅ | - |
|
|
|
|
|
| devPublicPath | ✅ | - |
|
|
|
|
|
| sourceMap | ✅ | - |
|
|
|
|
|
| externals | ✅ | - |
|
|
|
|
|
| hash | ✅ | - |
|
|
|
|
|
| outputDir | ✅ | - |
|
|
|
|
|
| proxy | ✅ | - |
|
|
|
|
|
| define | ✅ | - |
|
|
|
|
|
| ssr | ✅ | - |
|
|
|
|
|
| --disable-mock | ✅ | - |
|
|
|
|
|
| --https | ✅ | - |
|
|
|
|
|
| --analyzer | ✅ | - |
|
|
|
|
|
| dropLogLevel | ✅ | - |
|
|
|
|
|
| minify | ✅ | 简化配置(true/false) |
|
|
|
|
|
| compileDependencies | ✅ | 配合现有的 compileIncludes 能力 |
|
|
|
|
|
| eslint | ✅ | - |
|
|
|
|
|
| tsChecker | ✅ | - |
|
|
|
|
|
| postcssOptions / postcssrc | ✅ | - |
|
|
|
|
|
| polyfill | ✅ | 需要主动开启 |
|
|
|
|
|
| remoteRuntime | ❌ | - |
|
|
|
|
|
| --disable-assets | ❌ | 不常用通过环境变量控制日志输出详细程度 |
|
|
|
|
|
| --disable-reload | ❌ | 配置禁止 fastRefresh |
|
|
|
|
|
| terser | ❌ | 内置方案 |
|
|
|
|
|
| outputAssetsPath | ❌ | 后续输出最佳目录实践 |
|
|
|
|
|
| devServer | ❌ | 不支持全量配置 devServer,按需开启 server 相关能力 |
|
|
|
|
|
| browserslist | ❌ | 统一走 browserlist 文件 |
|
|
|
|
|
| vendor | ❌ | 内置的分包实践,可以通过 splitChunks 关闭 |
|
|
|
|
|
| libraryTarget / library / libraryExport | ❌ | - |
|
|
|
|
|
| cssLoaderOptions / lessLoaderOptions / sassLoaderOptions | ❌ | 不支持 webpack loader 相关,内置配置 |
|
|
|
|
|
| ignoreHtmlTemplate | ❌ | - |
|
|
|
|
|
| entry | ❌ | 自定义场景走 client.entry.tsx |
|
|
|
|
|
| vite / vitePlugins | ❌ | - |
|
|
|
|
|
| swc | ❌ | - |
|
|
|
|
|
| store / auth / request / pwa / router | ❌ | 通过定制的插件支持 |
|
|
|
|
|
| disableRuntime | ❌ | - |
|
|
|
|
|
| babelPlugins / babelPresets / webpackPlugins / webpackLoaders | ❌ | 不推荐直接配置 |
|
|
|
|
|
|
|
|
|
|
ice.js 3 新版本中不再支持 vite 模式,并且 webpack 相关的快捷配置也不再支持。我们将会将内置的逻辑做到最优。如果存在 webpack 定制需求,可以参考如下自定义方式定制:
|
|
|
|
|
|
|
|
|
|
```js title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import { modifyLoader } from '@ice/webpack-modify';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
// Set your configs here.
|
|
|
|
|
// ...
|
|
|
|
|
webpack: (webpackConfig) => {
|
|
|
|
|
if (typeof webpackConfig.devServer?.client === 'object') {
|
|
|
|
|
// 修改 webpack 配置
|
|
|
|
|
webpackConfig.devServer.client.overlay = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 修改内置的 webpack 规则,借助官方工具可以更便捷的修改
|
|
|
|
|
// 修改 css 样式规则下的 postcss-loader 配置项
|
|
|
|
|
return modifyLoader(webpackConfig, {
|
|
|
|
|
rule: '.css',
|
|
|
|
|
loader: 'postcss-loader',
|
|
|
|
|
options: (originOptions) => ({}),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
其他新版配置参考:[链接](../basic/config.md)
|
|
|
|
|
新版插件规范:[链接](../plugins/plugin-dev.md)
|
|
|
|
|
|
|
|
|
|
> 新版的 webpack 配置不再依赖 webpack-chain,如果有定制 webpack 的诉求可以直接通过 webpack-merge 的方式合并配置
|
|
|
|
|
|
|
|
|
|
### 常见配置迁移
|
|
|
|
|
|
|
|
|
|
新版框架对于大量配置进行了收敛,如果迁移时涉及到负责的定制场景,可以参考以下配置进行迁移
|
|
|
|
|
|
|
|
|
|
#### cssLoaderOptions
|
|
|
|
|
|
|
|
|
|
```js title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import { modifyLoader } from '@ice/webpack-modify';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
// Set your configs here.
|
|
|
|
|
// ...
|
|
|
|
|
webpack: (webpackConfig) => {
|
|
|
|
|
return ['css', 'less', 'sass'].reduce((acc, cur) => {
|
|
|
|
|
return modifyLoader(acc, {
|
|
|
|
|
rule: `.${cur}`,
|
|
|
|
|
loader: 'css-loader',
|
|
|
|
|
options: (originOptions) => ({}),
|
|
|
|
|
});
|
|
|
|
|
}, webpackConfig);
|
|
|
|
|
},
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### lessLoaderOptions
|
|
|
|
|
|
|
|
|
|
```js title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import { modifyLoader } from '@ice/webpack-modify';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
// Set your configs here.
|
|
|
|
|
// ...
|
|
|
|
|
webpack: (webpackConfig) => {
|
|
|
|
|
return modifyLoader(webpackConfig, {
|
|
|
|
|
rule: '.less',
|
|
|
|
|
loader: 'less-loader',
|
|
|
|
|
options: (originOptions) => ({}),
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### sassLoaderOptions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```js title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import { modifyLoader } from '@ice/webpack-modify';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
// Set your configs here.
|
|
|
|
|
...
|
|
|
|
|
webpack: (webpackConfig) => {
|
|
|
|
|
return modifyLoader(webpackConfig, {
|
|
|
|
|
rule: '.sass',
|
|
|
|
|
loader: 'sass-loader',
|
|
|
|
|
options: (originOptions) => ({}),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### postcssOptions / postcssrc
|
|
|
|
|
|
|
|
|
|
```js title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import { modifyLoader } from '@ice/webpack-modify';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
// Set your configs here.
|
|
|
|
|
// ...
|
|
|
|
|
webpack: (webpackConfig) => {
|
|
|
|
|
return ['css', 'less', 'sass'].reduce((acc, cur) => {
|
|
|
|
|
return modifyLoader(acc, {
|
|
|
|
|
rule: `.${cur}`,
|
|
|
|
|
loader: 'postcss-loader',
|
|
|
|
|
options: (originOptions) => ({}),
|
|
|
|
|
});
|
|
|
|
|
}, webpackConfig);
|
|
|
|
|
},
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
> 如果希望使用 postcssrc 能力,将 options 配置成如上空对象即可
|
|
|
|
|
|
|
|
|
|
#### webpackPlugins
|
|
|
|
|
|
|
|
|
|
```js title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import { removePlugin } from '@ice/webpack-modify';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
// Set your configs here.
|
|
|
|
|
// ...
|
|
|
|
|
webpack: (webpackConfig) => {
|
|
|
|
|
let modifiedConfig = webpackConfig;
|
|
|
|
|
// 添加插件
|
|
|
|
|
webpackConfig.plugins.push(new WebpackPlugin());
|
|
|
|
|
// webpack 插件修改,先删除插件在重新添加
|
|
|
|
|
modifiedConfig = removePlugin(webpackConfig, {
|
|
|
|
|
pluginName: 'AssetsManifestPlugin',
|
|
|
|
|
});
|
|
|
|
|
webpackConfig.plugins.push(new AssetsManifestPlugin());
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### webpackLoaders
|
|
|
|
|
|
|
|
|
|
```js title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import { addLoader, modifyLoader, removeLoader } from '@ice/webpack-modify';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
// Set your configs here.
|
|
|
|
|
//...
|
|
|
|
|
webpack: (webpackConfig) => {
|
|
|
|
|
let modifiedConfig = webpackConfig;
|
|
|
|
|
// 为 css 规则添加 loader
|
|
|
|
|
modifiedConfig = addLoader(modifiedConfig, {
|
|
|
|
|
rule: '.css',
|
|
|
|
|
before: 'css-loader',
|
|
|
|
|
useItem: {
|
|
|
|
|
loader: 'style-loader',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
// 移除 loader
|
|
|
|
|
modifiedConfig = removeLoader(modifiedConfig, {
|
|
|
|
|
rule: '.css',
|
|
|
|
|
loader: 'css-loader',
|
|
|
|
|
});
|
|
|
|
|
// 修改 loader
|
|
|
|
|
modifiedConfig = modifyLoader(getWebpackConfig(), {
|
|
|
|
|
rule: '.css',
|
|
|
|
|
loader: 'css-loader',
|
|
|
|
|
options: () => ({ module: true }),
|
|
|
|
|
});
|
|
|
|
|
return modifiedConfig;
|
|
|
|
|
},
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### babelPlugins / babelPresets
|
|
|
|
|
|
|
|
|
|
框架内置不再支持 babel 转换,一些常见语法转化逻辑已内置,如果存在定制 babel 插件的情况下,推荐以下方式转化
|
|
|
|
|
|
|
|
|
|
```js title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
2023-02-01 19:51:51 +08:00
|
|
|
|
import { transformSync } from '@babel/core';
|
2023-01-05 15:45:42 +08:00
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
// Set your configs here.
|
|
|
|
|
// ...
|
|
|
|
|
transform: async (source, id) => {
|
|
|
|
|
// 过滤条件
|
|
|
|
|
if (id.match(/\.(j|t)s(x)?$/) && !id.includes('node_modules')) {
|
|
|
|
|
// 借助 babel 编译
|
|
|
|
|
const { code, map } = transformSync(source, {
|
|
|
|
|
plugins: ['transform-decorators-legacy'],
|
|
|
|
|
});
|
|
|
|
|
return { code, map };
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 运行时修改
|
|
|
|
|
|
|
|
|
|
#### 应用入口修改
|
|
|
|
|
|
|
|
|
|
```diff
|
|
|
|
|
- import { runApp } from 'ice';
|
|
|
|
|
|
|
|
|
|
const appConfing = {};
|
|
|
|
|
|
|
|
|
|
- runApp(appConfig);
|
|
|
|
|
+ export default appConfig;
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
为了获得良好类型提示,推荐写法为:
|
|
|
|
|
|
|
|
|
|
```ts
|
2023-02-06 15:07:22 +08:00
|
|
|
|
import { defineAppConfig } from 'ice';
|
2023-01-05 15:45:42 +08:00
|
|
|
|
|
|
|
|
|
export default defineAppConfig(() => ({
|
|
|
|
|
app: {
|
|
|
|
|
strict: false,
|
|
|
|
|
},
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
原 appConfig 上大部分能力均通过不同的插件进行承载,目前应用入口能力,请参考[文档](../basic/app.md#%E9%85%8D%E7%BD%AE%E9%A1%B9)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 路由修改
|
|
|
|
|
|
|
|
|
|
为了提供更好的框架能力,新版 ice 默认提供的路由规则为[约定式路由](../basic/router.md)
|
|
|
|
|
|
|
|
|
|
原配置式路由推荐通过上述的规则重新组织目录结构,如果路由过于复杂,推荐如下方式进行迁移:
|
|
|
|
|
|
|
|
|
|
```js title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
routes: {
|
|
|
|
|
// 忽略所有约定式规则
|
|
|
|
|
ignoreFiles: ['**'],
|
|
|
|
|
defineRoutes: (route) => {
|
|
|
|
|
// 指定根路由页面为 home/index.ts
|
|
|
|
|
route('/', 'home/index.tsx');
|
|
|
|
|
// 为 /product 路由添加 layout.tsx 作为 layout,并渲染 products.tsx 内容
|
|
|
|
|
route('/', 'layout.tsx', () => {
|
|
|
|
|
route('/product', 'products.tsx');
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 进阶方案迁移
|
|
|
|
|
|
|
|
|
|
#### 状态管理
|
|
|
|
|
|
|
|
|
|
使用状态管理方案需主动安装 `@ice/plugin-store`:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ npm i @ice/plugin-store -D
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
在 `ice.config.mts` 中添加插件:
|
|
|
|
|
|
|
|
|
|
```ts title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import store from '@ice/plugin-store';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
plugins: [
|
|
|
|
|
store({ resetPageState: true }),
|
|
|
|
|
],
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
更多用法参考[状态管理](./store.md)
|
|
|
|
|
|
|
|
|
|
#### 数据请求
|
|
|
|
|
|
|
|
|
|
使用数据请求方案需主动安装 `@ice/plugin-request`:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ npm i @ice/plugin-request -D
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
在 `ice.config.mts` 中添加插件:
|
|
|
|
|
|
|
|
|
|
```ts title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import request from '@ice/plugin-request';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
plugins: [
|
|
|
|
|
request(),
|
|
|
|
|
],
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
在 `src/app.ts` 中导出统一的请求配置:
|
|
|
|
|
|
|
|
|
|
```ts title="src/app.ts"
|
|
|
|
|
export const requestConfig = {
|
|
|
|
|
...
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
更多配置和用法参考[网络请求](./request.md)
|
|
|
|
|
|
|
|
|
|
#### 权限方案
|
|
|
|
|
|
|
|
|
|
使用权限方案需主动安装 `@ice/plugin-auth`:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
$ npm i @ice/plugin-auth -D
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
在 `ice.config.mts` 中添加插件:
|
|
|
|
|
|
|
|
|
|
```ts title="ice.config.mts"
|
|
|
|
|
import { defineConfig } from '@ice/app';
|
|
|
|
|
import auth from '@ice/plugin-auth';
|
|
|
|
|
|
|
|
|
|
export default defineConfig(() => ({
|
|
|
|
|
plugins: [
|
|
|
|
|
auth(),
|
|
|
|
|
],
|
|
|
|
|
}));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
在 `src/app.ts` 中导出的权限配置:
|
|
|
|
|
|
|
|
|
|
```ts title="src/app.ts"
|
|
|
|
|
export const authConfig = {
|
|
|
|
|
...
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
更多配置和用法参考[权限管理](./auth.md)
|