title: 版本升级

order: 2

版本说明

飞冰的脚手架从 ice-scripts@1.xice-scripts@2.x 到 icejs 经过了三个大的版本变化,这些版本变化都是结合我们的业务实践以及用户诉求不断演进的,在能力和规范性上都在不断提高,核心的一些差别:

维度\版本 icejs 2.x icejs 1.x ice-scripts 2.x ice-scripts 1.x
定位 研发框架 研发框架 构建工具 构建工具
升级原因 Webpack 5&Vite 从构建工具到研发框架 工程配置插件化 统一管理工程配置
配置文件 build.json build.json ice.config.js package.json(buildConfig)
文档地址 访问 访问 访问 访问
发布时间 2021.09 2020.02 2019.06 2018.02
可渐进升级性 不好 不好
插件能力 工程+运行时 工程+运行时 工程
工程配置
运行时配置 默认支持 默认支持 默认不支持 默认不支持
SSR 支持 支持 不支持 不支持
SSG 支持 不支持 不支持 不支持

可渐进升级性「好」意味着整体设计较为稳定,未来的版本变化用户可以低成本的渐进升级。

从 icejs 1.x 升级

:::caution

不推荐旧版本直接升级到 2.0 的 Vite 模式,建议先升级到 Webpack 模式,再按需迁移到 Vite 模式

:::

1. 依赖版本升级

package.json:

  1. {
  2. "devDependencies": {
  3. - "ice.js": "^1.0.0",
  4. + "ice.js": "^2.0.0",
  5. }
  6. }

2. 工程配置升级

icejs 2.x 移除了已废弃的工程配置和插件,并将一些优化逻辑默认内置:

  1. {
  2. - "terserOptions": {}, // 请使用 minify 配置
  3. - "dll": true, // 废弃,请使用 remoteEntry
  4. - "dllEntry": { "react": ["react", "react-dom"] }, // 废弃
  5. - "modularImportRuntime": true, // 已默认开启,不再需要
  6. - "customWebpack": true, // 已升级 Webpack 5,不再需要
  7. - "injectBabel": {}, // 请使用 polyfill
  8. "plugins": [
  9. - "build-plugin-fast-refresh", // 已默认开启,不再需要
  10. - "build-plugin-esbuild", // 通过 "minify": "esbuild" 开启
  11. - "build-plugin-webpack5" // 已默认开启,不再需要
  12. ]
  13. }

详细说明请查阅 工程配置

3. 运行时 API 升级

核心 API

在 icejs 1.x 中已提示废弃的 API,在 2.0 版本中完全移除:

  1. - import { useSearchParams } from 'ice';
  2. + import { getSearchParams } from 'ice';
  3. - import { withSearchParams } from 'ice';
  4. + import { getSearchParams } from 'ice';
  5. - import { createApp } from 'ice';
  6. + import { runApp } from 'ice';

状态管理方案

在 1.x 中已提示废弃的用法,在 2.0 版本中完全移除:

权限管理方案

2.0 中权限方案不再耦合状态管理,直接基于 React Context 实现,更加轻量,开发者端的 API 无任何变化。

请求数据方案

将内置的 axios 版本从 0.19.x 升级到 0.21.x

4. 工程依赖版本变化

框架内置的一些工程依赖也同时做了升级,理论上对于项目没有影响,可视具体情况来看:

  1. webpack^4 -> 5
  2. postcss^7.0.32 -> 8.0.0
  3. css-loader ^3.2.0 -> 5.2.4
  4. sass-loader ^10.0.0 -> 11.0.1
  5. less-loader ^7.0.0 -> 8.1.1
  6. postcss-loader^3.0.0 -> 5.2.0
  7. mini-css-extract-plugin^1.0.0 -> 2.1.0
  8. terser-webpack-plugin^2.3.1 -> 5.1.4
  9. copy-webpack-plugin^5.0.4 -> 9.0.1
  10. html-webpack-plugin^4.0.0 -> 5.3.1

5. 自定义插件迁移

如果对框架进行了深度定制,并且开发了自定义的插件,需要关注插件相关 API 的变化。

内置规则名变更

  1. module.exports = ({ onGetWebpackConfig }) => {
  2. onGetWebpackConfig((config) => {
  3. config
  4. // 规则名从 OptimizeCSSAssetsPlugin 变更为 CssMinimizerPlugin
  5. // 插件依赖从 optimize-css-assets-webpack-plugin 变更为 css-minimizer-webpack-plugin
  6. - .plugin('OptimizeCSSAssetsPlugin')
  7. + .plugin('CssMinimizerPlugin)
  8. .tap((opts) => opts);
  9. });
  10. }

工程 API 变化

  1. module.exports = ({ applyMethod }) => {
  2. const templateDir = path.join(__dirname, '../src/types');
  3. - applyMethod('addTemplateDir', templateDir);
  4. + applyMethod('addPluginTemplate', templateDir);
  5. }

运行时 API 变化

框架运行时插件 API 变化如下:

  1. export default ({
  2. // wrapperPageComponent 和 wrapperPageComponent 用法一致,明确了针对 pages 目录下组件的处理场景
  3. - wrapperRouteComponent
  4. + wrapperPageComponent,
  5. - createHistory,
  6. - getSearchParams,
  7. + applyRuntimeAPI,
  8. }) => {
  9. - const history = createHistory({...});
  10. + const history = applyRuntimeAPI('createHistory', {...})
  11. - const params = getSearchParams();
  12. + const params = applyRuntimeAPI('getSearchParams');
  13. };

从 ice-scripts 2.x 迁移

1. 修改 package.json 依赖

icejs 基于 build-scripts 内置了工程开发构建能力,不在需要单独依赖 ice-scripts,同时相关插件也进行了一次重构优化。

  1. {
  2. - "ice-scripts": "^2.0.0",
  3. - "ice-plugin-fusion": "^0.1.4",
  4. - "ice-plugin-moment-locales": "^0.1.0",
  5. + "ice.js": "^1.0.0"
  6. + "build-plugin-fusion": "^0.1.0",
  7. + "build-plugin-moment-locales": "^0.1.0",
  8. }

2. 修改配置文件

icejs 提供 build.json 文件用于工程配置,因此需要将 ice.config.js 配置迁移到 build.json 中,具体如下:

假设你的 ice.config.js 配置如下:

  1. const path = require('path');
  2. module.exports = {
  3. entry: 'src/index.js',
  4. plugins: [
  5. [
  6. 'ice-plugin-fusion',
  7. {
  8. themePackage: '@icedesign/theme',
  9. },
  10. ],
  11. ],
  12. chainWebpack: (config, { command }) => {
  13. ['jsx', 'tsx'].forEach((rule) => {
  14. config.module
  15. .rule(rule)
  16. .use('babel-loader')
  17. .tap((options) => {
  18. options.plugins.push(require('jsx-control-statements'));
  19. return options;
  20. });
  21. });
  22. },
  23. };

新建 build.json 文件:(icejs 默认入口文件为 app.(js|ts),因此不需要单独配置 entry)

  1. {
  2. "plugins": [
  3. [
  4. "build-plugin-fusion",
  5. {
  6. "themePackage": "@icedesign/theme"
  7. }
  8. ],
  9. "./build.plugin.js"
  10. ]
  11. }

然后新建 build.plugin.js 文件,将自定义的 chainWebpack 配置移到新建的 build.plugin.js 中:

  1. module.exports = ({ onGetWebpackConfig }) => {
  2. onGetWebpackConfig((config) => {
  3. ['jsx', 'tsx'].forEach((rule) => {
  4. config.module
  5. .rule(rule)
  6. .use('babel-loader')
  7. .tap((options) => {
  8. options.plugins.push(require('jsx-control-statements'));
  9. return options;
  10. });
  11. });
  12. });
  13. };

最后删除 ice.config.js 配置文件。

3. 修改应用入口文件

将原有应用入口为 src/index.js 需要修改为 src/app.js,具体修改如下:

假设你的 src/index.js 文件内容如下:

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import './global.scss';
  4. import router from './router';
  5. const ICE_CONTAINER = document.getElementById('ice-container');
  6. if (!ICE_CONTAINER) {
  7. throw new Error('当前页面不存在 <div id="ice-container"></div> 节点.');
  8. }
  9. ReactDOM.render(router(), ICE_CONTAINER);

新建 src/app.js 文件:

  1. import { runApp } from 'ice';
  2. const appConfig = {
  3. router: {
  4. type: 'browser', // 配置 browser 路由
  5. },
  6. };
  7. runApp(appConfig);

最后,删除 src/index.js 文件

4. 其他文件修改

icejs 规范和强约束了项目的目录结构,因此只需要按照规范就行编辑即可,不在需要额外的引用

  • 删除 src/router.jsx 文件
  • 移动 src/config/routes.js 路由配置至 src/routes.js
  • .gitignore 中新增 .ice/ 目录
  • 在根目录下新建 tsconfig.json 文件,配置详见
  • 如果项目存在 src/models/*src/pages/*/model.js 或者 src/pages/*/models/* 的目录文件,需要在 build.json 中配置 store: false
  • 如果你的项目已经使用 icestore 且版本小于 1.0.0 版本,可以选择按需升级或者在 build.json 中配置 store: false 关闭内置的方案

从 ice-scripts 1.x 迁移

1. 修改 package.json 依赖

icejs 支持了 ice-scripts 工程开发构建能力,不在需要单独依赖 ice-scripts,修改为 ice.js 即可。

  1. {
  2. - "ice-scripts": "^1.0.0",
  3. + "ice.js": "^1.0.0"
  4. }

2. 修改配置文件

icejs 提供 build.json 文件用于工程配置,因此需要将 .webpackrc.js 配置迁移到 build.json 中,假设你的 .webpackrc.js 配置如下:

  1. module.exports = {
  2. entry: 'src/index.js',
  3. rules: [
  4. {
  5. test: /\.s[ac]ss$/i,
  6. use: [
  7. {
  8. loader: 'sass-loader',
  9. options: {
  10. sourceMap: true,
  11. },
  12. },
  13. ],
  14. },
  15. ],
  16. };

新建 build.json 文件

  1. {
  2. + "entry": "src/index.js"
  3. }

然后新建 build.plugin.js 文件,将自定义的插件配置移到新建的 build.plugin.js 中:

  1. module.exports = ({ onGetWebpackConfig }) => {
  2. onGetWebpackConfig((config) => {
  3. ['scss'].forEach((rule) => {
  4. if (config.module.rules.get(rule)) {
  5. config.module
  6. .rule(rule)
  7. .use('css-loader')
  8. .tap((options) => ({
  9. ...options,
  10. sourceMap: true
  11. }));
  12. }
  13. });
  14. }

同时将自定义的插件引入到 build.json 中,最后删除 .webpackrc.js 配置文件。

  1. {
  2. "entry": "src/index.js",
  3. + "plugins": [
  4. + "./build.plugin.js"
  5. + ]
  6. }

3. 禁用运行时能力

由于 icejs 相比 ice-scripts 除了提供工程能力外,还提供了运行时扩展的能力,因此对于 ice-scripts 的项目提供了禁用运行时能力的功能,确保最小化的升级和只使用工程能力。

build.json 中配置 disableRuntime 选项即可:

  1. {
  2. "entry": "src/index.js",
  3. "plugins": [
  4. "./build.plugin.js"
  5. ],
  6. + "disableRuntime": true
  7. }

更新主题配置

如果你的 package.json 中存在 buildConfigthemeConfig 配置,则需要将该配置移置 build.json 文件中。

  1. "buildConfig": {
  2. "theme": "@icedesign/skin",
  3. "localization": false
  4. },
  5. "themeConfig": {
  6. "primaryColor": "#908ce1"
  7. },

更新后的 build.json 如下:

  1. {
  2. "entry": "src/index.js",
  3. "plugins": [
  4. + [
  5. + "build-plugin-fusion", {
  6. + "themePackage": "@icedesign/skin",
  7. + "themeConfig": {
  8. + "primaryColor": "#908ce1"
  9. + }
  10. + }
  11. + ],
  12. "./build.plugin.js"
  13. ],
  14. "disableRuntime": true
  15. }

更新 proxyConfig

如果你的 package.json 中存在 proxyConfig 配置,则需要将该配置移置 build.json 文件中,并将 proxyConfig 更新为 proxy

  1. "proxyConfig": {
  2. "/api/**": {
  3. "enable": true,
  4. "target": "pre-faraday.alibaba-inc.com"
  5. }
  6. }

更新后的 build.json 项如下。

  1. {
  2. "entry": "src/index.js",
  3. "plugins": [
  4. [
  5. "build-plugin-fusion", {
  6. "themePackage": "@icedesign/skin",
  7. "themeConfig": {
  8. "primaryColor": "#908ce1"
  9. }
  10. }
  11. ],
  12. "./build.plugin.js"
  13. ],
  14. "disableRuntime": true,
  15. + "proxy": {
  16. + "/api/**": {
  17. + "enable": true,
  18. + "target": "pre-faraday.alibaba-inc.com"
  19. + }
  20. }
  21. }

更新 scripts 脚本

最后将 package.json 中启动项目的脚本替换如下:

  1. "scripts": {
  2. - "start": "ice dev",
  3. + "start": "icejs start",
  4. - "build": "ice build",
  5. + "build": "icejs build"
  6. }

通过以上步骤即可基于 ice-scripts@1.x 升级到 ice.js,如果还存在其他配置或者升级失败,可以通过飞冰社区群与我们联系。