├── website ├── static │ ├── .nojekyll │ ├── CNAME │ └── img │ │ ├── favicon.ico │ │ ├── tutorial │ │ ├── localeDropdown.png │ │ └── docsVersionDropdown.png │ │ └── logo.svg ├── docs │ ├── tutorial-basics │ │ ├── create-app.md │ │ └── _category_.json │ ├── tutorial-extras │ │ ├── version-control.md │ │ └── _category_.json │ └── intro.md ├── babel.config.js ├── src │ ├── pages │ │ ├── markdown-page.md │ │ ├── index.module.css │ │ └── index.js │ ├── components │ │ ├── HomepageFeatures.module.css │ │ └── HomepageFeatures.js │ └── css │ │ └── custom.css ├── .gitignore ├── sidebars.js ├── README.md ├── package.json └── docusaurus.config.js ├── .eslintignore ├── packages ├── fronts │ ├── index.ts │ ├── test │ │ └── index.test.ts │ ├── src │ │ ├── getAppName.ts │ │ ├── constants.ts │ │ ├── getUid.ts │ │ ├── loadApp.ts │ │ ├── getMeta.ts │ │ ├── unmount.ts │ │ ├── injectDependencies.ts │ │ ├── index.ts │ │ ├── injectScript.ts │ │ ├── cache.ts │ │ ├── boot.ts │ │ ├── loadScript.ts │ │ ├── injectStyle.ts │ │ ├── useApp.ts │ │ ├── useIframe.ts │ │ ├── interface.ts │ │ ├── useWebComponents.ts │ │ └── importApp.ts │ ├── README.md │ └── package.json ├── fronts-react │ ├── index.ts │ ├── test │ │ └── index.test.ts │ ├── src │ │ ├── index.ts │ │ ├── useIframe.tsx │ │ ├── interface.ts │ │ ├── useApp.tsx │ │ └── useWebComponents.tsx │ ├── README.md │ └── package.json ├── fronts-test │ ├── index.ts │ ├── src │ │ ├── index.ts │ │ ├── context.ts │ │ └── runner.ts │ ├── README.md │ └── package.json ├── fronts-vue │ ├── index.ts │ ├── test │ │ └── index.test.ts │ ├── src │ │ ├── useApp.tsx │ │ ├── useIframe.tsx │ │ ├── useWebComponents.tsx │ │ ├── index.ts │ │ └── interface.ts │ ├── README.md │ └── package.json ├── fronts-bundler │ ├── index.ts │ ├── test │ │ └── index.test.ts │ ├── src │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── utils.ts │ │ ├── getSiteConfig.ts │ │ ├── createWebpackConfig.ts │ │ ├── interface.ts │ │ └── insertStyle.ts │ ├── README.md │ └── package.json └── fronts-transport │ ├── index.ts │ ├── src │ ├── index.ts │ ├── postMessage.ts │ └── globalTransport.ts │ ├── README.md │ └── package.json ├── examples ├── all-features │ ├── app5 │ │ ├── index.html │ │ ├── src │ │ │ ├── bootstrap.js │ │ │ ├── main.js │ │ │ └── Layout.js │ │ ├── site.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app6 │ │ ├── index.html │ │ ├── site.json │ │ ├── src │ │ │ ├── logo.png │ │ │ ├── components │ │ │ │ └── Button.js │ │ │ ├── main.js │ │ │ └── App.js │ │ ├── package.json │ │ └── webpack.config.js │ ├── app1 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── bootstrap.tsx │ │ │ ├── Navigation.tsx │ │ │ ├── HomePage.tsx │ │ │ └── App.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── site.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app2 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── ButtonContainer.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── site.dev.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app3 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── Button.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── site.json │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app4 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── Button.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── site.json │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── lerna.json │ └── package.json ├── basic │ ├── app1 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── Navigation.tsx │ │ │ ├── bootstrap.tsx │ │ │ ├── HomePage.tsx │ │ │ └── App.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── site.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app2 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── ButtonContainer.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── site.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app3 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── Button.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── site.json │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app4 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── Button.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── lerna.json │ └── package.json ├── version-control │ ├── app1 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── Navigation.tsx │ │ │ ├── bootstrap.tsx │ │ │ ├── HomePage.tsx │ │ │ └── App.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── site.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app2 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── ButtonContainer.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── site.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app3 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── styles.css │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── Button.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── site.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── lerna.json │ ├── registry │ │ ├── api │ │ │ └── dev.json │ │ └── package.json │ └── package.json ├── non-module-federation │ ├── app1 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── Navigation.tsx │ │ │ ├── bootstrap.tsx │ │ │ ├── HomePage.tsx │ │ │ └── App.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app2 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── ButtonContainer.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── app3 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.tsx │ │ │ ├── bootstrap.tsx │ │ │ └── Button.tsx │ │ ├── public │ │ │ └── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── webpack.config.js │ ├── lerna.json │ └── package.json └── vite-react-simple │ ├── webpack-spa │ ├── src │ │ ├── index.js │ │ ├── bootstrap.js │ │ ├── Button.js │ │ └── App.js │ ├── .gitignore │ ├── package.json │ ├── index.html │ └── webpack.config.js │ ├── rs-sidecart │ ├── src │ │ ├── index.js │ │ └── Header.jsx │ ├── .babelrc │ ├── package.json │ ├── webpack.config.js │ └── .gitignore │ ├── vite-react │ ├── src │ │ ├── vite-env.d.ts │ │ ├── types │ │ │ └── fr.d.ts │ │ ├── main.tsx │ │ ├── index.css │ │ ├── App.css │ │ ├── App.tsx │ │ ├── favicon.svg │ │ ├── logo.svg │ │ └── index.js │ ├── .gitignore │ ├── tsconfig.json │ ├── package.json │ ├── index.html │ ├── plugins │ │ └── vite-plugin-transform-html.js │ ├── vite.config.ts │ └── serve.js │ └── README.md ├── .prettierrc ├── lerna.json ├── .vscode └── settings.json ├── scripts ├── jest │ ├── dev.config.json │ └── prod.config.json ├── workspaces.ts ├── build.ts ├── rollup.ts └── typescript.ts ├── .editorconfig ├── .github └── workflows │ ├── npm-publish.yml │ └── nodejs.yml ├── docs └── TODO.md ├── .eslintrc ├── LICENSE ├── .gitignore ├── global.d.ts ├── logo.svg └── package.json /website/static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /website/static/CNAME: -------------------------------------------------------------------------------- 1 | fronts.js.org 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | examples 3 | -------------------------------------------------------------------------------- /packages/fronts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/fronts-react/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/fronts-test/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/fronts-vue/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /examples/all-features/app5/index.html: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /examples/all-features/app6/index.html: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /examples/basic/app1/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/basic/app2/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/basic/app3/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/basic/app4/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /packages/fronts-bundler/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /packages/fronts-transport/index.ts: -------------------------------------------------------------------------------- 1 | export * from './src'; 2 | -------------------------------------------------------------------------------- /examples/all-features/app1/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/all-features/app2/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/all-features/app3/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/all-features/app4/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/all-features/app5/src/bootstrap.js: -------------------------------------------------------------------------------- 1 | import("./main.js"); 2 | -------------------------------------------------------------------------------- /examples/version-control/app1/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./bootstrap"); 2 | -------------------------------------------------------------------------------- /examples/version-control/app2/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./bootstrap"); 2 | -------------------------------------------------------------------------------- /examples/version-control/app3/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./bootstrap"); 2 | -------------------------------------------------------------------------------- /packages/fronts/test/index.test.ts: -------------------------------------------------------------------------------- 1 | test("", () => { 2 | // 3 | }); 4 | -------------------------------------------------------------------------------- /examples/non-module-federation/app1/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/non-module-federation/app2/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/non-module-federation/app3/src/index.ts: -------------------------------------------------------------------------------- 1 | import('./bootstrap'); 2 | -------------------------------------------------------------------------------- /examples/vite-react-simple/webpack-spa/src/index.js: -------------------------------------------------------------------------------- 1 | import("./bootstrap"); 2 | -------------------------------------------------------------------------------- /packages/fronts-react/test/index.test.ts: -------------------------------------------------------------------------------- 1 | test('', () => { 2 | // 3 | }); 4 | -------------------------------------------------------------------------------- /packages/fronts-vue/test/index.test.ts: -------------------------------------------------------------------------------- 1 | test('', () => { 2 | // 3 | }); 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /examples/version-control/app3/src/styles.css: -------------------------------------------------------------------------------- 1 | .button { 2 | color: red; 3 | } 4 | -------------------------------------------------------------------------------- /examples/vite-react-simple/rs-sidecart/src/index.js: -------------------------------------------------------------------------------- 1 | export default () => true; 2 | -------------------------------------------------------------------------------- /packages/fronts-bundler/test/index.test.ts: -------------------------------------------------------------------------------- 1 | test('', () => { 2 | // 3 | }); 4 | -------------------------------------------------------------------------------- /packages/fronts-bundler/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const identifier = '__FRONTS__'; 2 | -------------------------------------------------------------------------------- /packages/fronts/src/getAppName.ts: -------------------------------------------------------------------------------- 1 | export const getAppName = () => process.env.APP_NAME; 2 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "0.1.1" 6 | } 7 | -------------------------------------------------------------------------------- /packages/fronts-test/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './context'; 2 | export * from './runner'; 3 | -------------------------------------------------------------------------------- /website/docs/tutorial-basics/create-app.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | todo 6 | -------------------------------------------------------------------------------- /website/docs/tutorial-extras/version-control.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # todo 6 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | -------------------------------------------------------------------------------- /website/docs/tutorial-basics/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Tutorial - Basics", 3 | "position": 2 4 | } 5 | -------------------------------------------------------------------------------- /website/docs/tutorial-extras/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Tutorial - Extras", 3 | "position": 3 4 | } 5 | -------------------------------------------------------------------------------- /website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/fronts/HEAD/website/static/img/favicon.ico -------------------------------------------------------------------------------- /examples/all-features/app6/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app6", 3 | "exports": ["./src/components/Button"] 4 | } 5 | -------------------------------------------------------------------------------- /examples/vite-react-simple/webpack-spa/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | -------------------------------------------------------------------------------- /packages/fronts-transport/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from 'data-transport'; 2 | 3 | export * from './globalTransport'; 4 | -------------------------------------------------------------------------------- /packages/fronts/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const identifier = '__FRONTS__'; 2 | export const storePrefix = 'fronts:'; 3 | -------------------------------------------------------------------------------- /examples/basic/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["app1", "app2", "app3", "app4"], 3 | "version": "independent" 4 | } 5 | -------------------------------------------------------------------------------- /examples/vite-react-simple/rs-sidecart/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-react", "@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/all-features/app6/src/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/fronts/HEAD/examples/all-features/app6/src/logo.png -------------------------------------------------------------------------------- /examples/non-module-federation/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["app1", "app2", "app3"], 3 | "version": "independent" 4 | } 5 | -------------------------------------------------------------------------------- /website/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /examples/basic/app1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/basic/app2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/basic/app3/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/basic/app4/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/version-control/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["app1", "app2", "app3", "registry"], 3 | "version": "independent" 4 | } 5 | -------------------------------------------------------------------------------- /examples/all-features/app6/src/components/Button.js: -------------------------------------------------------------------------------- 1 | export default { 2 | template: ` 3 | 4 | `, 5 | }; 6 | -------------------------------------------------------------------------------- /examples/all-features/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["app1", "app2", "app3", "app4", "app5", "app6"], 3 | "version": "independent" 4 | } 5 | -------------------------------------------------------------------------------- /packages/fronts/src/getUid.ts: -------------------------------------------------------------------------------- 1 | export const getUid = (name: string) => 2 | `fronts-${name}-${Math.random().toString(36).slice(2, -1)}`; 3 | -------------------------------------------------------------------------------- /website/static/img/tutorial/localeDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/fronts/HEAD/website/static/img/tutorial/localeDropdown.png -------------------------------------------------------------------------------- /examples/all-features/app1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/all-features/app2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/all-features/app3/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/all-features/app4/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/version-control/app1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/version-control/app2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/version-control/app3/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /website/static/img/tutorial/docsVersionDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unadlib/fronts/HEAD/website/static/img/tutorial/docsVersionDropdown.png -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "frontends", 4 | "retarget", 5 | "retargeted", 6 | "unmount" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/non-module-federation/app1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/non-module-federation/app2/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/non-module-federation/app3/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /packages/fronts-vue/src/useApp.tsx: -------------------------------------------------------------------------------- 1 | import { UseApp } from './interface'; 2 | 3 | /** 4 | * 5 | */ 6 | export const useApp: UseApp = (options) => { 7 | // 8 | }; 9 | -------------------------------------------------------------------------------- /website/docs/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Tutorial Intro 6 | 7 | Let's discover **Fronts in less than 5 minutes**. 8 | 9 | todo 10 | -------------------------------------------------------------------------------- /packages/fronts-bundler/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './plugins'; 2 | export * from './interface'; 3 | export * from './createWebpackConfig'; 4 | export * from './insertStyle'; 5 | -------------------------------------------------------------------------------- /website/src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | # Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /examples/all-features/app5/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app5", 3 | "exports": ["./src/main"], 4 | "dependencies": { 5 | "app6": "http://localhost:3006/remoteEntry.js" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/all-features/app6/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import { App } from './App'; 3 | 4 | const app = createApp(App); 5 | app.mount(document.getElementById('app')); 6 | -------------------------------------------------------------------------------- /examples/basic/app3/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app3", 3 | "exports": ["./src/App"], 4 | "shared": { 5 | "react": { "singleton": true }, 6 | "react-dom": { "singleton": true } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/fronts-vue/src/useIframe.tsx: -------------------------------------------------------------------------------- 1 | import { UseIframe } from './interface'; 2 | 3 | /** 4 | * 5 | */ 6 | export const useIframe: UseIframe = ({ name, url = '', attrs = {} }) => { 7 | // 8 | }; 9 | -------------------------------------------------------------------------------- /packages/fronts-vue/src/useWebComponents.tsx: -------------------------------------------------------------------------------- 1 | import { UseWebComponents } from './interface'; 2 | 3 | /** 4 | * 5 | */ 6 | export const useWebComponents: UseWebComponents = (options) => { 7 | // 8 | }; 9 | -------------------------------------------------------------------------------- /examples/version-control/registry/api/dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "app1": "http://localhost:3001/remoteEntry.js", 3 | "app2": "http://localhost:3002/remoteEntry.js", 4 | "app3": "http://localhost:3003/remoteEntry.js" 5 | } 6 | -------------------------------------------------------------------------------- /examples/vite-react-simple/webpack-spa/src/bootstrap.js: -------------------------------------------------------------------------------- 1 | import App from "./App"; 2 | import React from "react"; 3 | import ReactDOM from "react-dom"; 4 | 5 | ReactDOM.render(, document.getElementById("root")); 6 | -------------------------------------------------------------------------------- /examples/basic/app1/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/basic/app2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/basic/app3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/basic/app4/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/all-features/app3/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app3", 3 | "exports": ["./src/App", "./src/bootstrap"], 4 | "shared": { 5 | "react": { "singleton": true }, 6 | "react-dom": { "singleton": true } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/all-features/app4/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app4", 3 | "exports": ["./src/App", "./src/bootstrap"], 4 | "shared": { 5 | "react": { "singleton": true }, 6 | "react-dom": { "singleton": true } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/src/types/fr.d.ts: -------------------------------------------------------------------------------- 1 | declare module "foo_app1/Button"; 2 | declare module "foo_rollup_spa/Header"; 3 | declare module "spa/header"; 4 | 5 | declare namespace Api { 6 | let name: string; 7 | } 8 | -------------------------------------------------------------------------------- /examples/all-features/app1/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/all-features/app2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/all-features/app3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/all-features/app4/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/version-control/app1/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/version-control/app2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/version-control/app3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /scripts/jest/dev.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "rootDir": "../../", 4 | "globals": { 5 | "__DEV__": true 6 | }, 7 | "testPathIgnorePatterns": [ 8 | "examples", 9 | "website" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /scripts/jest/prod.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "rootDir": "../../", 4 | "globals": { 5 | "__DEV__": false 6 | }, 7 | "testPathIgnorePatterns": [ 8 | "examples", 9 | "website" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /examples/non-module-federation/app1/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/non-module-federation/app2/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/non-module-federation/app3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "strict": true, 5 | "jsx": "react", 6 | "esModuleInterop": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/fronts/src/loadApp.ts: -------------------------------------------------------------------------------- 1 | import { DynamicImport } from './interface'; 2 | 3 | export const loadApp = (dynamicImport: DynamicImport, name: string) => { 4 | window.__FRONTS__DYNAMIC__IMPORT__ = true; 5 | return dynamicImport(name); 6 | }; 7 | -------------------------------------------------------------------------------- /packages/fronts-react/src/index.ts: -------------------------------------------------------------------------------- 1 | export { boot, loadScript, globalTransport, GlobalTransport } from 'fronts'; 2 | 3 | export * from './useApp'; 4 | export * from './interface'; 5 | export * from './useIframe'; 6 | export * from './useWebComponents'; 7 | -------------------------------------------------------------------------------- /packages/fronts-vue/src/index.ts: -------------------------------------------------------------------------------- 1 | export { boot, loadScript, globalTransport, GlobalTransport } from 'fronts'; 2 | 3 | export * from './useApp'; 4 | export * from './interface'; 5 | export * from './useIframe'; 6 | export * from './useWebComponents'; 7 | -------------------------------------------------------------------------------- /examples/basic/app4/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import LocalButton from './Button'; 3 | 4 | const App = () => ( 5 |
6 |

App 4

7 | 8 |
9 | ); 10 | 11 | export default App; 12 | -------------------------------------------------------------------------------- /packages/fronts-bundler/src/utils.ts: -------------------------------------------------------------------------------- 1 | export const getUrl = (externalLink: string) => { 2 | const link = new URL(externalLink.replace(/^.*@/, '')); 3 | const path = link.pathname.split('/').slice(0, -1).join('/'); 4 | return `${link.origin}${path}`; 5 | }; 6 | -------------------------------------------------------------------------------- /examples/basic/app1/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app1", 3 | "dependencies": { 4 | "app2": "http://localhost:3002/remoteEntry.js" 5 | }, 6 | "shared": { 7 | "react": { "singleton": true }, 8 | "react-dom": { "singleton": true } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/all-features/app4/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import LocalButton from './Button'; 3 | 4 | const App = () => ( 5 |
6 |

App 4 with iFrame

7 | 8 |
9 | ); 10 | 11 | export default App; 12 | -------------------------------------------------------------------------------- /examples/basic/app3/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import LocalButton from './Button'; 3 | 4 | const App = () => ( 5 |
6 |

Nested

7 |

App 3

8 | 9 |
10 | ); 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /examples/all-features/app3/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import LocalButton from './Button'; 3 | 4 | const App = () => ( 5 |
6 |

Nested

7 |

App 3

8 | 9 |
10 | ); 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /examples/version-control/app3/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from "react"; 2 | import LocalButton from "./Button"; 3 | 4 | const App = () => ( 5 |
6 |

Nested

7 |

App 3

8 | 9 |
10 | ); 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /examples/non-module-federation/app3/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import LocalButton from './Button'; 3 | 4 | const App = () => ( 5 |
6 |

Nested

7 |

App 3

8 | 9 |
10 | ); 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /examples/basic/app2/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app2", 3 | "exports": ["./src/App"], 4 | "dependencies": { 5 | "app3": "http://localhost:3003/remoteEntry.js" 6 | }, 7 | "shared": { 8 | "react": { "singleton": true }, 9 | "react-dom": { "singleton": true } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /website/src/components/HomepageFeatures.module.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | 3 | .features { 4 | display: flex; 5 | align-items: center; 6 | padding: 2rem 0; 7 | width: 100%; 8 | } 9 | 10 | .featureSvg { 11 | height: 200px; 12 | width: 200px; 13 | } 14 | -------------------------------------------------------------------------------- /examples/all-features/app6/src/App.js: -------------------------------------------------------------------------------- 1 | import Button from './components/Button'; 2 | 3 | export const App = { 4 | components: { 5 | App6Button: Button, 6 | }, 7 | template: ` 8 |

App6 with Vue

9 |
10 | 11 |
12 | `, 13 | }; -------------------------------------------------------------------------------- /examples/vite-react-simple/webpack-spa/src/Button.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const style = { 4 | background: "#800", 5 | color: "#fff", 6 | padding: 12, 7 | }; 8 | 9 | const Button = () => ; 10 | 11 | export default Button; 12 | -------------------------------------------------------------------------------- /packages/fronts/src/getMeta.ts: -------------------------------------------------------------------------------- 1 | import { identifier } from './constants'; 2 | import { getAppName } from './getAppName'; 3 | 4 | export const getMeta = () => { 5 | // TODO: uuid 6 | const info = { 7 | name: getAppName(), 8 | meta: window[identifier], 9 | }; 10 | return info; 11 | }; 12 | -------------------------------------------------------------------------------- /examples/all-features/app2/site.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app2", 3 | "exports": ["./src/App"], 4 | "dependencies": { 5 | "app3": "http://localhost:3003/remoteEntry.js" 6 | }, 7 | "shared": { 8 | "react": { "singleton": true }, 9 | "react-dom": { "singleton": true } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/fronts-test/src/context.ts: -------------------------------------------------------------------------------- 1 | type Context = Record; 2 | 3 | let context: Context = {}; 4 | 5 | export const useContext = (initialContext?: T) => { 6 | if (initialContext) { 7 | context = initialContext; 8 | } 9 | return context as T; 10 | }; 11 | -------------------------------------------------------------------------------- /examples/version-control/app3/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app3", 3 | "version": "1.0.0", 4 | "exports": ["./src/App", "./src/bootstrap"], 5 | "registry": "http://localhost:3000/dev.json", 6 | "shared": { 7 | "react": { "singleton": true }, 8 | "react-dom": { "singleton": true } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/basic/app2/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import ButtonContainer from './ButtonContainer'; 3 | 4 | const App: FC<{ version?: string }> = () => ( 5 |
6 |

Nested

7 |

App 2

8 | 9 |
10 | ); 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /examples/vite-react-simple/rs-sidecart/src/Header.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default () => ( 4 |
12 | Header 13 |
14 | ); 15 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById("root") 11 | ); 12 | -------------------------------------------------------------------------------- /examples/version-control/app1/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app1", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "app2": "1.0.0" 6 | }, 7 | "registry": "http://localhost:3000/dev.json", 8 | "shared": { 9 | "react": { "singleton": true }, 10 | "react-dom": { "singleton": true } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/all-features/app2/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import ButtonContainer from './ButtonContainer'; 3 | 4 | const App: FC<{ version?: string }> = () => ( 5 |
6 |

Nested

7 |

App 2

8 | 9 |
10 | ); 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /examples/version-control/app2/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from "react"; 2 | import ButtonContainer from "./ButtonContainer"; 3 | 4 | const App: FC<{ version?: string }> = () => ( 5 |
6 |

Nested

7 |

App 2

8 | 9 |
10 | ); 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /examples/non-module-federation/app2/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC } from 'react'; 2 | import ButtonContainer from './ButtonContainer'; 3 | 4 | const App: FC<{ version?: string }> = () => ( 5 |
6 |

Nested

7 |

App 2

8 | 9 |
10 | ); 11 | 12 | export default App; 13 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /examples/version-control/app2/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app2", 3 | "version": "1.0.0", 4 | "exports": ["./src/App"], 5 | "dependencies": { 6 | "app3": "1.0.0" 7 | }, 8 | "registry": "http://localhost:3000/dev.json", 9 | "shared": { 10 | "react": { "singleton": true }, 11 | "react-dom": { "singleton": true } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/fronts/README.md: -------------------------------------------------------------------------------- 1 | # fronts 2 | 3 | ![Node CI](https://github.com/unadlib/fronts/workflows/Node%20CI/badge.svg) 4 | 5 | A progressive micro frontends framework for building Web applications 6 | 7 | ## Usage 8 | 9 | ```sh 10 | yarn add fronts 11 | ``` 12 | 13 | You can visit [fronts.js.org](https://fronts.js.org/) for more documentation. 14 | -------------------------------------------------------------------------------- /examples/vite-react-simple/README.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | ```bash 4 | cd rs-sidecart yarn npm start 5 | cd webpack-spa yarn npm start 6 | cd vite-react yarn npm start 7 | ``` 8 | 9 | ## view 10 | 11 | ``` 12 | http://localhost:3000 13 | ``` 14 | 15 | ## build 16 | 17 | ``` 18 | npm run build 19 | 20 | npm run prod 21 | ``` 22 | -------------------------------------------------------------------------------- /examples/basic/app1/src/Navigation.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from 'react-router-dom'; 2 | import React from 'react'; 3 | 4 | const style = { border: '1px solid #000', padding: 12 }; 5 | 6 | const Navigation = () => ( 7 |
8 | Home - About 9 |
10 | ); 11 | 12 | export default Navigation; 13 | -------------------------------------------------------------------------------- /packages/fronts-vue/README.md: -------------------------------------------------------------------------------- 1 | # fronts-vue 2 | 3 | ![Node CI](https://github.com/unadlib/fronts/workflows/Node%20CI/badge.svg) 4 | 5 | A progressive micro frontends framework for building Web applications 6 | 7 | ## Usage 8 | 9 | ```sh 10 | yarn add fronts-vue 11 | ``` 12 | 13 | You can visit [fronts.js.org](https://fronts.js.org/) for more documentation. 14 | -------------------------------------------------------------------------------- /packages/fronts-react/README.md: -------------------------------------------------------------------------------- 1 | # fronts-react 2 | 3 | ![Node CI](https://github.com/unadlib/fronts/workflows/Node%20CI/badge.svg) 4 | 5 | A progressive micro frontends framework for building Web applications 6 | 7 | ## Usage 8 | 9 | ```sh 10 | yarn add fronts-react 11 | ``` 12 | 13 | You can visit [fronts.js.org](https://fronts.js.org/) for more documentation. 14 | -------------------------------------------------------------------------------- /packages/fronts-test/README.md: -------------------------------------------------------------------------------- 1 | # fronts-test 2 | 3 | ![Node CI](https://github.com/unadlib/fronts/workflows/Node%20CI/badge.svg) 4 | 5 | A progressive micro frontends framework for building Web applications 6 | 7 | ## Usage 8 | 9 | ```sh 10 | yarn add fronts-test 11 | ``` 12 | 13 | You can visit [fronts.js.org](https://fronts.js.org/) for more documentation. 14 | -------------------------------------------------------------------------------- /examples/version-control/app1/src/Navigation.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | import React from "react"; 3 | 4 | const style = { border: "1px solid #000", padding: 12 }; 5 | 6 | const Navigation = () => ( 7 |
8 | Home - About 9 |
10 | ); 11 | 12 | export default Navigation; 13 | -------------------------------------------------------------------------------- /packages/fronts-bundler/README.md: -------------------------------------------------------------------------------- 1 | # fronts-bundler 2 | 3 | ![Node CI](https://github.com/unadlib/fronts/workflows/Node%20CI/badge.svg) 4 | 5 | A progressive micro frontends framework for building Web applications 6 | 7 | ## Usage 8 | 9 | ```sh 10 | yarn add fronts-bundler 11 | ``` 12 | 13 | You can visit [fronts.js.org](https://fronts.js.org/) for more documentation. 14 | -------------------------------------------------------------------------------- /examples/non-module-federation/app1/src/Navigation.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from 'react-router-dom'; 2 | import React from 'react'; 3 | 4 | const style = { border: '1px solid #000', padding: 12 }; 5 | 6 | const Navigation = () => ( 7 |
8 | Home - About 9 |
10 | ); 11 | 12 | export default Navigation; 13 | -------------------------------------------------------------------------------- /examples/version-control/registry/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "registry", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "http-server api --cors -p 3000" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "http-server": "^0.12.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/fronts-transport/README.md: -------------------------------------------------------------------------------- 1 | # fronts-transport 2 | 3 | ![Node CI](https://github.com/unadlib/fronts/workflows/Node%20CI/badge.svg) 4 | 5 | A progressive micro frontends framework for building Web applications 6 | 7 | ## Usage 8 | 9 | ```sh 10 | yarn add fronts-transport 11 | ``` 12 | 13 | You can visit [fronts.js.org](https://fronts.js.org/) for more documentation. 14 | -------------------------------------------------------------------------------- /packages/fronts-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fronts-test", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "dist/index.cjs.js", 6 | "module": "dist/index.esm.js", 7 | "types": "dist/index.d.ts", 8 | "build": [ 9 | "cjs", 10 | "es" 11 | ], 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "author": "", 16 | "license": "MIT" 17 | } 18 | -------------------------------------------------------------------------------- /examples/basic/app1/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /examples/basic/app2/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /examples/basic/app3/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /examples/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "workspaces": [ 4 | "app1", 5 | "app2", 6 | "app3", 7 | "app4" 8 | ], 9 | "scripts": { 10 | "start": "lerna run --parallel start", 11 | "build": "lerna run build", 12 | "serve": "lerna run --parallel serve", 13 | "clean": "lerna run --parallel clean" 14 | }, 15 | "devDependencies": { 16 | "lerna": "^3.22.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/non-module-federation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "workspaces": [ 4 | "app1", 5 | "app2", 6 | "app3" 7 | ], 8 | "scripts": { 9 | "start": "lerna run --parallel start", 10 | "build": "lerna run build", 11 | "serve": "lerna run --parallel serve", 12 | "clean": "lerna run --parallel clean" 13 | }, 14 | "devDependencies": { 15 | "lerna": "^3.22.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/all-features/app1/site.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app1", 3 | "dependencies": { 4 | "app2": { 5 | "host": "http://localhost:3002", 6 | "main": "remoteEntry.js" 7 | }, 8 | "app4": "http://localhost:3004/remoteEntry.js", 9 | "app5": "http://localhost:3005/remoteEntry.js" 10 | }, 11 | "shared": { 12 | "react": { "singleton": true }, 13 | "react-dom": { "singleton": true } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/all-features/app1/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import { boot } from 'fronts'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /examples/all-features/app2/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import App from './App'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import { boot } from 'fronts'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /examples/all-features/app3/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /examples/all-features/app4/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /examples/version-control/app3/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!) 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /packages/fronts/src/unmount.ts: -------------------------------------------------------------------------------- 1 | import { InsertedStyle } from './interface'; 2 | 3 | export const unmount = (currentTarget: HTMLElement, name: string) => { 4 | const key = `__${name}__`; 5 | (window as any)[key] ??= {}; 6 | const insertedStyle: InsertedStyle = (window as any)[key]; 7 | insertedStyle.targets?.splice( 8 | insertedStyle.targets?.findIndex((target) => target === currentTarget), 9 | 1 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /examples/basic/app4/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts-react'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root'), 'app4'); 14 | -------------------------------------------------------------------------------- /examples/version-control/app1/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import { boot } from 'fronts'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /examples/version-control/app2/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | # install EditorConfig for VS Code extension 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | end_of_line = lf 9 | indent_size = 2 10 | indent_style = space 11 | insert_final_newline = true 12 | max_line_length = 80 13 | trim_trailing_whitespace = true 14 | 15 | [*.md] 16 | max_line_length = 0 17 | trim_trailing_whitespace = false 18 | -------------------------------------------------------------------------------- /examples/all-features/app1/src/Navigation.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from 'react-router-dom'; 2 | import React from 'react'; 3 | 4 | const style = { border: '1px solid #000', padding: 12 }; 5 | 6 | const Navigation = () => ( 7 |
8 | Home - App2 -{' '} 9 | App4 - App5 10 |
11 | ); 12 | 13 | export default Navigation; 14 | -------------------------------------------------------------------------------- /examples/version-control/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "workspaces": [ 4 | "app1", 5 | "app2", 6 | "app3", 7 | "registry" 8 | ], 9 | "scripts": { 10 | "start": "lerna run --parallel start", 11 | "build": "lerna run build", 12 | "serve": "lerna run --parallel serve", 13 | "clean": "lerna run --parallel clean" 14 | }, 15 | "devDependencies": { 16 | "lerna": "^3.22.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/basic/app1/src/HomePage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const style = { 4 | height: 400, 5 | backgroundColor: '#673ab7', 6 | color: 'white', 7 | padding: 12, 8 | }; 9 | 10 | const HomePage = () => ( 11 |
12 |

Home Page

13 |

Welcome to the future!

14 |

15 | a page being provided by App 1 16 |

17 |
18 | ); 19 | 20 | export default HomePage; 21 | -------------------------------------------------------------------------------- /examples/non-module-federation/app1/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts-react'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root'), 'app1'); 14 | -------------------------------------------------------------------------------- /examples/non-module-federation/app2/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts-react'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root'), 'app2'); 14 | -------------------------------------------------------------------------------- /examples/non-module-federation/app3/src/bootstrap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { boot } from 'fronts-react'; 4 | import App from './App'; 5 | 6 | export default function render(element: HTMLElement | null) { 7 | ReactDOM.render(, element); 8 | return () => { 9 | ReactDOM.unmountComponentAtNode(element!); 10 | }; 11 | } 12 | 13 | boot(render, document.getElementById('root'), 'app3'); 14 | -------------------------------------------------------------------------------- /examples/all-features/app1/src/HomePage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const style = { 4 | height: 400, 5 | backgroundColor: '#673ab7', 6 | color: 'white', 7 | padding: 12, 8 | }; 9 | 10 | const HomePage = () => ( 11 |
12 |

Home Page

13 |

Welcome to the future!

14 |

15 | a page being provided by App 1 16 |

17 |
18 | ); 19 | 20 | export default HomePage; 21 | -------------------------------------------------------------------------------- /examples/all-features/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "workspaces": [ 4 | "app1", 5 | "app2", 6 | "app3", 7 | "app4", 8 | "app5", 9 | "app6" 10 | ], 11 | "scripts": { 12 | "start": "lerna run --parallel start", 13 | "build": "lerna run build", 14 | "serve": "lerna run --parallel serve", 15 | "clean": "lerna run --parallel clean" 16 | }, 17 | "devDependencies": { 18 | "lerna": "^3.22.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/version-control/app1/src/HomePage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const style = { 4 | height: 400, 5 | backgroundColor: "#673ab7", 6 | color: "white", 7 | padding: 12, 8 | }; 9 | 10 | const HomePage = () => ( 11 |
12 |

Home Page

13 |

Welcome to the future!

14 |

15 | a page being provided by App 1 16 |

17 |
18 | ); 19 | 20 | export default HomePage; 21 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /examples/non-module-federation/app1/src/HomePage.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const style = { 4 | height: 400, 5 | backgroundColor: '#673ab7', 6 | color: 'white', 7 | padding: 12, 8 | }; 9 | 10 | const HomePage = () => ( 11 |
12 |

Home Page

13 |

Welcome to the future!

14 |

15 | a page being provided by App 1 16 |

17 |
18 | ); 19 | 20 | export default HomePage; 21 | -------------------------------------------------------------------------------- /examples/basic/app3/src/Button.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import * as React from 'react'; 3 | 4 | const style = { 5 | padding: 12, 6 | backgroundColor: 'aquamarine', 7 | }; 8 | 9 | const Button = () => { 10 | const [count, setCount] = React.useState(0); 11 | return ( 12 | 15 | ); 16 | }; 17 | 18 | export default Button; 19 | -------------------------------------------------------------------------------- /examples/basic/app4/src/Button.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import * as React from 'react'; 3 | 4 | const style = { 5 | padding: 12, 6 | backgroundColor: 'aquamarine', 7 | }; 8 | 9 | const Button = () => { 10 | const [count, setCount] = React.useState(0); 11 | return ( 12 | 15 | ); 16 | }; 17 | 18 | export default Button; 19 | -------------------------------------------------------------------------------- /examples/all-features/app4/src/Button.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import * as React from 'react'; 3 | 4 | const style = { 5 | padding: 12, 6 | backgroundColor: 'aquamarine', 7 | }; 8 | 9 | const Button = () => { 10 | const [count, setCount] = React.useState(0); 11 | return ( 12 | 15 | ); 16 | }; 17 | 18 | export default Button; 19 | -------------------------------------------------------------------------------- /packages/fronts-transport/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fronts-transport", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "author": "unadlib", 13 | "license": "MIT", 14 | "dependencies": { 15 | "data-transport": "^2.1.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/non-module-federation/app3/src/Button.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import * as React from 'react'; 3 | 4 | const style = { 5 | padding: 12, 6 | backgroundColor: 'aquamarine', 7 | }; 8 | 9 | const Button = () => { 10 | const [count, setCount] = React.useState(0); 11 | return ( 12 | 15 | ); 16 | }; 17 | 18 | export default Button; 19 | -------------------------------------------------------------------------------- /examples/vite-react-simple/webpack-spa/src/App.js: -------------------------------------------------------------------------------- 1 | import LocalButton from "./Button"; 2 | import React from "react"; 3 | 4 | import Button from "./Button"; 5 | const Header = React.lazy(() => import("rollup_spa/Header")); 6 | 7 | const App = () => ( 8 |
9 | Loading the header
}> 10 |
11 | 12 |

Webpack Remote

13 | 14 | 18 | ); 19 | }; 20 | 21 | export default Button; 22 | -------------------------------------------------------------------------------- /packages/fronts-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fronts-vue", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "MIT", 15 | "peerDependencies": {}, 16 | "dependencies": { 17 | "fronts": "^0.1.1" 18 | }, 19 | "devDependencies": {} 20 | } 21 | -------------------------------------------------------------------------------- /packages/fronts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fronts", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "peerDependencies": { 13 | "data-transport": "^2.0.1" 14 | }, 15 | "dependencies": { 16 | "fronts-transport": "^0.1.1" 17 | }, 18 | "author": "unadlib", 19 | "license": "MIT" 20 | } 21 | -------------------------------------------------------------------------------- /packages/fronts/src/injectDependencies.ts: -------------------------------------------------------------------------------- 1 | import { identifier } from "./constants"; 2 | 3 | try { 4 | window[identifier] = window[identifier] ?? {}; 5 | window[identifier].__main__ = 6 | window[identifier].__main__ ?? process.env.APP_NAME; 7 | window[identifier].__entry__ = 8 | window[identifier].__entry__ ?? window.location.href; 9 | if (!window[identifier][process.env.APP_NAME!]) { 10 | window[identifier][process.env.APP_NAME!] = JSON.parse( 11 | process.env.FPM_DEPS! 12 | ); 13 | } 14 | } catch (e) { 15 | // 16 | } 17 | -------------------------------------------------------------------------------- /website/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | 3 | /** 4 | * CSS files with the .module.css suffix will be treated as CSS modules 5 | * and scoped locally. 6 | */ 7 | 8 | .heroBanner { 9 | padding: 4rem 0; 10 | text-align: center; 11 | position: relative; 12 | overflow: hidden; 13 | } 14 | 15 | @media screen and (max-width: 966px) { 16 | .heroBanner { 17 | padding: 2rem; 18 | } 19 | } 20 | 21 | .buttons { 22 | display: flex; 23 | align-items: center; 24 | justify-content: center; 25 | } 26 | -------------------------------------------------------------------------------- /examples/version-control/app3/src/Button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | // @ts-ignore 3 | import styles from './styles.css'; 4 | 5 | const style = { 6 | padding: 12, 7 | backgroundColor: 'aquamarine', 8 | }; 9 | 10 | const Button = () => { 11 | const [count, setCount] = React.useState(0); 12 | return ( 13 | 20 | ); 21 | }; 22 | 23 | export default Button; 24 | -------------------------------------------------------------------------------- /examples/all-features/app5/src/main.js: -------------------------------------------------------------------------------- 1 | import { boot } from 'fronts'; 2 | import { createApp } from 'vue'; 3 | import Layout from './Layout'; 4 | 5 | const App = { 6 | components: { 7 | layout: Layout, 8 | }, 9 | template: ` 10 |

Vue

11 |
12 | 13 |
14 | `, 15 | }; 16 | 17 | export default function render(element) { 18 | const app = createApp(App); 19 | app.mount(element); 20 | return () => { 21 | app.unmount(element); 22 | }; 23 | } 24 | 25 | boot(render, document.getElementById('app')); 26 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | publish-npm: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 14 15 | registry-url: https://registry.npmjs.org/ 16 | - run: yarn 17 | - run: yarn build 18 | - run: yarn test 19 | - run: npm run publish 20 | env: 21 | NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}} 22 | CI: true 23 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [12.x, 14.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: yarn install, build, and test 21 | run: | 22 | yarn install 23 | yarn build 24 | yarn test 25 | env: 26 | CI: true 27 | -------------------------------------------------------------------------------- /examples/basic/app2/src/ButtonContainer.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import App3 from 'app3/src/App'; 3 | 4 | const style = { 5 | padding: 12, 6 | backgroundColor: '#cccccc', 7 | }; 8 | 9 | const ButtonContainer = () => { 10 | const [count, setCount] = useState(0); 11 | return ( 12 |
13 | App 2 Container 14 | 17 |
18 |
19 | 20 |
21 | ); 22 | }; 23 | 24 | export default ButtonContainer; 25 | -------------------------------------------------------------------------------- /packages/fronts-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fronts-react", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "dist/index.cjs.js", 6 | "unpkg": "dist/index.umd.js", 7 | "module": "dist/index.esm.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "MIT", 15 | "peerDependencies": { 16 | "react": "^16.13.0" 17 | }, 18 | "dependencies": { 19 | "fronts": "^0.1.1" 20 | }, 21 | "devDependencies": { 22 | "@types/react": "^16.13.0", 23 | "react": "^16.13.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 5 | "allowJs": false, 6 | "skipLibCheck": false, 7 | "esModuleInterop": false, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "module": "ESNext", 12 | "moduleResolution": "Node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "noEmit": true, 16 | "jsx": "react", 17 | "typeRoots": ["./node_modules/@types", "src/types"] 18 | }, 19 | "include": ["./src", "serve.js"] 20 | } 21 | -------------------------------------------------------------------------------- /packages/fronts/src/index.ts: -------------------------------------------------------------------------------- 1 | import './injectDependencies'; 2 | 3 | export { globalTransport, GlobalTransport } from 'fronts-transport'; 4 | 5 | export * from './loadApp'; 6 | export * from './interface'; 7 | export * from './boot'; 8 | export * from './useApp'; 9 | export * from './useIframe'; 10 | export * from './useWebComponents'; 11 | export * from './importApp'; 12 | export * from './injectScript'; 13 | export * from './loadScript'; 14 | export * from './getAppName'; 15 | export * from './cache'; 16 | export * from './injectStyle'; 17 | export * from './getMeta'; 18 | export * from './unmount'; 19 | export * from './retargetEvents'; 20 | export * from './getUid'; 21 | -------------------------------------------------------------------------------- /packages/fronts-bundler/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fronts-bundler", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "dist/index.cjs.js", 6 | "module": "dist/index.esm.js", 7 | "types": "dist/index.d.ts", 8 | "build": [ 9 | "cjs", 10 | "es" 11 | ], 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "author": "", 16 | "license": "MIT", 17 | "peerDependencies": { 18 | "string-replace-loader": "^3.0.1", 19 | "webpack": "^5.37.0" 20 | }, 21 | "devDependencies": { 22 | "webpack": "^5.37.0" 23 | }, 24 | "dependencies": { 25 | "string-replace-loader": "^3.0.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/fronts-vue/src/interface.ts: -------------------------------------------------------------------------------- 1 | import { 2 | UseIframeOptions, 3 | UseWebComponentsOptions, 4 | UseAppOptions, 5 | } from 'fronts'; 6 | 7 | export type UseApp = ( 8 | options: Pick< 9 | UseAppOptions, 10 | Exclude, 'target'> 11 | > 12 | ) => any; 13 | 14 | export type UseWebComponents = < 15 | T extends Record = Record 16 | >( 17 | options: Pick< 18 | UseWebComponentsOptions, 19 | Exclude 20 | > 21 | ) => any; 22 | 23 | export type UseIframe = ( 24 | options: Pick< 25 | UseIframeOptions, 26 | Exclude, 'target'> 27 | > 28 | ) => any; 29 | -------------------------------------------------------------------------------- /website/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | module.exports = { 13 | // By default, Docusaurus generates a sidebar from the docs folder structure 14 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], 15 | 16 | // But you can create a sidebar manually 17 | /* 18 | tutorialSidebar: [ 19 | { 20 | type: 'category', 21 | label: 'Tutorial', 22 | items: ['hello'], 23 | }, 24 | ], 25 | */ 26 | }; 27 | -------------------------------------------------------------------------------- /packages/fronts/src/injectScript.ts: -------------------------------------------------------------------------------- 1 | export const injectScript = ({ 2 | url, 3 | resolve, 4 | reject, 5 | }: { 6 | url: string; 7 | resolve?: (value: unknown) => void; 8 | reject?: (reason?: any) => void; 9 | }) => { 10 | // TODO: resolve browser compatibility issues 11 | const element = document.createElement('script'); 12 | element.src = url; 13 | element.async = true; 14 | element.type = 'text/javascript'; 15 | element.onload = () => { 16 | resolve?.(null); 17 | document.head.removeChild(element); 18 | }; 19 | element.onerror = () => { 20 | // TODO: retry load script from urls 21 | document.head.removeChild(element); 22 | reject?.(`Script Error: ${url}`); 23 | }; 24 | document.head.appendChild(element); 25 | }; 26 | -------------------------------------------------------------------------------- /packages/fronts/src/cache.ts: -------------------------------------------------------------------------------- 1 | import { CacheContainer } from './interface'; 2 | 3 | class LocalStorage implements CacheContainer { 4 | getItem(key: string) { 5 | return window.localStorage.getItem(key); 6 | } 7 | 8 | setItem(key: string, value: string) { 9 | window.localStorage.setItem(key, value); 10 | } 11 | } 12 | 13 | let storage: CacheContainer = new LocalStorage(); 14 | 15 | export const setCacheContainer = (cacheContainer: CacheContainer) => { 16 | storage = cacheContainer; 17 | }; 18 | 19 | export const setCacheLink = (storageKey: string, depLink: string) => { 20 | // todo: check and fallback 21 | storage.setItem(storageKey, depLink); 22 | }; 23 | 24 | export const getCacheLink = (storageKey: string) => storage.getItem(storageKey); 25 | -------------------------------------------------------------------------------- /examples/vite-react-simple/webpack-spa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-spa-systemjs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "webpack-cli serve", 7 | "build": "webpack --mode production", 8 | "serve": "serve -d ./dist -p 8081 --cors", 9 | "clean": "rm -rf dist" 10 | }, 11 | "dependencies": { 12 | "@babel/preset-env": "^7.14.7", 13 | "react": "^16.13.1", 14 | "react-dom": "^16.13.1", 15 | "serve": "^12.0.0" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "7.16.5", 19 | "@babel/preset-react": "7.16.5", 20 | "babel-loader": "8.2.3", 21 | "npm-run-all": "4.1.5", 22 | "webpack": "5.61.0", 23 | "webpack-cli": "4.8.0", 24 | "webpack-dev-server": "4.2.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/vite-react-simple/webpack-spa/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Webpack Remote 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /examples/all-features/app5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app5", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "start": "webpack-cli serve", 6 | "serve": "serve dist -p 3005", 7 | "build": "webpack --mode production", 8 | "clean": "rm -rf dist" 9 | }, 10 | "dependencies": { 11 | "@babel/core": "^7.11.0", 12 | "babel-loader": "^8.1.0", 13 | "serve": "^11.3.2", 14 | "vue": "^3.0.0-rc.5" 15 | }, 16 | "devDependencies": { 17 | "@vue/compiler-sfc": "3.0.0", 18 | "css-loader": "5.0.1", 19 | "file-loader": "6.1.1", 20 | "html-webpack-plugin": "^5.5.0", 21 | "mini-css-extract-plugin": "1.2.1", 22 | "url-loader": "4.1.1", 23 | "vue-loader": "16.0.0-beta.8", 24 | "webpack": "^5.11.0", 25 | "webpack-cli": "^4.3.0", 26 | "webpack-dev-server": "^3.11.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/all-features/app6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app6", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "start": "webpack-cli serve", 6 | "serve": "serve dist -p 3006", 7 | "build": "webpack --mode production", 8 | "clean": "rm -rf dist" 9 | }, 10 | "dependencies": { 11 | "@babel/core": "^7.11.0", 12 | "babel-loader": "^8.1.0", 13 | "serve": "^11.3.2", 14 | "vue": "^3.0.0-rc.5" 15 | }, 16 | "devDependencies": { 17 | "@vue/compiler-sfc": "3.0.0", 18 | "css-loader": "5.0.1", 19 | "file-loader": "6.1.1", 20 | "html-webpack-plugin": "^5.5.0", 21 | "mini-css-extract-plugin": "1.2.1", 22 | "url-loader": "4.1.1", 23 | "vue-loader": "16.0.0-beta.8", 24 | "webpack": "^5.11.0", 25 | "webpack-cli": "^4.3.0", 26 | "webpack-dev-server": "^3.11.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /docs/TODO.md: -------------------------------------------------------------------------------- 1 | ## TODO 2 | 3 | - [ ] `fronts-webpack` - 2.10 4 | - [ ] `fronts-vite` - 2.10 5 | - [ ] `fronts-sandbox`- 2.10 6 | - [ ] `fronts-html`- 2.10 7 | - [ ] `fronts-vue`- 2.10 8 | - [ ] `fronts-ng` 9 | - [ ] UT/IT/E2E 10 | - [ ] Doc for API 11 | - [ ] Support static `import` for version control 12 | - [ ] refactor `import()` for version control 13 | - [ ] `fronts-svelte` 14 | - [ ] `fronts-solid` 15 | - [ ] `fronts-builder` 16 | - [ ] `fronts-cli` 17 | - [ ] `fronts-c4` 18 | - [ ] `fronts-ssr` 19 | - [ ] `fronts-registry` with `semver` for version control 20 | - [ ] `fronts-vscode-toolkit` 21 | - [ ] `fronts-extension` 22 | - [ ] `fronts-logger` 23 | - [ ] `fronts-sentry` 24 | - [ ] `fronts-reactant` 25 | - [ ] `fronts-reactant-share` 26 | - [ ] Building tools CLI 27 | - [ ] Error handling/Fallback 28 | - [ ] Logger/Debugger/Testing tools 29 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | 40 | button { 41 | font-size: calc(10px + 2vmin); 42 | } 43 | -------------------------------------------------------------------------------- /examples/basic/app3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app3", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "html-webpack-plugin": "^4.5.0", 12 | "serve": "^11.3.2", 13 | "webpack": "^5.11.0", 14 | "webpack-cli": "^4.3.0", 15 | "webpack-dev-server": "^3.11.0" 16 | }, 17 | "scripts": { 18 | "start": "webpack-cli serve", 19 | "build": "webpack --mode production", 20 | "serve": "serve dist -p 3003", 21 | "clean": "rm -rf dist" 22 | }, 23 | "dependencies": { 24 | "react": "^16.13.0", 25 | "react-dom": "^16.13.0", 26 | "react-router-dom": "^5.1.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/basic/app4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app4", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "html-webpack-plugin": "^4.5.0", 12 | "serve": "^11.3.2", 13 | "webpack": "^5.11.0", 14 | "webpack-cli": "^4.3.0", 15 | "webpack-dev-server": "^3.11.0" 16 | }, 17 | "scripts": { 18 | "start": "webpack-cli serve", 19 | "build": "webpack --mode production", 20 | "serve": "serve dist -p 3004", 21 | "clean": "rm -rf dist" 22 | }, 23 | "dependencies": { 24 | "react": "^16.13.0", 25 | "react-dom": "^16.13.0", 26 | "react-router-dom": "^5.1.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/all-features/app3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app3", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "html-webpack-plugin": "^4.5.0", 12 | "serve": "^11.3.2", 13 | "webpack": "^5.11.0", 14 | "webpack-cli": "^4.3.0", 15 | "webpack-dev-server": "^3.11.0" 16 | }, 17 | "scripts": { 18 | "start": "webpack-cli serve", 19 | "build": "webpack --mode production", 20 | "serve": "serve dist -p 3003", 21 | "clean": "rm -rf dist" 22 | }, 23 | "dependencies": { 24 | "react": "^16.13.0", 25 | "react-dom": "^16.13.0", 26 | "react-router-dom": "^5.1.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/all-features/app4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app4", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "html-webpack-plugin": "^4.5.0", 12 | "serve": "^11.3.2", 13 | "webpack": "^5.11.0", 14 | "webpack-cli": "^4.3.0", 15 | "webpack-dev-server": "^3.11.0" 16 | }, 17 | "scripts": { 18 | "start": "webpack-cli serve", 19 | "build": "webpack --mode production", 20 | "serve": "serve dist -p 3004", 21 | "clean": "rm -rf dist" 22 | }, 23 | "dependencies": { 24 | "react": "^16.13.0", 25 | "react-dom": "^16.13.0", 26 | "react-router-dom": "^5.1.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/non-module-federation/app3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app3", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "html-webpack-plugin": "^4.5.0", 12 | "serve": "^11.3.2", 13 | "webpack": "^5.11.0", 14 | "webpack-cli": "^4.3.0", 15 | "webpack-dev-server": "^3.11.0" 16 | }, 17 | "scripts": { 18 | "start": "webpack-cli serve", 19 | "build": "webpack --mode production", 20 | "serve": "serve dist -p 3003", 21 | "clean": "rm -rf dist" 22 | }, 23 | "dependencies": { 24 | "react": "^16.13.0", 25 | "react-dom": "^16.13.0", 26 | "react-router-dom": "^5.1.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/basic/app2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app2", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "html-webpack-plugin": "^4.5.0", 12 | "serve": "^11.3.2", 13 | "webpack": "^5.11.0", 14 | "webpack-cli": "^4.3.0", 15 | "webpack-dev-server": "^3.11.0" 16 | }, 17 | "scripts": { 18 | "start": "webpack-cli serve", 19 | "build": "webpack --mode production", 20 | "serve": "serve dist -p 3002", 21 | "clean": "rm -rf dist" 22 | }, 23 | "dependencies": { 24 | "app3": "^0.0.0", 25 | "react": "^16.13.0", 26 | "react-dom": "^16.13.0", 27 | "react-router-dom": "^5.1.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/all-features/app2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app2", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "html-webpack-plugin": "^4.5.0", 12 | "serve": "^11.3.2", 13 | "webpack": "^5.11.0", 14 | "webpack-cli": "^4.3.0", 15 | "webpack-dev-server": "^3.11.0" 16 | }, 17 | "scripts": { 18 | "start": "webpack-cli serve", 19 | "build": "webpack --mode production", 20 | "serve": "serve dist -p 3002", 21 | "clean": "rm -rf dist" 22 | }, 23 | "dependencies": { 24 | "app3": "^0.0.0", 25 | "react": "^16.13.0", 26 | "react-dom": "^16.13.0", 27 | "react-router-dom": "^5.1.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/version-control/app2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app2", 3 | "version": "1.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "html-webpack-plugin": "^4.5.0", 12 | "serve": "^11.3.2", 13 | "webpack": "^5.11.0", 14 | "webpack-cli": "^4.3.0", 15 | "webpack-dev-server": "^3.11.0" 16 | }, 17 | "scripts": { 18 | "start": "webpack-cli serve", 19 | "build": "webpack --mode production", 20 | "serve": "serve dist -p 3002", 21 | "clean": "rm -rf dist" 22 | }, 23 | "dependencies": { 24 | "app3": "^1.0.0", 25 | "react": "^16.13.0", 26 | "react-dom": "^16.13.0", 27 | "react-router-dom": "^5.1.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/non-module-federation/app2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app2", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "html-webpack-plugin": "^4.5.0", 12 | "serve": "^11.3.2", 13 | "webpack": "^5.11.0", 14 | "webpack-cli": "^4.3.0", 15 | "webpack-dev-server": "^3.11.0" 16 | }, 17 | "scripts": { 18 | "start": "webpack-cli serve", 19 | "build": "webpack --mode production", 20 | "serve": "serve dist -p 3002", 21 | "clean": "rm -rf dist" 22 | }, 23 | "dependencies": { 24 | "app3": "^0.0.0", 25 | "react": "^16.13.0", 26 | "react-dom": "^16.13.0", 27 | "react-router-dom": "^5.1.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 4 | 5 | ## Installation 6 | 7 | ```console 8 | yarn install 9 | ``` 10 | 11 | ## Local Development 12 | 13 | ```console 14 | yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ## Build 20 | 21 | ```console 22 | yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ## Deployment 28 | 29 | ```console 30 | GIT_USER= USE_SSH=true yarn deploy 31 | ``` 32 | 33 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 34 | -------------------------------------------------------------------------------- /examples/version-control/app3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app3", 3 | "version": "1.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "babel-loader": "^8.2.2", 11 | "css-loader": "^5.2.4", 12 | "html-webpack-plugin": "^4.5.0", 13 | "serve": "^11.3.2", 14 | "style-loader": "^2.0.0", 15 | "webpack": "^5.11.0", 16 | "webpack-cli": "^4.3.0", 17 | "webpack-dev-server": "^3.11.0" 18 | }, 19 | "scripts": { 20 | "start": "webpack-cli serve", 21 | "build": "webpack --mode production", 22 | "serve": "serve dist -p 3003", 23 | "clean": "rm -rf dist" 24 | }, 25 | "dependencies": { 26 | "react": "^16.13.0", 27 | "react-dom": "^16.13.0", 28 | "react-router-dom": "^5.1.2" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/basic/app1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app1", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "@types/react-router-dom": "^5.1.7", 11 | "babel-loader": "^8.2.2", 12 | "html-webpack-plugin": "^4.5.0", 13 | "serve": "^11.3.2", 14 | "webpack": "^5.11.0", 15 | "webpack-cli": "^4.3.0", 16 | "webpack-dev-server": "^3.11.0" 17 | }, 18 | "scripts": { 19 | "start": "webpack-cli serve --open", 20 | "build": "webpack --mode production", 21 | "serve": "serve dist -p 3001", 22 | "clean": "rm -rf dist" 23 | }, 24 | "dependencies": { 25 | "app2": "^0.0.0", 26 | "react": "^16.13.0", 27 | "react-dom": "^16.13.0", 28 | "react-router-dom": "^5.2.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/all-features/app1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app1", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "@types/react-router-dom": "^5.1.7", 11 | "babel-loader": "^8.2.2", 12 | "html-webpack-plugin": "^4.5.0", 13 | "serve": "^11.3.2", 14 | "webpack": "^5.11.0", 15 | "webpack-cli": "^4.3.0", 16 | "webpack-dev-server": "^3.11.0" 17 | }, 18 | "scripts": { 19 | "start": "webpack-cli serve --open", 20 | "build": "webpack --mode production", 21 | "serve": "serve dist -p 3001", 22 | "clean": "rm -rf dist" 23 | }, 24 | "dependencies": { 25 | "app2": "^0.0.0", 26 | "react": "^16.13.0", 27 | "react-dom": "^16.13.0", 28 | "react-router-dom": "^5.2.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/version-control/app1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app1", 3 | "version": "1.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "@types/react-router-dom": "^5.1.7", 11 | "babel-loader": "^8.2.2", 12 | "html-webpack-plugin": "^4.5.0", 13 | "serve": "^11.3.2", 14 | "webpack": "^5.11.0", 15 | "webpack-cli": "^4.3.0", 16 | "webpack-dev-server": "^3.11.0" 17 | }, 18 | "scripts": { 19 | "start": "webpack-cli serve --open", 20 | "build": "webpack --mode production", 21 | "serve": "serve dist -p 3001", 22 | "clean": "rm -rf dist" 23 | }, 24 | "dependencies": { 25 | "app2": "^1.0.0", 26 | "react": "^16.13.0", 27 | "react-dom": "^16.13.0", 28 | "react-router-dom": "^5.2.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/non-module-federation/app1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app1", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "@babel/core": "^7.12.10", 6 | "@babel/preset-react": "^7.12.10", 7 | "@babel/preset-typescript": "^7.12.7", 8 | "@types/react": "^17.0.0", 9 | "@types/react-dom": "^17.0.0", 10 | "@types/react-router-dom": "^5.1.7", 11 | "babel-loader": "^8.2.2", 12 | "html-webpack-plugin": "^4.5.0", 13 | "serve": "^11.3.2", 14 | "webpack": "^5.11.0", 15 | "webpack-cli": "^4.3.0", 16 | "webpack-dev-server": "^3.11.0" 17 | }, 18 | "scripts": { 19 | "start": "webpack-cli serve --open", 20 | "build": "webpack --mode production", 21 | "serve": "serve dist -p 3001", 22 | "clean": "rm -rf dist" 23 | }, 24 | "dependencies": { 25 | "app2": "^0.0.0", 26 | "react": "^16.13.0", 27 | "react-dom": "^16.13.0", 28 | "react-router-dom": "^5.2.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /website/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * Any CSS included here will be global. The classic template 4 | * bundles Infima by default. Infima is a CSS framework designed to 5 | * work well for content-centric websites. 6 | */ 7 | 8 | /* You can override the default Infima variables here. */ 9 | :root { 10 | --ifm-color-primary: #25c2a0; 11 | --ifm-color-primary-dark: rgb(33, 175, 144); 12 | --ifm-color-primary-darker: rgb(31, 165, 136); 13 | --ifm-color-primary-darkest: rgb(26, 136, 112); 14 | --ifm-color-primary-light: rgb(70, 203, 174); 15 | --ifm-color-primary-lighter: rgb(102, 212, 189); 16 | --ifm-color-primary-lightest: rgb(146, 224, 208); 17 | --ifm-code-font-size: 95%; 18 | } 19 | 20 | .docusaurus-highlight-code-line { 21 | background-color: rgb(72, 77, 91); 22 | display: block; 23 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 24 | padding: 0 var(--ifm-pre-padding); 25 | } 26 | -------------------------------------------------------------------------------- /packages/fronts/src/boot.ts: -------------------------------------------------------------------------------- 1 | import { NodeElement, Render } from './interface'; 2 | 3 | export const boot = (render: Render, element: NodeElement, name?: string) => { 4 | if (!window.__FRONTS__DYNAMIC__IMPORT__) { 5 | render(element); 6 | } 7 | if (typeof name !== 'undefined') { 8 | if (typeof name !== 'string') { 9 | throw new Error(`The current App name should be a string.`); 10 | } else { 11 | // for non-module-federation 12 | window.__FRONTS__DYNAMIC__MODULES__ = 13 | window.__FRONTS__DYNAMIC__MODULES__ ?? {}; 14 | window.__FRONTS__DYNAMIC__MODULES__[name] = { default: render }; 15 | if (window.__FRONTS__FETCH__MODULES__?.[name]) { 16 | for (const fn of window.__FRONTS__FETCH__MODULES__?.[name]) { 17 | try { 18 | fn(); 19 | } catch (e) { 20 | // handle error 21 | console.error(e); 22 | } 23 | } 24 | } 25 | } 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "node": true, 6 | "jest": true 7 | }, 8 | "extends": [ 9 | "prettier", 10 | "eslint:recommended", 11 | "plugin:@typescript-eslint/eslint-recommended", 12 | "plugin:@typescript-eslint/recommended" 13 | ], 14 | "globals": { 15 | "Atomics": "readonly", 16 | "SharedArrayBuffer": "readonly" 17 | }, 18 | "parser": "@typescript-eslint/parser", 19 | "parserOptions": { 20 | "ecmaFeatures": { 21 | "jsx": true 22 | }, 23 | "ecmaVersion": 2019, 24 | "sourceType": "module" 25 | }, 26 | "plugins": ["prettier", "@typescript-eslint"], 27 | "rules": { 28 | "@typescript-eslint/no-non-null-assertion": 0, 29 | "@typescript-eslint/explicit-module-boundary-types": 0 30 | }, 31 | "settings": { 32 | "import/resolver": { 33 | "node": { 34 | "extensions": [".js", ".jsx", ".ts", ".tsx"] 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/non-module-federation/app1/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const path = require('path'); 3 | 4 | module.exports = { 5 | entry: './src/index', 6 | mode: 'development', 7 | devServer: { 8 | contentBase: path.join(__dirname, 'dist'), 9 | port: 3001, 10 | }, 11 | output: { 12 | filename: 'bundle.js', 13 | }, 14 | resolve: { 15 | extensions: ['.ts', '.tsx', '.js', '.jsx'], 16 | alias: { 17 | react: path.resolve(__dirname, '../../../node_modules/react'), 18 | }, 19 | }, 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.(j|t)sx?$/, 24 | loader: 'babel-loader', 25 | exclude: /node_modules/, 26 | options: { 27 | presets: ['@babel/preset-react', '@babel/preset-typescript'], 28 | }, 29 | }, 30 | ], 31 | }, 32 | plugins: [ 33 | new HtmlWebpackPlugin({ 34 | template: './public/index.html', 35 | }), 36 | ], 37 | }; 38 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.0.0", 3 | "scripts": { 4 | "start": "nodemon serve.js", 5 | "dev": "vite", 6 | "build": "tsc && vite build", 7 | "serve": "vite preview", 8 | "prod": "cross-env NODE_ENV=production node serve.js" 9 | }, 10 | "dependencies": { 11 | "compression": "^1.7.4", 12 | "express": "^4.17.1", 13 | "lodash-es": "^4.17.21", 14 | "react": "^17.0.0", 15 | "react-dom": "^17.0.0", 16 | "serve-static": "^1.14.1" 17 | }, 18 | "devDependencies": { 19 | "@types/lodash-es": "4.17.5", 20 | "@types/react": "17.0.38", 21 | "@types/react-dom": "17.0.11", 22 | "@vitejs/plugin-react-refresh": "1.3.5", 23 | "cross-env": "7.0.3", 24 | "nodemon": "2.0.15", 25 | "typescript": "4.3.5", 26 | "vite": "2.4.1", 27 | "vite-plugin-externals": "0.1.5", 28 | "estree-walker": "1.0.1", 29 | "@rollup/plugin-virtual": "2.0.3", 30 | "magic-string": "0.25.7" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/vite-react-simple/vite-react/plugins/vite-plugin-transform-html.js: -------------------------------------------------------------------------------- 1 | const transformHtml = function (url) { 2 | return ` 3 | `; 13 | }; 14 | export default function htmlPlugin() { 15 | let isProd = process.env.NODE_ENV === "production"; 16 | return { 17 | name: "html-transform", 18 | transformIndexHtml(html) { 19 | if (!isProd) { 20 | html = html.replace(/(react(-dom)?).production.min/g, `$1.development`); 21 | } 22 | html = html.replace( 23 | /<\/script>/, 24 | transformHtml(`$1`) 25 | ); 26 | return html; 27 | }, 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /examples/vite-react-simple/rs-sidecart/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wp5-starter-react", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "build": "webpack --mode production", 6 | "build:dev": "webpack --mode development", 7 | "start": "webpack-cli serve", 8 | "serve": "serve -d ./dist -p 8080 --cors", 9 | "start:live": "webpack serve --open --mode development --liveReload" 10 | }, 11 | "license": "MIT", 12 | "author": { 13 | "name": "Jack Herrington", 14 | "email": "jherr@pobox.com" 15 | }, 16 | "devDependencies": { 17 | "@babel/core": "7.16.5", 18 | "@babel/preset-env": "7.16.5", 19 | "@babel/preset-react": "7.16.5", 20 | "babel-loader": "8.2.3", 21 | "css-loader": "6.5.1", 22 | "html-webpack-plugin": "5.5.0", 23 | "style-loader": "3.3.1", 24 | "webpack": "5.61.0", 25 | "webpack-cli": "4.8.0", 26 | "webpack-dev-server": "4.2.1" 27 | }, 28 | "dependencies": { 29 | "react": "^16.13.0", 30 | "react-dom": "^16.13.0", 31 | "serve": "^12.0.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/basic/app1/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const path = require('path'); 3 | const { createWebpackConfig } = require('fronts-bundler'); 4 | 5 | module.exports = createWebpackConfig({ 6 | entry: './src/index', 7 | mode: 'development', 8 | devServer: { 9 | contentBase: path.join(__dirname, 'dist'), 10 | port: 3001, 11 | }, 12 | output: { 13 | publicPath: 'auto', 14 | }, 15 | resolve: { 16 | extensions: ['.ts', '.tsx', '.js', '.jsx'], 17 | alias: { 18 | react: path.resolve(__dirname, '../../../node_modules/react'), 19 | }, 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.(j|t)sx?$/, 25 | loader: 'babel-loader', 26 | exclude: /node_modules/, 27 | options: { 28 | presets: ['@babel/preset-react', '@babel/preset-typescript'], 29 | }, 30 | }, 31 | ], 32 | }, 33 | plugins: [ 34 | new HtmlWebpackPlugin({ 35 | template: './public/index.html', 36 | }), 37 | ], 38 | }); 39 | -------------------------------------------------------------------------------- /examples/all-features/app1/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const path = require('path'); 3 | const { createWebpackConfig } = require('fronts-bundler'); 4 | 5 | module.exports = createWebpackConfig({ 6 | entry: './src/index', 7 | mode: 'development', 8 | devServer: { 9 | contentBase: path.join(__dirname, 'dist'), 10 | port: 3001, 11 | }, 12 | output: { 13 | publicPath: 'auto', 14 | }, 15 | resolve: { 16 | extensions: ['.ts', '.tsx', '.js', '.jsx'], 17 | alias: { 18 | react: path.resolve(__dirname, '../../../node_modules/react'), 19 | }, 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.(j|t)sx?$/, 25 | loader: 'babel-loader', 26 | exclude: /node_modules/, 27 | options: { 28 | presets: ['@babel/preset-react', '@babel/preset-typescript'], 29 | }, 30 | }, 31 | ], 32 | }, 33 | plugins: [ 34 | new HtmlWebpackPlugin({ 35 | template: './public/index.html', 36 | }), 37 | ], 38 | }); 39 | -------------------------------------------------------------------------------- /examples/version-control/app1/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const path = require('path'); 3 | const { createWebpackConfig } = require('fronts-bundler'); 4 | 5 | module.exports = createWebpackConfig({ 6 | entry: './src/index', 7 | mode: 'development', 8 | devServer: { 9 | contentBase: path.join(__dirname, 'dist'), 10 | port: 3001, 11 | }, 12 | output: { 13 | publicPath: 'auto', 14 | }, 15 | resolve: { 16 | extensions: ['.ts', '.tsx', '.js', '.jsx'], 17 | alias: { 18 | react: path.resolve(__dirname, '../../../node_modules/react'), 19 | }, 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.(j|t)sx?$/, 25 | loader: 'babel-loader', 26 | exclude: /node_modules/, 27 | options: { 28 | presets: ['@babel/preset-react', '@babel/preset-typescript'], 29 | }, 30 | }, 31 | ], 32 | }, 33 | plugins: [ 34 | new HtmlWebpackPlugin({ 35 | template: './public/index.html', 36 | }), 37 | ], 38 | }); 39 | -------------------------------------------------------------------------------- /examples/basic/app4/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const ModuleFederationPlugin = require('webpack').container 3 | .ModuleFederationPlugin; 4 | const path = require('path'); 5 | 6 | module.exports = { 7 | entry: './src/index', 8 | mode: 'development', 9 | devServer: { 10 | contentBase: path.join(__dirname, 'dist'), 11 | port: 3004, 12 | }, 13 | output: { 14 | filename: 'bundle.js', 15 | }, 16 | resolve: { 17 | extensions: ['.ts', '.tsx', '.js', '.jsx'], 18 | alias: { 19 | react: path.resolve(__dirname, '../../../node_modules/react'), 20 | }, 21 | }, 22 | module: { 23 | rules: [ 24 | { 25 | test: /\.(j|t)sx?$/, 26 | loader: 'babel-loader', 27 | exclude: /node_modules/, 28 | options: { 29 | presets: ['@babel/preset-react', '@babel/preset-typescript'], 30 | }, 31 | }, 32 | ], 33 | }, 34 | plugins: [ 35 | new HtmlWebpackPlugin({ 36 | template: './public/index.html', 37 | }), 38 | ], 39 | }; 40 | -------------------------------------------------------------------------------- /examples/non-module-federation/app2/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const ModuleFederationPlugin = require('webpack').container 3 | .ModuleFederationPlugin; 4 | const path = require('path'); 5 | 6 | module.exports = { 7 | entry: './src/index', 8 | mode: 'development', 9 | devServer: { 10 | contentBase: path.join(__dirname, 'dist'), 11 | port: 3002, 12 | }, 13 | output: { 14 | filename: 'bundle.js', 15 | }, 16 | resolve: { 17 | extensions: [".ts", ".tsx", ".js", ".jsx"], 18 | alias: { 19 | react: path.resolve(__dirname, '../../../node_modules/react'), 20 | }, 21 | }, 22 | module: { 23 | rules: [ 24 | { 25 | test: /\.(j|t)sx?$/, 26 | loader: 'babel-loader', 27 | exclude: /node_modules/, 28 | options: { 29 | presets: ['@babel/preset-react', '@babel/preset-typescript'], 30 | }, 31 | }, 32 | ], 33 | }, 34 | plugins: [ 35 | new HtmlWebpackPlugin({ 36 | template: './public/index.html', 37 | }), 38 | ], 39 | }; 40 | -------------------------------------------------------------------------------- /examples/non-module-federation/app3/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | const ModuleFederationPlugin = require('webpack').container 3 | .ModuleFederationPlugin; 4 | const path = require('path'); 5 | 6 | module.exports = { 7 | entry: './src/index', 8 | mode: 'development', 9 | devServer: { 10 | contentBase: path.join(__dirname, 'dist'), 11 | port: 3003, 12 | }, 13 | output: { 14 | filename: 'bundle.js', 15 | }, 16 | resolve: { 17 | extensions: ['.ts', '.tsx', '.js', '.jsx'], 18 | alias: { 19 | react: path.resolve(__dirname, '../../../node_modules/react'), 20 | }, 21 | }, 22 | module: { 23 | rules: [ 24 | { 25 | test: /\.(j|t)sx?$/, 26 | loader: 'babel-loader', 27 | exclude: /node_modules/, 28 | options: { 29 | presets: ['@babel/preset-react', '@babel/preset-typescript'], 30 | }, 31 | }, 32 | ], 33 | }, 34 | plugins: [ 35 | new HtmlWebpackPlugin({ 36 | template: './public/index.html', 37 | }), 38 | ], 39 | }; 40 | -------------------------------------------------------------------------------- /packages/fronts/src/loadScript.ts: -------------------------------------------------------------------------------- 1 | import { injectScript } from './injectScript'; 2 | import { Render } from './interface'; 3 | 4 | /** 5 | * Loading script with non-module-federation module 6 | */ 7 | export const loadScript = (url: string) => (name: string) => 8 | new Promise<{ 9 | default: Render; 10 | }>((resolve, reject) => { 11 | const app = window.__FRONTS__DYNAMIC__MODULES__?.[name]; 12 | if (typeof app !== 'undefined') { 13 | // Script have already been loaded. 14 | return resolve(app); 15 | } 16 | 17 | const onLoadApp = () => { 18 | const app = window.__FRONTS__DYNAMIC__MODULES__?.[name]; 19 | resolve(app); 20 | window.__FRONTS__FETCH__MODULES__[name].delete(onLoadApp); 21 | }; 22 | window.__FRONTS__FETCH__MODULES__ = window.__FRONTS__FETCH__MODULES__ ?? {}; 23 | window.__FRONTS__FETCH__MODULES__[name] = 24 | window.__FRONTS__FETCH__MODULES__[name] ?? new Set(); 25 | window.__FRONTS__FETCH__MODULES__[name].add(onLoadApp); 26 | 27 | injectScript({ 28 | url, 29 | reject, 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/fronts-react/src/useIframe.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo, useCallback, useEffect, useState } from 'react'; 2 | import { getIframeUrl, getUid } from 'fronts'; 3 | import { UseIframe } from './interface'; 4 | 5 | /** 6 | * 7 | */ 8 | export const useIframe: UseIframe = ({ name, url = '', attrs = {} }) => { 9 | const Iframe = useCallback( 10 | memo(() => { 11 | const [iframeUrl, setIframeUrl] = useState(url); 12 | if (__DEV__) { 13 | if (Object.hasOwnProperty.call(attrs, 'src')) { 14 | console.warn( 15 | `The iframe component of the site named "${name}" does not pass "src" props.` 16 | ); 17 | } 18 | } 19 | useEffect(() => { 20 | !iframeUrl && 21 | getIframeUrl(name).then((url) => { 22 | setIframeUrl(url); 23 | }); 24 | }, []); 25 | const uid = getUid(name); 26 | return iframeUrl ? ( 27 |