ice/website/docs/guide/advanced/update-from-icejs2.md

436 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 从 ice.js 2.x 升级
order: 0902
---
# 从 ice.js 2.x 升级
## 前言
升级 ice.js 3.x 可以带来构建速度和页面性能的提升,并且带来更多移动端功能,比如开箱即用的 PHA、Weex 和小程序方案等。
## 升级指南
### 依赖修改
```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';
import { transformSync } from '@babel/core';
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
import { defineAppConfig } from 'ice';
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)