{"id":13393685,"url":"https://github.com/ice-lab/icestark","last_synced_at":"2025-05-14T13:06:01.573Z","repository":{"id":34873871,"uuid":"185713295","full_name":"ice-lab/icestark","owner":"ice-lab","description":":tiger: Micro Frontends solution for large application（面向大型应用的微前端解决方案），站点国内镜像：https://icestark.gitee.io","archived":false,"fork":false,"pushed_at":"2025-05-14T08:53:17.000Z","size":5897,"stargazers_count":2063,"open_issues_count":148,"forks_count":175,"subscribers_count":42,"default_branch":"master","last_synced_at":"2025-05-14T09:48:20.997Z","etag":null,"topics":["frontend","micro-frontends","micro-frontends-solution","microfrontends","mpa","single-spa","spa"],"latest_commit_sha":null,"homepage":"https://micro-frontends.ice.work","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ice-lab.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-05-09T02:39:05.000Z","updated_at":"2025-04-28T03:21:22.000Z","dependencies_parsed_at":"2023-12-12T03:27:32.275Z","dependency_job_id":"9802c2cd-d67f-4c44-8eff-d6cd15373fa8","html_url":"https://github.com/ice-lab/icestark","commit_stats":{"total_commits":270,"total_committers":14,"mean_commits":"19.285714285714285","dds":0.7592592592592593,"last_synced_commit":"ec2d44244a2b4ebd7af0e0ff0a10f528b33b8a64"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-lab%2Ficestark","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-lab%2Ficestark/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-lab%2Ficestark/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-lab%2Ficestark/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ice-lab","download_url":"https://codeload.github.com/ice-lab/icestark/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254131198,"owners_count":22019909,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["frontend","micro-frontends","micro-frontends-solution","microfrontends","mpa","single-spa","spa"],"created_at":"2024-07-30T17:00:58.610Z","updated_at":"2025-05-14T13:06:01.519Z","avatar_url":"https://github.com/ice-lab.png","language":"TypeScript","readme":"English | [简体中文](https://ice-lab.github.io/icestark/)\n\n# icestark\n\n\u003e Micro Frontends solution for large application. [Website Chinese docs](https://ice-lab.github.io/icestark/).\n\n[![NPM version](https://img.shields.io/npm/v/@ice/stark.svg?style=flat)](https://npmjs.org/package/@ice/stark) [![build status](https://img.shields.io/travis/ice-lab/icestark.svg?style=flat-square)](https://travis-ci.org/ice-lab/icestark) [![Test coverage](https://img.shields.io/codecov/c/github/ice-lab/icestark.svg?style=flat-square)](https://codecov.io/gh/ice-lab/icestark) [![NPM downloads](http://img.shields.io/npm/dm/@ice/stark.svg?style=flat)](https://npmjs.org/package/@ice/stark) [![David deps](https://img.shields.io/david/ice-lab/icestark.svg?style=flat-square)](https://david-dm.org/ice-lab/icestark)\n\n## Features 🎉\n\n- No framework constraint for main\u0026sub applications, support React/Vue/Angular/...\n- Sub-application support multiple types of entry: js\u0026css, html entry, html content\n- Compatible with [single-spa](https://single-spa.js.org/) sub-application and lifecycles\n- JavaScript sandbox by `Proxy` API\n\n## Showcases 🎃\n\n### Vue main-application\n\nhttps://icestark-vue.surge.sh/\n\nMain-application based on Vue, And sub-applications based on React, Vue respectively.\n\n### React main-application\n\nhttps://icestark-react.surge.sh/\n\nMain-application based on React, And sub-applications based on React, Vue, Angular respectively.\n\n## Architecture\u0026Concepts 🚁\n\n\u003ca href=\"https://img.alicdn.com/tfs/TB167fiexD1gK0jSZFsXXbldVXa-1421-1416.png\" target=\"_blank\"\u003e\u003cimg src=\"https://img.alicdn.com/tfs/TB167fiexD1gK0jSZFsXXbldVXa-1421-1416.png\" height=\"600\" /\u003e\u003c/a\u003e\n\nConcepts:\n\n- Main-application: also named framework application, responsible for sub-applications registration\u0026load\u0026render, layout display (Header, Sidebar, Footer, etc.)\n- Sub-application: responsible for content display related to its own business\n\n## Getting Started 🥢🍚\n\n### Use Scaffold\n\nMain-application:\n\n```bash\n# Based on React\n$ npm init ice icestark-layout @icedesign/stark-layout-scaffold\n# Based on Vue\n$ npm init ice icestark-layout @vue-materials/icestark-layout-app\n\n$ cd icestark-layout\n$ npm install\n$ npm start\n```\n\nSub-application:\n\n```bash\n# Based on React\n$ npm init ice icestark-child @icedesign/stark-child-scaffold\n# Based on Vue\n$ npm init ice icestark-child @vue-materials/icestark-child-app\n\n$ cd icestark-child\n$ npm install\n$ npm run start\n```\n\n### Main-application\n\n#### setup in react app\n\n```javascript\n// src/App.jsx\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { AppRouter, AppRoute } from '@ice/stark';\n\nclass App extends React.Component {\n  onRouteChange = (pathname, query) =\u003e {\n    console.log(pathname, query);\n  };\n\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cdiv\u003ethis is common header\u003c/div\u003e\n        \u003cAppRouter\n          onRouteChange={this.onRouteChange}\n          ErrorComponent={\u003cdiv\u003ejs bundle loaded error\u003c/div\u003e}\n          NotFoundComponent={\u003cdiv\u003eNotFound\u003c/div\u003e}\n        \u003e\n          \u003cAppRoute\n            path={['/', '/message', '/about']}\n            exact\n            title=\"通用页面\"\n            url={['//unpkg.com/icestark-child-common/build/js/index.js']}\n          /\u003e\n          \u003cAppRoute\n            path=\"/seller\"\n            url={[\n              '//unpkg.com/icestark-child-seller/build/js/index.js',\n              '//unpkg.com/icestark-child-seller/build/css/index.css',\n            ]}\n          /\u003e\n        \u003c/AppRouter\u003e\n        \u003cdiv\u003ethis is common footer\u003c/div\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n\nReactDOM.render(\u003cApp /\u003e, document.getElementById('ice-container'));\n```\n\n- `AppRouter` locates the sub-application rendering node\n- `AppRoute` corresponds to the configuration of a sub-application, `path` configures all route information, `basename` configures a uniform route prefix, `url` configures assets url\n- `icestark` will follow the route parsing rules like to determine the current `path`, load the static resources of the corresponding sub-application, and render\n\n#### setup with APIs\n\n\u003e supported by @ice/stark@2.0.0\n\n```javascript\nimport { registerMicroApps } from '@ice/stark';\n\nregsiterMicroApps([\n  {\n    name: 'app1',\n    activePath: ['/', '/message', '/about'],\n    exact: true,\n    title: '通用页面',\n    container: document.getElementById('icestarkNode'),\n    url: ['//unpkg.com/icestark-child-common/build/js/index.js'],\n  },\n  {\n    name: 'app2',\n    activePath: '/seller',\n    title: '商家平台',\n    container: document.getElementById('icestarkNode'),\n    url: [\n      '//unpkg.com/icestark-child-seller/build/js/index.js',\n      '//unpkg.com/icestark-child-seller/build/css/index.css',\n    ],\n  },\n]);\n\nstart();\n```\n\nafter sub-application is registered, icestark will load app according to the `activePath`.\n\n### Sub-application\n\nsub-application can expose lifecycles in both register lifecycles and export lifecycles(umd) ways.\n\n#### 1. regsiter lifecycles\n\n```javascript\n// src/index.js\nimport ReactDOM from 'react-dom';\nimport { isInIcestark, getMountNode, registerAppEnter, registerAppLeave } from '@ice/stark-app';\nimport router from './router';\n\nif (isInIcestark()) {\n  const mountNode = getMountNode();\n\n  registerAppEnter(() =\u003e {\n    ReactDOM.render(router(), mountNode);\n  });\n\n  // make sure the unmount event is triggered\n  registerAppLeave(() =\u003e {\n    ReactDOM.unmountComponentAtNode(mountNode);\n  });\n} else {\n  ReactDOM.render(router(), document.getElementById('ice-container'));\n}\n```\n\n- Get the render `DOM Node` via `getMountNode`\n- Trigger app mount manually via `registerAppEnter`\n- Trigger app unmount manually via `registerAppLeave`\n\n```javascript\n// src/router.js\nimport React from 'react';\nimport { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';\nimport { renderNotFound, getBasename } from '@ice/stark-app';\n\nfunction List() {\n  return \u003cdiv\u003eList\u003c/div\u003e;\n}\n\nfunction Detail() {\n  return \u003cdiv\u003eDetail\u003c/div\u003e;\n}\n\nexport default class App extends React.Component {\n  render() {\n    return (\n      \u003cRouter basename={getBasename()}\u003e\n        \u003cSwitch\u003e\n          \u003cRoute path=\"/list\" component={List} /\u003e\n          \u003cRoute path=\"/detail\" component={Detail} /\u003e\n          \u003cRedirect exact from=\"/\" to=\"list\" /\u003e\n          \u003cRoute\n            component={() =\u003e {\n              return renderNotFound();\n            }}\n          /\u003e\n        \u003c/Switch\u003e\n      \u003c/Router\u003e\n    );\n  }\n}\n```\n\n- Get the `basename` configuration in the framework application via `getBasename`\n- `renderNotFound` triggers the framework application rendering global NotFound\n\n#### 2. exports lifecycles(umd)\n\nexports lifecycles in sub-application:\n\n```javascript\nimport ReactDOM from 'react-dom';\nimport App from './app';\n\nexport function mount(props) {\n  ReactDOM.render(\u003cApp /\u003e, document.getElementById('icestarkNode'));\n}\n\nexport function unmount() {\n  ReactDOM.unmountComponentAtNode(document.getElementById('icestarkNode'));\n}\n```\n\nsub-application should be bundled as an UMD module, add the following configuration of webpack:\n\n```javascript\nmodule.exports = {\n  output: {\n    library: 'sub-app-name',\n    libraryTarget: 'umd',\n  },\n};\n```\n\n## Documentation 📝\n\n[https://micro-frontends.ice.work/](https://micro-frontends.ice.work/)\n\n## Contributors\n\n\u003ctable\u003e\n\u003ctr\u003e\n    \u003ctd align=\"center\" style=\"word-wrap: break-word; width: 90.0; height: 90.0\"\u003e\n        \u003ca href=https://github.com/maoxiaoke\u003e\n            \u003cimg src=https://avatars.githubusercontent.com/u/13417006?v=4 width=\"60;\"  style=\"border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px\" alt=那吒/\u003e\n            \u003cbr /\u003e\n            \u003csub style=\"font-size:14px\"\u003e\u003cb\u003e那吒\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\" style=\"word-wrap: break-word; width: 90.0; height: 90.0\"\u003e\n        \u003ca href=https://github.com/ClarkXia\u003e\n            \u003cimg src=https://avatars.githubusercontent.com/u/4219965?v=4 width=\"60;\"  style=\"border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px\" alt=ClarkXia/\u003e\n            \u003cbr /\u003e\n            \u003csub style=\"font-size:14px\"\u003e\u003cb\u003eClarkXia\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\" style=\"word-wrap: break-word; width: 90.0; height: 90.0\"\u003e\n        \u003ca href=https://github.com/daysai\u003e\n            \u003cimg src=https://avatars.githubusercontent.com/u/18555391?v=4 width=\"60;\"  style=\"border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px\" alt=daysai/\u003e\n            \u003cbr /\u003e\n            \u003csub style=\"font-size:14px\"\u003e\u003cb\u003edaysai\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\" style=\"word-wrap: break-word; width: 90.0; height: 90.0\"\u003e\n        \u003ca href=https://github.com/imsobear\u003e\n            \u003cimg src=https://avatars.githubusercontent.com/u/2505411?v=4 width=\"60;\"  style=\"border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px\" alt=大果/\u003e\n            \u003cbr /\u003e\n            \u003csub style=\"font-size:14px\"\u003e\u003cb\u003e大果\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\" style=\"word-wrap: break-word; width: 90.0; height: 90.0\"\u003e\n        \u003ca href=https://github.com/temper357\u003e\n            \u003cimg src=https://avatars.githubusercontent.com/u/5419233?v=4 width=\"60;\"  style=\"border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px\" alt=站稳/\u003e\n            \u003cbr /\u003e\n            \u003csub style=\"font-size:14px\"\u003e\u003cb\u003e站稳\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\" style=\"word-wrap: break-word; width: 90.0; height: 90.0\"\u003e\n        \u003ca href=https://github.com/alvinhui\u003e\n            \u003cimg src=https://avatars.githubusercontent.com/u/4392234?v=4 width=\"60;\"  style=\"border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px\" alt=许文涛/\u003e\n            \u003cbr /\u003e\n            \u003csub style=\"font-size:14px\"\u003e\u003cb\u003e许文涛\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\" style=\"word-wrap: break-word; width: 90.0; height: 90.0\"\u003e\n        \u003ca href=https://github.com/skyFi\u003e\n            \u003cimg src=https://avatars.githubusercontent.com/u/12740180?v=4 width=\"60;\"  style=\"border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px\" alt=Skylor.Min/\u003e\n            \u003cbr /\u003e\n            \u003csub style=\"font-size:14px\"\u003e\u003cb\u003eSkylor.Min\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\" style=\"word-wrap: break-word; width: 90.0; height: 90.0\"\u003e\n        \u003ca href=https://github.com/liqupan\u003e\n            \u003cimg src=https://avatars.githubusercontent.com/u/21078925?v=4 width=\"60;\"  style=\"border-radius:50%;align-items:center;justify-content:center;overflow:hidden;padding-top:10px\" alt=liqupan/\u003e\n            \u003cbr /\u003e\n            \u003csub style=\"font-size:14px\"\u003e\u003cb\u003eliqupan\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\nFeel free to report any questions as an [issue](https://github.com/ice-lab/icestark/issues/new), we'd love to have your helping hand on `icestark`.\n\n## License\n\n[MIT](LICENSE)\n","funding_links":[],"categories":["Tools","TypeScript","Uncategorized","Micro-Frontends"],"sub_categories":["Uncategorized","Admin Template \u0026 Component Library","Frameworks"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fice-lab%2Ficestark","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fice-lab%2Ficestark","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fice-lab%2Ficestark/lists"}