{"owner":"alibaba","repo":"ice","hasSkills":true,"totalSkillsCount":39,"totalTokensCount":11885,"categories":["plugin-manifest","anthropic-skill","cursor-rule"],"hasMcp":false,"mcpConfig":null,"found":["packages/appear/README.md","packages/bundles/README.md","packages/cache-canvas/README.md","packages/create-ice/README.md","packages/ice/README.md","packages/jsx-runtime/README.md","packages/miniapp-html-styles/README.md","packages/miniapp-loader/README.md","packages/miniapp-react-dom/README.md","packages/miniapp-runtime/README.md","packages/plugin-antd/README.md","packages/plugin-auth/README.md","packages/plugin-cavans/README.md","packages/plugin-css-assets-local/README.md","packages/plugin-externals/README.md","packages/plugin-fusion/README.md","packages/plugin-i18n/README.md","packages/plugin-icestark/README.md","packages/plugin-intl/README.md","packages/plugin-jsx-plus/README.md","packages/plugin-miniapp/README.md","packages/plugin-moment-locales/README.md","packages/plugin-pha/README.md","packages/plugin-rax-compat/README.md","packages/plugin-request/README.md","packages/plugin-store/README.md","packages/plugin-stream-error/README.md","packages/plugin-unocss/README.md","packages/rax-compat/README.md","packages/route-manifest/README.md","packages/rspack-config/README.md","packages/runtime/README.md","packages/shared-config/README.md","packages/style-import/README.md","packages/webpack-config/README.md","packages/webpack-modify/README.md","website/docs/guide/plugins/plugin-dev.md","website/docs/guide/plugins/plugin-list.md",".cursorrules (dragonruby-best-practices-cursorrules-prompt-file.mdc)"],"skills":{"packages/appear/README.md":"# @ice/appear\n\nReact component for supporting `appear` and `disappear` events.  \n\n## Usage\n\n```bash\nnpm i @ice/appear -S\n```\n\n```jsx\nimport VisibilityChange from '@ice/appear';\n\nexport default function Home() {\n  return (\n    <VisibilityChange\n      onAppear={() => {\n        console.log('Something has been shown.')\n      }}\n      onDisappear={() => {\n        console.log('Something has disappeard.')\n      }}\n    >\n      Anything you want to show.\n    </VisibilityChange>\n  );\n}\n```\n","packages/bundles/README.md":"# @ice/bundles\n\nPrepacked bundles for ice.js.\n\n**DO NOT USE THIS PACKAGE DIRECTLY.**\n","packages/cache-canvas/README.md":"# @ice/cache-canvas\n\nReact component for supporting canvas for cache.\n\n## Usage\n\n```bash\nnpm i @ice/cache-canvas -S\n```\n\n```jsx\nimport MainGame from './game'; // eva.js 的封装\n\nconst GAME_CANVAS = 'game-canvas';\n\nexport default (props) => {\n  useEffect(() => {\n    const gameEl = document.getElementById(GAME_CANVAS);\n    new MainGame(gameEl, getGameHeight());\n  }, []);\n\n  const init = () => {\n     return new Promise((resolve) => {\n      const canvas: HTMLCanvasElement | null = document.getElementById(GAME_CANVAS_ID) as HTMLCanvasElement;\n      if (canvas && typeof canvas.getContext === 'function') {\n        let ctx: CanvasRenderingContext2D | null = canvas.getContext('2d');\n\n        ctx?.fillRect(25, 25, 100, 100);\n        ctx?.clearRect(45, 45, 60, 60);\n        ctx?.strokeRect(50, 50, 50, 50);\n      }\n\n      setTimeout(() => {\n        console.log('canvas paint ready!');\n        resolve(true);\n      }, 5000);\n    });\n  }\n\n  return (\n    <>\n       <CanvasCache id={GAME_CANVAS} useCache={false} init={init} />\n    </>\n  );\n};\n```\n","packages/create-ice/README.md":"# create-ice\n\ncreate ice.js project.\n\n## Usage\n\n```bash\n# use npm\n$ npm create ice <projectName>\n# use yarn\n$ yarn create ice <projectName>\n# use pnpm\n$ pnpm create ice <projectName>\n\n# or with template\n# use npm\n$ npm create ice <projectName> --template <template>\n# use yarn\n$ yarn create ice <projectName> --template <template>\n# use pnpm\n$ pnpm create ice <projectName> --template <template>\n\n$ cd <projectName>\n$ npm install\n$ npm start\n```\n","packages/ice/README.md":"# ice.js\n\nice.js is the best user experience for web developing based on React.\nThis package includes scripts and configuration used by web framework `ice`.\n\n## Install\n\n```bash\n$ npm i @ice/app -D\n```\n\n## usage\n\n```json\n{\n  \"name\": \"my-app\",\n  \"devDependencies\": {\n    \"@ice/app\": \"^3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"ice start\",\n    \"build\": \"ice build\"\n  }\n}\n```\n\n## Command line interface\n\n```bash\nUsage: ice <command> [options]\n\nOptions:\n  -V, --version    output the version number\n  -h, --help       output usage information\n\nCommands:\n  build [options]  build project\n  start [options]  start dev server\n```\n\n## Open Source\n\nOpen Source with ❤️ and MIT License.\n","packages/jsx-runtime/README.md":"# @ice/jsx-runtime\n\nJSX runtime for ice.js.\n\n## Install\n\n```bash\n$ npm i @ice/jsx-runtime --save\n```\n","packages/miniapp-html-styles/README.md":"# @ice/miniapp-html-styles\n\n> Forked from [@tarojs/taro](https://github.com/NervJS/taro/tree/next/packages/taro) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\n## html.css\n\nHTML4 built-in styles for compatibility with HTML tag styles.\n\n## html5.css\n\nHTML5 built-in styles for compatibility with HTML tag styles.\n","packages/miniapp-loader/README.md":"# `@ice/miniapp-loader`\n\n> Forked from [@tarojs/loader](https://github.com/NervJS/taro/tree/next/packages/taro-loader) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nWebpack loader exposed to ice.js for building applet artifacts, including the following `loader`:\n\n## page\n\nMiniapp usage only. Call the `createPageConfig` method of `@ice/miniapp-runtime` in the miniapp page file to create an object accepted by the miniapp `Page` constructor.\n","packages/miniapp-react-dom/README.md":"# @ice/miniapp-react-dom\n\n> Forked from [@tarojs/react](https://github.com/NervJS/taro/tree/next/packages/taro-react) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nA React renderer for mini-programs based on `react-reconciler`, connected to the DOM instance of `@ice/miniapp-runtime`, equivalent to the mini-program version of `react-dom`, and the exposed API is also the same as `react-dom` consistent.\n","packages/miniapp-runtime/README.md":"# @ice/miniapp-runtime\n\n> Forked from [@tarojs/runtime](https://github.com/NervJS/taro/tree/next/packages/taro-runtime) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nice.js miniapp runtime. Connect the framework (DSL) rendering mechanism to the miniapp rendering mechanism, and connect the miniapp routing and life cycle to the corresponding life cycle of the framework\n\n## Core API\n\n### createPageConfig()\n\nExpose to `@ice/miniapp-loader/page` calls, called in the miniapp page file, to create a miniapp page specification object accepted by the miniapp `Page` constructor.\n\n### window\n\nAn object that imitates the browser's `window` implementation on the miniapp side, and returns the browser's own `window` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n### navigator\n\nAn object that imitates the browser's `navigator` implementation on the miniapp side, and returns the browser's own `navigator` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n###document\n\nAn object that imitates the browser's `document` implementation on the miniapp side, and returns the browser's own `document` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n### Current\n\nGlobal variables exposed to developers currently have three properties:\n\n* `Current.app`, returns the current miniapp application instance, which can be used to call the miniapp specification life cycle.\n* `Current.page`, returns the current miniapp page instance, which can be used to call the miniapp specification life cycle.\n* `Current.router`, returns the current miniapp routing information.\n","packages/plugin-antd/README.md":"# `@ice/plugin-antd`\n\nAn ice.js plugin to use `antd` components.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport antd from '@ice/plugin-antd';\n\nexport default defineConfig(() => ({\n  plugins: [antd({\n    dark: true,\n    compact: true,\n    theme: {\n      'primary-color': '#fd8',\n    },\n  })],\n}));\n```\n","packages/plugin-auth/README.md":"# `@ice/plugin-auth`\n\nAn ice.js plugin to enable auth ability.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport auth from '@ice/plugin-auth';\n\nexport default defineConfig(() => ({\n  plugins: [\n    auth(),\n  ],\n}));\n```\n\nMore details to see https://v3.ice.work/docs/guide/advanced/auth\n","packages/plugin-cavans/README.md":"# @ice/plugin-canvas\n\nAn ice.js plugin for canvas projects.\n\n## Usage\n\nAdd plugin in `ice.config.mts`:\n\n```js\nimport { defineConfig } from 'ice';\nimport canvasPlugin from '@ice/plugin-canvas';\n\nexport default defineConfig(() => ({\n  plugins: [canvasPlugin({ /* options */ })],\n}));\n```  \n","packages/plugin-css-assets-local/README.md":"# @ice/plugin-css-assets-local\n\nAn ice.js plugin for localize css assets resource.\n\n## Install\n\n```bash\nnpm i -D @ice/plugin-css-assets-local\n```\n\n## Usage\n\nAdd plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport cssAssetsLocal from '@ice/plugin-css-assets-local';\n\nexport default defineConfig(() => ({\n  plugins: [\n    cssAssetsLocal(),\n  ],\n}));\n```\n\nAfter running `npm run build`, you can see asset resources will be downloaded to your local disk.\n\n## Options\n\n### `outputPath`\n\nThe assets resource output path.\n\n- Type: `string`\n- Default: `\"assets\"`\n\n### `relativeCssPath`\n\nThe asset paths relative to the css file path.\n\n- Type: `string`\n- Default: `\"../\"`\n\n### `enableInDev`\n\nWhether enable the plugin in dev or not.\n\n- Type: `boolean`\n- Default: `false`\n","packages/plugin-externals/README.md":"# @ice/plugin-externals\n\n`@ice/plugin-externals` is a ice.js plugin. It provides a simple way to add externals support to your application.\n\n## Install\n\n```bash\n$ npm i @ice/plugin-externals --save-dev\n```\n\n## Usage\n\nSet preset `react` to external react in a easy way.\n\n```js\nimport { defineConfig } from '@ice/app';\nimport externals from '@ice/plugin-externals';\n\nexport default defineConfig(() => ({\n  plugins: [externals({ preset: 'react' })]\n}));\n```\n\nFramework will auto add externals of `react` and `react-dom` to your application, and the cdn url will be inject to the document by default.\n\nAlso, you can custom externals and cdn url by yourself:\n\n```js\nimport { defineConfig } from '@ice/app';\nimport externals from '@ice/plugin-externals';\n\nexport default defineConfig(() => ({\n  plugins: [externals({\n    externals: {\n      antd: 'Antd',\n    },\n    cdnMap: {\n      antd: {\n        development: 'https://unpkg.com/antd/dist/antd.js',\n        production: 'https://unpkg.com/antd/dist/antd.min.js',\n      }\n    }\n  })]\n}));\n```\n","packages/plugin-fusion/README.md":"# @ice/plugin-fusion\n\nice.js plugin for using fusion components.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport fusion from '@ice/plugin-fusion';\n\nexport default defineConfig(() => ({\n  plugins: [fusion({\n    importStyle: true,\n    themePackage: '@alifd/theme-design-pro',\n    theme: {\n      'primary-color': '#fff',\n    },\n  })],\n}));\n```\n\n## Options\n\n- importStyle: Fusion component styles will be automatically imported after enabling.\n- themePackage: Fusion component theme package configuration, if set to an array, multi-theme capability is enabled.\n- theme: theme configuration, overwrite existing themes by setting sass variables.\n","packages/plugin-i18n/README.md":"# @ice/plugin-i18n\n\n组件功能描述\n\n## Install\n\n```bash\n$ npm i @ice/plugin-i18n --save-dev\n```\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport i18n from '@ice/plugin-i18n';\n\nexport default defineConfig({\n  plugins: [\n    i18n({\n      locales: ['zh-CN', 'en-US'],\n      defaultLocale: 'zh-CN',\n    }),\n  ],\n});\n```\n\n## Options\n\n### `locales`\n\n- **type:** `string[]`\n\nThe locales you want to support in your app. This option is required.\n\n### defaultLocale\n\n- **type:** `string`\n\nThe default locale you want to be used when visiting a non-locale prefixed path. This option is required.\n\n### autoRedirect\n\n- **type:** `boolean`\n- **default:** `true`\n\nRedirect to the preferred locale automatically. This option should be used with the middleware. If you deploy your application in production, you should read the [example]() for more detail.\n","packages/plugin-icestark/README.md":"# plugin-icestark\n\n> Easy use [`icestark`](https://github.com/ice-lab/icestark) in [icejs](https://github.com/alibaba/ice).\n\n## Usage\n\n### Install\n\n```bash\nnpm i -D @ice/plugin-icestark\n```\n\n### Framework Application\n\nConfigurate plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport icestark from '@ice/plugin-icestark';\n\nexport default defineConfig(() => ({\n  plugins: [\n    icestark({ type: 'framework' }),\n  ],\n}));\n```\n\nThrough export `icestark` configuration of your framework application.\n\n```ts title=\"src/app.ts\"\nimport { defineFrameworkConfig } from '@ice/plugin-icestark/esm/types';\n\nexport const icestark = defineFrameworkConfig(() => ({\n  getApps: () => ([]),\n}));\n```\n\n**Options:**\n - `getApps`: get sub-application information, support async function\n - `appRouter`\n   - `ErrorComponent`: error component\n   - `LoadingComponent`: loading component\n   - `NotFoundComponent`: 404 not found component\n   - `shouldAssetsRemove`: check assets if it should be removed\n - `layout`: specify Framework application Layout\n\n### Sub-application\n\nConfigurate plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport icestark from '@ice/plugin-icestark';\n\nexport default defineConfig(() => ({\n  plugins: [\n    icestark({ type: 'child' }),\n  ],\n}));\n```\n\nmodify `icestark` exports in `src/app.ts`:\n\n```ts title=\"src/app.ts\"\n// app.ts\nimport { defineChildConfig } from '@ice/plugin-icestark/esm/types';\n\nexport const icestark = defineChildConfig(() => ({\n  mount: () => {},\n  unmount: () => {},\n}));\n```\n\n**Options:**\n - `mount`: excute before Sub-application mounted\n - `unmount`: excute after Sub-application unmounted","packages/plugin-intl/README.md":"# @ice/plugin-intl\n\n`@ice/plugin-intl` is a ice.js plugin. It provides a simple way to add internationalization support to your application.\n\n> `@ice/plugin-intl` is based on `react-intl`.\n\n## Install\n\n```bash\n$ npm i @ice/plugin-intl --save-dev\n```\n\n## Usage\n\nDefine the plugin in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport intl from '@ice/plugin-intl';\n\nexport default defineConfig({\n  plugins: [\n    intl(),\n  ],\n});\n```\n\nDefine locale config in `src/app.ts`:\n\n```ts\nimport { defineAppConfig } from 'ice';\nimport type { LocaleConfig } from '@ice/plugin-intl/types';\n\nexport default defineAppConfig(() => ({}));\n\nexport const locale: LocaleConfig = {\n  // Cutomize getLocale method and other options supported by react-intl.\n  getLocale: () => 'en-US',\n};\n```\n\n## Locales\n\nLocales are defined in the `src/locales` directory. Each locale is defined in a separate file, with the locale name as the file name. For example, `en-US.ts`:\n\n```ts\nexport default {\n  'app.title': 'My Application',\n  'app.welcome': 'Welcome to my application!',\n};\n```\n\nUse the `useIntl` hook to access the current locale:\n\n```tsx\nimport { useIntl } from 'ice';\n\nexport default function Home() {\n  const intl = useIntl();\n  console.log(intl.formatMessage({ id: 'new' }));\n  return <h1>home</h1>;\n}\n```\n\nUse the `intl` function to access the current locale:\n\n```tsx\nimport { intl } from 'ice';\n\nfunction alertMessage() {\n  alert(intl.formatMessage({ id: 'app.welcome' }));\n}\n```\n\n## Simple mode\n\nSimple mode for remove the dependency of `react-intl`:\n\nDefine the plugin in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport intl from '@ice/plugin-intl';\n\nexport default defineConfig({\n  plugins: [\n    // Add intlSolution to remove the dependency of react-intl\n    intl({ intlSolution: 'simple' }),\n  ],\n});\n```\n\nWhen you use the `simple` mode, you can only use the `intl.formateMessage` function to get the locale message:\n\n```tsx\nimport { ice } from 'ice';\n\nexport default function Home() {\n  console.log(intl.formatMessage({ id: 'new' }));\n  return <h1>home</h1>;\n}\n```\n\nFunction `intl.formatMessage` is limited, you can only use the syntax below to get the locale message:\n\nSimple Usage:\n\n```tsx\nintl.formatMessage({ id: 'app.welcome', defaultMessage: 'Welcome to my application!' });\nintl.formatMessage('app.welcome');\n```\n\nWith Variables:\n\n```tsx\nintl.formatMessage({ id: 'app.welcome' }, { name: 'icejs' });\n```\n\n> Caution: the message Syntax only support the pattern like `{name}`.\n","packages/plugin-jsx-plus/README.md":"# @ice/plugin-jsx-plus\n\nThis plugin adds support for JSX+ syntax to the ice.js.\n\n## Definition of JSX Plus\n\nhttps://github.com/jsx-plus/jsx-plus\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport jsxplus from '@ice/plugin-jsx-plus';\n\nexport default defineConfig(() => ({\n  plugins: [\n    jsxplus({\n      // options\n    }),\n  ],\n}));\n```\n\n## Options\n\n- `include`: `(string | RegExp)[]`\n  - Files to be included.\n  - Default: the project `src` directory.\n- `exclude`: `(string | RegExp)[]`\n  - Files to be excluded.\n  - Default: `[]`\n- `extensions`: `string[]`\n  - File extensions to be processed.\n  - Default: `['.jsx', '.tsx']`\n\n> If `include` and `exclude` are both set, `exclude` will be priority executed.\n","packages/plugin-miniapp/README.md":"# @ice/plugin-miniapp\n\n> Forked from [taro](https://github.com/NervJS/taro) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/main/LICENSE\n\nice.js plugin to enable miniapp development.\n\nSee [documentation](https://v3.ice.work) for more details.\n","packages/plugin-moment-locales/README.md":"# @ice/plugin-moment-locales\n\nice.js Plugin for load moment locales and reduce size of moment.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport moment from '@ice/plugin-moment-locales';\n\nexport default defineConfig(() => ({\n  plugins: [\n    moment({\n      locales: ['zh-CN'],\n    }),\n  ],\n}));\n```\n","packages/plugin-pha/README.md":"# @ice/plugin-pha\n\nAn ice.js plugin to enable PHA features.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport pha from '@ice/plugin-pha';\n\nexport default defineConfig(() => ({\n  plugins: [pha()],\n}));\n```\n","packages/plugin-rax-compat/README.md":"# @ice/plugin-rax-compat\n\nAn ice.js plugin for migrating `rax-app` projects.\n\n## Usage\n\nAdd plugin in `ice.config.mts`:\n\n```js\nimport { defineConfig } from 'ice';\nimport compatRax from '@ice/plugin-rax-compat';\n\nexport default defineConfig(() => ({\n  plugins: [compatRax({ /* options */ })],\n}));\n```\n\n## Options\n\n### `inlineStyle`\n\n- Default: `false`.\n- Enable stylesheet loader to import CSS files.\n\n### `cssModule`\n\n- Default: `true`\n- When `inlineStyle` enabled and `cssModule` disabled, process CSS Module files to inline included styles(not recommended).\n\n### `legacy`\n\n- Default: `false`\n- Enable legacy way to import rax as namespace, like `v0.6`:\n\n```typescript\nimport Rax from 'rax';\n\nRax.createContext();\n```\n\n## 说明\n\n这个插件将会处理这些兼容逻辑：\n\n- 类型定义，Rax 中的类型定义来自于 React 16.8 前，与 React 18 的类型定义存在一些差异。\n  - 这个插件会新增一个对 Rax namespace 进行声明的 .d.ts 文件，内部使用 React 类型定义来进行声明。\n\n- 别名，将组成 rax 核心逻辑的 rax- 包，如 rax-children 等，映射到 rax-compat 的内部实现。\n\n  - 同时，在启用 legacy 模式时，会将 rax 映射到 rax-compat-legacy-exports.ts，此文件支持了 Rax.createContext 这样的使用方式（Rax v0.6.x）。\n\n- JSX，插件内部将基于源码类型来调整 swc 的编译配置。\n\n  - 在源码中使用了 `@jsx createElement` annotation 时，将设置 jsx runtime 为 classic。\n  - 在源码导入了 rax 包时，将设置 importSource 为 rax-compat/runtime（与 React 18 保持一致）。\n\n- 样式，在启用 inlineStyle 时，插件内部将额外处理行内样式逻辑。\n\n  - 首先，JSXClassNameTransformer 会将源码中的 `<div className=\"header\" />` 的写法转换为 `<div style={styleSheet.header} />`。\n        - 注意，只有项目源码内的代码才会被转换。\n\n        - 注意，`<div className={'xxx'} />` 这样的写法不会被转换。\n            \n        - 注意，`import './x.module.css'` 这样的写法不会被转换。\n\n  - 接着，在 ClientSide，插件会覆盖原本的 Webpack Ruleset：\n\n    - 对于命中了 inlineStyle 的资源文件，会使用 stylesheet-loader 进行处理为 styleSheet 对象（非 css 文件还会先交由预处理器编译）。其它文件会保持原本的处理逻辑，即处理到额外的 CSS 文件中。\n    - 注意，目前在 --speedup 下此逻辑无法生效。\n    - 注意，如果禁用了 cssModule ，那么 .module.css(less/...) 文件也会被交由 stylesheet-loader 处理。\n\n- 在 ServerSide，对命中了 inlineStyle 的资源文件，会使用 esbuild 进行处理为 styleSheet 对象(文件的类型会被改变为 JS 文件)。\n\n关于行内样式的额外说明：\n\n- 只有项目源码中使用了 `className=\"xxx\"` 的写法，才会被转换为 `style={styleSheet.xxx}` 的写法，因此 CSS Module 使用的 `className={styles.xxx}` 这种写法也不会被转换。另外，来自 node_modules 的代码不会被转换。\n","packages/plugin-request/README.md":"# @ice/plugin-request\n\nProvides a unified request method for ice.js projects.\n\n## Usage\n\n```bash\n$ npm i @ice/plugin-request -S\n```\n\nAdd plugin.\n\n```js title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport request from '@ice/plugin-request';\n\nexport default defineConfig(() => ({\n  plugins: [\n    request(),\n  ],\n}));\n```\n\n## API\n\n### request\n\n```js title=\"service.ts\"\nimport { request } from 'ice';\n\nexport async function getUser(id) {\n  return await request(`/api/user/${id}`);\n}\n```\n\n### useRequest\n\n```js title=\"home.tsx\"\nimport { useEffect } from 'react';\nimport { useRequest } from 'ice';\n\nexport default function Home() {\n  const {\n    data,\n    error,\n    loading,\n    request\n  } = useRequest(service.getUser);\n\n  useEffect(() => {\n    request();\n  }, []);\n\n  if (error) {\n    return <div>failed to load</div>;\n  }\n  if (!data || loading) {\n    return <div>loading...</div>;\n  }\n  return (\n    <h2 className={styles.title}>\n      Name: {data.name} Age: {data.age}\n    </h2>\n  );\n}\n```\n","packages/plugin-store/README.md":"# @ice/plugin-store\n\nA plugin of state management base on Redux and React Redux used in ice.js`.\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport store from '@ice/plugin-store';\n\nexport default defineConfig(() => ({\n  plugins: [\n    store(),\n  ],\n}));\n```\n\n## Options\n\n- `disableResetPageState` \n  - The default value is `false`.\n  - After it is turned on, the page state will not be reinitialized after switching the page and entering the original page again.\n","packages/plugin-stream-error/README.md":"# @ice/plugin-stream-error\n\nA plugin for re-render app when stream error.\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport streamError from '@ice/plugin-stream-error';\n\nexport default defineConfig(() => ({\n  plugins: [\n    streamError(),\n  ],\n}));\n```\n\n> Causion: This plugin only works when stream content ends with javascripts which triggered an custom event of `stream_end`\n","packages/plugin-unocss/README.md":"# @ice/plugin-unocss\n\nA plugin for enable unocss in your app based on `@ice/app`.\n\n\n## Usage\n\nInstall `@ice/plugin-unocss`:\n\n```bash\n$ npm install @ice/plugin-unocss --save-dev\n```\n\nConfigure it in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport Unocss from '@ice/plugin-unocss';\n\nexport default defineConfig(() => ({\n  plugins: [\n    Unocss(),\n  ]\n}));\n```\n\n## Plugin Options\n\nPlugin options is as same as [UnoCSS ConfigFle](https://unocss.dev/guide/config-file).\n\nPlugin has a default preset `@unocss/preset-uno` for UnoCSS. You can pass options of presets to override the default preset:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport Unocss from '@ice/plugin-unocss';\nimport {\n  defineConfig,\n  presetAttributify,\n  presetIcons,\n  presetTypography,\n  presetUno,\n  presetWebFonts,\n  transformerDirectives,\n  transformerVariantGroup\n} from 'unocss';\n\nexport default defineConfig(() => ({\n  plugins: [\n    Unocss({\n      shortcuts: [\n        // ...\n      ],\n      theme: {\n        colors: {\n          // ...\n        }\n      },\n      presets: [\n        presetUno(),\n        presetAttributify(),\n        presetIcons(),\n        presetTypography(),\n        presetWebFonts({\n          fonts: {\n            // ...\n          },\n        }),\n      ],\n      transformers: [\n        transformerDirectives(),\n        transformerVariantGroup(),\n      ],\n    }),\n  ],\n}));\n```\n","packages/rax-compat/README.md":"# rax-compat\n\nA runtime polyfill, for writing rax, but rendering in real React.\n\n## Usage\n\n```js\nimport { createElement } from 'rax-compat';\n\nexport default function() {\n  return createElement('div', null, 'Hello World');\n}\n```\n\nAlso works with JSX, should be configured with packer(webpack/turbopack).\n\nSee also [@ice/plugin-rax-compat](https://www.npmjs.com/package/@ice/plugin-rax-compat).\n","packages/route-manifest/README.md":"# @ice/route-manifest\n\nGenerate route manifest based on the `src` directory in the project for ice.js 3.\n\n## API\n\n### `generateRouteManifest(rootDir: string)`\n\n- rootDir: the project directory absolute path\n\nWill scan the page files in the `rootDir` and generate the routeManifest. For example:\n\n```ts\nconst routeManifest = generateRouteManifest(__dirname);\nconsole.log(routeManifest);\n/**\n[\n  layout: {\n    path: \"\",\n    id: \"layout\",\n    componentName: \"Layout\",\n    file: \"layout.tsx\",\n  },\n  \"pages/About/index\": {\n    path: \"/About\",\n    index: true,\n    id: \"pages/About/index\",\n    parentId: \"layout\",\n    file: \"pages/About/index.tsx\",\n    componentName: \"PagesAboutIndex\",\n  },\n}\n*/\n```\n\n### `formatNestedRouteManifest(routeManifest: RouteManifest)`\n\n- routeManifest: generated by the `generateRouteManifest` function\n\nIt will get the nested route by the routeManifest. For example:\n\nrouteManifest:\n\n```ts\nconst routeManifest = [\n  layout: {\n    path: \"\",\n    id: \"layout\",\n    componentName: \"Layout\",\n    file: \"layout.tsx\",\n  },\n  \"pages/About/index\": {\n    path: \"/About\",\n    index: true,\n    id: \"pages/About/index\",\n    parentId: \"layout\",\n    file: \"pages/About/index.tsx\",\n    componentName: \"PagesAboutIndex\",\n  },\n}\n\nconst nestedRouteManifest = formatNestedRouteManifest(routeManifest);\n\nconsole.log(nestedRouteManifest);\n/**\n[\n  {\n    path: \"\",\n    id: \"layout\",\n    componentName: \"Layout\",\n    file: \"layout.tsx\",\n    children: [\n      {\n        path: \"/About\",\n        index: true,\n        id: \"pages/About/index\",\n        parentId: \"layout\",\n        file: \"pages/About/index.tsx\",\n        componentName: \"PagesAboutIndex\",\n      },\n    ]\n  }\n]\n*/\n```\n","packages/rspack-config/README.md":"# @ice/rspack-config\n\nThis package providers basic rspack configuration.\n","packages/runtime/README.md":"# @ice/runtime\n\nruntime dependencies for webpack framework `ice`.\n\n`@ice/runtime` includes almost every runtime dependencies for `ice`, the dependencies version will be locked to keep the stability of web framework.","packages/shared-config/README.md":"# @ice/shared-config\n\nThis package providers shared configuration for rspack and webpack.\n","packages/style-import/README.md":"# `@ice/style-import`\n\nA transform function for automatic import style.\n\n## Usage\n\n```js\nimport transform from '@ice/style-import';\n\ntransform(`import { Button } from 'antd';\nReactDOM.render(<Button>xxxx</Button>);`, [{\n  libraryName: 'antd',\n  style: (importSpecifiers) =>\n    importSpecifiers.map(specifier =>\n      `import 'antd/es/${specifier}/style'`).join('\\n'),\n}]);\n\n// the code will turn out as blew:\n/* \nimport { Button } from 'Button';\nimport 'antd/es/Button/style';\nReactDOM.render(<Button>xxxx</Button>); */\n```\n","packages/webpack-config/README.md":"# @ice/webpack-config\n\nThis package providers basic webpack configuration.\n\n## Usage\n\n```js\nimport { getWebpackConfig } from '@ice/webpack-config';\nimport webpack from 'webpack';\n\nconst config = { alias: {} };\nconst rootDir = process.cwd();\nconst runtimeTmpDir = '.ice';   // the path of the asset-manifest.json\n\nconst webpackConfig = getWebpackConfig({ \n  rootDir, \n  config,\n  webpack, \n  runtimeTmpDir,\n  target: 'web',\n});\n```\n","packages/webpack-modify/README.md":"# @ice/webpack-modify\n\nThis package providers several APIs to simplify the modification of webpack configurations.\n\n## Usage\n\n```js\nimport { removeLoader, modifyLoader, addLoader, removePlugin } from '@ice/webpack-modify';\n\nlet modifiedConfig = {};\n\nconst webpackConfig = {\n  module: {\n    rules: [\n      {\n        test: /\\.css$/,\n        use: [{ loader: \"style-loader\" }, { loader: \"sass-loader\" }],\n      },\n    ],\n  },\n};\n\n// remove loader\nmodifiedConfig = removeLoader(webpackConfig, {\n  rule: 'css',\n  loader: 'style-loader',\n});\n// modify loader\nmodifiedConfig = modifyLoader(webpackConfig, {\n  rule: 'css',\n  loader: 'style-loader',\n  options: () => ({}),\n});\n// add loader\nmodifiedConfig = addLoader(webpackConfig, {\n  rule: 'css',\n  before: 'style-loader'\n});\nmodifiedConfig = addLoader(webpackConfig, {\n  rule: 'css',\n  after: 'style-loader'\n});\n// modify webpack rule options\nmodifiedConfig = modifyRule(webpackConfig, {\n  rule: 'css',\n  options: () => {\n    return [\n      {\n        loader: 'css-loader',\n        options: () => ([]),\n      },\n    ]\n  },\n})\n// remove plugin\nmodifiedConfig = removePlugin(webpackConfig, {\n  pluginName: 'AssetsManifestPlugin',\n});\n```\n","website/docs/guide/plugins/plugin-dev.md":"---\ntitle: 开发插件\norder: 1\n---\n\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';\n\nice.js 底层基于 [build-scripts](https://github.com/ice-lab/build-scripts) 插件系统，在提供丰富的框架能力的基础上也可以让开发者可以在框架能力不满足诉求的情况下进行定制：\n\n- 定制修改框架构建配置\n- 支持在整个构建生命周期定制行为，比如项目启动前拉取某些资源\n- 支持扩展运行时能力，比如统一为路由组件增加鉴权逻辑（添加高阶组件）\n\n## 插件规范\n\nice.js 插件本质是一个 JS 模块，官方推荐以 TS 进行开发以获得良好的类型提示：\n\n```ts\nimport type { Plugin } from '@ice/app/types';\n\ninterface PluginOptions {\n  id: string;\n}\n\nconst plugin: Plugin<PluginOptions> = (options) => ({\n  // name 可选，插件名称\n  name: 'plugin-name',\n  // setup 必选，用于定制工程构建配置\n  setup: (pluginAPI) => { console.log(options.id) },\n  // runtime 可选，用于定制运行时配置\n  runtime: '/path/to/runtime',\n});\n\nexport default plugin;\n```\n\n### 开发本地插件\n\n推荐在项目根目录下新建一个插件目录，目录名比如叫 `my-plugin`。然后在该目录下新建以下文件：\n\n- `index.ts`：必选，插件入口，用于定制工程构建能力\n- `runtime.tsx`：可选，用于定制运行时能力\n\n<Tabs>\n\n<TabItem value=\"index.ts\" label=\"my-plugin/index.ts\">\n\n```ts\nimport * as path from 'path';\nimport type { Plugin } from '@ice/app/types';\n\nconst plugin: Plugin = () => ({\n  name: 'my-plugin',\n  setup: (pluginAPI) => {\n    console.log(pluginAPI);\n  },\n  // runtime 为可选，用于定制运行时配置。runtime 的值必须是一个绝对路径\n  runtime: path.join(__dirname, 'runtime.tsx'),\n});\n\nexport default plugin;\n```\n\n</TabItem>\n\n<TabItem value=\"runtime.tsx\" label=\"my-plugin/runtime.tsx\">\n\n```tsx\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = async ({ appContext }) => {\n  console.log(appContext);\n}\n\nexport default runtime;\n```\n\n</TabItem>\n\n</Tabs>\n\n开发完成后，我们需要把插件添加到应用的构建配置中：\n\n```diff title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\n+ import myPlugin from './my-plugin/index.js';\n\nexport default defineConfig(() => ({\n  plugins: [\n+   myPlugin(),\n  ],\n}))\n```\n\n### 发布插件到 npm \n\n:::tip\n插件模板可参考：https://github.com/ice-lab/icejs-plugin-template\n:::\n\n假设现在需要开发一个插件（包括修改工程配置和运行时配置），并发布到 npm 上。插件的文件目录如下：\n\n```md\n/xxx/@ice/my-plugin\n├── package.json\n├── src\n|  ├── index.ts       // 插件入口\n|  └── runtime.tsx    // 定制运行时能力\n```\n\n推荐以 [ES Module](https://nodejs.org/api/packages.html) 的方式编写插件，并使用 `exports` 字段导出插件入口和运行时配置：\n\n```json title=\"package.json\"\n{\n  \"name\": \"@ice/my-plugin\",\n  \"type\": \"module\",\n  \"exports\": {\n    \".\": {\n      \"types\": \"./esm/index.d.ts\",\n      \"import\": \"./esm/index.js\",\n      \"default\": \"./esm/index.js\"\n    },\n    \"./runtime\": {\n      \"types\": \"./esm/runtime/index.d.ts\",\n      \"import\": \"./esm/runtime/index.js\",\n      \"default\": \"./esm/runtime/index.js\"\n    }\n  },\n  \"main\": \"./esm/index.js\",\n  \"types\": \"./esm/index.d.ts\",\n  \"files\": [\n    \"esm\",\n    \"!esm/**/*.map\"\n  ],\n}\n```\n<Tabs>\n\n<TabItem value=\"index.ts\" label=\"src/index.ts\">\n\n```ts\nimport type { Plugin } from '@ice/app/types';\n\nconst plugin: Plugin = () => ({\n  name: '@ice/my-plugin',\n  setup: (pluginAPI) => {},\n  // runtime 的值需要配置为「模块引入路径」，对应上面 package.json 中 exports 里的 \"./runtime\" 导出\n  runtime: '@ice/my-plugin/runtime',\n});\n\nexport default plugin;\n```\n\n</TabItem>\n\n<TabItem value=\"runtime.tsx\" label=\"src/runtime.tsx\">\n\n```tsx\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = async ({ appContext }) => {\n  console.log(appContext);\n}\n\nexport default runtime;\n```\n\n</TabItem>\n\n</Tabs>\n\n\n把插件发布到 npm 后，需要把插件添加到构建配置中：\n\n```diff title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\n+ import myPlugin from '@ice/my-plugin';\n\nexport default defineConfig(() => ({\n  plugins: [\n+   myPlugin(),\n  ],\n}));\n```\n\n## 工程能力定制\n\n框架为定制工程能力提供了插件 API，方便开发者扩展和自定义能力。\n\n### `context`\n\n`context` 包含构建时的上下文信息：\n\n- `command` 当前运行命令，start/build/test\n- `commandArgs` script 命令执行时接受到的参数\n- `rootDir` 项目根目录\n- `userConfig` 用户在构建配置文件 ice.config.mts 中配置的内容\n- `pkg` 项目 package.json 中的内容\n- `webpack` webpack 实例，工程不建议安装多个 webpack 版本，可以从 `context.webpack` 上获取内置的 webpack 实例\n\n```ts\nconst plugin = () => ({\n  setup: ({ context }) => {\n    console.log('context: ', context);\n  },\n})\n\nexport default plugin;\n```\n### `onGetConfig`\n\n通过 `onGetConfig` 获取框架的工程配置，并可通过该 API 对配置进行自定义修改：\n\n```ts\nconst plugin = () => ({\n  name: 'plugin-test',\n  setup: ({ onGetConfig }) => {\n    onGetConfig((config) => {\n      config.alias = {\n        '@': './src/',\n      };\n    });\n  },\n});\n\nexport default plugin;\n```\n\n为了简化开发者的配置，通过 `onGetConfig` 修改配置项是基于底层工程工具的抽象，包括以下配置项：\n\n- `mode` 配置 `'none' | 'development' | 'production'` 以确定构建环境\n- `entry` 配置应用入口文件\n- `define` 注入到运行时的变量\n- `experimental` 实验性能力，同 [webpack.experiments](https://webpack.js.org/configuration/experiments/#experiments)\n- `outputDir` 构建输出目录\n- `externals` 同 [webpack.externals](https://webpack.js.org/configuration/externals/)\n- `outputAssetsPath` 静态资源输出目录，可以分别配置 js 和 css\n- `sourceMap` 源码调试映射，同 [webpack.devtool](https://webpack.js.org/configuration/devtool/)\n- `publicPath` 同 [webpack.output.publicPath](https://webpack.js.org/guides/public-path/#root)\n- `alias` 同 [webpack.resolve.alias](https://webpack.js.org/configuration/resolve/#resolvealias)\n- `hash` 配置资源输出文件名是否带 hash\n- `transformPlugins` [unplugin 标准](https://github.com/unjs/unplugin) 插件，该插件对于服务端和浏览器端产物同时生效\n- `transforms` 配置源码转化，支持对源码进行定制转化\n- `middlewares` development 开发阶段配置中间件\n- `proxy` 配置代理服务\n- `compileIncludes` 配置需要进行编译的三方依赖\n- `minify` 是否进行压缩\n- `minimizerOptions` 压缩配置项，基于 [minify-options](https://github.com/terser/terser#minify-options)\n- `analyzer` 开启产物分析\n- `https` 配置 https 服务\n- `port` 配置调试端口\n- `cacheDir` 配置构建缓存目录\n- `tsCheckerOptions` ts 类型检查 [配置项](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin)\n- `eslintOptions` eslint 检查 [配置项](https://www.npmjs.com/package/eslint-webpack-plugin)\n- `splitChunks` 是否分包\n- `assetsManifest` 是否生成资源 manifest\n- `devServer` 配置 webpack dev server [配置](https://webpack.js.org/configuration/dev-server/)\n- `fastRefresh` 是否开启 fast-refresh 能力\n- `configureWebpack` 如果上述快捷配置项不满足定制需求，可以通过 configureWebpack 进行自定义\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ onGetConfig }) => {\n    onGetConfig((config) => {\n      config.configureWebpack.push((webpackConfig) => {\n        webpackConfig.mode = 'development';\n        return webpackConfig;\n      })\n    });\n  },\n})\n```\n\n### `onHook`\n\n通过 `onHook` 监听命令构建时事件，`onHook` 注册的函数执行完成后才会执行后续操作，可以用于在命令运行中途插入插件想做的操作：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ onHook }) => {\n    onHook('before.build.load', () => {\n      // do something before build\n    });\n    onHook('after.build.compile', (stats) => {\n      // do something after build\n    });\n  },\n})\n```\n\n目前支持的生命周期如下：\n\n- `before.start.run` 构建命令 start 执行前，该阶段可以获取各项构建任务最终配置\n- `before.build.run` 构建命令 build 执行前，同 start\n- `after.start.compile` 构建命令 start 执行结束，该阶段可以获取构建的执行结果\n- `after.build.compile` 构建命令 build 执行结束，同 start\n- `after.start.devServer` dev 阶段的 server 服务启动后，该阶段可以获取相关 dev server 启动的 url 等信息\n\n> 每个周期可以获取的具体的参数类型可以参考 [TS 类型](https://github.com/alibaba/ice/blob/master/packages/ice/src/types/plugin.ts)。\n\n### `registerUserConfig`\n\n为用户配置文件 `ice.config.mts` 中添加自定义字段：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerUserConfig }) => {\n    registerUserConfig({\n      name: 'custom-key',\n      validation: 'boolean', // 可选，支持类型有 string, number, array, object, boolean\n      setConfig: () => {\n        // 该字段对于配置的影响，通过 onGetConfig 设置\n      },\n    });\n  },\n});\n```\n\n### `registerCliOption`\n\n为命令行启动添加自定义参数：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerCliOption }) => {\n    registerCliOption({\n      name: 'custom-option',\n      commands: ['start'], // 支持的扩展的命令\n      setConfig: () => {\n        // 该字段对于配置的影响，通过 onGetConfig 设置\n      },\n    });\n  },\n});\n```\n\n### `modifyUserConfig`\n\n修改用户配置：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ modifyUserConfig }) => {\n    modifyUserConfig('key', 'value'); // key, value 分别为用户配置文件键值对\n    // 例如：把 ssr 配置项修改为 true，以开启 SSR\n    modifyUserConfig('ssr', true);\n  },\n});\n```\n\n### `registerTask`\n\n添加自定义任务：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerTask }) => {\n    const config = {\n      sourceMap: true,\n    };\n    registerTask('task name', config); // name: Task名, config: 对于任务配置同 onGetConfig 配置项\n  },\n});\n```\n\n### `getAllTask`\n\n获取所有任务名称，内置主要任务名为 `web`：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ getAllTask }) => {\n    const tasks = getAllTask();\n    console.log(tasks);\n  },\n});\n```\n\n### `generator`\n\n支持生成或者修改模版，支持的 API 如下：\n\n#### `addRenderTemplate`\n\n添加模块生成目录：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addRenderTemplate({\n      template: '/path/to/template/dir',\n      targetDir: 'router',\n    }, {});\n  },\n});\n```\n\n#### `addRenderFile`\n\n添加模块生成文件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addRenderFile('/path/to/file.ts.ejs', 'folder/file.ts', {});\n  },\n});\n```\n\n#### `addExport`\n\n向 ice.js 里注册模块，实现 `import { request } from 'ice';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addExport({\n      source: './request/request',\n      exportName: 'request',\n    });\n  },\n});\n```\n\n#### `addExportTypes`\n\n向 ice.js 里注册类型，实现 `import type { Request } from 'ice';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addExportTypes({\n      source: './request/types',\n      specifier: '{ Request }',\n      exportName: 'Request',\n    });\n  },\n});\n```\n\n#### `addDataLoaderImport`\n\n向 ice.js 里注册 data-loader 的自定义发送方法，实现 `import { customFetch as fetcher } from 'custom-fetch';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addDataLoaderImport({\n      source: 'custom-fetch',\n      alias: {\n        customFetch: 'fetcher',\n      },\n      specifier: ['customFetch'],\n    });\n  },\n});\n```\n\n### `watch`\n\n支持统一的 watch 服务\n\n#### addEvent\n\n添加 watch 事件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ watch }) => {\n    watch.addEvent([\n      /src\\/global.(scss|less|css)/,\n      (event: string, filePath: string) => {},\n      'cssWatch',\n    ]);\n  },\n});\n```\n\n#### removeEvent\n\n移除 watch 事件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ watch }) => {\n    watch.removeEvent('cssWatch');\n  },\n});\n```\n\n## 运行时能力定制\n\n插件运行时可以定制框架的运行时能力：\n\n```ts\nimport type { Plugin } from '@ice/app/types';\nconst plugin: Plugin = () => ({\n  name: 'plugin-name',\n  runtime: '/absolute/path/to/runtime',\n});\n\nexport default plugin;\n```\n\n框架运行时指向的文件地址为一个 JS 模块，源码阶段推荐用 TS 进行开发：\n\n```ts\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = () => {};\nexport default runtime;\n```\n\n### `appContext`\n\nappContext 上包含框架相关上下文配置信息，主要包括：\n\n- `appConfig`：应用配置，详细内容可以参考 [应用入口](../basic/app)\n- `assetsManifest`：应用资讯配置信息\n- `routesData`：路由信息\n\n```ts\nconst runtime = ({ appContext }) => {\n  console.log(appContext);\n}\nexport default runtime;\n```\n\n### `addProvider`\n\n在应用最外层添加全局 Provider：\n\n```tsx\nexport default ({ addProvider }) => {\n  function Provider({ children }) {\n    return (\n      <div>{children}</div>\n    )\n  }\n\n  const StoreProvider = ({ children }) => {\n    return <Provider>{children}</Provider>;\n  };\n  addProvider(StoreProvider);\n};\n```\n\n### `addWrapper`\n\n为所有路由组件添加一层包裹：\n\n```tsx\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper }) => {\n  const PageWrapper = ({ children }) => {\n    useEffect(() => {\n      document.title = 'Hello ICE';\n    }, [])\n    return <>{children}</>\n  }\n\n  addWrapper(PageWrapper);\n\n  // 如果希望同样为 layout 组件添加可以添加第二个参数\n  addWrapper(PageWrapper, true);\n};\n```\n\n#### setAppRouter\n\n定制 Router 渲染方式\n\n```ts\nexport default ({ setAppRouter }) => {\n  // setAppRouter 入参为路由数组\n  const renderRouter = (routes) => () => {\n    return <div>route</div>;\n  };\n  setAppRouter(renderRouter);\n};\n```\n\n### `setRender`\n\n自定义渲染，默认使用 `react-dom` 进行渲染\n\n```ts\nimport ReactDOM from 'react-dom';\n\nexport default ({ setRender }) => {\n  // App: React 组件\n  // appMountNode: App 挂载点\n  const DOMRender = (appMountNode, App) => {\n    ReactDOM.render(<App />, appMountNode);\n  };\n  setRender(DOMRender);\n};\n```\n\n### `useData`\n\n获取页面组件的数据，一般配合 addWrapper 进行使用：\n\n```ts\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper, useData }) => {\n  const PageWrapper = (PageComponent) => {\n    const pageData = useData();\n    console.log(pageData);\n    return PageComponent;\n  };\n  addWrapper(PageWrapper);\n};\n```\n\n### `useConfig`\n\n获取页面组件的配置，一般配合 `addWrapper` 进行使用：\n\n```ts\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper, useConfig }) => {\n  const PageWrapper = (PageComponent) => {\n    const pageConfig = useConfig();\n    console.log(pageConfig);\n    return PageComponent;\n  };\n  addWrapper(PageWrapper);\n};\n```\n","website/docs/guide/plugins/plugin-list.md":"---\ntitle: 插件列表\norder: 2\n---\n\n## [@ice/plugin-miniapp](../miniapp/start)\n\n提供小程序的开发能力。\n\n## [@ice/plugin-auth](../advanced/auth)\n\n提供权限管理方案。\n\n## [@ice/plugin-store](../advanced/store)\n\n提供基于单向数据流的数据管理方案。\n\n## [@ice/plugin-css-assets-local](../advanced/css-assets-local)\n\n提供将 CSS 中的网络资源本地化的能力。\n\n## [@ice/plugin-antd](../advanced/antd)\n\n提供 antd 组件样式按需加载及主题配置能力。\n\n## [@ice/plugin-fusion](../advanced/fusion)\n\n提供 fusion 组件样式按需加载及主题配置能力。\n\n## [@ice/plugin-unocss](../advanced/unocss)\n\n提供 UnoCSS 原子化 CSS 能力。\n",".cursorrules (dragonruby-best-practices-cursorrules-prompt-file.mdc)":"---\ndescription: \"Cursor rules for DragonRuby development with best practices integration.\"\nglobs: **/*\nalwaysApply: false\n---\nYou are an expert game developer in Ruby using the DragonRuby Game Toolkit.\n\nCode Style and Structure\n\n- Write concise, idiomatic Ruby code with accurate examples.\n- Follow Ruby and DragonRuby conventions and best practices.\n- Use object-oriented and functional programming patterns as appropriate.\n- Prefer iteration and modularization over code duplication.\n- Use descriptive variable and method names (e.g., user_signed_in?, calculate_total).\n- Structure files according to DragonRuby conventions.\n\nNaming Conventions\n\n- Use snake_case for file names, method names, and variables.\n- Use CamelCase for class and module names.\n- Follow DragonRuby naming conventions.\n\nSyntax and Formatting\n\n- Follow the Ruby Style Guide (https://rubystyle.guide/)\n- Use Ruby's expressive syntax (e.g., unless, ||=, &.)\n- Prefer single quotes for strings unless interpolation is needed.\n\nError Handling and Validation\n\n- Use exceptions for exceptional cases, not for control flow.\n- Implement proper error logging and user-friendly messages.\n\nFollow the official DragonRuby Game Toolkit guides for best practices in routing, controllers, models, views, and other Rails components.\n"},"files":{"packages/appear/README.md":"# @ice/appear\n\nReact component for supporting `appear` and `disappear` events.  \n\n## Usage\n\n```bash\nnpm i @ice/appear -S\n```\n\n```jsx\nimport VisibilityChange from '@ice/appear';\n\nexport default function Home() {\n  return (\n    <VisibilityChange\n      onAppear={() => {\n        console.log('Something has been shown.')\n      }}\n      onDisappear={() => {\n        console.log('Something has disappeard.')\n      }}\n    >\n      Anything you want to show.\n    </VisibilityChange>\n  );\n}\n```\n","packages/bundles/README.md":"# @ice/bundles\n\nPrepacked bundles for ice.js.\n\n**DO NOT USE THIS PACKAGE DIRECTLY.**\n","packages/cache-canvas/README.md":"# @ice/cache-canvas\n\nReact component for supporting canvas for cache.\n\n## Usage\n\n```bash\nnpm i @ice/cache-canvas -S\n```\n\n```jsx\nimport MainGame from './game'; // eva.js 的封装\n\nconst GAME_CANVAS = 'game-canvas';\n\nexport default (props) => {\n  useEffect(() => {\n    const gameEl = document.getElementById(GAME_CANVAS);\n    new MainGame(gameEl, getGameHeight());\n  }, []);\n\n  const init = () => {\n     return new Promise((resolve) => {\n      const canvas: HTMLCanvasElement | null = document.getElementById(GAME_CANVAS_ID) as HTMLCanvasElement;\n      if (canvas && typeof canvas.getContext === 'function') {\n        let ctx: CanvasRenderingContext2D | null = canvas.getContext('2d');\n\n        ctx?.fillRect(25, 25, 100, 100);\n        ctx?.clearRect(45, 45, 60, 60);\n        ctx?.strokeRect(50, 50, 50, 50);\n      }\n\n      setTimeout(() => {\n        console.log('canvas paint ready!');\n        resolve(true);\n      }, 5000);\n    });\n  }\n\n  return (\n    <>\n       <CanvasCache id={GAME_CANVAS} useCache={false} init={init} />\n    </>\n  );\n};\n```\n","packages/create-ice/README.md":"# create-ice\n\ncreate ice.js project.\n\n## Usage\n\n```bash\n# use npm\n$ npm create ice <projectName>\n# use yarn\n$ yarn create ice <projectName>\n# use pnpm\n$ pnpm create ice <projectName>\n\n# or with template\n# use npm\n$ npm create ice <projectName> --template <template>\n# use yarn\n$ yarn create ice <projectName> --template <template>\n# use pnpm\n$ pnpm create ice <projectName> --template <template>\n\n$ cd <projectName>\n$ npm install\n$ npm start\n```\n","packages/ice/README.md":"# ice.js\n\nice.js is the best user experience for web developing based on React.\nThis package includes scripts and configuration used by web framework `ice`.\n\n## Install\n\n```bash\n$ npm i @ice/app -D\n```\n\n## usage\n\n```json\n{\n  \"name\": \"my-app\",\n  \"devDependencies\": {\n    \"@ice/app\": \"^3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"ice start\",\n    \"build\": \"ice build\"\n  }\n}\n```\n\n## Command line interface\n\n```bash\nUsage: ice <command> [options]\n\nOptions:\n  -V, --version    output the version number\n  -h, --help       output usage information\n\nCommands:\n  build [options]  build project\n  start [options]  start dev server\n```\n\n## Open Source\n\nOpen Source with ❤️ and MIT License.\n","packages/jsx-runtime/README.md":"# @ice/jsx-runtime\n\nJSX runtime for ice.js.\n\n## Install\n\n```bash\n$ npm i @ice/jsx-runtime --save\n```\n","packages/miniapp-html-styles/README.md":"# @ice/miniapp-html-styles\n\n> Forked from [@tarojs/taro](https://github.com/NervJS/taro/tree/next/packages/taro) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\n## html.css\n\nHTML4 built-in styles for compatibility with HTML tag styles.\n\n## html5.css\n\nHTML5 built-in styles for compatibility with HTML tag styles.\n","packages/miniapp-loader/README.md":"# `@ice/miniapp-loader`\n\n> Forked from [@tarojs/loader](https://github.com/NervJS/taro/tree/next/packages/taro-loader) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nWebpack loader exposed to ice.js for building applet artifacts, including the following `loader`:\n\n## page\n\nMiniapp usage only. Call the `createPageConfig` method of `@ice/miniapp-runtime` in the miniapp page file to create an object accepted by the miniapp `Page` constructor.\n","packages/miniapp-react-dom/README.md":"# @ice/miniapp-react-dom\n\n> Forked from [@tarojs/react](https://github.com/NervJS/taro/tree/next/packages/taro-react) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nA React renderer for mini-programs based on `react-reconciler`, connected to the DOM instance of `@ice/miniapp-runtime`, equivalent to the mini-program version of `react-dom`, and the exposed API is also the same as `react-dom` consistent.\n","packages/miniapp-runtime/README.md":"# @ice/miniapp-runtime\n\n> Forked from [@tarojs/runtime](https://github.com/NervJS/taro/tree/next/packages/taro-runtime) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nice.js miniapp runtime. Connect the framework (DSL) rendering mechanism to the miniapp rendering mechanism, and connect the miniapp routing and life cycle to the corresponding life cycle of the framework\n\n## Core API\n\n### createPageConfig()\n\nExpose to `@ice/miniapp-loader/page` calls, called in the miniapp page file, to create a miniapp page specification object accepted by the miniapp `Page` constructor.\n\n### window\n\nAn object that imitates the browser's `window` implementation on the miniapp side, and returns the browser's own `window` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n### navigator\n\nAn object that imitates the browser's `navigator` implementation on the miniapp side, and returns the browser's own `navigator` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n###document\n\nAn object that imitates the browser's `document` implementation on the miniapp side, and returns the browser's own `document` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n### Current\n\nGlobal variables exposed to developers currently have three properties:\n\n* `Current.app`, returns the current miniapp application instance, which can be used to call the miniapp specification life cycle.\n* `Current.page`, returns the current miniapp page instance, which can be used to call the miniapp specification life cycle.\n* `Current.router`, returns the current miniapp routing information.\n","packages/plugin-antd/README.md":"# `@ice/plugin-antd`\n\nAn ice.js plugin to use `antd` components.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport antd from '@ice/plugin-antd';\n\nexport default defineConfig(() => ({\n  plugins: [antd({\n    dark: true,\n    compact: true,\n    theme: {\n      'primary-color': '#fd8',\n    },\n  })],\n}));\n```\n","packages/plugin-auth/README.md":"# `@ice/plugin-auth`\n\nAn ice.js plugin to enable auth ability.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport auth from '@ice/plugin-auth';\n\nexport default defineConfig(() => ({\n  plugins: [\n    auth(),\n  ],\n}));\n```\n\nMore details to see https://v3.ice.work/docs/guide/advanced/auth\n","packages/plugin-cavans/README.md":"# @ice/plugin-canvas\n\nAn ice.js plugin for canvas projects.\n\n## Usage\n\nAdd plugin in `ice.config.mts`:\n\n```js\nimport { defineConfig } from 'ice';\nimport canvasPlugin from '@ice/plugin-canvas';\n\nexport default defineConfig(() => ({\n  plugins: [canvasPlugin({ /* options */ })],\n}));\n```  \n","packages/plugin-css-assets-local/README.md":"# @ice/plugin-css-assets-local\n\nAn ice.js plugin for localize css assets resource.\n\n## Install\n\n```bash\nnpm i -D @ice/plugin-css-assets-local\n```\n\n## Usage\n\nAdd plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport cssAssetsLocal from '@ice/plugin-css-assets-local';\n\nexport default defineConfig(() => ({\n  plugins: [\n    cssAssetsLocal(),\n  ],\n}));\n```\n\nAfter running `npm run build`, you can see asset resources will be downloaded to your local disk.\n\n## Options\n\n### `outputPath`\n\nThe assets resource output path.\n\n- Type: `string`\n- Default: `\"assets\"`\n\n### `relativeCssPath`\n\nThe asset paths relative to the css file path.\n\n- Type: `string`\n- Default: `\"../\"`\n\n### `enableInDev`\n\nWhether enable the plugin in dev or not.\n\n- Type: `boolean`\n- Default: `false`\n","packages/plugin-externals/README.md":"# @ice/plugin-externals\n\n`@ice/plugin-externals` is a ice.js plugin. It provides a simple way to add externals support to your application.\n\n## Install\n\n```bash\n$ npm i @ice/plugin-externals --save-dev\n```\n\n## Usage\n\nSet preset `react` to external react in a easy way.\n\n```js\nimport { defineConfig } from '@ice/app';\nimport externals from '@ice/plugin-externals';\n\nexport default defineConfig(() => ({\n  plugins: [externals({ preset: 'react' })]\n}));\n```\n\nFramework will auto add externals of `react` and `react-dom` to your application, and the cdn url will be inject to the document by default.\n\nAlso, you can custom externals and cdn url by yourself:\n\n```js\nimport { defineConfig } from '@ice/app';\nimport externals from '@ice/plugin-externals';\n\nexport default defineConfig(() => ({\n  plugins: [externals({\n    externals: {\n      antd: 'Antd',\n    },\n    cdnMap: {\n      antd: {\n        development: 'https://unpkg.com/antd/dist/antd.js',\n        production: 'https://unpkg.com/antd/dist/antd.min.js',\n      }\n    }\n  })]\n}));\n```\n","packages/plugin-fusion/README.md":"# @ice/plugin-fusion\n\nice.js plugin for using fusion components.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport fusion from '@ice/plugin-fusion';\n\nexport default defineConfig(() => ({\n  plugins: [fusion({\n    importStyle: true,\n    themePackage: '@alifd/theme-design-pro',\n    theme: {\n      'primary-color': '#fff',\n    },\n  })],\n}));\n```\n\n## Options\n\n- importStyle: Fusion component styles will be automatically imported after enabling.\n- themePackage: Fusion component theme package configuration, if set to an array, multi-theme capability is enabled.\n- theme: theme configuration, overwrite existing themes by setting sass variables.\n","packages/plugin-i18n/README.md":"# @ice/plugin-i18n\n\n组件功能描述\n\n## Install\n\n```bash\n$ npm i @ice/plugin-i18n --save-dev\n```\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport i18n from '@ice/plugin-i18n';\n\nexport default defineConfig({\n  plugins: [\n    i18n({\n      locales: ['zh-CN', 'en-US'],\n      defaultLocale: 'zh-CN',\n    }),\n  ],\n});\n```\n\n## Options\n\n### `locales`\n\n- **type:** `string[]`\n\nThe locales you want to support in your app. This option is required.\n\n### defaultLocale\n\n- **type:** `string`\n\nThe default locale you want to be used when visiting a non-locale prefixed path. This option is required.\n\n### autoRedirect\n\n- **type:** `boolean`\n- **default:** `true`\n\nRedirect to the preferred locale automatically. This option should be used with the middleware. If you deploy your application in production, you should read the [example]() for more detail.\n","packages/plugin-icestark/README.md":"# plugin-icestark\n\n> Easy use [`icestark`](https://github.com/ice-lab/icestark) in [icejs](https://github.com/alibaba/ice).\n\n## Usage\n\n### Install\n\n```bash\nnpm i -D @ice/plugin-icestark\n```\n\n### Framework Application\n\nConfigurate plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport icestark from '@ice/plugin-icestark';\n\nexport default defineConfig(() => ({\n  plugins: [\n    icestark({ type: 'framework' }),\n  ],\n}));\n```\n\nThrough export `icestark` configuration of your framework application.\n\n```ts title=\"src/app.ts\"\nimport { defineFrameworkConfig } from '@ice/plugin-icestark/esm/types';\n\nexport const icestark = defineFrameworkConfig(() => ({\n  getApps: () => ([]),\n}));\n```\n\n**Options:**\n - `getApps`: get sub-application information, support async function\n - `appRouter`\n   - `ErrorComponent`: error component\n   - `LoadingComponent`: loading component\n   - `NotFoundComponent`: 404 not found component\n   - `shouldAssetsRemove`: check assets if it should be removed\n - `layout`: specify Framework application Layout\n\n### Sub-application\n\nConfigurate plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport icestark from '@ice/plugin-icestark';\n\nexport default defineConfig(() => ({\n  plugins: [\n    icestark({ type: 'child' }),\n  ],\n}));\n```\n\nmodify `icestark` exports in `src/app.ts`:\n\n```ts title=\"src/app.ts\"\n// app.ts\nimport { defineChildConfig } from '@ice/plugin-icestark/esm/types';\n\nexport const icestark = defineChildConfig(() => ({\n  mount: () => {},\n  unmount: () => {},\n}));\n```\n\n**Options:**\n - `mount`: excute before Sub-application mounted\n - `unmount`: excute after Sub-application unmounted","packages/plugin-intl/README.md":"# @ice/plugin-intl\n\n`@ice/plugin-intl` is a ice.js plugin. It provides a simple way to add internationalization support to your application.\n\n> `@ice/plugin-intl` is based on `react-intl`.\n\n## Install\n\n```bash\n$ npm i @ice/plugin-intl --save-dev\n```\n\n## Usage\n\nDefine the plugin in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport intl from '@ice/plugin-intl';\n\nexport default defineConfig({\n  plugins: [\n    intl(),\n  ],\n});\n```\n\nDefine locale config in `src/app.ts`:\n\n```ts\nimport { defineAppConfig } from 'ice';\nimport type { LocaleConfig } from '@ice/plugin-intl/types';\n\nexport default defineAppConfig(() => ({}));\n\nexport const locale: LocaleConfig = {\n  // Cutomize getLocale method and other options supported by react-intl.\n  getLocale: () => 'en-US',\n};\n```\n\n## Locales\n\nLocales are defined in the `src/locales` directory. Each locale is defined in a separate file, with the locale name as the file name. For example, `en-US.ts`:\n\n```ts\nexport default {\n  'app.title': 'My Application',\n  'app.welcome': 'Welcome to my application!',\n};\n```\n\nUse the `useIntl` hook to access the current locale:\n\n```tsx\nimport { useIntl } from 'ice';\n\nexport default function Home() {\n  const intl = useIntl();\n  console.log(intl.formatMessage({ id: 'new' }));\n  return <h1>home</h1>;\n}\n```\n\nUse the `intl` function to access the current locale:\n\n```tsx\nimport { intl } from 'ice';\n\nfunction alertMessage() {\n  alert(intl.formatMessage({ id: 'app.welcome' }));\n}\n```\n\n## Simple mode\n\nSimple mode for remove the dependency of `react-intl`:\n\nDefine the plugin in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport intl from '@ice/plugin-intl';\n\nexport default defineConfig({\n  plugins: [\n    // Add intlSolution to remove the dependency of react-intl\n    intl({ intlSolution: 'simple' }),\n  ],\n});\n```\n\nWhen you use the `simple` mode, you can only use the `intl.formateMessage` function to get the locale message:\n\n```tsx\nimport { ice } from 'ice';\n\nexport default function Home() {\n  console.log(intl.formatMessage({ id: 'new' }));\n  return <h1>home</h1>;\n}\n```\n\nFunction `intl.formatMessage` is limited, you can only use the syntax below to get the locale message:\n\nSimple Usage:\n\n```tsx\nintl.formatMessage({ id: 'app.welcome', defaultMessage: 'Welcome to my application!' });\nintl.formatMessage('app.welcome');\n```\n\nWith Variables:\n\n```tsx\nintl.formatMessage({ id: 'app.welcome' }, { name: 'icejs' });\n```\n\n> Caution: the message Syntax only support the pattern like `{name}`.\n","packages/plugin-jsx-plus/README.md":"# @ice/plugin-jsx-plus\n\nThis plugin adds support for JSX+ syntax to the ice.js.\n\n## Definition of JSX Plus\n\nhttps://github.com/jsx-plus/jsx-plus\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport jsxplus from '@ice/plugin-jsx-plus';\n\nexport default defineConfig(() => ({\n  plugins: [\n    jsxplus({\n      // options\n    }),\n  ],\n}));\n```\n\n## Options\n\n- `include`: `(string | RegExp)[]`\n  - Files to be included.\n  - Default: the project `src` directory.\n- `exclude`: `(string | RegExp)[]`\n  - Files to be excluded.\n  - Default: `[]`\n- `extensions`: `string[]`\n  - File extensions to be processed.\n  - Default: `['.jsx', '.tsx']`\n\n> If `include` and `exclude` are both set, `exclude` will be priority executed.\n","packages/plugin-miniapp/README.md":"# @ice/plugin-miniapp\n\n> Forked from [taro](https://github.com/NervJS/taro) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/main/LICENSE\n\nice.js plugin to enable miniapp development.\n\nSee [documentation](https://v3.ice.work) for more details.\n","packages/plugin-moment-locales/README.md":"# @ice/plugin-moment-locales\n\nice.js Plugin for load moment locales and reduce size of moment.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport moment from '@ice/plugin-moment-locales';\n\nexport default defineConfig(() => ({\n  plugins: [\n    moment({\n      locales: ['zh-CN'],\n    }),\n  ],\n}));\n```\n","packages/plugin-pha/README.md":"# @ice/plugin-pha\n\nAn ice.js plugin to enable PHA features.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport pha from '@ice/plugin-pha';\n\nexport default defineConfig(() => ({\n  plugins: [pha()],\n}));\n```\n","packages/plugin-rax-compat/README.md":"# @ice/plugin-rax-compat\n\nAn ice.js plugin for migrating `rax-app` projects.\n\n## Usage\n\nAdd plugin in `ice.config.mts`:\n\n```js\nimport { defineConfig } from 'ice';\nimport compatRax from '@ice/plugin-rax-compat';\n\nexport default defineConfig(() => ({\n  plugins: [compatRax({ /* options */ })],\n}));\n```\n\n## Options\n\n### `inlineStyle`\n\n- Default: `false`.\n- Enable stylesheet loader to import CSS files.\n\n### `cssModule`\n\n- Default: `true`\n- When `inlineStyle` enabled and `cssModule` disabled, process CSS Module files to inline included styles(not recommended).\n\n### `legacy`\n\n- Default: `false`\n- Enable legacy way to import rax as namespace, like `v0.6`:\n\n```typescript\nimport Rax from 'rax';\n\nRax.createContext();\n```\n\n## 说明\n\n这个插件将会处理这些兼容逻辑：\n\n- 类型定义，Rax 中的类型定义来自于 React 16.8 前，与 React 18 的类型定义存在一些差异。\n  - 这个插件会新增一个对 Rax namespace 进行声明的 .d.ts 文件，内部使用 React 类型定义来进行声明。\n\n- 别名，将组成 rax 核心逻辑的 rax- 包，如 rax-children 等，映射到 rax-compat 的内部实现。\n\n  - 同时，在启用 legacy 模式时，会将 rax 映射到 rax-compat-legacy-exports.ts，此文件支持了 Rax.createContext 这样的使用方式（Rax v0.6.x）。\n\n- JSX，插件内部将基于源码类型来调整 swc 的编译配置。\n\n  - 在源码中使用了 `@jsx createElement` annotation 时，将设置 jsx runtime 为 classic。\n  - 在源码导入了 rax 包时，将设置 importSource 为 rax-compat/runtime（与 React 18 保持一致）。\n\n- 样式，在启用 inlineStyle 时，插件内部将额外处理行内样式逻辑。\n\n  - 首先，JSXClassNameTransformer 会将源码中的 `<div className=\"header\" />` 的写法转换为 `<div style={styleSheet.header} />`。\n        - 注意，只有项目源码内的代码才会被转换。\n\n        - 注意，`<div className={'xxx'} />` 这样的写法不会被转换。\n            \n        - 注意，`import './x.module.css'` 这样的写法不会被转换。\n\n  - 接着，在 ClientSide，插件会覆盖原本的 Webpack Ruleset：\n\n    - 对于命中了 inlineStyle 的资源文件，会使用 stylesheet-loader 进行处理为 styleSheet 对象（非 css 文件还会先交由预处理器编译）。其它文件会保持原本的处理逻辑，即处理到额外的 CSS 文件中。\n    - 注意，目前在 --speedup 下此逻辑无法生效。\n    - 注意，如果禁用了 cssModule ，那么 .module.css(less/...) 文件也会被交由 stylesheet-loader 处理。\n\n- 在 ServerSide，对命中了 inlineStyle 的资源文件，会使用 esbuild 进行处理为 styleSheet 对象(文件的类型会被改变为 JS 文件)。\n\n关于行内样式的额外说明：\n\n- 只有项目源码中使用了 `className=\"xxx\"` 的写法，才会被转换为 `style={styleSheet.xxx}` 的写法，因此 CSS Module 使用的 `className={styles.xxx}` 这种写法也不会被转换。另外，来自 node_modules 的代码不会被转换。\n","packages/plugin-request/README.md":"# @ice/plugin-request\n\nProvides a unified request method for ice.js projects.\n\n## Usage\n\n```bash\n$ npm i @ice/plugin-request -S\n```\n\nAdd plugin.\n\n```js title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport request from '@ice/plugin-request';\n\nexport default defineConfig(() => ({\n  plugins: [\n    request(),\n  ],\n}));\n```\n\n## API\n\n### request\n\n```js title=\"service.ts\"\nimport { request } from 'ice';\n\nexport async function getUser(id) {\n  return await request(`/api/user/${id}`);\n}\n```\n\n### useRequest\n\n```js title=\"home.tsx\"\nimport { useEffect } from 'react';\nimport { useRequest } from 'ice';\n\nexport default function Home() {\n  const {\n    data,\n    error,\n    loading,\n    request\n  } = useRequest(service.getUser);\n\n  useEffect(() => {\n    request();\n  }, []);\n\n  if (error) {\n    return <div>failed to load</div>;\n  }\n  if (!data || loading) {\n    return <div>loading...</div>;\n  }\n  return (\n    <h2 className={styles.title}>\n      Name: {data.name} Age: {data.age}\n    </h2>\n  );\n}\n```\n","packages/plugin-store/README.md":"# @ice/plugin-store\n\nA plugin of state management base on Redux and React Redux used in ice.js`.\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport store from '@ice/plugin-store';\n\nexport default defineConfig(() => ({\n  plugins: [\n    store(),\n  ],\n}));\n```\n\n## Options\n\n- `disableResetPageState` \n  - The default value is `false`.\n  - After it is turned on, the page state will not be reinitialized after switching the page and entering the original page again.\n","packages/plugin-stream-error/README.md":"# @ice/plugin-stream-error\n\nA plugin for re-render app when stream error.\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport streamError from '@ice/plugin-stream-error';\n\nexport default defineConfig(() => ({\n  plugins: [\n    streamError(),\n  ],\n}));\n```\n\n> Causion: This plugin only works when stream content ends with javascripts which triggered an custom event of `stream_end`\n","packages/plugin-unocss/README.md":"# @ice/plugin-unocss\n\nA plugin for enable unocss in your app based on `@ice/app`.\n\n\n## Usage\n\nInstall `@ice/plugin-unocss`:\n\n```bash\n$ npm install @ice/plugin-unocss --save-dev\n```\n\nConfigure it in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport Unocss from '@ice/plugin-unocss';\n\nexport default defineConfig(() => ({\n  plugins: [\n    Unocss(),\n  ]\n}));\n```\n\n## Plugin Options\n\nPlugin options is as same as [UnoCSS ConfigFle](https://unocss.dev/guide/config-file).\n\nPlugin has a default preset `@unocss/preset-uno` for UnoCSS. You can pass options of presets to override the default preset:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport Unocss from '@ice/plugin-unocss';\nimport {\n  defineConfig,\n  presetAttributify,\n  presetIcons,\n  presetTypography,\n  presetUno,\n  presetWebFonts,\n  transformerDirectives,\n  transformerVariantGroup\n} from 'unocss';\n\nexport default defineConfig(() => ({\n  plugins: [\n    Unocss({\n      shortcuts: [\n        // ...\n      ],\n      theme: {\n        colors: {\n          // ...\n        }\n      },\n      presets: [\n        presetUno(),\n        presetAttributify(),\n        presetIcons(),\n        presetTypography(),\n        presetWebFonts({\n          fonts: {\n            // ...\n          },\n        }),\n      ],\n      transformers: [\n        transformerDirectives(),\n        transformerVariantGroup(),\n      ],\n    }),\n  ],\n}));\n```\n","packages/rax-compat/README.md":"# rax-compat\n\nA runtime polyfill, for writing rax, but rendering in real React.\n\n## Usage\n\n```js\nimport { createElement } from 'rax-compat';\n\nexport default function() {\n  return createElement('div', null, 'Hello World');\n}\n```\n\nAlso works with JSX, should be configured with packer(webpack/turbopack).\n\nSee also [@ice/plugin-rax-compat](https://www.npmjs.com/package/@ice/plugin-rax-compat).\n","packages/route-manifest/README.md":"# @ice/route-manifest\n\nGenerate route manifest based on the `src` directory in the project for ice.js 3.\n\n## API\n\n### `generateRouteManifest(rootDir: string)`\n\n- rootDir: the project directory absolute path\n\nWill scan the page files in the `rootDir` and generate the routeManifest. For example:\n\n```ts\nconst routeManifest = generateRouteManifest(__dirname);\nconsole.log(routeManifest);\n/**\n[\n  layout: {\n    path: \"\",\n    id: \"layout\",\n    componentName: \"Layout\",\n    file: \"layout.tsx\",\n  },\n  \"pages/About/index\": {\n    path: \"/About\",\n    index: true,\n    id: \"pages/About/index\",\n    parentId: \"layout\",\n    file: \"pages/About/index.tsx\",\n    componentName: \"PagesAboutIndex\",\n  },\n}\n*/\n```\n\n### `formatNestedRouteManifest(routeManifest: RouteManifest)`\n\n- routeManifest: generated by the `generateRouteManifest` function\n\nIt will get the nested route by the routeManifest. For example:\n\nrouteManifest:\n\n```ts\nconst routeManifest = [\n  layout: {\n    path: \"\",\n    id: \"layout\",\n    componentName: \"Layout\",\n    file: \"layout.tsx\",\n  },\n  \"pages/About/index\": {\n    path: \"/About\",\n    index: true,\n    id: \"pages/About/index\",\n    parentId: \"layout\",\n    file: \"pages/About/index.tsx\",\n    componentName: \"PagesAboutIndex\",\n  },\n}\n\nconst nestedRouteManifest = formatNestedRouteManifest(routeManifest);\n\nconsole.log(nestedRouteManifest);\n/**\n[\n  {\n    path: \"\",\n    id: \"layout\",\n    componentName: \"Layout\",\n    file: \"layout.tsx\",\n    children: [\n      {\n        path: \"/About\",\n        index: true,\n        id: \"pages/About/index\",\n        parentId: \"layout\",\n        file: \"pages/About/index.tsx\",\n        componentName: \"PagesAboutIndex\",\n      },\n    ]\n  }\n]\n*/\n```\n","packages/rspack-config/README.md":"# @ice/rspack-config\n\nThis package providers basic rspack configuration.\n","packages/runtime/README.md":"# @ice/runtime\n\nruntime dependencies for webpack framework `ice`.\n\n`@ice/runtime` includes almost every runtime dependencies for `ice`, the dependencies version will be locked to keep the stability of web framework.","packages/shared-config/README.md":"# @ice/shared-config\n\nThis package providers shared configuration for rspack and webpack.\n","packages/style-import/README.md":"# `@ice/style-import`\n\nA transform function for automatic import style.\n\n## Usage\n\n```js\nimport transform from '@ice/style-import';\n\ntransform(`import { Button } from 'antd';\nReactDOM.render(<Button>xxxx</Button>);`, [{\n  libraryName: 'antd',\n  style: (importSpecifiers) =>\n    importSpecifiers.map(specifier =>\n      `import 'antd/es/${specifier}/style'`).join('\\n'),\n}]);\n\n// the code will turn out as blew:\n/* \nimport { Button } from 'Button';\nimport 'antd/es/Button/style';\nReactDOM.render(<Button>xxxx</Button>); */\n```\n","packages/webpack-config/README.md":"# @ice/webpack-config\n\nThis package providers basic webpack configuration.\n\n## Usage\n\n```js\nimport { getWebpackConfig } from '@ice/webpack-config';\nimport webpack from 'webpack';\n\nconst config = { alias: {} };\nconst rootDir = process.cwd();\nconst runtimeTmpDir = '.ice';   // the path of the asset-manifest.json\n\nconst webpackConfig = getWebpackConfig({ \n  rootDir, \n  config,\n  webpack, \n  runtimeTmpDir,\n  target: 'web',\n});\n```\n","packages/webpack-modify/README.md":"# @ice/webpack-modify\n\nThis package providers several APIs to simplify the modification of webpack configurations.\n\n## Usage\n\n```js\nimport { removeLoader, modifyLoader, addLoader, removePlugin } from '@ice/webpack-modify';\n\nlet modifiedConfig = {};\n\nconst webpackConfig = {\n  module: {\n    rules: [\n      {\n        test: /\\.css$/,\n        use: [{ loader: \"style-loader\" }, { loader: \"sass-loader\" }],\n      },\n    ],\n  },\n};\n\n// remove loader\nmodifiedConfig = removeLoader(webpackConfig, {\n  rule: 'css',\n  loader: 'style-loader',\n});\n// modify loader\nmodifiedConfig = modifyLoader(webpackConfig, {\n  rule: 'css',\n  loader: 'style-loader',\n  options: () => ({}),\n});\n// add loader\nmodifiedConfig = addLoader(webpackConfig, {\n  rule: 'css',\n  before: 'style-loader'\n});\nmodifiedConfig = addLoader(webpackConfig, {\n  rule: 'css',\n  after: 'style-loader'\n});\n// modify webpack rule options\nmodifiedConfig = modifyRule(webpackConfig, {\n  rule: 'css',\n  options: () => {\n    return [\n      {\n        loader: 'css-loader',\n        options: () => ([]),\n      },\n    ]\n  },\n})\n// remove plugin\nmodifiedConfig = removePlugin(webpackConfig, {\n  pluginName: 'AssetsManifestPlugin',\n});\n```\n","website/docs/guide/plugins/plugin-dev.md":"---\ntitle: 开发插件\norder: 1\n---\n\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';\n\nice.js 底层基于 [build-scripts](https://github.com/ice-lab/build-scripts) 插件系统，在提供丰富的框架能力的基础上也可以让开发者可以在框架能力不满足诉求的情况下进行定制：\n\n- 定制修改框架构建配置\n- 支持在整个构建生命周期定制行为，比如项目启动前拉取某些资源\n- 支持扩展运行时能力，比如统一为路由组件增加鉴权逻辑（添加高阶组件）\n\n## 插件规范\n\nice.js 插件本质是一个 JS 模块，官方推荐以 TS 进行开发以获得良好的类型提示：\n\n```ts\nimport type { Plugin } from '@ice/app/types';\n\ninterface PluginOptions {\n  id: string;\n}\n\nconst plugin: Plugin<PluginOptions> = (options) => ({\n  // name 可选，插件名称\n  name: 'plugin-name',\n  // setup 必选，用于定制工程构建配置\n  setup: (pluginAPI) => { console.log(options.id) },\n  // runtime 可选，用于定制运行时配置\n  runtime: '/path/to/runtime',\n});\n\nexport default plugin;\n```\n\n### 开发本地插件\n\n推荐在项目根目录下新建一个插件目录，目录名比如叫 `my-plugin`。然后在该目录下新建以下文件：\n\n- `index.ts`：必选，插件入口，用于定制工程构建能力\n- `runtime.tsx`：可选，用于定制运行时能力\n\n<Tabs>\n\n<TabItem value=\"index.ts\" label=\"my-plugin/index.ts\">\n\n```ts\nimport * as path from 'path';\nimport type { Plugin } from '@ice/app/types';\n\nconst plugin: Plugin = () => ({\n  name: 'my-plugin',\n  setup: (pluginAPI) => {\n    console.log(pluginAPI);\n  },\n  // runtime 为可选，用于定制运行时配置。runtime 的值必须是一个绝对路径\n  runtime: path.join(__dirname, 'runtime.tsx'),\n});\n\nexport default plugin;\n```\n\n</TabItem>\n\n<TabItem value=\"runtime.tsx\" label=\"my-plugin/runtime.tsx\">\n\n```tsx\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = async ({ appContext }) => {\n  console.log(appContext);\n}\n\nexport default runtime;\n```\n\n</TabItem>\n\n</Tabs>\n\n开发完成后，我们需要把插件添加到应用的构建配置中：\n\n```diff title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\n+ import myPlugin from './my-plugin/index.js';\n\nexport default defineConfig(() => ({\n  plugins: [\n+   myPlugin(),\n  ],\n}))\n```\n\n### 发布插件到 npm \n\n:::tip\n插件模板可参考：https://github.com/ice-lab/icejs-plugin-template\n:::\n\n假设现在需要开发一个插件（包括修改工程配置和运行时配置），并发布到 npm 上。插件的文件目录如下：\n\n```md\n/xxx/@ice/my-plugin\n├── package.json\n├── src\n|  ├── index.ts       // 插件入口\n|  └── runtime.tsx    // 定制运行时能力\n```\n\n推荐以 [ES Module](https://nodejs.org/api/packages.html) 的方式编写插件，并使用 `exports` 字段导出插件入口和运行时配置：\n\n```json title=\"package.json\"\n{\n  \"name\": \"@ice/my-plugin\",\n  \"type\": \"module\",\n  \"exports\": {\n    \".\": {\n      \"types\": \"./esm/index.d.ts\",\n      \"import\": \"./esm/index.js\",\n      \"default\": \"./esm/index.js\"\n    },\n    \"./runtime\": {\n      \"types\": \"./esm/runtime/index.d.ts\",\n      \"import\": \"./esm/runtime/index.js\",\n      \"default\": \"./esm/runtime/index.js\"\n    }\n  },\n  \"main\": \"./esm/index.js\",\n  \"types\": \"./esm/index.d.ts\",\n  \"files\": [\n    \"esm\",\n    \"!esm/**/*.map\"\n  ],\n}\n```\n<Tabs>\n\n<TabItem value=\"index.ts\" label=\"src/index.ts\">\n\n```ts\nimport type { Plugin } from '@ice/app/types';\n\nconst plugin: Plugin = () => ({\n  name: '@ice/my-plugin',\n  setup: (pluginAPI) => {},\n  // runtime 的值需要配置为「模块引入路径」，对应上面 package.json 中 exports 里的 \"./runtime\" 导出\n  runtime: '@ice/my-plugin/runtime',\n});\n\nexport default plugin;\n```\n\n</TabItem>\n\n<TabItem value=\"runtime.tsx\" label=\"src/runtime.tsx\">\n\n```tsx\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = async ({ appContext }) => {\n  console.log(appContext);\n}\n\nexport default runtime;\n```\n\n</TabItem>\n\n</Tabs>\n\n\n把插件发布到 npm 后，需要把插件添加到构建配置中：\n\n```diff title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\n+ import myPlugin from '@ice/my-plugin';\n\nexport default defineConfig(() => ({\n  plugins: [\n+   myPlugin(),\n  ],\n}));\n```\n\n## 工程能力定制\n\n框架为定制工程能力提供了插件 API，方便开发者扩展和自定义能力。\n\n### `context`\n\n`context` 包含构建时的上下文信息：\n\n- `command` 当前运行命令，start/build/test\n- `commandArgs` script 命令执行时接受到的参数\n- `rootDir` 项目根目录\n- `userConfig` 用户在构建配置文件 ice.config.mts 中配置的内容\n- `pkg` 项目 package.json 中的内容\n- `webpack` webpack 实例，工程不建议安装多个 webpack 版本，可以从 `context.webpack` 上获取内置的 webpack 实例\n\n```ts\nconst plugin = () => ({\n  setup: ({ context }) => {\n    console.log('context: ', context);\n  },\n})\n\nexport default plugin;\n```\n### `onGetConfig`\n\n通过 `onGetConfig` 获取框架的工程配置，并可通过该 API 对配置进行自定义修改：\n\n```ts\nconst plugin = () => ({\n  name: 'plugin-test',\n  setup: ({ onGetConfig }) => {\n    onGetConfig((config) => {\n      config.alias = {\n        '@': './src/',\n      };\n    });\n  },\n});\n\nexport default plugin;\n```\n\n为了简化开发者的配置，通过 `onGetConfig` 修改配置项是基于底层工程工具的抽象，包括以下配置项：\n\n- `mode` 配置 `'none' | 'development' | 'production'` 以确定构建环境\n- `entry` 配置应用入口文件\n- `define` 注入到运行时的变量\n- `experimental` 实验性能力，同 [webpack.experiments](https://webpack.js.org/configuration/experiments/#experiments)\n- `outputDir` 构建输出目录\n- `externals` 同 [webpack.externals](https://webpack.js.org/configuration/externals/)\n- `outputAssetsPath` 静态资源输出目录，可以分别配置 js 和 css\n- `sourceMap` 源码调试映射，同 [webpack.devtool](https://webpack.js.org/configuration/devtool/)\n- `publicPath` 同 [webpack.output.publicPath](https://webpack.js.org/guides/public-path/#root)\n- `alias` 同 [webpack.resolve.alias](https://webpack.js.org/configuration/resolve/#resolvealias)\n- `hash` 配置资源输出文件名是否带 hash\n- `transformPlugins` [unplugin 标准](https://github.com/unjs/unplugin) 插件，该插件对于服务端和浏览器端产物同时生效\n- `transforms` 配置源码转化，支持对源码进行定制转化\n- `middlewares` development 开发阶段配置中间件\n- `proxy` 配置代理服务\n- `compileIncludes` 配置需要进行编译的三方依赖\n- `minify` 是否进行压缩\n- `minimizerOptions` 压缩配置项，基于 [minify-options](https://github.com/terser/terser#minify-options)\n- `analyzer` 开启产物分析\n- `https` 配置 https 服务\n- `port` 配置调试端口\n- `cacheDir` 配置构建缓存目录\n- `tsCheckerOptions` ts 类型检查 [配置项](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin)\n- `eslintOptions` eslint 检查 [配置项](https://www.npmjs.com/package/eslint-webpack-plugin)\n- `splitChunks` 是否分包\n- `assetsManifest` 是否生成资源 manifest\n- `devServer` 配置 webpack dev server [配置](https://webpack.js.org/configuration/dev-server/)\n- `fastRefresh` 是否开启 fast-refresh 能力\n- `configureWebpack` 如果上述快捷配置项不满足定制需求，可以通过 configureWebpack 进行自定义\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ onGetConfig }) => {\n    onGetConfig((config) => {\n      config.configureWebpack.push((webpackConfig) => {\n        webpackConfig.mode = 'development';\n        return webpackConfig;\n      })\n    });\n  },\n})\n```\n\n### `onHook`\n\n通过 `onHook` 监听命令构建时事件，`onHook` 注册的函数执行完成后才会执行后续操作，可以用于在命令运行中途插入插件想做的操作：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ onHook }) => {\n    onHook('before.build.load', () => {\n      // do something before build\n    });\n    onHook('after.build.compile', (stats) => {\n      // do something after build\n    });\n  },\n})\n```\n\n目前支持的生命周期如下：\n\n- `before.start.run` 构建命令 start 执行前，该阶段可以获取各项构建任务最终配置\n- `before.build.run` 构建命令 build 执行前，同 start\n- `after.start.compile` 构建命令 start 执行结束，该阶段可以获取构建的执行结果\n- `after.build.compile` 构建命令 build 执行结束，同 start\n- `after.start.devServer` dev 阶段的 server 服务启动后，该阶段可以获取相关 dev server 启动的 url 等信息\n\n> 每个周期可以获取的具体的参数类型可以参考 [TS 类型](https://github.com/alibaba/ice/blob/master/packages/ice/src/types/plugin.ts)。\n\n### `registerUserConfig`\n\n为用户配置文件 `ice.config.mts` 中添加自定义字段：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerUserConfig }) => {\n    registerUserConfig({\n      name: 'custom-key',\n      validation: 'boolean', // 可选，支持类型有 string, number, array, object, boolean\n      setConfig: () => {\n        // 该字段对于配置的影响，通过 onGetConfig 设置\n      },\n    });\n  },\n});\n```\n\n### `registerCliOption`\n\n为命令行启动添加自定义参数：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerCliOption }) => {\n    registerCliOption({\n      name: 'custom-option',\n      commands: ['start'], // 支持的扩展的命令\n      setConfig: () => {\n        // 该字段对于配置的影响，通过 onGetConfig 设置\n      },\n    });\n  },\n});\n```\n\n### `modifyUserConfig`\n\n修改用户配置：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ modifyUserConfig }) => {\n    modifyUserConfig('key', 'value'); // key, value 分别为用户配置文件键值对\n    // 例如：把 ssr 配置项修改为 true，以开启 SSR\n    modifyUserConfig('ssr', true);\n  },\n});\n```\n\n### `registerTask`\n\n添加自定义任务：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerTask }) => {\n    const config = {\n      sourceMap: true,\n    };\n    registerTask('task name', config); // name: Task名, config: 对于任务配置同 onGetConfig 配置项\n  },\n});\n```\n\n### `getAllTask`\n\n获取所有任务名称，内置主要任务名为 `web`：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ getAllTask }) => {\n    const tasks = getAllTask();\n    console.log(tasks);\n  },\n});\n```\n\n### `generator`\n\n支持生成或者修改模版，支持的 API 如下：\n\n#### `addRenderTemplate`\n\n添加模块生成目录：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addRenderTemplate({\n      template: '/path/to/template/dir',\n      targetDir: 'router',\n    }, {});\n  },\n});\n```\n\n#### `addRenderFile`\n\n添加模块生成文件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addRenderFile('/path/to/file.ts.ejs', 'folder/file.ts', {});\n  },\n});\n```\n\n#### `addExport`\n\n向 ice.js 里注册模块，实现 `import { request } from 'ice';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addExport({\n      source: './request/request',\n      exportName: 'request',\n    });\n  },\n});\n```\n\n#### `addExportTypes`\n\n向 ice.js 里注册类型，实现 `import type { Request } from 'ice';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addExportTypes({\n      source: './request/types',\n      specifier: '{ Request }',\n      exportName: 'Request',\n    });\n  },\n});\n```\n\n#### `addDataLoaderImport`\n\n向 ice.js 里注册 data-loader 的自定义发送方法，实现 `import { customFetch as fetcher } from 'custom-fetch';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addDataLoaderImport({\n      source: 'custom-fetch',\n      alias: {\n        customFetch: 'fetcher',\n      },\n      specifier: ['customFetch'],\n    });\n  },\n});\n```\n\n### `watch`\n\n支持统一的 watch 服务\n\n#### addEvent\n\n添加 watch 事件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ watch }) => {\n    watch.addEvent([\n      /src\\/global.(scss|less|css)/,\n      (event: string, filePath: string) => {},\n      'cssWatch',\n    ]);\n  },\n});\n```\n\n#### removeEvent\n\n移除 watch 事件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ watch }) => {\n    watch.removeEvent('cssWatch');\n  },\n});\n```\n\n## 运行时能力定制\n\n插件运行时可以定制框架的运行时能力：\n\n```ts\nimport type { Plugin } from '@ice/app/types';\nconst plugin: Plugin = () => ({\n  name: 'plugin-name',\n  runtime: '/absolute/path/to/runtime',\n});\n\nexport default plugin;\n```\n\n框架运行时指向的文件地址为一个 JS 模块，源码阶段推荐用 TS 进行开发：\n\n```ts\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = () => {};\nexport default runtime;\n```\n\n### `appContext`\n\nappContext 上包含框架相关上下文配置信息，主要包括：\n\n- `appConfig`：应用配置，详细内容可以参考 [应用入口](../basic/app)\n- `assetsManifest`：应用资讯配置信息\n- `routesData`：路由信息\n\n```ts\nconst runtime = ({ appContext }) => {\n  console.log(appContext);\n}\nexport default runtime;\n```\n\n### `addProvider`\n\n在应用最外层添加全局 Provider：\n\n```tsx\nexport default ({ addProvider }) => {\n  function Provider({ children }) {\n    return (\n      <div>{children}</div>\n    )\n  }\n\n  const StoreProvider = ({ children }) => {\n    return <Provider>{children}</Provider>;\n  };\n  addProvider(StoreProvider);\n};\n```\n\n### `addWrapper`\n\n为所有路由组件添加一层包裹：\n\n```tsx\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper }) => {\n  const PageWrapper = ({ children }) => {\n    useEffect(() => {\n      document.title = 'Hello ICE';\n    }, [])\n    return <>{children}</>\n  }\n\n  addWrapper(PageWrapper);\n\n  // 如果希望同样为 layout 组件添加可以添加第二个参数\n  addWrapper(PageWrapper, true);\n};\n```\n\n#### setAppRouter\n\n定制 Router 渲染方式\n\n```ts\nexport default ({ setAppRouter }) => {\n  // setAppRouter 入参为路由数组\n  const renderRouter = (routes) => () => {\n    return <div>route</div>;\n  };\n  setAppRouter(renderRouter);\n};\n```\n\n### `setRender`\n\n自定义渲染，默认使用 `react-dom` 进行渲染\n\n```ts\nimport ReactDOM from 'react-dom';\n\nexport default ({ setRender }) => {\n  // App: React 组件\n  // appMountNode: App 挂载点\n  const DOMRender = (appMountNode, App) => {\n    ReactDOM.render(<App />, appMountNode);\n  };\n  setRender(DOMRender);\n};\n```\n\n### `useData`\n\n获取页面组件的数据，一般配合 addWrapper 进行使用：\n\n```ts\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper, useData }) => {\n  const PageWrapper = (PageComponent) => {\n    const pageData = useData();\n    console.log(pageData);\n    return PageComponent;\n  };\n  addWrapper(PageWrapper);\n};\n```\n\n### `useConfig`\n\n获取页面组件的配置，一般配合 `addWrapper` 进行使用：\n\n```ts\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper, useConfig }) => {\n  const PageWrapper = (PageComponent) => {\n    const pageConfig = useConfig();\n    console.log(pageConfig);\n    return PageComponent;\n  };\n  addWrapper(PageWrapper);\n};\n```\n","website/docs/guide/plugins/plugin-list.md":"---\ntitle: 插件列表\norder: 2\n---\n\n## [@ice/plugin-miniapp](../miniapp/start)\n\n提供小程序的开发能力。\n\n## [@ice/plugin-auth](../advanced/auth)\n\n提供权限管理方案。\n\n## [@ice/plugin-store](../advanced/store)\n\n提供基于单向数据流的数据管理方案。\n\n## [@ice/plugin-css-assets-local](../advanced/css-assets-local)\n\n提供将 CSS 中的网络资源本地化的能力。\n\n## [@ice/plugin-antd](../advanced/antd)\n\n提供 antd 组件样式按需加载及主题配置能力。\n\n## [@ice/plugin-fusion](../advanced/fusion)\n\n提供 fusion 组件样式按需加载及主题配置能力。\n\n## [@ice/plugin-unocss](../advanced/unocss)\n\n提供 UnoCSS 原子化 CSS 能力。\n",".cursorrules (dragonruby-best-practices-cursorrules-prompt-file.mdc)":"---\ndescription: \"Cursor rules for DragonRuby development with best practices integration.\"\nglobs: **/*\nalwaysApply: false\n---\nYou are an expert game developer in Ruby using the DragonRuby Game Toolkit.\n\nCode Style and Structure\n\n- Write concise, idiomatic Ruby code with accurate examples.\n- Follow Ruby and DragonRuby conventions and best practices.\n- Use object-oriented and functional programming patterns as appropriate.\n- Prefer iteration and modularization over code duplication.\n- Use descriptive variable and method names (e.g., user_signed_in?, calculate_total).\n- Structure files according to DragonRuby conventions.\n\nNaming Conventions\n\n- Use snake_case for file names, method names, and variables.\n- Use CamelCase for class and module names.\n- Follow DragonRuby naming conventions.\n\nSyntax and Formatting\n\n- Follow the Ruby Style Guide (https://rubystyle.guide/)\n- Use Ruby's expressive syntax (e.g., unless, ||=, &.)\n- Prefer single quotes for strings unless interpolation is needed.\n\nError Handling and Validation\n\n- Use exceptions for exceptional cases, not for control flow.\n- Implement proper error logging and user-friendly messages.\n\nFollow the official DragonRuby Game Toolkit guides for best practices in routing, controllers, models, views, and other Rails components.\n"},"items":[{"name":"plugin-dev.md","path":"website/docs/guide/plugins/plugin-dev.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/website/docs/guide/plugins/plugin-dev.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: 开发插件\norder: 1\n---\n\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';\n\nice.js 底层基于 [build-scripts](https://github.com/ice-lab/build-scripts) 插件系统，在提供丰富的框架能力的基础上也可以让开发者可以在框架能力不满足诉求的情况下进行定制：\n\n- 定制修改框架构建配置\n- 支持在整个构建生命周期定制行为，比如项目启动前拉取某些资源\n- 支持扩展运行时能力，比如统一为路由组件增加鉴权逻辑（添加高阶组件）\n\n## 插件规范\n\nice.js 插件本质是一个 JS 模块，官方推荐以 TS 进行开发以获得良好的类型提示：\n\n```ts\nimport type { Plugin } from '@ice/app/types';\n\ninterface PluginOptions {\n  id: string;\n}\n\nconst plugin: Plugin<PluginOptions> = (options) => ({\n  // name 可选，插件名称\n  name: 'plugin-name',\n  // setup 必选，用于定制工程构建配置\n  setup: (pluginAPI) => { console.log(options.id) },\n  // runtime 可选，用于定制运行时配置\n  runtime: '/path/to/runtime',\n});\n\nexport default plugin;\n```\n\n### 开发本地插件\n\n推荐在项目根目录下新建一个插件目录，目录名比如叫 `my-plugin`。然后在该目录下新建以下文件：\n\n- `index.ts`：必选，插件入口，用于定制工程构建能力\n- `runtime.tsx`：可选，用于定制运行时能力\n\n<Tabs>\n\n<TabItem value=\"index.ts\" label=\"my-plugin/index.ts\">\n\n```ts\nimport * as path from 'path';\nimport type { Plugin } from '@ice/app/types';\n\nconst plugin: Plugin = () => ({\n  name: 'my-plugin',\n  setup: (pluginAPI) => {\n    console.log(pluginAPI);\n  },\n  // runtime 为可选，用于定制运行时配置。runtime 的值必须是一个绝对路径\n  runtime: path.join(__dirname, 'runtime.tsx'),\n});\n\nexport default plugin;\n```\n\n</TabItem>\n\n<TabItem value=\"runtime.tsx\" label=\"my-plugin/runtime.tsx\">\n\n```tsx\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = async ({ appContext }) => {\n  console.log(appContext);\n}\n\nexport default runtime;\n```\n\n</TabItem>\n\n</Tabs>\n\n开发完成后，我们需要把插件添加到应用的构建配置中：\n\n```diff title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\n+ import myPlugin from './my-plugin/index.js';\n\nexport default defineConfig(() => ({\n  plugins: [\n+   myPlugin(),\n  ],\n}))\n```\n\n### 发布插件到 npm \n\n:::tip\n插件模板可参考：https://github.com/ice-lab/icejs-plugin-template\n:::\n\n假设现在需要开发一个插件（包括修改工程配置和运行时配置），并发布到 npm 上。插件的文件目录如下：\n\n```md\n/xxx/@ice/my-plugin\n├── package.json\n├── src\n|  ├── index.ts       // 插件入口\n|  └── runtime.tsx    // 定制运行时能力\n```\n\n推荐以 [ES Module](https://nodejs.org/api/packages.html) 的方式编写插件，并使用 `exports` 字段导出插件入口和运行时配置：\n\n```json title=\"package.json\"\n{\n  \"name\": \"@ice/my-plugin\",\n  \"type\": \"module\",\n  \"exports\": {\n    \".\": {\n      \"types\": \"./esm/index.d.ts\",\n      \"import\": \"./esm/index.js\",\n      \"default\": \"./esm/index.js\"\n    },\n    \"./runtime\": {\n      \"types\": \"./esm/runtime/index.d.ts\",\n      \"import\": \"./esm/runtime/index.js\",\n      \"default\": \"./esm/runtime/index.js\"\n    }\n  },\n  \"main\": \"./esm/index.js\",\n  \"types\": \"./esm/index.d.ts\",\n  \"files\": [\n    \"esm\",\n    \"!esm/**/*.map\"\n  ],\n}\n```\n<Tabs>\n\n<TabItem value=\"index.ts\" label=\"src/index.ts\">\n\n```ts\nimport type { Plugin } from '@ice/app/types';\n\nconst plugin: Plugin = () => ({\n  name: '@ice/my-plugin',\n  setup: (pluginAPI) => {},\n  // runtime 的值需要配置为「模块引入路径」，对应上面 package.json 中 exports 里的 \"./runtime\" 导出\n  runtime: '@ice/my-plugin/runtime',\n});\n\nexport default plugin;\n```\n\n</TabItem>\n\n<TabItem value=\"runtime.tsx\" label=\"src/runtime.tsx\">\n\n```tsx\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = async ({ appContext }) => {\n  console.log(appContext);\n}\n\nexport default runtime;\n```\n\n</TabItem>\n\n</Tabs>\n\n\n把插件发布到 npm 后，需要把插件添加到构建配置中：\n\n```diff title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\n+ import myPlugin from '@ice/my-plugin';\n\nexport default defineConfig(() => ({\n  plugins: [\n+   myPlugin(),\n  ],\n}));\n```\n\n## 工程能力定制\n\n框架为定制工程能力提供了插件 API，方便开发者扩展和自定义能力。\n\n### `context`\n\n`context` 包含构建时的上下文信息：\n\n- `command` 当前运行命令，start/build/test\n- `commandArgs` script 命令执行时接受到的参数\n- `rootDir` 项目根目录\n- `userConfig` 用户在构建配置文件 ice.config.mts 中配置的内容\n- `pkg` 项目 package.json 中的内容\n- `webpack` webpack 实例，工程不建议安装多个 webpack 版本，可以从 `context.webpack` 上获取内置的 webpack 实例\n\n```ts\nconst plugin = () => ({\n  setup: ({ context }) => {\n    console.log('context: ', context);\n  },\n})\n\nexport default plugin;\n```\n### `onGetConfig`\n\n通过 `onGetConfig` 获取框架的工程配置，并可通过该 API 对配置进行自定义修改：\n\n```ts\nconst plugin = () => ({\n  name: 'plugin-test',\n  setup: ({ onGetConfig }) => {\n    onGetConfig((config) => {\n      config.alias = {\n        '@': './src/',\n      };\n    });\n  },\n});\n\nexport default plugin;\n```\n\n为了简化开发者的配置，通过 `onGetConfig` 修改配置项是基于底层工程工具的抽象，包括以下配置项：\n\n- `mode` 配置 `'none' | 'development' | 'production'` 以确定构建环境\n- `entry` 配置应用入口文件\n- `define` 注入到运行时的变量\n- `experimental` 实验性能力，同 [webpack.experiments](https://webpack.js.org/configuration/experiments/#experiments)\n- `outputDir` 构建输出目录\n- `externals` 同 [webpack.externals](https://webpack.js.org/configuration/externals/)\n- `outputAssetsPath` 静态资源输出目录，可以分别配置 js 和 css\n- `sourceMap` 源码调试映射，同 [webpack.devtool](https://webpack.js.org/configuration/devtool/)\n- `publicPath` 同 [webpack.output.publicPath](https://webpack.js.org/guides/public-path/#root)\n- `alias` 同 [webpack.resolve.alias](https://webpack.js.org/configuration/resolve/#resolvealias)\n- `hash` 配置资源输出文件名是否带 hash\n- `transformPlugins` [unplugin 标准](https://github.com/unjs/unplugin) 插件，该插件对于服务端和浏览器端产物同时生效\n- `transforms` 配置源码转化，支持对源码进行定制转化\n- `middlewares` development 开发阶段配置中间件\n- `proxy` 配置代理服务\n- `compileIncludes` 配置需要进行编译的三方依赖\n- `minify` 是否进行压缩\n- `minimizerOptions` 压缩配置项，基于 [minify-options](https://github.com/terser/terser#minify-options)\n- `analyzer` 开启产物分析\n- `https` 配置 https 服务\n- `port` 配置调试端口\n- `cacheDir` 配置构建缓存目录\n- `tsCheckerOptions` ts 类型检查 [配置项](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin)\n- `eslintOptions` eslint 检查 [配置项](https://www.npmjs.com/package/eslint-webpack-plugin)\n- `splitChunks` 是否分包\n- `assetsManifest` 是否生成资源 manifest\n- `devServer` 配置 webpack dev server [配置](https://webpack.js.org/configuration/dev-server/)\n- `fastRefresh` 是否开启 fast-refresh 能力\n- `configureWebpack` 如果上述快捷配置项不满足定制需求，可以通过 configureWebpack 进行自定义\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ onGetConfig }) => {\n    onGetConfig((config) => {\n      config.configureWebpack.push((webpackConfig) => {\n        webpackConfig.mode = 'development';\n        return webpackConfig;\n      })\n    });\n  },\n})\n```\n\n### `onHook`\n\n通过 `onHook` 监听命令构建时事件，`onHook` 注册的函数执行完成后才会执行后续操作，可以用于在命令运行中途插入插件想做的操作：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ onHook }) => {\n    onHook('before.build.load', () => {\n      // do something before build\n    });\n    onHook('after.build.compile', (stats) => {\n      // do something after build\n    });\n  },\n})\n```\n\n目前支持的生命周期如下：\n\n- `before.start.run` 构建命令 start 执行前，该阶段可以获取各项构建任务最终配置\n- `before.build.run` 构建命令 build 执行前，同 start\n- `after.start.compile` 构建命令 start 执行结束，该阶段可以获取构建的执行结果\n- `after.build.compile` 构建命令 build 执行结束，同 start\n- `after.start.devServer` dev 阶段的 server 服务启动后，该阶段可以获取相关 dev server 启动的 url 等信息\n\n> 每个周期可以获取的具体的参数类型可以参考 [TS 类型](https://github.com/alibaba/ice/blob/master/packages/ice/src/types/plugin.ts)。\n\n### `registerUserConfig`\n\n为用户配置文件 `ice.config.mts` 中添加自定义字段：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerUserConfig }) => {\n    registerUserConfig({\n      name: 'custom-key',\n      validation: 'boolean', // 可选，支持类型有 string, number, array, object, boolean\n      setConfig: () => {\n        // 该字段对于配置的影响，通过 onGetConfig 设置\n      },\n    });\n  },\n});\n```\n\n### `registerCliOption`\n\n为命令行启动添加自定义参数：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerCliOption }) => {\n    registerCliOption({\n      name: 'custom-option',\n      commands: ['start'], // 支持的扩展的命令\n      setConfig: () => {\n        // 该字段对于配置的影响，通过 onGetConfig 设置\n      },\n    });\n  },\n});\n```\n\n### `modifyUserConfig`\n\n修改用户配置：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ modifyUserConfig }) => {\n    modifyUserConfig('key', 'value'); // key, value 分别为用户配置文件键值对\n    // 例如：把 ssr 配置项修改为 true，以开启 SSR\n    modifyUserConfig('ssr', true);\n  },\n});\n```\n\n### `registerTask`\n\n添加自定义任务：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerTask }) => {\n    const config = {\n      sourceMap: true,\n    };\n    registerTask('task name', config); // name: Task名, config: 对于任务配置同 onGetConfig 配置项\n  },\n});\n```\n\n### `getAllTask`\n\n获取所有任务名称，内置主要任务名为 `web`：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ getAllTask }) => {\n    const tasks = getAllTask();\n    console.log(tasks);\n  },\n});\n```\n\n### `generator`\n\n支持生成或者修改模版，支持的 API 如下：\n\n#### `addRenderTemplate`\n\n添加模块生成目录：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addRenderTemplate({\n      template: '/path/to/template/dir',\n      targetDir: 'router',\n    }, {});\n  },\n});\n```\n\n#### `addRenderFile`\n\n添加模块生成文件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addRenderFile('/path/to/file.ts.ejs', 'folder/file.ts', {});\n  },\n});\n```\n\n#### `addExport`\n\n向 ice.js 里注册模块，实现 `import { request } from 'ice';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addExport({\n      source: './request/request',\n      exportName: 'request',\n    });\n  },\n});\n```\n\n#### `addExportTypes`\n\n向 ice.js 里注册类型，实现 `import type { Request } from 'ice';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addExportTypes({\n      source: './request/types',\n      specifier: '{ Request }',\n      exportName: 'Request',\n    });\n  },\n});\n```\n\n#### `addDataLoaderImport`\n\n向 ice.js 里注册 data-loader 的自定义发送方法，实现 `import { customFetch as fetcher } from 'custom-fetch';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addDataLoaderImport({\n      source: 'custom-fetch',\n      alias: {\n        customFetch: 'fetcher',\n      },\n      specifier: ['customFetch'],\n    });\n  },\n});\n```\n\n### `watch`\n\n支持统一的 watch 服务\n\n#### addEvent\n\n添加 watch 事件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ watch }) => {\n    watch.addEvent([\n      /src\\/global.(scss|less|css)/,\n      (event: string, filePath: string) => {},\n      'cssWatch',\n    ]);\n  },\n});\n```\n\n#### removeEvent\n\n移除 watch 事件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ watch }) => {\n    watch.removeEvent('cssWatch');\n  },\n});\n```\n\n## 运行时能力定制\n\n插件运行时可以定制框架的运行时能力：\n\n```ts\nimport type { Plugin } from '@ice/app/types';\nconst plugin: Plugin = () => ({\n  name: 'plugin-name',\n  runtime: '/absolute/path/to/runtime',\n});\n\nexport default plugin;\n```\n\n框架运行时指向的文件地址为一个 JS 模块，源码阶段推荐用 TS 进行开发：\n\n```ts\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = () => {};\nexport default runtime;\n```\n\n### `appContext`\n\nappContext 上包含框架相关上下文配置信息，主要包括：\n\n- `appConfig`：应用配置，详细内容可以参考 [应用入口](../basic/app)\n- `assetsManifest`：应用资讯配置信息\n- `routesData`：路由信息\n\n```ts\nconst runtime = ({ appContext }) => {\n  console.log(appContext);\n}\nexport default runtime;\n```\n\n### `addProvider`\n\n在应用最外层添加全局 Provider：\n\n```tsx\nexport default ({ addProvider }) => {\n  function Provider({ children }) {\n    return (\n      <div>{children}</div>\n    )\n  }\n\n  const StoreProvider = ({ children }) => {\n    return <Provider>{children}</Provider>;\n  };\n  addProvider(StoreProvider);\n};\n```\n\n### `addWrapper`\n\n为所有路由组件添加一层包裹：\n\n```tsx\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper }) => {\n  const PageWrapper = ({ children }) => {\n    useEffect(() => {\n      document.title = 'Hello ICE';\n    }, [])\n    return <>{children}</>\n  }\n\n  addWrapper(PageWrapper);\n\n  // 如果希望同样为 layout 组件添加可以添加第二个参数\n  addWrapper(PageWrapper, true);\n};\n```\n\n#### setAppRouter\n\n定制 Router 渲染方式\n\n```ts\nexport default ({ setAppRouter }) => {\n  // setAppRouter 入参为路由数组\n  const renderRouter = (routes) => () => {\n    return <div>route</div>;\n  };\n  setAppRouter(renderRouter);\n};\n```\n\n### `setRender`\n\n自定义渲染，默认使用 `react-dom` 进行渲染\n\n```ts\nimport ReactDOM from 'react-dom';\n\nexport default ({ setRender }) => {\n  // App: React 组件\n  // appMountNode: App 挂载点\n  const DOMRender = (appMountNode, App) => {\n    ReactDOM.render(<App />, appMountNode);\n  };\n  setRender(DOMRender);\n};\n```\n\n### `useData`\n\n获取页面组件的数据，一般配合 addWrapper 进行使用：\n\n```ts\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper, useData }) => {\n  const PageWrapper = (PageComponent) => {\n    const pageData = useData();\n    console.log(pageData);\n    return PageComponent;\n  };\n  addWrapper(PageWrapper);\n};\n```\n\n### `useConfig`\n\n获取页面组件的配置，一般配合 `addWrapper` 进行使用：\n\n```ts\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper, useConfig }) => {\n  const PageWrapper = (PageComponent) => {\n    const pageConfig = useConfig();\n    console.log(pageConfig);\n    return PageComponent;\n  };\n  addWrapper(PageWrapper);\n};\n```\n","frontmatter":{"title":"开发插件","order":1},"isInternal":false,"tokens":4453,"sizeBytes":15642},{"name":"plugin-list.md","path":"website/docs/guide/plugins/plugin-list.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/website/docs/guide/plugins/plugin-list.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: 插件列表\norder: 2\n---\n\n## [@ice/plugin-miniapp](../miniapp/start)\n\n提供小程序的开发能力。\n\n## [@ice/plugin-auth](../advanced/auth)\n\n提供权限管理方案。\n\n## [@ice/plugin-store](../advanced/store)\n\n提供基于单向数据流的数据管理方案。\n\n## [@ice/plugin-css-assets-local](../advanced/css-assets-local)\n\n提供将 CSS 中的网络资源本地化的能力。\n\n## [@ice/plugin-antd](../advanced/antd)\n\n提供 antd 组件样式按需加载及主题配置能力。\n\n## [@ice/plugin-fusion](../advanced/fusion)\n\n提供 fusion 组件样式按需加载及主题配置能力。\n\n## [@ice/plugin-unocss](../advanced/unocss)\n\n提供 UnoCSS 原子化 CSS 能力。\n","frontmatter":{"title":"插件列表","order":2},"isInternal":false,"tokens":193,"sizeBytes":698},{"name":"README.md","path":"packages/appear/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/appear/README.md","title":"appear Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/appear\n\nReact component for supporting `appear` and `disappear` events.  \n\n## Usage\n\n```bash\nnpm i @ice/appear -S\n```\n\n```jsx\nimport VisibilityChange from '@ice/appear';\n\nexport default function Home() {\n  return (\n    <VisibilityChange\n      onAppear={() => {\n        console.log('Something has been shown.')\n      }}\n      onDisappear={() => {\n        console.log('Something has disappeard.')\n      }}\n    >\n      Anything you want to show.\n    </VisibilityChange>\n  );\n}\n```\n","isInternal":false,"tokens":117,"sizeBytes":485},{"name":"README.md","path":"packages/bundles/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/bundles/README.md","title":"bundles Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/bundles\n\nPrepacked bundles for ice.js.\n\n**DO NOT USE THIS PACKAGE DIRECTLY.**\n","isInternal":false,"tokens":23,"sizeBytes":85},{"name":"README.md","path":"packages/cache-canvas/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/cache-canvas/README.md","title":"cache-canvas Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/cache-canvas\n\nReact component for supporting canvas for cache.\n\n## Usage\n\n```bash\nnpm i @ice/cache-canvas -S\n```\n\n```jsx\nimport MainGame from './game'; // eva.js 的封装\n\nconst GAME_CANVAS = 'game-canvas';\n\nexport default (props) => {\n  useEffect(() => {\n    const gameEl = document.getElementById(GAME_CANVAS);\n    new MainGame(gameEl, getGameHeight());\n  }, []);\n\n  const init = () => {\n     return new Promise((resolve) => {\n      const canvas: HTMLCanvasElement | null = document.getElementById(GAME_CANVAS_ID) as HTMLCanvasElement;\n      if (canvas && typeof canvas.getContext === 'function') {\n        let ctx: CanvasRenderingContext2D | null = canvas.getContext('2d');\n\n        ctx?.fillRect(25, 25, 100, 100);\n        ctx?.clearRect(45, 45, 60, 60);\n        ctx?.strokeRect(50, 50, 50, 50);\n      }\n\n      setTimeout(() => {\n        console.log('canvas paint ready!');\n        resolve(true);\n      }, 5000);\n    });\n  }\n\n  return (\n    <>\n       <CanvasCache id={GAME_CANVAS} useCache={false} init={init} />\n    </>\n  );\n};\n```\n","isInternal":false,"tokens":281,"sizeBytes":1045},{"name":"README.md","path":"packages/create-ice/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/create-ice/README.md","title":"create-ice Documentation","category":"plugin-manifest","format":"markdown","content":"# create-ice\n\ncreate ice.js project.\n\n## Usage\n\n```bash\n# use npm\n$ npm create ice <projectName>\n# use yarn\n$ yarn create ice <projectName>\n# use pnpm\n$ pnpm create ice <projectName>\n\n# or with template\n# use npm\n$ npm create ice <projectName> --template <template>\n# use yarn\n$ yarn create ice <projectName> --template <template>\n# use pnpm\n$ pnpm create ice <projectName> --template <template>\n\n$ cd <projectName>\n$ npm install\n$ npm start\n```\n","isInternal":false,"tokens":128,"sizeBytes":446},{"name":"README.md","path":"packages/ice/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/ice/README.md","title":"ice Documentation","category":"plugin-manifest","format":"markdown","content":"# ice.js\n\nice.js is the best user experience for web developing based on React.\nThis package includes scripts and configuration used by web framework `ice`.\n\n## Install\n\n```bash\n$ npm i @ice/app -D\n```\n\n## usage\n\n```json\n{\n  \"name\": \"my-app\",\n  \"devDependencies\": {\n    \"@ice/app\": \"^3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"ice start\",\n    \"build\": \"ice build\"\n  }\n}\n```\n\n## Command line interface\n\n```bash\nUsage: ice <command> [options]\n\nOptions:\n  -V, --version    output the version number\n  -h, --help       output usage information\n\nCommands:\n  build [options]  build project\n  start [options]  start dev server\n```\n\n## Open Source\n\nOpen Source with ❤️ and MIT License.\n","isInternal":false,"tokens":187,"sizeBytes":680},{"name":"README.md","path":"packages/jsx-runtime/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/jsx-runtime/README.md","title":"jsx-runtime Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/jsx-runtime\n\nJSX runtime for ice.js.\n\n## Install\n\n```bash\n$ npm i @ice/jsx-runtime --save\n```\n","isInternal":false,"tokens":33,"sizeBytes":101},{"name":"README.md","path":"packages/miniapp-html-styles/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/miniapp-html-styles/README.md","title":"miniapp-html-styles Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/miniapp-html-styles\n\n> Forked from [@tarojs/taro](https://github.com/NervJS/taro/tree/next/packages/taro) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\n## html.css\n\nHTML4 built-in styles for compatibility with HTML tag styles.\n\n## html5.css\n\nHTML5 built-in styles for compatibility with HTML tag styles.\n","isInternal":false,"tokens":97,"sizeBytes":370},{"name":"README.md","path":"packages/miniapp-loader/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/miniapp-loader/README.md","title":"miniapp-loader Documentation","category":"plugin-manifest","format":"markdown","content":"# `@ice/miniapp-loader`\n\n> Forked from [@tarojs/loader](https://github.com/NervJS/taro/tree/next/packages/taro-loader) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nWebpack loader exposed to ice.js for building applet artifacts, including the following `loader`:\n\n## page\n\nMiniapp usage only. Call the `createPageConfig` method of `@ice/miniapp-runtime` in the miniapp page file to create an object accepted by the miniapp `Page` constructor.\n","isInternal":false,"tokens":127,"sizeBytes":502},{"name":"README.md","path":"packages/miniapp-react-dom/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/miniapp-react-dom/README.md","title":"miniapp-react-dom Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/miniapp-react-dom\n\n> Forked from [@tarojs/react](https://github.com/NervJS/taro/tree/next/packages/taro-react) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nA React renderer for mini-programs based on `react-reconciler`, connected to the DOM instance of `@ice/miniapp-runtime`, equivalent to the mini-program version of `react-dom`, and the exposed API is also the same as `react-dom` consistent.\n","isInternal":false,"tokens":118,"sizeBytes":463},{"name":"README.md","path":"packages/miniapp-runtime/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/miniapp-runtime/README.md","title":"miniapp-runtime Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/miniapp-runtime\n\n> Forked from [@tarojs/runtime](https://github.com/NervJS/taro/tree/next/packages/taro-runtime) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nice.js miniapp runtime. Connect the framework (DSL) rendering mechanism to the miniapp rendering mechanism, and connect the miniapp routing and life cycle to the corresponding life cycle of the framework\n\n## Core API\n\n### createPageConfig()\n\nExpose to `@ice/miniapp-loader/page` calls, called in the miniapp page file, to create a miniapp page specification object accepted by the miniapp `Page` constructor.\n\n### window\n\nAn object that imitates the browser's `window` implementation on the miniapp side, and returns the browser's own `window` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n### navigator\n\nAn object that imitates the browser's `navigator` implementation on the miniapp side, and returns the browser's own `navigator` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n###document\n\nAn object that imitates the browser's `document` implementation on the miniapp side, and returns the browser's own `document` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n### Current\n\nGlobal variables exposed to developers currently have three properties:\n\n* `Current.app`, returns the current miniapp application instance, which can be used to call the miniapp specification life cycle.\n* `Current.page`, returns the current miniapp page instance, which can be used to call the miniapp specification life cycle.\n* `Current.router`, returns the current miniapp routing information.\n","isInternal":false,"tokens":431,"sizeBytes":2029},{"name":"README.md","path":"packages/plugin-antd/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-antd/README.md","title":"plugin-antd Documentation","category":"plugin-manifest","format":"markdown","content":"# `@ice/plugin-antd`\n\nAn ice.js plugin to use `antd` components.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport antd from '@ice/plugin-antd';\n\nexport default defineConfig(() => ({\n  plugins: [antd({\n    dark: true,\n    compact: true,\n    theme: {\n      'primary-color': '#fd8',\n    },\n  })],\n}));\n```\n","isInternal":false,"tokens":89,"sizeBytes":319},{"name":"README.md","path":"packages/plugin-auth/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-auth/README.md","title":"plugin-auth Documentation","category":"plugin-manifest","format":"markdown","content":"# `@ice/plugin-auth`\n\nAn ice.js plugin to enable auth ability.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport auth from '@ice/plugin-auth';\n\nexport default defineConfig(() => ({\n  plugins: [\n    auth(),\n  ],\n}));\n```\n\nMore details to see https://v3.ice.work/docs/guide/advanced/auth\n","isInternal":false,"tokens":77,"sizeBytes":301},{"name":"README.md","path":"packages/plugin-cavans/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-cavans/README.md","title":"plugin-cavans Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-canvas\n\nAn ice.js plugin for canvas projects.\n\n## Usage\n\nAdd plugin in `ice.config.mts`:\n\n```js\nimport { defineConfig } from 'ice';\nimport canvasPlugin from '@ice/plugin-canvas';\n\nexport default defineConfig(() => ({\n  plugins: [canvasPlugin({ /* options */ })],\n}));\n```  \n","isInternal":false,"tokens":72,"sizeBytes":288},{"name":"README.md","path":"packages/plugin-css-assets-local/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-css-assets-local/README.md","title":"plugin-css-assets-local Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-css-assets-local\n\nAn ice.js plugin for localize css assets resource.\n\n## Install\n\n```bash\nnpm i -D @ice/plugin-css-assets-local\n```\n\n## Usage\n\nAdd plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport cssAssetsLocal from '@ice/plugin-css-assets-local';\n\nexport default defineConfig(() => ({\n  plugins: [\n    cssAssetsLocal(),\n  ],\n}));\n```\n\nAfter running `npm run build`, you can see asset resources will be downloaded to your local disk.\n\n## Options\n\n### `outputPath`\n\nThe assets resource output path.\n\n- Type: `string`\n- Default: `\"assets\"`\n\n### `relativeCssPath`\n\nThe asset paths relative to the css file path.\n\n- Type: `string`\n- Default: `\"../\"`\n\n### `enableInDev`\n\nWhether enable the plugin in dev or not.\n\n- Type: `boolean`\n- Default: `false`\n","isInternal":false,"tokens":204,"sizeBytes":821},{"name":"README.md","path":"packages/plugin-externals/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-externals/README.md","title":"plugin-externals Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-externals\n\n`@ice/plugin-externals` is a ice.js plugin. It provides a simple way to add externals support to your application.\n\n## Install\n\n```bash\n$ npm i @ice/plugin-externals --save-dev\n```\n\n## Usage\n\nSet preset `react` to external react in a easy way.\n\n```js\nimport { defineConfig } from '@ice/app';\nimport externals from '@ice/plugin-externals';\n\nexport default defineConfig(() => ({\n  plugins: [externals({ preset: 'react' })]\n}));\n```\n\nFramework will auto add externals of `react` and `react-dom` to your application, and the cdn url will be inject to the document by default.\n\nAlso, you can custom externals and cdn url by yourself:\n\n```js\nimport { defineConfig } from '@ice/app';\nimport externals from '@ice/plugin-externals';\n\nexport default defineConfig(() => ({\n  plugins: [externals({\n    externals: {\n      antd: 'Antd',\n    },\n    cdnMap: {\n      antd: {\n        development: 'https://unpkg.com/antd/dist/antd.js',\n        production: 'https://unpkg.com/antd/dist/antd.min.js',\n      }\n    }\n  })]\n}));\n```\n","isInternal":false,"tokens":275,"sizeBytes":1035},{"name":"README.md","path":"packages/plugin-fusion/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-fusion/README.md","title":"plugin-fusion Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-fusion\n\nice.js plugin for using fusion components.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport fusion from '@ice/plugin-fusion';\n\nexport default defineConfig(() => ({\n  plugins: [fusion({\n    importStyle: true,\n    themePackage: '@alifd/theme-design-pro',\n    theme: {\n      'primary-color': '#fff',\n    },\n  })],\n}));\n```\n\n## Options\n\n- importStyle: Fusion component styles will be automatically imported after enabling.\n- themePackage: Fusion component theme package configuration, if set to an array, multi-theme capability is enabled.\n- theme: theme configuration, overwrite existing themes by setting sass variables.\n","isInternal":false,"tokens":144,"sizeBytes":657},{"name":"README.md","path":"packages/plugin-i18n/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-i18n/README.md","title":"plugin-i18n Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-i18n\n\n组件功能描述\n\n## Install\n\n```bash\n$ npm i @ice/plugin-i18n --save-dev\n```\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport i18n from '@ice/plugin-i18n';\n\nexport default defineConfig({\n  plugins: [\n    i18n({\n      locales: ['zh-CN', 'en-US'],\n      defaultLocale: 'zh-CN',\n    }),\n  ],\n});\n```\n\n## Options\n\n### `locales`\n\n- **type:** `string[]`\n\nThe locales you want to support in your app. This option is required.\n\n### defaultLocale\n\n- **type:** `string`\n\nThe default locale you want to be used when visiting a non-locale prefixed path. This option is required.\n\n### autoRedirect\n\n- **type:** `boolean`\n- **default:** `true`\n\nRedirect to the preferred locale automatically. This option should be used with the middleware. If you deploy your application in production, you should read the [example]() for more detail.\n","isInternal":false,"tokens":218,"sizeBytes":861},{"name":"README.md","path":"packages/plugin-icestark/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-icestark/README.md","title":"plugin-icestark Documentation","category":"plugin-manifest","format":"markdown","content":"# plugin-icestark\n\n> Easy use [`icestark`](https://github.com/ice-lab/icestark) in [icejs](https://github.com/alibaba/ice).\n\n## Usage\n\n### Install\n\n```bash\nnpm i -D @ice/plugin-icestark\n```\n\n### Framework Application\n\nConfigurate plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport icestark from '@ice/plugin-icestark';\n\nexport default defineConfig(() => ({\n  plugins: [\n    icestark({ type: 'framework' }),\n  ],\n}));\n```\n\nThrough export `icestark` configuration of your framework application.\n\n```ts title=\"src/app.ts\"\nimport { defineFrameworkConfig } from '@ice/plugin-icestark/esm/types';\n\nexport const icestark = defineFrameworkConfig(() => ({\n  getApps: () => ([]),\n}));\n```\n\n**Options:**\n - `getApps`: get sub-application information, support async function\n - `appRouter`\n   - `ErrorComponent`: error component\n   - `LoadingComponent`: loading component\n   - `NotFoundComponent`: 404 not found component\n   - `shouldAssetsRemove`: check assets if it should be removed\n - `layout`: specify Framework application Layout\n\n### Sub-application\n\nConfigurate plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport icestark from '@ice/plugin-icestark';\n\nexport default defineConfig(() => ({\n  plugins: [\n    icestark({ type: 'child' }),\n  ],\n}));\n```\n\nmodify `icestark` exports in `src/app.ts`:\n\n```ts title=\"src/app.ts\"\n// app.ts\nimport { defineChildConfig } from '@ice/plugin-icestark/esm/types';\n\nexport const icestark = defineChildConfig(() => ({\n  mount: () => {},\n  unmount: () => {},\n}));\n```\n\n**Options:**\n - `mount`: excute before Sub-application mounted\n - `unmount`: excute after Sub-application unmounted","isInternal":false,"tokens":452,"sizeBytes":1730},{"name":"README.md","path":"packages/plugin-intl/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-intl/README.md","title":"plugin-intl Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-intl\n\n`@ice/plugin-intl` is a ice.js plugin. It provides a simple way to add internationalization support to your application.\n\n> `@ice/plugin-intl` is based on `react-intl`.\n\n## Install\n\n```bash\n$ npm i @ice/plugin-intl --save-dev\n```\n\n## Usage\n\nDefine the plugin in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport intl from '@ice/plugin-intl';\n\nexport default defineConfig({\n  plugins: [\n    intl(),\n  ],\n});\n```\n\nDefine locale config in `src/app.ts`:\n\n```ts\nimport { defineAppConfig } from 'ice';\nimport type { LocaleConfig } from '@ice/plugin-intl/types';\n\nexport default defineAppConfig(() => ({}));\n\nexport const locale: LocaleConfig = {\n  // Cutomize getLocale method and other options supported by react-intl.\n  getLocale: () => 'en-US',\n};\n```\n\n## Locales\n\nLocales are defined in the `src/locales` directory. Each locale is defined in a separate file, with the locale name as the file name. For example, `en-US.ts`:\n\n```ts\nexport default {\n  'app.title': 'My Application',\n  'app.welcome': 'Welcome to my application!',\n};\n```\n\nUse the `useIntl` hook to access the current locale:\n\n```tsx\nimport { useIntl } from 'ice';\n\nexport default function Home() {\n  const intl = useIntl();\n  console.log(intl.formatMessage({ id: 'new' }));\n  return <h1>home</h1>;\n}\n```\n\nUse the `intl` function to access the current locale:\n\n```tsx\nimport { intl } from 'ice';\n\nfunction alertMessage() {\n  alert(intl.formatMessage({ id: 'app.welcome' }));\n}\n```\n\n## Simple mode\n\nSimple mode for remove the dependency of `react-intl`:\n\nDefine the plugin in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport intl from '@ice/plugin-intl';\n\nexport default defineConfig({\n  plugins: [\n    // Add intlSolution to remove the dependency of react-intl\n    intl({ intlSolution: 'simple' }),\n  ],\n});\n```\n\nWhen you use the `simple` mode, you can only use the `intl.formateMessage` function to get the locale message:\n\n```tsx\nimport { ice } from 'ice';\n\nexport default function Home() {\n  console.log(intl.formatMessage({ id: 'new' }));\n  return <h1>home</h1>;\n}\n```\n\nFunction `intl.formatMessage` is limited, you can only use the syntax below to get the locale message:\n\nSimple Usage:\n\n```tsx\nintl.formatMessage({ id: 'app.welcome', defaultMessage: 'Welcome to my application!' });\nintl.formatMessage('app.welcome');\n```\n\nWith Variables:\n\n```tsx\nintl.formatMessage({ id: 'app.welcome' }, { name: 'icejs' });\n```\n\n> Caution: the message Syntax only support the pattern like `{name}`.\n","isInternal":false,"tokens":656,"sizeBytes":2517},{"name":"README.md","path":"packages/plugin-jsx-plus/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-jsx-plus/README.md","title":"plugin-jsx-plus Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-jsx-plus\n\nThis plugin adds support for JSX+ syntax to the ice.js.\n\n## Definition of JSX Plus\n\nhttps://github.com/jsx-plus/jsx-plus\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport jsxplus from '@ice/plugin-jsx-plus';\n\nexport default defineConfig(() => ({\n  plugins: [\n    jsxplus({\n      // options\n    }),\n  ],\n}));\n```\n\n## Options\n\n- `include`: `(string | RegExp)[]`\n  - Files to be included.\n  - Default: the project `src` directory.\n- `exclude`: `(string | RegExp)[]`\n  - Files to be excluded.\n  - Default: `[]`\n- `extensions`: `string[]`\n  - File extensions to be processed.\n  - Default: `['.jsx', '.tsx']`\n\n> If `include` and `exclude` are both set, `exclude` will be priority executed.\n","isInternal":false,"tokens":198,"sizeBytes":723},{"name":"README.md","path":"packages/plugin-miniapp/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-miniapp/README.md","title":"plugin-miniapp Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-miniapp\n\n> Forked from [taro](https://github.com/NervJS/taro) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/main/LICENSE\n\nice.js plugin to enable miniapp development.\n\nSee [documentation](https://v3.ice.work) for more details.\n","isInternal":false,"tokens":76,"sizeBytes":286},{"name":"README.md","path":"packages/plugin-moment-locales/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-moment-locales/README.md","title":"plugin-moment-locales Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-moment-locales\n\nice.js Plugin for load moment locales and reduce size of moment.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport moment from '@ice/plugin-moment-locales';\n\nexport default defineConfig(() => ({\n  plugins: [\n    moment({\n      locales: ['zh-CN'],\n    }),\n  ],\n}));\n```\n","isInternal":false,"tokens":77,"sizeBytes":314},{"name":"README.md","path":"packages/plugin-pha/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-pha/README.md","title":"plugin-pha Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-pha\n\nAn ice.js plugin to enable PHA features.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport pha from '@ice/plugin-pha';\n\nexport default defineConfig(() => ({\n  plugins: [pha()],\n}));\n```\n","isInternal":false,"tokens":59,"sizeBytes":220},{"name":"README.md","path":"packages/plugin-rax-compat/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-rax-compat/README.md","title":"plugin-rax-compat Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-rax-compat\n\nAn ice.js plugin for migrating `rax-app` projects.\n\n## Usage\n\nAdd plugin in `ice.config.mts`:\n\n```js\nimport { defineConfig } from 'ice';\nimport compatRax from '@ice/plugin-rax-compat';\n\nexport default defineConfig(() => ({\n  plugins: [compatRax({ /* options */ })],\n}));\n```\n\n## Options\n\n### `inlineStyle`\n\n- Default: `false`.\n- Enable stylesheet loader to import CSS files.\n\n### `cssModule`\n\n- Default: `true`\n- When `inlineStyle` enabled and `cssModule` disabled, process CSS Module files to inline included styles(not recommended).\n\n### `legacy`\n\n- Default: `false`\n- Enable legacy way to import rax as namespace, like `v0.6`:\n\n```typescript\nimport Rax from 'rax';\n\nRax.createContext();\n```\n\n## 说明\n\n这个插件将会处理这些兼容逻辑：\n\n- 类型定义，Rax 中的类型定义来自于 React 16.8 前，与 React 18 的类型定义存在一些差异。\n  - 这个插件会新增一个对 Rax namespace 进行声明的 .d.ts 文件，内部使用 React 类型定义来进行声明。\n\n- 别名，将组成 rax 核心逻辑的 rax- 包，如 rax-children 等，映射到 rax-compat 的内部实现。\n\n  - 同时，在启用 legacy 模式时，会将 rax 映射到 rax-compat-legacy-exports.ts，此文件支持了 Rax.createContext 这样的使用方式（Rax v0.6.x）。\n\n- JSX，插件内部将基于源码类型来调整 swc 的编译配置。\n\n  - 在源码中使用了 `@jsx createElement` annotation 时，将设置 jsx runtime 为 classic。\n  - 在源码导入了 rax 包时，将设置 importSource 为 rax-compat/runtime（与 React 18 保持一致）。\n\n- 样式，在启用 inlineStyle 时，插件内部将额外处理行内样式逻辑。\n\n  - 首先，JSXClassNameTransformer 会将源码中的 `<div className=\"header\" />` 的写法转换为 `<div style={styleSheet.header} />`。\n        - 注意，只有项目源码内的代码才会被转换。\n\n        - 注意，`<div className={'xxx'} />` 这样的写法不会被转换。\n            \n        - 注意，`import './x.module.css'` 这样的写法不会被转换。\n\n  - 接着，在 ClientSide，插件会覆盖原本的 Webpack Ruleset：\n\n    - 对于命中了 inlineStyle 的资源文件，会使用 stylesheet-loader 进行处理为 styleSheet 对象（非 css 文件还会先交由预处理器编译）。其它文件会保持原本的处理逻辑，即处理到额外的 CSS 文件中。\n    - 注意，目前在 --speedup 下此逻辑无法生效。\n    - 注意，如果禁用了 cssModule ，那么 .module.css(less/...) 文件也会被交由 stylesheet-loader 处理。\n\n- 在 ServerSide，对命中了 inlineStyle 的资源文件，会使用 esbuild 进行处理为 styleSheet 对象(文件的类型会被改变为 JS 文件)。\n\n关于行内样式的额外说明：\n\n- 只有项目源码中使用了 `className=\"xxx\"` 的写法，才会被转换为 `style={styleSheet.xxx}` 的写法，因此 CSS Module 使用的 `className={styles.xxx}` 这种写法也不会被转换。另外，来自 node_modules 的代码不会被转换。\n","isInternal":false,"tokens":899,"sizeBytes":3058},{"name":"README.md","path":"packages/plugin-request/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-request/README.md","title":"plugin-request Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-request\n\nProvides a unified request method for ice.js projects.\n\n## Usage\n\n```bash\n$ npm i @ice/plugin-request -S\n```\n\nAdd plugin.\n\n```js title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport request from '@ice/plugin-request';\n\nexport default defineConfig(() => ({\n  plugins: [\n    request(),\n  ],\n}));\n```\n\n## API\n\n### request\n\n```js title=\"service.ts\"\nimport { request } from 'ice';\n\nexport async function getUser(id) {\n  return await request(`/api/user/${id}`);\n}\n```\n\n### useRequest\n\n```js title=\"home.tsx\"\nimport { useEffect } from 'react';\nimport { useRequest } from 'ice';\n\nexport default function Home() {\n  const {\n    data,\n    error,\n    loading,\n    request\n  } = useRequest(service.getUser);\n\n  useEffect(() => {\n    request();\n  }, []);\n\n  if (error) {\n    return <div>failed to load</div>;\n  }\n  if (!data || loading) {\n    return <div>loading...</div>;\n  }\n  return (\n    <h2 className={styles.title}>\n      Name: {data.name} Age: {data.age}\n    </h2>\n  );\n}\n```\n","isInternal":false,"tokens":266,"sizeBytes":1011},{"name":"README.md","path":"packages/plugin-store/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-store/README.md","title":"plugin-store Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-store\n\nA plugin of state management base on Redux and React Redux used in ice.js`.\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport store from '@ice/plugin-store';\n\nexport default defineConfig(() => ({\n  plugins: [\n    store(),\n  ],\n}));\n```\n\n## Options\n\n- `disableResetPageState` \n  - The default value is `false`.\n  - After it is turned on, the page state will not be reinitialized after switching the page and entering the original page again.\n","isInternal":false,"tokens":112,"sizeBytes":477},{"name":"README.md","path":"packages/plugin-stream-error/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-stream-error/README.md","title":"plugin-stream-error Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-stream-error\n\nA plugin for re-render app when stream error.\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport streamError from '@ice/plugin-stream-error';\n\nexport default defineConfig(() => ({\n  plugins: [\n    streamError(),\n  ],\n}));\n```\n\n> Causion: This plugin only works when stream content ends with javascripts which triggered an custom event of `stream_end`\n","isInternal":false,"tokens":88,"sizeBytes":393},{"name":"README.md","path":"packages/plugin-unocss/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/plugin-unocss/README.md","title":"plugin-unocss Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/plugin-unocss\n\nA plugin for enable unocss in your app based on `@ice/app`.\n\n\n## Usage\n\nInstall `@ice/plugin-unocss`:\n\n```bash\n$ npm install @ice/plugin-unocss --save-dev\n```\n\nConfigure it in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport Unocss from '@ice/plugin-unocss';\n\nexport default defineConfig(() => ({\n  plugins: [\n    Unocss(),\n  ]\n}));\n```\n\n## Plugin Options\n\nPlugin options is as same as [UnoCSS ConfigFle](https://unocss.dev/guide/config-file).\n\nPlugin has a default preset `@unocss/preset-uno` for UnoCSS. You can pass options of presets to override the default preset:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport Unocss from '@ice/plugin-unocss';\nimport {\n  defineConfig,\n  presetAttributify,\n  presetIcons,\n  presetTypography,\n  presetUno,\n  presetWebFonts,\n  transformerDirectives,\n  transformerVariantGroup\n} from 'unocss';\n\nexport default defineConfig(() => ({\n  plugins: [\n    Unocss({\n      shortcuts: [\n        // ...\n      ],\n      theme: {\n        colors: {\n          // ...\n        }\n      },\n      presets: [\n        presetUno(),\n        presetAttributify(),\n        presetIcons(),\n        presetTypography(),\n        presetWebFonts({\n          fonts: {\n            // ...\n          },\n        }),\n      ],\n      transformers: [\n        transformerDirectives(),\n        transformerVariantGroup(),\n      ],\n    }),\n  ],\n}));\n```\n","isInternal":false,"tokens":346,"sizeBytes":1397},{"name":"README.md","path":"packages/rax-compat/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/rax-compat/README.md","title":"rax-compat Documentation","category":"plugin-manifest","format":"markdown","content":"# rax-compat\n\nA runtime polyfill, for writing rax, but rendering in real React.\n\n## Usage\n\n```js\nimport { createElement } from 'rax-compat';\n\nexport default function() {\n  return createElement('div', null, 'Hello World');\n}\n```\n\nAlso works with JSX, should be configured with packer(webpack/turbopack).\n\nSee also [@ice/plugin-rax-compat](https://www.npmjs.com/package/@ice/plugin-rax-compat).\n","isInternal":false,"tokens":102,"sizeBytes":393},{"name":"README.md","path":"packages/route-manifest/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/route-manifest/README.md","title":"route-manifest Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/route-manifest\n\nGenerate route manifest based on the `src` directory in the project for ice.js 3.\n\n## API\n\n### `generateRouteManifest(rootDir: string)`\n\n- rootDir: the project directory absolute path\n\nWill scan the page files in the `rootDir` and generate the routeManifest. For example:\n\n```ts\nconst routeManifest = generateRouteManifest(__dirname);\nconsole.log(routeManifest);\n/**\n[\n  layout: {\n    path: \"\",\n    id: \"layout\",\n    componentName: \"Layout\",\n    file: \"layout.tsx\",\n  },\n  \"pages/About/index\": {\n    path: \"/About\",\n    index: true,\n    id: \"pages/About/index\",\n    parentId: \"layout\",\n    file: \"pages/About/index.tsx\",\n    componentName: \"PagesAboutIndex\",\n  },\n}\n*/\n```\n\n### `formatNestedRouteManifest(routeManifest: RouteManifest)`\n\n- routeManifest: generated by the `generateRouteManifest` function\n\nIt will get the nested route by the routeManifest. For example:\n\nrouteManifest:\n\n```ts\nconst routeManifest = [\n  layout: {\n    path: \"\",\n    id: \"layout\",\n    componentName: \"Layout\",\n    file: \"layout.tsx\",\n  },\n  \"pages/About/index\": {\n    path: \"/About\",\n    index: true,\n    id: \"pages/About/index\",\n    parentId: \"layout\",\n    file: \"pages/About/index.tsx\",\n    componentName: \"PagesAboutIndex\",\n  },\n}\n\nconst nestedRouteManifest = formatNestedRouteManifest(routeManifest);\n\nconsole.log(nestedRouteManifest);\n/**\n[\n  {\n    path: \"\",\n    id: \"layout\",\n    componentName: \"Layout\",\n    file: \"layout.tsx\",\n    children: [\n      {\n        path: \"/About\",\n        index: true,\n        id: \"pages/About/index\",\n        parentId: \"layout\",\n        file: \"pages/About/index.tsx\",\n        componentName: \"PagesAboutIndex\",\n      },\n    ]\n  }\n]\n*/\n```\n","isInternal":false,"tokens":426,"sizeBytes":1676},{"name":"README.md","path":"packages/rspack-config/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/rspack-config/README.md","title":"rspack-config Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/rspack-config\n\nThis package providers basic rspack configuration.\n","isInternal":false,"tokens":16,"sizeBytes":73},{"name":"README.md","path":"packages/runtime/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/runtime/README.md","title":"runtime Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/runtime\n\nruntime dependencies for webpack framework `ice`.\n\n`@ice/runtime` includes almost every runtime dependencies for `ice`, the dependencies version will be locked to keep the stability of web framework.","isInternal":false,"tokens":41,"sizeBytes":215},{"name":"README.md","path":"packages/shared-config/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/shared-config/README.md","title":"shared-config Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/shared-config\n\nThis package providers shared configuration for rspack and webpack.\n","isInternal":false,"tokens":17,"sizeBytes":90},{"name":"README.md","path":"packages/style-import/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/style-import/README.md","title":"style-import Documentation","category":"plugin-manifest","format":"markdown","content":"# `@ice/style-import`\n\nA transform function for automatic import style.\n\n## Usage\n\n```js\nimport transform from '@ice/style-import';\n\ntransform(`import { Button } from 'antd';\nReactDOM.render(<Button>xxxx</Button>);`, [{\n  libraryName: 'antd',\n  style: (importSpecifiers) =>\n    importSpecifiers.map(specifier =>\n      `import 'antd/es/${specifier}/style'`).join('\\n'),\n}]);\n\n// the code will turn out as blew:\n/* \nimport { Button } from 'Button';\nimport 'antd/es/Button/style';\nReactDOM.render(<Button>xxxx</Button>); */\n```\n","isInternal":false,"tokens":132,"sizeBytes":525},{"name":"README.md","path":"packages/webpack-config/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/webpack-config/README.md","title":"webpack-config Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/webpack-config\n\nThis package providers basic webpack configuration.\n\n## Usage\n\n```js\nimport { getWebpackConfig } from '@ice/webpack-config';\nimport webpack from 'webpack';\n\nconst config = { alias: {} };\nconst rootDir = process.cwd();\nconst runtimeTmpDir = '.ice';   // the path of the asset-manifest.json\n\nconst webpackConfig = getWebpackConfig({ \n  rootDir, \n  config,\n  webpack, \n  runtimeTmpDir,\n  target: 'web',\n});\n```\n","isInternal":false,"tokens":108,"sizeBytes":431},{"name":"README.md","path":"packages/webpack-modify/README.md","rawUrl":"https://raw.githubusercontent.com/alibaba/ice/HEAD/packages/webpack-modify/README.md","title":"webpack-modify Documentation","category":"plugin-manifest","format":"markdown","content":"# @ice/webpack-modify\n\nThis package providers several APIs to simplify the modification of webpack configurations.\n\n## Usage\n\n```js\nimport { removeLoader, modifyLoader, addLoader, removePlugin } from '@ice/webpack-modify';\n\nlet modifiedConfig = {};\n\nconst webpackConfig = {\n  module: {\n    rules: [\n      {\n        test: /\\.css$/,\n        use: [{ loader: \"style-loader\" }, { loader: \"sass-loader\" }],\n      },\n    ],\n  },\n};\n\n// remove loader\nmodifiedConfig = removeLoader(webpackConfig, {\n  rule: 'css',\n  loader: 'style-loader',\n});\n// modify loader\nmodifiedConfig = modifyLoader(webpackConfig, {\n  rule: 'css',\n  loader: 'style-loader',\n  options: () => ({}),\n});\n// add loader\nmodifiedConfig = addLoader(webpackConfig, {\n  rule: 'css',\n  before: 'style-loader'\n});\nmodifiedConfig = addLoader(webpackConfig, {\n  rule: 'css',\n  after: 'style-loader'\n});\n// modify webpack rule options\nmodifiedConfig = modifyRule(webpackConfig, {\n  rule: 'css',\n  options: () => {\n    return [\n      {\n        loader: 'css-loader',\n        options: () => ([]),\n      },\n    ]\n  },\n})\n// remove plugin\nmodifiedConfig = removePlugin(webpackConfig, {\n  pluginName: 'AssetsManifestPlugin',\n});\n```\n","isInternal":false,"tokens":297,"sizeBytes":1179},{"name":".cursorrules","path":".cursorrules (dragonruby-best-practices-cursorrules-prompt-file.mdc)","rawUrl":"https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/dragonruby-best-practices-cursorrules-prompt-file.mdc","title":"Awesome Cursorrules: dragonruby best practices","category":"cursor-rule","format":"markdown","content":"---\ndescription: \"Cursor rules for DragonRuby development with best practices integration.\"\nglobs: **/*\nalwaysApply: false\n---\nYou are an expert game developer in Ruby using the DragonRuby Game Toolkit.\n\nCode Style and Structure\n\n- Write concise, idiomatic Ruby code with accurate examples.\n- Follow Ruby and DragonRuby conventions and best practices.\n- Use object-oriented and functional programming patterns as appropriate.\n- Prefer iteration and modularization over code duplication.\n- Use descriptive variable and method names (e.g., user_signed_in?, calculate_total).\n- Structure files according to DragonRuby conventions.\n\nNaming Conventions\n\n- Use snake_case for file names, method names, and variables.\n- Use CamelCase for class and module names.\n- Follow DragonRuby naming conventions.\n\nSyntax and Formatting\n\n- Follow the Ruby Style Guide (https://rubystyle.guide/)\n- Use Ruby's expressive syntax (e.g., unless, ||=, &.)\n- Prefer single quotes for strings unless interpolation is needed.\n\nError Handling and Validation\n\n- Use exceptions for exceptional cases, not for control flow.\n- Implement proper error logging and user-friendly messages.\n\nFollow the official DragonRuby Game Toolkit guides for best practices in routing, controllers, models, views, and other Rails components.\n","tokens":250,"sizeBytes":1292}],"systemPromptSnippet":"<yakaai_skills repo=\"alibaba/ice\">\n<!-- File: website/docs/guide/plugins/plugin-dev.md (Tokens: ~4453 | Category: anthropic-skill) -->\n---\ntitle: 开发插件\norder: 1\n---\n\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';\n\nice.js 底层基于 [build-scripts](https://github.com/ice-lab/build-scripts) 插件系统，在提供丰富的框架能力的基础上也可以让开发者可以在框架能力不满足诉求的情况下进行定制：\n\n- 定制修改框架构建配置\n- 支持在整个构建生命周期定制行为，比如项目启动前拉取某些资源\n- 支持扩展运行时能力，比如统一为路由组件增加鉴权逻辑（添加高阶组件）\n\n## 插件规范\n\nice.js 插件本质是一个 JS 模块，官方推荐以 TS 进行开发以获得良好的类型提示：\n\n```ts\nimport type { Plugin } from '@ice/app/types';\n\ninterface PluginOptions {\n  id: string;\n}\n\nconst plugin: Plugin<PluginOptions> = (options) => ({\n  // name 可选，插件名称\n  name: 'plugin-name',\n  // setup 必选，用于定制工程构建配置\n  setup: (pluginAPI) => { console.log(options.id) },\n  // runtime 可选，用于定制运行时配置\n  runtime: '/path/to/runtime',\n});\n\nexport default plugin;\n```\n\n### 开发本地插件\n\n推荐在项目根目录下新建一个插件目录，目录名比如叫 `my-plugin`。然后在该目录下新建以下文件：\n\n- `index.ts`：必选，插件入口，用于定制工程构建能力\n- `runtime.tsx`：可选，用于定制运行时能力\n\n<Tabs>\n\n<TabItem value=\"index.ts\" label=\"my-plugin/index.ts\">\n\n```ts\nimport * as path from 'path';\nimport type { Plugin } from '@ice/app/types';\n\nconst plugin: Plugin = () => ({\n  name: 'my-plugin',\n  setup: (pluginAPI) => {\n    console.log(pluginAPI);\n  },\n  // runtime 为可选，用于定制运行时配置。runtime 的值必须是一个绝对路径\n  runtime: path.join(__dirname, 'runtime.tsx'),\n});\n\nexport default plugin;\n```\n\n</TabItem>\n\n<TabItem value=\"runtime.tsx\" label=\"my-plugin/runtime.tsx\">\n\n```tsx\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = async ({ appContext }) => {\n  console.log(appContext);\n}\n\nexport default runtime;\n```\n\n</TabItem>\n\n</Tabs>\n\n开发完成后，我们需要把插件添加到应用的构建配置中：\n\n```diff title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\n+ import myPlugin from './my-plugin/index.js';\n\nexport default defineConfig(() => ({\n  plugins: [\n+   myPlugin(),\n  ],\n}))\n```\n\n### 发布插件到 npm \n\n:::tip\n插件模板可参考：https://github.com/ice-lab/icejs-plugin-template\n:::\n\n假设现在需要开发一个插件（包括修改工程配置和运行时配置），并发布到 npm 上。插件的文件目录如下：\n\n```md\n/xxx/@ice/my-plugin\n├── package.json\n├── src\n|  ├── index.ts       // 插件入口\n|  └── runtime.tsx    // 定制运行时能力\n```\n\n推荐以 [ES Module](https://nodejs.org/api/packages.html) 的方式编写插件，并使用 `exports` 字段导出插件入口和运行时配置：\n\n```json title=\"package.json\"\n{\n  \"name\": \"@ice/my-plugin\",\n  \"type\": \"module\",\n  \"exports\": {\n    \".\": {\n      \"types\": \"./esm/index.d.ts\",\n      \"import\": \"./esm/index.js\",\n      \"default\": \"./esm/index.js\"\n    },\n    \"./runtime\": {\n      \"types\": \"./esm/runtime/index.d.ts\",\n      \"import\": \"./esm/runtime/index.js\",\n      \"default\": \"./esm/runtime/index.js\"\n    }\n  },\n  \"main\": \"./esm/index.js\",\n  \"types\": \"./esm/index.d.ts\",\n  \"files\": [\n    \"esm\",\n    \"!esm/**/*.map\"\n  ],\n}\n```\n<Tabs>\n\n<TabItem value=\"index.ts\" label=\"src/index.ts\">\n\n```ts\nimport type { Plugin } from '@ice/app/types';\n\nconst plugin: Plugin = () => ({\n  name: '@ice/my-plugin',\n  setup: (pluginAPI) => {},\n  // runtime 的值需要配置为「模块引入路径」，对应上面 package.json 中 exports 里的 \"./runtime\" 导出\n  runtime: '@ice/my-plugin/runtime',\n});\n\nexport default plugin;\n```\n\n</TabItem>\n\n<TabItem value=\"runtime.tsx\" label=\"src/runtime.tsx\">\n\n```tsx\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = async ({ appContext }) => {\n  console.log(appContext);\n}\n\nexport default runtime;\n```\n\n</TabItem>\n\n</Tabs>\n\n\n把插件发布到 npm 后，需要把插件添加到构建配置中：\n\n```diff title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\n+ import myPlugin from '@ice/my-plugin';\n\nexport default defineConfig(() => ({\n  plugins: [\n+   myPlugin(),\n  ],\n}));\n```\n\n## 工程能力定制\n\n框架为定制工程能力提供了插件 API，方便开发者扩展和自定义能力。\n\n### `context`\n\n`context` 包含构建时的上下文信息：\n\n- `command` 当前运行命令，start/build/test\n- `commandArgs` script 命令执行时接受到的参数\n- `rootDir` 项目根目录\n- `userConfig` 用户在构建配置文件 ice.config.mts 中配置的内容\n- `pkg` 项目 package.json 中的内容\n- `webpack` webpack 实例，工程不建议安装多个 webpack 版本，可以从 `context.webpack` 上获取内置的 webpack 实例\n\n```ts\nconst plugin = () => ({\n  setup: ({ context }) => {\n    console.log('context: ', context);\n  },\n})\n\nexport default plugin;\n```\n### `onGetConfig`\n\n通过 `onGetConfig` 获取框架的工程配置，并可通过该 API 对配置进行自定义修改：\n\n```ts\nconst plugin = () => ({\n  name: 'plugin-test',\n  setup: ({ onGetConfig }) => {\n    onGetConfig((config) => {\n      config.alias = {\n        '@': './src/',\n      };\n    });\n  },\n});\n\nexport default plugin;\n```\n\n为了简化开发者的配置，通过 `onGetConfig` 修改配置项是基于底层工程工具的抽象，包括以下配置项：\n\n- `mode` 配置 `'none' | 'development' | 'production'` 以确定构建环境\n- `entry` 配置应用入口文件\n- `define` 注入到运行时的变量\n- `experimental` 实验性能力，同 [webpack.experiments](https://webpack.js.org/configuration/experiments/#experiments)\n- `outputDir` 构建输出目录\n- `externals` 同 [webpack.externals](https://webpack.js.org/configuration/externals/)\n- `outputAssetsPath` 静态资源输出目录，可以分别配置 js 和 css\n- `sourceMap` 源码调试映射，同 [webpack.devtool](https://webpack.js.org/configuration/devtool/)\n- `publicPath` 同 [webpack.output.publicPath](https://webpack.js.org/guides/public-path/#root)\n- `alias` 同 [webpack.resolve.alias](https://webpack.js.org/configuration/resolve/#resolvealias)\n- `hash` 配置资源输出文件名是否带 hash\n- `transformPlugins` [unplugin 标准](https://github.com/unjs/unplugin) 插件，该插件对于服务端和浏览器端产物同时生效\n- `transforms` 配置源码转化，支持对源码进行定制转化\n- `middlewares` development 开发阶段配置中间件\n- `proxy` 配置代理服务\n- `compileIncludes` 配置需要进行编译的三方依赖\n- `minify` 是否进行压缩\n- `minimizerOptions` 压缩配置项，基于 [minify-options](https://github.com/terser/terser#minify-options)\n- `analyzer` 开启产物分析\n- `https` 配置 https 服务\n- `port` 配置调试端口\n- `cacheDir` 配置构建缓存目录\n- `tsCheckerOptions` ts 类型检查 [配置项](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin)\n- `eslintOptions` eslint 检查 [配置项](https://www.npmjs.com/package/eslint-webpack-plugin)\n- `splitChunks` 是否分包\n- `assetsManifest` 是否生成资源 manifest\n- `devServer` 配置 webpack dev server [配置](https://webpack.js.org/configuration/dev-server/)\n- `fastRefresh` 是否开启 fast-refresh 能力\n- `configureWebpack` 如果上述快捷配置项不满足定制需求，可以通过 configureWebpack 进行自定义\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ onGetConfig }) => {\n    onGetConfig((config) => {\n      config.configureWebpack.push((webpackConfig) => {\n        webpackConfig.mode = 'development';\n        return webpackConfig;\n      })\n    });\n  },\n})\n```\n\n### `onHook`\n\n通过 `onHook` 监听命令构建时事件，`onHook` 注册的函数执行完成后才会执行后续操作，可以用于在命令运行中途插入插件想做的操作：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ onHook }) => {\n    onHook('before.build.load', () => {\n      // do something before build\n    });\n    onHook('after.build.compile', (stats) => {\n      // do something after build\n    });\n  },\n})\n```\n\n目前支持的生命周期如下：\n\n- `before.start.run` 构建命令 start 执行前，该阶段可以获取各项构建任务最终配置\n- `before.build.run` 构建命令 build 执行前，同 start\n- `after.start.compile` 构建命令 start 执行结束，该阶段可以获取构建的执行结果\n- `after.build.compile` 构建命令 build 执行结束，同 start\n- `after.start.devServer` dev 阶段的 server 服务启动后，该阶段可以获取相关 dev server 启动的 url 等信息\n\n> 每个周期可以获取的具体的参数类型可以参考 [TS 类型](https://github.com/alibaba/ice/blob/master/packages/ice/src/types/plugin.ts)。\n\n### `registerUserConfig`\n\n为用户配置文件 `ice.config.mts` 中添加自定义字段：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerUserConfig }) => {\n    registerUserConfig({\n      name: 'custom-key',\n      validation: 'boolean', // 可选，支持类型有 string, number, array, object, boolean\n      setConfig: () => {\n        // 该字段对于配置的影响，通过 onGetConfig 设置\n      },\n    });\n  },\n});\n```\n\n### `registerCliOption`\n\n为命令行启动添加自定义参数：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerCliOption }) => {\n    registerCliOption({\n      name: 'custom-option',\n      commands: ['start'], // 支持的扩展的命令\n      setConfig: () => {\n        // 该字段对于配置的影响，通过 onGetConfig 设置\n      },\n    });\n  },\n});\n```\n\n### `modifyUserConfig`\n\n修改用户配置：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ modifyUserConfig }) => {\n    modifyUserConfig('key', 'value'); // key, value 分别为用户配置文件键值对\n    // 例如：把 ssr 配置项修改为 true，以开启 SSR\n    modifyUserConfig('ssr', true);\n  },\n});\n```\n\n### `registerTask`\n\n添加自定义任务：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ registerTask }) => {\n    const config = {\n      sourceMap: true,\n    };\n    registerTask('task name', config); // name: Task名, config: 对于任务配置同 onGetConfig 配置项\n  },\n});\n```\n\n### `getAllTask`\n\n获取所有任务名称，内置主要任务名为 `web`：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ getAllTask }) => {\n    const tasks = getAllTask();\n    console.log(tasks);\n  },\n});\n```\n\n### `generator`\n\n支持生成或者修改模版，支持的 API 如下：\n\n#### `addRenderTemplate`\n\n添加模块生成目录：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addRenderTemplate({\n      template: '/path/to/template/dir',\n      targetDir: 'router',\n    }, {});\n  },\n});\n```\n\n#### `addRenderFile`\n\n添加模块生成文件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addRenderFile('/path/to/file.ts.ejs', 'folder/file.ts', {});\n  },\n});\n```\n\n#### `addExport`\n\n向 ice.js 里注册模块，实现 `import { request } from 'ice';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addExport({\n      source: './request/request',\n      exportName: 'request',\n    });\n  },\n});\n```\n\n#### `addExportTypes`\n\n向 ice.js 里注册类型，实现 `import type { Request } from 'ice';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addExportTypes({\n      source: './request/types',\n      specifier: '{ Request }',\n      exportName: 'Request',\n    });\n  },\n});\n```\n\n#### `addDataLoaderImport`\n\n向 ice.js 里注册 data-loader 的自定义发送方法，实现 `import { customFetch as fetcher } from 'custom-fetch';` 的能力：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ generator }) => {\n    generator.addDataLoaderImport({\n      source: 'custom-fetch',\n      alias: {\n        customFetch: 'fetcher',\n      },\n      specifier: ['customFetch'],\n    });\n  },\n});\n```\n\n### `watch`\n\n支持统一的 watch 服务\n\n#### addEvent\n\n添加 watch 事件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ watch }) => {\n    watch.addEvent([\n      /src\\/global.(scss|less|css)/,\n      (event: string, filePath: string) => {},\n      'cssWatch',\n    ]);\n  },\n});\n```\n\n#### removeEvent\n\n移除 watch 事件：\n\n```ts\nexport default () => ({\n  name: 'plugin-test',\n  setup: ({ watch }) => {\n    watch.removeEvent('cssWatch');\n  },\n});\n```\n\n## 运行时能力定制\n\n插件运行时可以定制框架的运行时能力：\n\n```ts\nimport type { Plugin } from '@ice/app/types';\nconst plugin: Plugin = () => ({\n  name: 'plugin-name',\n  runtime: '/absolute/path/to/runtime',\n});\n\nexport default plugin;\n```\n\n框架运行时指向的文件地址为一个 JS 模块，源码阶段推荐用 TS 进行开发：\n\n```ts\nimport type { RuntimePlugin } from '@ice/runtime/types';\n\nconst runtime: RuntimePlugin = () => {};\nexport default runtime;\n```\n\n### `appContext`\n\nappContext 上包含框架相关上下文配置信息，主要包括：\n\n- `appConfig`：应用配置，详细内容可以参考 [应用入口](../basic/app)\n- `assetsManifest`：应用资讯配置信息\n- `routesData`：路由信息\n\n```ts\nconst runtime = ({ appContext }) => {\n  console.log(appContext);\n}\nexport default runtime;\n```\n\n### `addProvider`\n\n在应用最外层添加全局 Provider：\n\n```tsx\nexport default ({ addProvider }) => {\n  function Provider({ children }) {\n    return (\n      <div>{children}</div>\n    )\n  }\n\n  const StoreProvider = ({ children }) => {\n    return <Provider>{children}</Provider>;\n  };\n  addProvider(StoreProvider);\n};\n```\n\n### `addWrapper`\n\n为所有路由组件添加一层包裹：\n\n```tsx\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper }) => {\n  const PageWrapper = ({ children }) => {\n    useEffect(() => {\n      document.title = 'Hello ICE';\n    }, [])\n    return <>{children}</>\n  }\n\n  addWrapper(PageWrapper);\n\n  // 如果希望同样为 layout 组件添加可以添加第二个参数\n  addWrapper(PageWrapper, true);\n};\n```\n\n#### setAppRouter\n\n定制 Router 渲染方式\n\n```ts\nexport default ({ setAppRouter }) => {\n  // setAppRouter 入参为路由数组\n  const renderRouter = (routes) => () => {\n    return <div>route</div>;\n  };\n  setAppRouter(renderRouter);\n};\n```\n\n### `setRender`\n\n自定义渲染，默认使用 `react-dom` 进行渲染\n\n```ts\nimport ReactDOM from 'react-dom';\n\nexport default ({ setRender }) => {\n  // App: React 组件\n  // appMountNode: App 挂载点\n  const DOMRender = (appMountNode, App) => {\n    ReactDOM.render(<App />, appMountNode);\n  };\n  setRender(DOMRender);\n};\n```\n\n### `useData`\n\n获取页面组件的数据，一般配合 addWrapper 进行使用：\n\n```ts\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper, useData }) => {\n  const PageWrapper = (PageComponent) => {\n    const pageData = useData();\n    console.log(pageData);\n    return PageComponent;\n  };\n  addWrapper(PageWrapper);\n};\n```\n\n### `useConfig`\n\n获取页面组件的配置，一般配合 `addWrapper` 进行使用：\n\n```ts\nimport { useEffect } from 'react';\n\nexport default ({ addWrapper, useConfig }) => {\n  const PageWrapper = (PageComponent) => {\n    const pageConfig = useConfig();\n    console.log(pageConfig);\n    return PageComponent;\n  };\n  addWrapper(PageWrapper);\n};\n```\n\n<!-- File: website/docs/guide/plugins/plugin-list.md (Tokens: ~193 | Category: anthropic-skill) -->\n---\ntitle: 插件列表\norder: 2\n---\n\n## [@ice/plugin-miniapp](../miniapp/start)\n\n提供小程序的开发能力。\n\n## [@ice/plugin-auth](../advanced/auth)\n\n提供权限管理方案。\n\n## [@ice/plugin-store](../advanced/store)\n\n提供基于单向数据流的数据管理方案。\n\n## [@ice/plugin-css-assets-local](../advanced/css-assets-local)\n\n提供将 CSS 中的网络资源本地化的能力。\n\n## [@ice/plugin-antd](../advanced/antd)\n\n提供 antd 组件样式按需加载及主题配置能力。\n\n## [@ice/plugin-fusion](../advanced/fusion)\n\n提供 fusion 组件样式按需加载及主题配置能力。\n\n## [@ice/plugin-unocss](../advanced/unocss)\n\n提供 UnoCSS 原子化 CSS 能力。\n\n<!-- File: packages/appear/README.md (Tokens: ~117 | Category: plugin-manifest) -->\n# @ice/appear\n\nReact component for supporting `appear` and `disappear` events.  \n\n## Usage\n\n```bash\nnpm i @ice/appear -S\n```\n\n```jsx\nimport VisibilityChange from '@ice/appear';\n\nexport default function Home() {\n  return (\n    <VisibilityChange\n      onAppear={() => {\n        console.log('Something has been shown.')\n      }}\n      onDisappear={() => {\n        console.log('Something has disappeard.')\n      }}\n    >\n      Anything you want to show.\n    </VisibilityChange>\n  );\n}\n```\n\n<!-- File: packages/bundles/README.md (Tokens: ~23 | Category: plugin-manifest) -->\n# @ice/bundles\n\nPrepacked bundles for ice.js.\n\n**DO NOT USE THIS PACKAGE DIRECTLY.**\n\n<!-- File: packages/cache-canvas/README.md (Tokens: ~281 | Category: plugin-manifest) -->\n# @ice/cache-canvas\n\nReact component for supporting canvas for cache.\n\n## Usage\n\n```bash\nnpm i @ice/cache-canvas -S\n```\n\n```jsx\nimport MainGame from './game'; // eva.js 的封装\n\nconst GAME_CANVAS = 'game-canvas';\n\nexport default (props) => {\n  useEffect(() => {\n    const gameEl = document.getElementById(GAME_CANVAS);\n    new MainGame(gameEl, getGameHeight());\n  }, []);\n\n  const init = () => {\n     return new Promise((resolve) => {\n      const canvas: HTMLCanvasElement | null = document.getElementById(GAME_CANVAS_ID) as HTMLCanvasElement;\n      if (canvas && typeof canvas.getContext === 'function') {\n        let ctx: CanvasRenderingContext2D | null = canvas.getContext('2d');\n\n        ctx?.fillRect(25, 25, 100, 100);\n        ctx?.clearRect(45, 45, 60, 60);\n        ctx?.strokeRect(50, 50, 50, 50);\n      }\n\n      setTimeout(() => {\n        console.log('canvas paint ready!');\n        resolve(true);\n      }, 5000);\n    });\n  }\n\n  return (\n    <>\n       <CanvasCache id={GAME_CANVAS} useCache={false} init={init} />\n    </>\n  );\n};\n```\n\n<!-- File: packages/create-ice/README.md (Tokens: ~128 | Category: plugin-manifest) -->\n# create-ice\n\ncreate ice.js project.\n\n## Usage\n\n```bash\n# use npm\n$ npm create ice <projectName>\n# use yarn\n$ yarn create ice <projectName>\n# use pnpm\n$ pnpm create ice <projectName>\n\n# or with template\n# use npm\n$ npm create ice <projectName> --template <template>\n# use yarn\n$ yarn create ice <projectName> --template <template>\n# use pnpm\n$ pnpm create ice <projectName> --template <template>\n\n$ cd <projectName>\n$ npm install\n$ npm start\n```\n\n<!-- File: packages/ice/README.md (Tokens: ~187 | Category: plugin-manifest) -->\n# ice.js\n\nice.js is the best user experience for web developing based on React.\nThis package includes scripts and configuration used by web framework `ice`.\n\n## Install\n\n```bash\n$ npm i @ice/app -D\n```\n\n## usage\n\n```json\n{\n  \"name\": \"my-app\",\n  \"devDependencies\": {\n    \"@ice/app\": \"^3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"ice start\",\n    \"build\": \"ice build\"\n  }\n}\n```\n\n## Command line interface\n\n```bash\nUsage: ice <command> [options]\n\nOptions:\n  -V, --version    output the version number\n  -h, --help       output usage information\n\nCommands:\n  build [options]  build project\n  start [options]  start dev server\n```\n\n## Open Source\n\nOpen Source with ❤️ and MIT License.\n\n<!-- File: packages/jsx-runtime/README.md (Tokens: ~33 | Category: plugin-manifest) -->\n# @ice/jsx-runtime\n\nJSX runtime for ice.js.\n\n## Install\n\n```bash\n$ npm i @ice/jsx-runtime --save\n```\n\n<!-- File: packages/miniapp-html-styles/README.md (Tokens: ~97 | Category: plugin-manifest) -->\n# @ice/miniapp-html-styles\n\n> Forked from [@tarojs/taro](https://github.com/NervJS/taro/tree/next/packages/taro) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\n## html.css\n\nHTML4 built-in styles for compatibility with HTML tag styles.\n\n## html5.css\n\nHTML5 built-in styles for compatibility with HTML tag styles.\n\n<!-- File: packages/miniapp-loader/README.md (Tokens: ~127 | Category: plugin-manifest) -->\n# `@ice/miniapp-loader`\n\n> Forked from [@tarojs/loader](https://github.com/NervJS/taro/tree/next/packages/taro-loader) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nWebpack loader exposed to ice.js for building applet artifacts, including the following `loader`:\n\n## page\n\nMiniapp usage only. Call the `createPageConfig` method of `@ice/miniapp-runtime` in the miniapp page file to create an object accepted by the miniapp `Page` constructor.\n\n<!-- File: packages/miniapp-react-dom/README.md (Tokens: ~118 | Category: plugin-manifest) -->\n# @ice/miniapp-react-dom\n\n> Forked from [@tarojs/react](https://github.com/NervJS/taro/tree/next/packages/taro-react) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nA React renderer for mini-programs based on `react-reconciler`, connected to the DOM instance of `@ice/miniapp-runtime`, equivalent to the mini-program version of `react-dom`, and the exposed API is also the same as `react-dom` consistent.\n\n<!-- File: packages/miniapp-runtime/README.md (Tokens: ~431 | Category: plugin-manifest) -->\n# @ice/miniapp-runtime\n\n> Forked from [@tarojs/runtime](https://github.com/NervJS/taro/tree/next/packages/taro-runtime) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/next/LICENSE\n\nice.js miniapp runtime. Connect the framework (DSL) rendering mechanism to the miniapp rendering mechanism, and connect the miniapp routing and life cycle to the corresponding life cycle of the framework\n\n## Core API\n\n### createPageConfig()\n\nExpose to `@ice/miniapp-loader/page` calls, called in the miniapp page file, to create a miniapp page specification object accepted by the miniapp `Page` constructor.\n\n### window\n\nAn object that imitates the browser's `window` implementation on the miniapp side, and returns the browser's own `window` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n### navigator\n\nAn object that imitates the browser's `navigator` implementation on the miniapp side, and returns the browser's own `navigator` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n###document\n\nAn object that imitates the browser's `document` implementation on the miniapp side, and returns the browser's own `document` in the browser environment. This object is injected into the global object via Webpack's [ProvidePlugin](https://webpack.js.org/plugins/provide-plugin/) for third-party libraries to call.\n\n### Current\n\nGlobal variables exposed to developers currently have three properties:\n\n* `Current.app`, returns the current miniapp application instance, which can be used to call the miniapp specification life cycle.\n* `Current.page`, returns the current miniapp page instance, which can be used to call the miniapp specification life cycle.\n* `Current.router`, returns the current miniapp routing information.\n\n<!-- File: packages/plugin-antd/README.md (Tokens: ~89 | Category: plugin-manifest) -->\n# `@ice/plugin-antd`\n\nAn ice.js plugin to use `antd` components.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport antd from '@ice/plugin-antd';\n\nexport default defineConfig(() => ({\n  plugins: [antd({\n    dark: true,\n    compact: true,\n    theme: {\n      'primary-color': '#fd8',\n    },\n  })],\n}));\n```\n\n<!-- File: packages/plugin-auth/README.md (Tokens: ~77 | Category: plugin-manifest) -->\n# `@ice/plugin-auth`\n\nAn ice.js plugin to enable auth ability.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport auth from '@ice/plugin-auth';\n\nexport default defineConfig(() => ({\n  plugins: [\n    auth(),\n  ],\n}));\n```\n\nMore details to see https://v3.ice.work/docs/guide/advanced/auth\n\n<!-- File: packages/plugin-cavans/README.md (Tokens: ~72 | Category: plugin-manifest) -->\n# @ice/plugin-canvas\n\nAn ice.js plugin for canvas projects.\n\n## Usage\n\nAdd plugin in `ice.config.mts`:\n\n```js\nimport { defineConfig } from 'ice';\nimport canvasPlugin from '@ice/plugin-canvas';\n\nexport default defineConfig(() => ({\n  plugins: [canvasPlugin({ /* options */ })],\n}));\n```\n\n<!-- File: packages/plugin-css-assets-local/README.md (Tokens: ~204 | Category: plugin-manifest) -->\n# @ice/plugin-css-assets-local\n\nAn ice.js plugin for localize css assets resource.\n\n## Install\n\n```bash\nnpm i -D @ice/plugin-css-assets-local\n```\n\n## Usage\n\nAdd plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport cssAssetsLocal from '@ice/plugin-css-assets-local';\n\nexport default defineConfig(() => ({\n  plugins: [\n    cssAssetsLocal(),\n  ],\n}));\n```\n\nAfter running `npm run build`, you can see asset resources will be downloaded to your local disk.\n\n## Options\n\n### `outputPath`\n\nThe assets resource output path.\n\n- Type: `string`\n- Default: `\"assets\"`\n\n### `relativeCssPath`\n\nThe asset paths relative to the css file path.\n\n- Type: `string`\n- Default: `\"../\"`\n\n### `enableInDev`\n\nWhether enable the plugin in dev or not.\n\n- Type: `boolean`\n- Default: `false`\n\n<!-- File: packages/plugin-externals/README.md (Tokens: ~275 | Category: plugin-manifest) -->\n# @ice/plugin-externals\n\n`@ice/plugin-externals` is a ice.js plugin. It provides a simple way to add externals support to your application.\n\n## Install\n\n```bash\n$ npm i @ice/plugin-externals --save-dev\n```\n\n## Usage\n\nSet preset `react` to external react in a easy way.\n\n```js\nimport { defineConfig } from '@ice/app';\nimport externals from '@ice/plugin-externals';\n\nexport default defineConfig(() => ({\n  plugins: [externals({ preset: 'react' })]\n}));\n```\n\nFramework will auto add externals of `react` and `react-dom` to your application, and the cdn url will be inject to the document by default.\n\nAlso, you can custom externals and cdn url by yourself:\n\n```js\nimport { defineConfig } from '@ice/app';\nimport externals from '@ice/plugin-externals';\n\nexport default defineConfig(() => ({\n  plugins: [externals({\n    externals: {\n      antd: 'Antd',\n    },\n    cdnMap: {\n      antd: {\n        development: 'https://unpkg.com/antd/dist/antd.js',\n        production: 'https://unpkg.com/antd/dist/antd.min.js',\n      }\n    }\n  })]\n}));\n```\n\n<!-- File: packages/plugin-fusion/README.md (Tokens: ~144 | Category: plugin-manifest) -->\n# @ice/plugin-fusion\n\nice.js plugin for using fusion components.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport fusion from '@ice/plugin-fusion';\n\nexport default defineConfig(() => ({\n  plugins: [fusion({\n    importStyle: true,\n    themePackage: '@alifd/theme-design-pro',\n    theme: {\n      'primary-color': '#fff',\n    },\n  })],\n}));\n```\n\n## Options\n\n- importStyle: Fusion component styles will be automatically imported after enabling.\n- themePackage: Fusion component theme package configuration, if set to an array, multi-theme capability is enabled.\n- theme: theme configuration, overwrite existing themes by setting sass variables.\n\n<!-- File: packages/plugin-i18n/README.md (Tokens: ~218 | Category: plugin-manifest) -->\n# @ice/plugin-i18n\n\n组件功能描述\n\n## Install\n\n```bash\n$ npm i @ice/plugin-i18n --save-dev\n```\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport i18n from '@ice/plugin-i18n';\n\nexport default defineConfig({\n  plugins: [\n    i18n({\n      locales: ['zh-CN', 'en-US'],\n      defaultLocale: 'zh-CN',\n    }),\n  ],\n});\n```\n\n## Options\n\n### `locales`\n\n- **type:** `string[]`\n\nThe locales you want to support in your app. This option is required.\n\n### defaultLocale\n\n- **type:** `string`\n\nThe default locale you want to be used when visiting a non-locale prefixed path. This option is required.\n\n### autoRedirect\n\n- **type:** `boolean`\n- **default:** `true`\n\nRedirect to the preferred locale automatically. This option should be used with the middleware. If you deploy your application in production, you should read the [example]() for more detail.\n\n<!-- File: packages/plugin-icestark/README.md (Tokens: ~452 | Category: plugin-manifest) -->\n# plugin-icestark\n\n> Easy use [`icestark`](https://github.com/ice-lab/icestark) in [icejs](https://github.com/alibaba/ice).\n\n## Usage\n\n### Install\n\n```bash\nnpm i -D @ice/plugin-icestark\n```\n\n### Framework Application\n\nConfigurate plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport icestark from '@ice/plugin-icestark';\n\nexport default defineConfig(() => ({\n  plugins: [\n    icestark({ type: 'framework' }),\n  ],\n}));\n```\n\nThrough export `icestark` configuration of your framework application.\n\n```ts title=\"src/app.ts\"\nimport { defineFrameworkConfig } from '@ice/plugin-icestark/esm/types';\n\nexport const icestark = defineFrameworkConfig(() => ({\n  getApps: () => ([]),\n}));\n```\n\n**Options:**\n - `getApps`: get sub-application information, support async function\n - `appRouter`\n   - `ErrorComponent`: error component\n   - `LoadingComponent`: loading component\n   - `NotFoundComponent`: 404 not found component\n   - `shouldAssetsRemove`: check assets if it should be removed\n - `layout`: specify Framework application Layout\n\n### Sub-application\n\nConfigurate plugin to your `ice.config.mts`:\n\n```ts title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport icestark from '@ice/plugin-icestark';\n\nexport default defineConfig(() => ({\n  plugins: [\n    icestark({ type: 'child' }),\n  ],\n}));\n```\n\nmodify `icestark` exports in `src/app.ts`:\n\n```ts title=\"src/app.ts\"\n// app.ts\nimport { defineChildConfig } from '@ice/plugin-icestark/esm/types';\n\nexport const icestark = defineChildConfig(() => ({\n  mount: () => {},\n  unmount: () => {},\n}));\n```\n\n**Options:**\n - `mount`: excute before Sub-application mounted\n - `unmount`: excute after Sub-application unmounted\n\n<!-- File: packages/plugin-intl/README.md (Tokens: ~656 | Category: plugin-manifest) -->\n# @ice/plugin-intl\n\n`@ice/plugin-intl` is a ice.js plugin. It provides a simple way to add internationalization support to your application.\n\n> `@ice/plugin-intl` is based on `react-intl`.\n\n## Install\n\n```bash\n$ npm i @ice/plugin-intl --save-dev\n```\n\n## Usage\n\nDefine the plugin in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport intl from '@ice/plugin-intl';\n\nexport default defineConfig({\n  plugins: [\n    intl(),\n  ],\n});\n```\n\nDefine locale config in `src/app.ts`:\n\n```ts\nimport { defineAppConfig } from 'ice';\nimport type { LocaleConfig } from '@ice/plugin-intl/types';\n\nexport default defineAppConfig(() => ({}));\n\nexport const locale: LocaleConfig = {\n  // Cutomize getLocale method and other options supported by react-intl.\n  getLocale: () => 'en-US',\n};\n```\n\n## Locales\n\nLocales are defined in the `src/locales` directory. Each locale is defined in a separate file, with the locale name as the file name. For example, `en-US.ts`:\n\n```ts\nexport default {\n  'app.title': 'My Application',\n  'app.welcome': 'Welcome to my application!',\n};\n```\n\nUse the `useIntl` hook to access the current locale:\n\n```tsx\nimport { useIntl } from 'ice';\n\nexport default function Home() {\n  const intl = useIntl();\n  console.log(intl.formatMessage({ id: 'new' }));\n  return <h1>home</h1>;\n}\n```\n\nUse the `intl` function to access the current locale:\n\n```tsx\nimport { intl } from 'ice';\n\nfunction alertMessage() {\n  alert(intl.formatMessage({ id: 'app.welcome' }));\n}\n```\n\n## Simple mode\n\nSimple mode for remove the dependency of `react-intl`:\n\nDefine the plugin in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport intl from '@ice/plugin-intl';\n\nexport default defineConfig({\n  plugins: [\n    // Add intlSolution to remove the dependency of react-intl\n    intl({ intlSolution: 'simple' }),\n  ],\n});\n```\n\nWhen you use the `simple` mode, you can only use the `intl.formateMessage` function to get the locale message:\n\n```tsx\nimport { ice } from 'ice';\n\nexport default function Home() {\n  console.log(intl.formatMessage({ id: 'new' }));\n  return <h1>home</h1>;\n}\n```\n\nFunction `intl.formatMessage` is limited, you can only use the syntax below to get the locale message:\n\nSimple Usage:\n\n```tsx\nintl.formatMessage({ id: 'app.welcome', defaultMessage: 'Welcome to my application!' });\nintl.formatMessage('app.welcome');\n```\n\nWith Variables:\n\n```tsx\nintl.formatMessage({ id: 'app.welcome' }, { name: 'icejs' });\n```\n\n> Caution: the message Syntax only support the pattern like `{name}`.\n\n<!-- File: packages/plugin-jsx-plus/README.md (Tokens: ~198 | Category: plugin-manifest) -->\n# @ice/plugin-jsx-plus\n\nThis plugin adds support for JSX+ syntax to the ice.js.\n\n## Definition of JSX Plus\n\nhttps://github.com/jsx-plus/jsx-plus\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport jsxplus from '@ice/plugin-jsx-plus';\n\nexport default defineConfig(() => ({\n  plugins: [\n    jsxplus({\n      // options\n    }),\n  ],\n}));\n```\n\n## Options\n\n- `include`: `(string | RegExp)[]`\n  - Files to be included.\n  - Default: the project `src` directory.\n- `exclude`: `(string | RegExp)[]`\n  - Files to be excluded.\n  - Default: `[]`\n- `extensions`: `string[]`\n  - File extensions to be processed.\n  - Default: `['.jsx', '.tsx']`\n\n> If `include` and `exclude` are both set, `exclude` will be priority executed.\n\n<!-- File: packages/plugin-miniapp/README.md (Tokens: ~76 | Category: plugin-manifest) -->\n# @ice/plugin-miniapp\n\n> Forked from [taro](https://github.com/NervJS/taro) with respect ❤️\n> Licensed under the MIT License\n> https://github.com/NervJS/taro/blob/main/LICENSE\n\nice.js plugin to enable miniapp development.\n\nSee [documentation](https://v3.ice.work) for more details.\n\n<!-- File: packages/plugin-moment-locales/README.md (Tokens: ~77 | Category: plugin-manifest) -->\n# @ice/plugin-moment-locales\n\nice.js Plugin for load moment locales and reduce size of moment.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport moment from '@ice/plugin-moment-locales';\n\nexport default defineConfig(() => ({\n  plugins: [\n    moment({\n      locales: ['zh-CN'],\n    }),\n  ],\n}));\n```\n\n<!-- File: packages/plugin-pha/README.md (Tokens: ~59 | Category: plugin-manifest) -->\n# @ice/plugin-pha\n\nAn ice.js plugin to enable PHA features.\n\n## Usage\n\n```js\nimport { defineConfig } from '@ice/app';\nimport pha from '@ice/plugin-pha';\n\nexport default defineConfig(() => ({\n  plugins: [pha()],\n}));\n```\n\n<!-- File: packages/plugin-rax-compat/README.md (Tokens: ~899 | Category: plugin-manifest) -->\n# @ice/plugin-rax-compat\n\nAn ice.js plugin for migrating `rax-app` projects.\n\n## Usage\n\nAdd plugin in `ice.config.mts`:\n\n```js\nimport { defineConfig } from 'ice';\nimport compatRax from '@ice/plugin-rax-compat';\n\nexport default defineConfig(() => ({\n  plugins: [compatRax({ /* options */ })],\n}));\n```\n\n## Options\n\n### `inlineStyle`\n\n- Default: `false`.\n- Enable stylesheet loader to import CSS files.\n\n### `cssModule`\n\n- Default: `true`\n- When `inlineStyle` enabled and `cssModule` disabled, process CSS Module files to inline included styles(not recommended).\n\n### `legacy`\n\n- Default: `false`\n- Enable legacy way to import rax as namespace, like `v0.6`:\n\n```typescript\nimport Rax from 'rax';\n\nRax.createContext();\n```\n\n## 说明\n\n这个插件将会处理这些兼容逻辑：\n\n- 类型定义，Rax 中的类型定义来自于 React 16.8 前，与 React 18 的类型定义存在一些差异。\n  - 这个插件会新增一个对 Rax namespace 进行声明的 .d.ts 文件，内部使用 React 类型定义来进行声明。\n\n- 别名，将组成 rax 核心逻辑的 rax- 包，如 rax-children 等，映射到 rax-compat 的内部实现。\n\n  - 同时，在启用 legacy 模式时，会将 rax 映射到 rax-compat-legacy-exports.ts，此文件支持了 Rax.createContext 这样的使用方式（Rax v0.6.x）。\n\n- JSX，插件内部将基于源码类型来调整 swc 的编译配置。\n\n  - 在源码中使用了 `@jsx createElement` annotation 时，将设置 jsx runtime 为 classic。\n  - 在源码导入了 rax 包时，将设置 importSource 为 rax-compat/runtime（与 React 18 保持一致）。\n\n- 样式，在启用 inlineStyle 时，插件内部将额外处理行内样式逻辑。\n\n  - 首先，JSXClassNameTransformer 会将源码中的 `<div className=\"header\" />` 的写法转换为 `<div style={styleSheet.header} />`。\n        - 注意，只有项目源码内的代码才会被转换。\n\n        - 注意，`<div className={'xxx'} />` 这样的写法不会被转换。\n            \n        - 注意，`import './x.module.css'` 这样的写法不会被转换。\n\n  - 接着，在 ClientSide，插件会覆盖原本的 Webpack Ruleset：\n\n    - 对于命中了 inlineStyle 的资源文件，会使用 stylesheet-loader 进行处理为 styleSheet 对象（非 css 文件还会先交由预处理器编译）。其它文件会保持原本的处理逻辑，即处理到额外的 CSS 文件中。\n    - 注意，目前在 --speedup 下此逻辑无法生效。\n    - 注意，如果禁用了 cssModule ，那么 .module.css(less/...) 文件也会被交由 stylesheet-loader 处理。\n\n- 在 ServerSide，对命中了 inlineStyle 的资源文件，会使用 esbuild 进行处理为 styleSheet 对象(文件的类型会被改变为 JS 文件)。\n\n关于行内样式的额外说明：\n\n- 只有项目源码中使用了 `className=\"xxx\"` 的写法，才会被转换为 `style={styleSheet.xxx}` 的写法，因此 CSS Module 使用的 `className={styles.xxx}` 这种写法也不会被转换。另外，来自 node_modules 的代码不会被转换。\n\n<!-- File: packages/plugin-request/README.md (Tokens: ~266 | Category: plugin-manifest) -->\n# @ice/plugin-request\n\nProvides a unified request method for ice.js projects.\n\n## Usage\n\n```bash\n$ npm i @ice/plugin-request -S\n```\n\nAdd plugin.\n\n```js title=\"ice.config.mts\"\nimport { defineConfig } from '@ice/app';\nimport request from '@ice/plugin-request';\n\nexport default defineConfig(() => ({\n  plugins: [\n    request(),\n  ],\n}));\n```\n\n## API\n\n### request\n\n```js title=\"service.ts\"\nimport { request } from 'ice';\n\nexport async function getUser(id) {\n  return await request(`/api/user/${id}`);\n}\n```\n\n### useRequest\n\n```js title=\"home.tsx\"\nimport { useEffect } from 'react';\nimport { useRequest } from 'ice';\n\nexport default function Home() {\n  const {\n    data,\n    error,\n    loading,\n    request\n  } = useRequest(service.getUser);\n\n  useEffect(() => {\n    request();\n  }, []);\n\n  if (error) {\n    return <div>failed to load</div>;\n  }\n  if (!data || loading) {\n    return <div>loading...</div>;\n  }\n  return (\n    <h2 className={styles.title}>\n      Name: {data.name} Age: {data.age}\n    </h2>\n  );\n}\n```\n\n<!-- File: packages/plugin-store/README.md (Tokens: ~112 | Category: plugin-manifest) -->\n# @ice/plugin-store\n\nA plugin of state management base on Redux and React Redux used in ice.js`.\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport store from '@ice/plugin-store';\n\nexport default defineConfig(() => ({\n  plugins: [\n    store(),\n  ],\n}));\n```\n\n## Options\n\n- `disableResetPageState` \n  - The default value is `false`.\n  - After it is turned on, the page state will not be reinitialized after switching the page and entering the original page again.\n\n<!-- File: packages/plugin-stream-error/README.md (Tokens: ~88 | Category: plugin-manifest) -->\n# @ice/plugin-stream-error\n\nA plugin for re-render app when stream error.\n\n## Usage\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport streamError from '@ice/plugin-stream-error';\n\nexport default defineConfig(() => ({\n  plugins: [\n    streamError(),\n  ],\n}));\n```\n\n> Causion: This plugin only works when stream content ends with javascripts which triggered an custom event of `stream_end`\n\n<!-- File: packages/plugin-unocss/README.md (Tokens: ~346 | Category: plugin-manifest) -->\n# @ice/plugin-unocss\n\nA plugin for enable unocss in your app based on `@ice/app`.\n\n\n## Usage\n\nInstall `@ice/plugin-unocss`:\n\n```bash\n$ npm install @ice/plugin-unocss --save-dev\n```\n\nConfigure it in `ice.config.mts`:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport Unocss from '@ice/plugin-unocss';\n\nexport default defineConfig(() => ({\n  plugins: [\n    Unocss(),\n  ]\n}));\n```\n\n## Plugin Options\n\nPlugin options is as same as [UnoCSS ConfigFle](https://unocss.dev/guide/config-file).\n\nPlugin has a default preset `@unocss/preset-uno` for UnoCSS. You can pass options of presets to override the default preset:\n\n```ts\nimport { defineConfig } from '@ice/app';\nimport Unocss from '@ice/plugin-unocss';\nimport {\n  defineConfig,\n  presetAttributify,\n  presetIcons,\n  presetTypography,\n  presetUno,\n  presetWebFonts,\n  transformerDirectives,\n  transformerVariantGroup\n} from 'unocss';\n\nexport default defineConfig(() => ({\n  plugins: [\n    Unocss({\n      shortcuts: [\n        // ...\n      ],\n      theme: {\n        colors: {\n          // ...\n        }\n      },\n      presets: [\n        presetUno(),\n        presetAttributify(),\n        presetIcons(),\n        presetTypography(),\n        presetWebFonts({\n          fonts: {\n            // ...\n          },\n        }),\n      ],\n      transformers: [\n        transformerDirectives(),\n        transformerVariantGroup(),\n      ],\n    }),\n  ],\n}));\n```\n\n<!-- ... +9 more modular skills available via /api/skills/alibaba/ice?path={path} -->\n</yakaai_skills>"}