Compare commits

...

4 Commits

Author SHA1 Message Date
ClarkXia ab7ef19b1c
Merge 6fb7336cb7 into bb60ab5a04 2025-07-11 11:04:51 +08:00
ClarkXia bb60ab5a04
feat: support option rootId to empty root (#7031)
CI / build (16.x, ubuntu-latest) (push) Has been cancelled Details
CI / build (16.x, windows-latest) (push) Has been cancelled Details
CI / build (18.x, ubuntu-latest) (push) Has been cancelled Details
CI / build (18.x, windows-latest) (push) Has been cancelled Details
Coverage / coverage (16.x) (push) Has been cancelled Details
Release / Release (16) (push) Has been cancelled Details
2025-07-09 10:59:28 +08:00
ClarkXia 412faf03d1
Feat: support externals field in assets-manifest (#7116) (#7117)
* feat: support externals field in assets-manifest (#7116)

* chore: version

* chore: update version
2025-07-09 10:59:06 +08:00
ClarkXia 6fb7336cb7 docs: update migrate docs 2025-06-23 16:27:12 +08:00
14 changed files with 169 additions and 36 deletions

View File

@ -1,5 +1,11 @@
# @ice/plugin-externals # @ice/plugin-externals
## 1.0.1
### Patch Changes
- 4569200ca: fix: support externals field in assets-manifest
## 1.0.0 ## 1.0.0
- Initial release - Initial release

View File

@ -1,6 +1,6 @@
{ {
"name": "@ice/plugin-externals", "name": "@ice/plugin-externals",
"version": "1.0.0", "version": "1.0.1",
"description": "plugin to make externals much easier in ice.js", "description": "plugin to make externals much easier in ice.js",
"files": [ "files": [
"esm", "esm",

View File

@ -26,7 +26,9 @@ export default class InjectExternalScriptsWebpackPlugin {
if (assetsManifest) { if (assetsManifest) {
const json = JSON.parse(assetsManifest.source().toString()); const json = JSON.parse(assetsManifest.source().toString());
delete compilation.assets[ASSET_MANIFEST_JSON_NAME]; delete compilation.assets[ASSET_MANIFEST_JSON_NAME];
json.entries.main.unshift(...this.options.externals); // Ensure externals array exists and add new externals at the beginning.
json.externals ||= [];
json.externals.unshift(...this.options.externals);
compilation.emitAsset( compilation.emitAsset(
ASSET_MANIFEST_JSON_NAME, ASSET_MANIFEST_JSON_NAME,
new webpack.sources.RawSource(JSON.stringify(json)), new webpack.sources.RawSource(JSON.stringify(json)),

View File

@ -56,7 +56,7 @@
"webpack-dev-server": "4.15.0" "webpack-dev-server": "4.15.0"
}, },
"peerDependencies": { "peerDependencies": {
"@ice/app": "^3.6.4", "@ice/app": "^3.6.3",
"@ice/runtime": "^1.5.4" "@ice/runtime": "^1.5.4"
}, },
"publishConfig": { "publishConfig": {

View File

@ -50,7 +50,7 @@
"sax": "^1.2.4" "sax": "^1.2.4"
}, },
"devDependencies": { "devDependencies": {
"@ice/app": "^3.6.4", "@ice/app": "^3.6.3",
"@ice/runtime": "^1.5.4", "@ice/runtime": "^1.5.4",
"webpack": "^5.88.0" "webpack": "^5.88.0"
}, },

View File

@ -1,5 +1,9 @@
# @ice/plugin-stream-error # @ice/plugin-stream-error
## 1.0.3
- feat: empty root element when stream error
## 1.0.0 ## 1.0.0
### Major Changes ### Major Changes

View File

@ -1,6 +1,6 @@
{ {
"name": "@ice/plugin-stream-error", "name": "@ice/plugin-stream-error",
"version": "1.0.2", "version": "1.0.3",
"description": "", "description": "",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",

View File

@ -2,13 +2,16 @@ import type { Plugin } from '@ice/app/types';
interface PluginOptions { interface PluginOptions {
activeInDev?: boolean; activeInDev?: boolean;
rootId?: string;
} }
const PLUGIN_NAME = '@ice/plugin-stream-error'; const PLUGIN_NAME = '@ice/plugin-stream-error';
const plugin: Plugin<PluginOptions> = (options = {}) => ({ const plugin: Plugin<PluginOptions> = (options = {
rootId: 'root',
}) => ({
name: PLUGIN_NAME, name: PLUGIN_NAME,
setup: ({ generator, context }) => { setup: ({ generator, context }) => {
const { activeInDev } = options; const { activeInDev, rootId } = options;
const { userConfig } = context; const { userConfig } = context;
if (userConfig.ssr) { if (userConfig.ssr) {
generator.addEntryCode((originalCode) => { generator.addEntryCode((originalCode) => {
@ -18,6 +21,11 @@ if (import.meta.renderer === 'client') {
// _$ServerTimePoints will returned at the end of last stream, // _$ServerTimePoints will returned at the end of last stream,
// if the value is undefined, try to re-render app with CSR. // if the value is undefined, try to re-render app with CSR.
if (${activeInDev ? '' : 'process.env.NODE_ENV === \'production\' && '}!window._$ServerTimePoints && window.__ICE_APP_CONTEXT__.renderMode === 'SSR') { if (${activeInDev ? '' : 'process.env.NODE_ENV === \'production\' && '}!window._$ServerTimePoints && window.__ICE_APP_CONTEXT__.renderMode === 'SSR') {
const root = document.getElementById('${rootId}');
if (root) {
root.innerHTML = '';
}
window.__ICE_APP_CONTEXT__.renderMode = 'CSR';
render({ hydrate: false }); render({ hydrate: false });
} }
}); });

View File

@ -1,5 +1,11 @@
# @ice/runtime # @ice/runtime
## 1.5.5
### Patch Changes
- 4569200ca: fix: support externals field in assets-manifest
## 1.5.4 ## 1.5.4
### Patch Changes ### Patch Changes

View File

@ -1,6 +1,6 @@
{ {
"name": "@ice/runtime", "name": "@ice/runtime",
"version": "1.5.4", "version": "1.5.5",
"description": "Runtime module for ice.js", "description": "Runtime module for ice.js",
"type": "module", "type": "module",
"types": "./esm/index.d.ts", "types": "./esm/index.d.ts",

View File

@ -129,6 +129,9 @@ export const Scripts: ScriptsType = (props: ScriptsProps) => {
return ( return (
<> <>
<Data ScriptElement={ScriptElement} /> <Data ScriptElement={ScriptElement} />
{assetsManifest.externals?.map(external => (
<ScriptElement key={external} src={external} {...rest} data-external-script />
))}
{ {
routeScripts.map(routeScriptProps => { routeScripts.map(routeScriptProps => {
return <ScriptElement key={routeScriptProps.src} {...rest} {...routeScriptProps} data-route-script />; return <ScriptElement key={routeScriptProps.src} {...rest} {...routeScriptProps} data-route-script />;

View File

@ -205,6 +205,7 @@ export interface RouteModules {
} }
export interface AssetsManifest { export interface AssetsManifest {
externals?: string[];
dataLoader?: string; dataLoader?: string;
publicPath: string; publicPath: string;
entries: { entries: {

View File

@ -2157,7 +2157,7 @@ importers:
version: 1.2.4 version: 1.2.4
devDependencies: devDependencies:
'@ice/app': '@ice/app':
specifier: ^3.6.4 specifier: ^3.6.3
version: link:../ice version: link:../ice
'@ice/runtime': '@ice/runtime':
specifier: ^1.5.4 specifier: ^1.5.4

View File

@ -12,6 +12,8 @@ order: 0902
### 依赖修改 ### 依赖修改
#### 框架依赖
```diff ```diff
{ {
"devDependencies": { "devDependencies": {
@ -22,40 +24,146 @@ order: 0902
} }
``` ```
对应插件能力: #### 插件依赖
- @ali/build-plugin-ice-def -> @ali/ice-plugin-def ##### @ali/build-plugin-ice-def
- build-plugin-moment-locales -> @ice/plugin-moment-locales 插件替换为 `@ali/ice-plugin-def`,使用版本 1.2.4+,使用方式:
- 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" ```ts title="ice.config.mts"
import { defineConfig } from '@ice/app'; import { defineConfig } from '@ice/app';
import jsxPlus from '@ice/plugin-jsx-plus'; import def from '@ali/ice-plugin-def';
export default defineConfig(() => ({ export default defineConfig(() => ({
plugins: [ plugins: [
jsxPlus(), def(),
], ],
})); }));
``` ```
##### build-plugin-moment-locales
插件替换为 `@ice/plugin-moment-locales`,使用版本 1.0.2+,使用方式:
```ts title="ice.config.mts"
import { defineConfig } from '@ice/app';
import moment from '@ice/plugin-moment-locales';
export default defineConfig(() => ({
plugins: [
moment({
locales: ['zh-CN'],
}),
],
}));
```
##### build-plugin-fusion
替换为 `@ice/plugin-fusion`,使用版本 1.1.0+,使用方式:
```ts title="ice.config.mts"
import { defineConfig } from '@ice/app';
import fusion from '@ice/plugin-fusion';
export default defineConfig(() => ({
plugins: [fusion({
importStyle: true,
themePackage: '@alifd/theme-design-pro',
theme: {
'primary-color': '#fff',
},
})],
}));
```
fusion 插件文档:[链接](../plugins/plugin-fusion.md)
> ice3 下的 fusion 插件不再支持多主题能力,仅支持配置 importStyle、themePackage 和 theme 三个配置项
##### build-plugin-antd
插件替换为 `@ice/plugin-antd`,使用版本 1.0.2+,使用方式:
```ts title="ice.config.mts"
import { defineConfig } from '@ice/app';
import antd from '@ice/plugin-antd';
export default defineConfig(() => ({
plugins: [antd({
dark: true,
compact: true,
theme: {
'primary-color': '#fd8',
},
})],
}));
```
antd 插件文档:[链接](../advanced/antd.md)
##### build-plugin-css-assets-local
插件替换为 `@ice/plugin-css-assets-local`,使用版本 1.0.2+,使用方式:
```ts title="ice.config.mts"
import { defineConfig } from '@ice/app';
import cssAssetsLocal from '@ice/plugin-css-assets-local';
export default defineConfig(() => ({
plugins: [
cssAssetsLocal(),
],
}));
```
css-assets-local 插件文档:[链接](../advanced/css-assets-local.md)
##### build-plugin-jsx-plus
插件替换为 `@ice/plugin-jsx-plus`,使用版本 1.0.4+,使用方式:
```ts title="ice.config.mts"
import { defineConfig } from '@ice/app';
import jsxplus from '@ice/plugin-jsx-plus';
export default defineConfig(() => ({
plugins: [
jsxplus({
// options
}),
],
}));
```
jsx-plus 插件文档:[链接](../advanced/jsx-plus.md)
##### build-plugin-keep-alive
ice 3 不再支持插件形式的 keep-alive 方案。由框架内置提供的 `<KeepAliveOutlet />` 组件替代。
keep-alive 插件文档:[链接](../advanced/keep-alive.md)
> 完成依赖升级后推荐重新安装依赖,即执行 npm update > 完成依赖升级后推荐重新安装依赖,即执行 npm update
### 工程配置文件升级 ### 工程配置文件升级
为了获取更好的类型提示ice 新版本中推荐使用 ts 文件进行配置,即在项目目录下新增 `ice.config.mts` 文件,原 json 中的能力支持情况如下: 为了获取更好的类型提示ice 新版本中推荐使用 ts 文件进行配置,即在项目目录下新增 `ice.config.mts` 文件,原 json 中的能力支持情况如下:
#### 命令行参数
| ice 2.x | ice 3.0 | 备注 |
| ---- | ---- | ---- |
| --port | --port | - |
| --host | --host | - |
| --config | --config | - |
| --disable-open | --no-open | - |
| --disable-mock | --no-mock | - |
| --https | --https | - |
| --analyzer | --analyzer | - |
| --disable-assets | ❌ | 不常用通过环境变量控制日志输出详细程度 |
| --disable-reload | ❌ | 配置禁止 fastRefresh |
#### 配置项
| ice 2.x | ice 3.0 | 备注 | | ice 2.x | ice 3.0 | 备注 |
| ---- | ---- | ---- | | ---- | ---- | ---- |
| --port | ✅ | - |
| --host | ✅ | - |
| --config | ✅ | - |
| --disable-open | ✅ | - |
| plugins | ✅ | - | | plugins | ✅ | - |
| alias | ✅ | - | | alias | ✅ | - |
| publicPath | ✅ | - | | publicPath | ✅ | - |
@ -67,9 +175,6 @@ export default defineConfig(() => ({
| proxy | ✅ | - | | proxy | ✅ | - |
| define | ✅ | - | | define | ✅ | - |
| ssr | ✅ | - | | ssr | ✅ | - |
| --disable-mock | ✅ | - |
| --https | ✅ | - |
| --analyzer | ✅ | - |
| dropLogLevel | ✅ | - | | dropLogLevel | ✅ | - |
| minify | ✅ | 简化配置true/false | | minify | ✅ | 简化配置true/false |
| compileDependencies | ✅ | 配合现有的 compileIncludes 能力 | | compileDependencies | ✅ | 配合现有的 compileIncludes 能力 |
@ -78,8 +183,6 @@ export default defineConfig(() => ({
| postcssOptions / postcssrc | ✅ | - | | postcssOptions / postcssrc | ✅ | - |
| polyfill | ✅ | 需要主动开启 | | polyfill | ✅ | 需要主动开启 |
| remoteRuntime | ❌ | - | | remoteRuntime | ❌ | - |
| --disable-assets | ❌ | 不常用通过环境变量控制日志输出详细程度 |
| --disable-reload | ❌ | 配置禁止 fastRefresh |
| terser | ❌ | 内置方案 | | terser | ❌ | 内置方案 |
| outputAssetsPath | ❌ | 后续输出最佳目录实践 | | outputAssetsPath | ❌ | 后续输出最佳目录实践 |
| devServer | ❌ | 不支持全量配置 devServer按需开启 server 相关能力 | | devServer | ❌ | 不支持全量配置 devServer按需开启 server 相关能力 |
@ -93,7 +196,7 @@ export default defineConfig(() => ({
| swc | ❌ | - | | swc | ❌ | - |
| store / auth / request / pwa / router | ❌ | 通过定制的插件支持 | | store / auth / request / pwa / router | ❌ | 通过定制的插件支持 |
| disableRuntime | ❌ | - | | disableRuntime | ❌ | - |
| babelPlugins / babelPresets / webpackPlugins / webpackLoaders | ❌ | 不推荐直接配置 | | babelPlugins / babelPresets / webpackPlugins / webpackLoaders | ❌ | 不推荐直接配置,如果有定制需求通过 webpack 配置进行迁移 |
ice.js 3 新版本中不再支持 vite 模式,并且 webpack 相关的快捷配置也不再支持。我们将会将内置的逻辑做到最优。如果存在 webpack 定制需求,可以参考如下自定义方式定制: ice.js 3 新版本中不再支持 vite 模式,并且 webpack 相关的快捷配置也不再支持。我们将会将内置的逻辑做到最优。如果存在 webpack 定制需求,可以参考如下自定义方式定制:
@ -117,7 +220,7 @@ export default defineConfig(() => ({
loader: 'postcss-loader', loader: 'postcss-loader',
options: (originOptions) => ({}), options: (originOptions) => ({}),
}); });
} },
})); }));
``` ```