@xiaoman/o-modules
Ease to use micro-modules from any remote, with Native-JS function to attach component
Install
# use pnpm
pnpm install @xiaoman/o-modules
# use npm
npm install @xiaoman/o-modules
# use yarn
yarn add @xiaoman/o-modules
Features
🔨 With TypeScript, fully types💪 Fetch modules from multiple remote servers👀 Fetch on Demand
Usage
Step 1
Use exposeModule
to expose module on window:
import { exposeModule } from '@xiaoman/o-modules'
function moduleFn() {
return 'hello oModules'
}
exposeModule('HelloOModules', moduleFn)
use @xiaoman/webpack-plugin-module-manifest
or @xiaoman/vite-plugin-module-manifest
to generate module manifest, like:
{
"CustomerActions": {
"js": ["static/js/CustomerActions-b23edb27.js"],
"css": [
"static/css/entry-cb2eef2e.css",
"static/css/api-9fb5ff20.css",
"static/css/index.265f4a95.css",
"static/css/deal-data-d7649152.css",
"static/css/conf-c7843131.css",
"static/css/index.04fd6d71.css"
]
},
"Dynamic": {
"js": ["static/js/Dynamic-def41451.js"],
"css": [
"static/css/entry-cb2eef2e.css",
"static/css/api-9fb5ff20.css",
"static/css/index.265f4a95.css"
]
},
"Info": {
"js": ["static/js/Info-169de637.js"],
"css": [
"static/css/entry-cb2eef2e.css",
"static/css/api-9fb5ff20.css",
"static/css/InfoField-cbffb9bc.css"
]
},
"Tags": {
"js": ["static/js/Tags-8e020b71.js"],
"css": [
"static/css/entry-cb2eef2e.css",
"static/css/api-9fb5ff20.css",
"static/css/index.04fd6d71.css",
"static/css/index.265f4a95.css"
]
}
}
Step 2
Step 2-1
init oModules
// src/plugins/o-modules/valar.ts
import oModules from '@xiaoman/o-modules'
export async function useValarModules() {
const options = {
assetsRemote: 'https://127.0.0.1:5050/',
manifestPath: 'https://127.0.0.1:5050/vite-assets.json',
group: 'Valar' // stored all modules of the current remote server
}
return await oModules(options)
}
// NOTE: await top level support Chrome ≥ 89
// https://caniuse.com/mdn-javascript_operators_await_top_level
export const valarModules = await useValarModules()
// src/plugins/o-modules/tms.ts
import oModules from '@xiaoman/o-modules'
export async function useTmsModules() {
const options = {
assetsRemote: 'https://127.0.0.1:5055',
manifestPath: 'https://127.0.0.1:5055/webpack-assets.json',
group: 'TMS',
// ineject js/css files
inject: {
js: ['https://cdn.jsdelivr.net/npm/antd@5.0.0/dist/antd.min.js'],
css: ['https://cdn.jsdelivr.net/npm/antd@5.0.0/dist/reset.css']
}
}
return await oModules(options)
}
// NOTE: await top level support Chrome ≥ 89
// https://caniuse.com/mdn-javascript_operators_await_top_level
export const tmsModules = await useTmsModules()
Step 2-2
maybe you need to prefetch some modules
import { useValarModules } from 'src/plugins/o-modules/valar.ts'
// import { valarModules } from 'src/plugins/o-modules/valar.ts'
const valarModules = await useValarModules()
valarModules.prefetchModules(['CustomerCard', 'CustomerList'])
import { useTmsModules } from 'src/plugins/o-modules/valar.ts'
// import { tmsModules } from 'src/plugins/o-modules/valar.ts'
const tmsModules = await useTmsModules()
tmsModules.prefetchModules(['TmsCard', 'TmsList'])
Step 3
use fetchModule
to attach component or module
import { useValarModules } from 'src/plugins/o-modules/valar.ts'
const valarModules = await useValarModules()
// fetch on Demand
const dynamic = await valarModules.fetchModule('DynamicTab')
dynamic({
container: '.remote-component-container',
props: {
companyInfo: props.companyInfo,
isOwner: props.isOwner,
companyId: props.companyInfo?.company_id
},
userInfo: userInfo?.value
})
Environment
All components supported in modern browsers, I try to ensure the support of neerly two or three versions.
I have limited energy and it's not start writing unit tests currently, if you encountered any bug, don't scold me and create a issue or PR.
Edge |
Firefox |
Chrome |
Safari |
iOS Safari |
Opera |
Electron |
---|---|---|---|---|---|---|
≥ 79 | ≥ 67 | ≥ 63 | ≥ 11.1 | ≥ 11 | ≥ 50 | last 2 versions |