feat: qiankun插件支持vite (#157)

* feat: qiankun支持vite

* fix: 优化根据meta创建qiankun子路由逻辑

* refactor: 优化模板代码
This commit is contained in:
听海 2022-11-29 11:12:51 +08:00 committed by GitHub
parent a3569bf1b0
commit 5c44181fcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 667 additions and 274 deletions

View File

@ -42,6 +42,11 @@ export default {
};
```
当使用 `vite` 构建时需注意,**name** 必须跟子应用 `package.json``name`保持一致。
### 第二步:装载子应用
#### 使用路由绑定的方式
@ -72,7 +77,7 @@ export default {
}
```
我们现在想在 `/son` 加载子应用 `app1`,只需要增加这样一些配置即可:
```js {16-23}
```js {16-21}
export default {
router: {
routes: [{
@ -92,8 +97,6 @@ export default {
"path": "/son",
"meta": {
"name": "son",
"title": "子应用",
"microApp": "app1"
}
}
]
@ -101,7 +104,7 @@ export default {
}
}
```
当前我们依然提倡约定路由的方式,`src/pages` 目录新建 `son.vue`
`src/pages` 目录新建 `son.vue`
```vue
<config>
{
@ -172,6 +175,17 @@ export default {
};
```
如果使用 `vite` 构建,当执行 `dev` 时需要额外配置:
```js
export default {
qiankun: {
micro: {
useDevMode: true
},
}
};
```
### 第二步:配置运行时生命周期钩子(可选)
插件会自动为你创建好 `qiankun` 子应用需要的生命周期钩子,但是如果你想在生命周期期间加一些自定义逻辑,可以在子应用的 `src/app.js` 里导出 `qiankun` 对象,并实现每一个生命周期钩子,其中钩子函数的入参 `props` 由主应用自动注入。
```js

View File

@ -1,10 +0,0 @@
// .fes.js 只负责管理编译时配置只能使用plain Object
export default {
qiankun: {
micro: {}
},
plugins: [
require.resolve('../../../fes-plugin-model/lib'),
require.resolve('../../../fes-plugin-qiankun/lib'),
]
};

View File

@ -1,38 +1,59 @@
// .fes.js 只负责管理编译时配置只能使用plain Object
export default {
access: {
roles: {
admin: ["*"]
}
admin: ['*'],
},
},
layout: {
title: "Fes.js",
title: 'vite 主应用',
footer: 'Created by MumbleFE',
multiTabs: false,
navigation: 'mixin',
menus: [{
menus: [
{
name: 'index',
}, {
title: "子应用",
children: [{
name: 'micro-index'
},{
name: 'micro-test'
}]
}]
},
{
title: 'webpack子应用',
children: [
{
name: 'webpack-micro-index',
},
{
name: 'webpack-micro-test',
},
],
},
{
title: 'vite子应用',
children: [
{
name: 'vite-micro-index',
},
{
name: 'vite-micro-test',
},
],
},
],
},
qiankun: {
main: {
apps: [
{
name: 'micro', // 唯一 id
name: 'webpack-micro', // 唯一 id
entry: '//localhost:9001', // html entry
props: {}, // 传递给子应用的数据
},
{
name: 'vite-micro', // 唯一 id
entry: '//localhost:8001', // html entry
props: {} // 传递给子应用的数据
}
]
}
props: {}, // 传递给子应用的数据
},
],
},
},
plugins: [
require.resolve('../../../fes-plugin-model/lib'),
@ -40,7 +61,5 @@ export default {
require.resolve('../../../fes-plugin-access/lib'),
require.resolve('../../../fes-plugin-qiankun/lib'),
],
presets: [
require.resolve('../../../fes-builder-vite/lib'),
]
presets: [require.resolve('../../../fes-builder-vite/lib')],
};

View File

@ -1,5 +1,5 @@
{
"name": "main",
"name": "vite-main",
"version": "2.0.0",
"description": "fes项目模版",
"scripts": {
@ -43,8 +43,8 @@
"access": "public"
},
"dependencies": {
"@fesjs/fes": "^2.0.0",
"vue": "^3.2.37",
"@fesjs/fes": "^2.0.0",
"@fesjs/fes-design": "^0.7.0"
},
"private": true

View File

@ -9,7 +9,7 @@ export const beforeRender = {
setTimeout(() => {
setRole('admin');
resolve();
}, 1000);
}, 100);
});
},
};

View File

@ -1,17 +1,18 @@
<template>
<div>
main
<input />
<FTabs v-model="activeKey">
<FTabPane name="Tab 1" value="1">
<MicroAppWithMemoHistory key="1" name="micro" url="/micro" />
<FTabPane name="webpack子应用首页" value="1">
<MicroAppWithMemoHistory key="1" name="webpack-micro" url="/webpack" />
</FTabPane>
<FTabPane name="Tab 2" value="2">
<MicroAppWithMemoHistory key="2" name="micro" url="/micro/test" />
<FTabPane name="webpack子应用测试页" value="2">
<MicroAppWithMemoHistory key="2" name="webpack-micro" url="/webpack/test" />
</FTabPane>
<FTabPane name="vite子应用首页" value="3">
<MicroAppWithMemoHistory key="3" name="vite-micro" url="/vite" />
</FTabPane>
<FTabPane name="vite子应用测试页" value="4">
<MicroAppWithMemoHistory key="4" name="vite-micro" url="/vite/test" />
</FTabPane>
<FTabPane name="Tab 3" value="3"> Content of Tab Pane 3 </FTabPane>
</FTabs>
</div>
</template>
<config>
{
@ -20,22 +21,15 @@
}
</config>
<script>
import { ref, onMounted } from 'vue';
import { ref } from 'vue';
import { MicroAppWithMemoHistory } from '@fesjs/fes';
import { FTabPane, FTabs } from '@fesjs/fes-design';
export default {
components: { FTabs, FTabPane, MicroAppWithMemoHistory },
setup() {
const url = ref('/micro/test');
onMounted(() => {
setTimeout(() => {
url.value = '/micro';
}, 3000);
});
return {
activeKey: ref('1'),
url,
};
},
};

View File

@ -1,7 +0,0 @@
<config>
{
"name": "micro-index",
"title": "子应用1-首页",
"microApp": "micro"
}
</config>

View File

@ -1,7 +0,0 @@
<config>
{
"name": "micro-test",
"title": "子应用1-测试",
"microApp": "micro"
}
</config>

View File

@ -0,0 +1,7 @@
<config>
{
"name": "vite-micro-index",
"title": "vite子应用-首页",
"microApp": "vite-micro"
}
</config>

View File

@ -0,0 +1,7 @@
<config>
{
"name": "vite-micro-test",
"title": "vite子应用-测试",
"microApp": "vite-micro"
}
</config>

View File

@ -0,0 +1,7 @@
<config>
{
"name": "webpack-micro-index",
"title": "webpack子应用-首页",
"microApp": "webpack-micro"
}
</config>

View File

@ -0,0 +1,7 @@
<config>
{
"name": "webpack-micro-test",
"title": "webpack子应用-测试",
"microApp": "webpack-micro"
}
</config>

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
<%= title %>
</title>
<link rel="shortcut icon" type="image/x-icon" href="./logo.png">
</head>
<body>
<div id="<%= mountElementId %>"></div>
</body>
</html>

View File

@ -0,0 +1,51 @@
{
"name": "vite-micro",
"version": "2.0.0",
"description": "fes项目模版",
"scripts": {
"build": "fes build",
"prod": "FES_ENV=prod fes build",
"analyze": "ANALYZE=1 fes build",
"dev": "fes dev",
"test": "fes test"
},
"keywords": [
"管理端",
"fes",
"fast",
"easy",
"strong"
],
"files": [
".eslintrc.js",
".gitignore",
".fes.js",
".fes.prod.js",
"mock.js",
"package.json",
"README.md",
"tsconfig.json",
"/src",
"/config"
],
"repository": {
"type": "git",
"url": "git+https://github.com/WeBankFinTech/fes.js.git",
"directory": "packages/fes-template"
},
"author": "harrywan",
"license": "MIT",
"bugs": {
"url": "https://github.com/WeBankFinTech/fes.js/issues"
},
"homepage": "https://github.com/WeBankFinTech/fes.js#readme",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@fesjs/fes": "^2.0.0",
"vue": "^3.2.37",
"@fesjs/fes-design": "^0.7.0"
},
"private": true
}

View File

@ -14,18 +14,18 @@ export const beforeRender = {
export const qiankun = {
//
async bootstrap(props) {
console.log('micro bootstrap', props);
console.log('vite micro bootstrap', props);
},
// render
async mount(props) {
console.log('micro mount', props);
console.log('vite micro mount', props);
},
// props
async update(props) {
console.log('micro update', props);
console.log('vite micro update', props);
},
//
async unmount(props) {
console.log('micro unmount', props);
console.log('vite micro unmount', props);
},
};

View File

@ -0,0 +1,3 @@
html, body {
margin: 0;
}

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -1,6 +1,5 @@
<template>
<div class="haizekuo">micro - index</div>
<input />
<div>vite - micro - index</div>
</template>
<config>
{
@ -17,5 +16,3 @@ export default {
},
};
</script>
<style scoped></style>

View File

@ -1,6 +1,5 @@
<template>
<div class="haizekuo">micro - test</div>
<input />
<div>vite - micro - test</div>
</template>
<config>
{
@ -17,5 +16,3 @@ export default {
},
};
</script>
<style scoped></style>

View File

@ -1 +1 @@
PORT=8080
PORT=9000

View File

@ -2,35 +2,57 @@
export default {
access: {
roles: {
admin: ["*"]
}
admin: ['*'],
},
},
layout: {
title: "Fes.js",
title: 'webpack 主应用',
footer: 'Created by MumbleFE',
multiTabs: false,
navigation: 'mixin',
menus: [{
menus: [
{
name: 'index',
}, {
title: "子应用1",
children: [{
name: 'micro-index'
},{
name: 'micro-test'
}]
}]
},
{
title: 'webpack子应用',
children: [
{
name: 'webpack-micro-index',
},
{
name: 'webpack-micro-test',
},
],
},
{
title: 'vite子应用',
children: [
{
name: 'vite-micro-index',
},
{
name: 'vite-micro-test',
},
],
},
],
},
qiankun: {
main: {
apps: [
{
name: 'micro', // 唯一 id
name: 'webpack-micro', // 唯一 id
entry: '//localhost:9001', // html entry
props: {}, // 传递给子应用的数据
},
{
name: 'vite-micro', // 唯一 id
entry: '//localhost:8001', // html entry
props: {} // 传递给子应用的数据
}
]
}
props: {}, // 传递给子应用的数据
},
],
},
},
plugins: [
require.resolve('../../../fes-plugin-model/lib'),
@ -38,7 +60,5 @@ export default {
require.resolve('../../../fes-plugin-access/lib'),
require.resolve('../../../fes-plugin-qiankun/lib'),
],
presets: [
require.resolve('../../../fes-builder-webpack/lib'),
]
presets: [require.resolve('../../../fes-builder-webpack/lib')],
};

View File

@ -1,5 +1,5 @@
{
"name": "main",
"name": "webpack-main",
"version": "2.0.0",
"description": "fes项目模版",
"scripts": {

View File

@ -1,16 +1,18 @@
<template>
<div>
main
<FTabs v-model="activeKey">
<FTabPane name="Tab 1" value="1">
<MicroAppWithMemoHistory key="1" name="micro" url="/micro" />
<FTabPane name="webpack子应用首页" value="1">
<MicroAppWithMemoHistory key="1" name="webpack-micro" url="/webpack" />
</FTabPane>
<FTabPane name="Tab 2" value="2">
<MicroAppWithMemoHistory key="2" name="micro" url="/micro/test" />
<FTabPane name="webpack子应用测试页" value="2">
<MicroAppWithMemoHistory key="2" name="webpack-micro" url="/webpack/test" />
</FTabPane>
<FTabPane name="vite子应用首页" value="3">
<MicroAppWithMemoHistory key="3" name="vite-micro" url="/vite" />
</FTabPane>
<FTabPane name="vite子应用测试页" value="4">
<MicroAppWithMemoHistory key="4" name="vite-micro" url="/vite/test" />
</FTabPane>
<FTabPane name="Tab 3" value="3"> Content of Tab Pane 3 </FTabPane>
</FTabs>
</div>
</template>
<config>
{
@ -19,22 +21,15 @@
}
</config>
<script>
import { ref, onMounted } from 'vue';
import { ref } from 'vue';
import { MicroAppWithMemoHistory } from '@fesjs/fes';
import { FTabPane, FTabs } from '@fesjs/fes-design';
export default {
components: { FTabs, FTabPane, MicroAppWithMemoHistory },
setup() {
const url = ref('/micro/test');
onMounted(() => {
setTimeout(() => {
url.value = '/micro';
}, 3000);
});
return {
activeKey: ref('1'),
url,
};
},
};

View File

@ -1,7 +0,0 @@
<config>
{
"name": "micro-index",
"title": "子应用1-首页",
"microApp": "micro"
}
</config>

View File

@ -1,7 +0,0 @@
<config>
{
"name": "micro-test",
"title": "子应用1-测试",
"microApp": "micro"
}
</config>

View File

@ -0,0 +1,7 @@
<config>
{
"name": "vite-micro-index",
"title": "vite子应用-首页",
"microApp": "vite-micro"
}
</config>

View File

@ -0,0 +1,7 @@
<config>
{
"name": "vite-micro-test",
"title": "vite子应用-测试",
"microApp": "vite-micro"
}
</config>

View File

@ -0,0 +1,7 @@
<config>
{
"name": "webpack-micro-index",
"title": "webpack子应用-首页",
"microApp": "webpack-micro"
}
</config>

View File

@ -0,0 +1,7 @@
<config>
{
"name": "webpack-micro-test",
"title": "webpack子应用-测试",
"microApp": "webpack-micro"
}
</config>

View File

@ -0,0 +1 @@
PORT=9001

View File

@ -1,5 +1,5 @@
{
"name": "micro",
"name": "webpack-micro",
"version": "2.0.0",
"description": "fes项目模版",
"scripts": {

View File

@ -0,0 +1,31 @@
import PageLoading from '@/components/PageLoading.vue';
export const beforeRender = {
loading: <PageLoading />,
action() {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 200);
});
},
};
export const qiankun = {
// 应用加载之前
async bootstrap(props) {
console.log('webpack micro bootstrap', props);
},
// 应用 render 之前触发
async mount(props) {
console.log('webpack micro mount', props);
},
// 当 props 更新时触发
async update(props) {
console.log('webpack micro update', props);
},
// 应用卸载之后触发
async unmount(props) {
console.log('webpack micro unmount', props);
},
};

View File

@ -0,0 +1,29 @@
<template>
<div class="page-loading">
<f-spin size="large" stroke="#5384ff" />
</div>
</template>
<script>
import { FSpin } from '@fesjs/fes-design';
export default {
components: {
FSpin,
},
setup() {
return {};
},
};
</script>
<style>
.page-loading {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,18 @@
<template>
<div>webpack - micro - index</div>
</template>
<config>
{
"name": "index",
"title": "home"
}
</config>
<script>
export default {
setup() {
return {
bigData: new Array(5 * 1024 * 1024),
};
},
};
</script>

View File

@ -0,0 +1,18 @@
<template>
<div>webpack - micro - test</div>
</template>
<config>
{
"name": "test",
"title": "test"
}
</config>
<script>
export default {
setup() {
return {
bigData: new Array(5 * 1024 * 1024),
};
},
};
</script>

View File

@ -0,0 +1,37 @@
{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "esnext",
"lib": ["esnext", "dom"],
"sourceMap": true,
"baseUrl": ".",
"jsx": "preserve",
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"allowJs": true,
"skipLibCheck": true,
"experimentalDecorators": true,
"strict": true,
"paths": {
"@/*": ["./src/*"],
"@@/*": ["./src/.fes/*"]
}
},
"include": [
"src/**/*",
"tests/**/*",
"test/**/*",
"__test__/**/*",
"typings/**/*",
"config/**/*",
".eslintrc.js",
".stylelintrc.js",
".prettierrc.js"
],
"exclude": ["node_modules", "build", "dist", "scripts", "src/.fes/*", "webpack", "jest"]
}

View File

@ -10,8 +10,9 @@
"scripts": {
"start": "npm-run-all --parallel start:*",
"start:vite-main": "cd ./examples/vite-main && fes dev",
"start:vite-micro": "cd ./examples/vite-micro && fes dev",
"start:webpack-main": "cd ./examples/webpack-main && fes dev",
"start:micro": "cd ./examples/micro && fes dev"
"start:webpack-micro": "cd ./examples/webpack-micro && fes dev"
},
"repository": {
"type": "git",
@ -34,7 +35,8 @@
"@fesjs/utils": "3.0.0-rc.2",
"address": "^1.1.2",
"lodash-es": "^4.17.15",
"qiankun": "^2.7.0"
"qiankun": "^2.7.0",
"vite-plugin-qiankun": "^1.0.15"
},
"devDependencies": {
"npm-run-all": "^4.1.5"

View File

@ -30,7 +30,6 @@ export default function (api) {
const absMicroAppWithMemoHistoryPath = join(namespace, 'MicroAppWithMemoHistory.jsx');
const absRuntimePath = join(namespace, 'runtime.js');
const absMasterOptionsPath = join(namespace, 'masterOptions.js');
const absGetMicroAppRouteCompPath = join(namespace, 'getMicroAppRouteComponent.jsx');
api.onGenerateFiles(() => {
const HAS_PLUGIN_MODEL = api.hasPlugins(['@fesjs/plugin-model']);
@ -85,11 +84,4 @@ export default function (api) {
source: absMicroAppWithMemoHistoryPath,
},
]);
api.addPluginExports(() => [
{
specifiers: ['getMicroAppRouteComponent'],
source: absGetMicroAppRouteCompPath,
},
]);
}

View File

@ -1,44 +1,36 @@
import { join } from 'path';
import { readFileSync } from 'fs';
import { defaultHistoryType } from '../constants';
function getMicroApp(options) {
const { key, microAppName, cacheName, masterHistoryType, base, namespace, ...normalizedRouteProps } = options;
return `(async () => {
const { getMicroAppRouteComponent } = await import('@@/${namespace}/getMicroAppRouteComponent');
return getMicroAppRouteComponent({key: '${key}', appName: '${microAppName}', cacheName: '${cacheName}', base: '${base}', masterHistoryType: '${masterHistoryType}', routeProps: ${JSON.stringify(
normalizedRouteProps,
)} })
})()`;
}
let index = 0;
function modifyRoutesWithAttachMode({ routes, masterHistoryType, base, namespace }) {
const patchRoutes = (_routes) => {
if (_routes.length) {
_routes.forEach((route) => {
function modifyRoutesWithAttachMode({ routes, api, namespace, masterHistoryType, base }) {
if (!routes.length) return;
routes.forEach((route) => {
if (route.meta && route.meta.microApp) {
route.component = getMicroApp({
key: route.path,
const fileName = `MicroAppRouteComponent${index++}.vue`;
route.component = `@@/${namespace}/${fileName}`;
api.writeTmpFile({
path: join(namespace, fileName),
content: api.utils.Mustache.render(readFileSync(join(__dirname, 'runtime/MicroAppRouteComponent.tpl'), 'utf-8'), {
cacheName: route.meta.cacheName ?? route.path,
microAppName: route.meta.microApp,
masterHistoryType,
base,
namespace,
}),
});
}
if (route.children?.length) {
modifyRoutesWithAttachMode({
routes: route.children,
api,
namespace,
masterHistoryType,
base,
namespace,
});
}
});
}
};
patchRoutes(routes);
return routes;
}
export default function modifyRoutes({ api, namespace }) {
@ -47,10 +39,11 @@ export default function modifyRoutes({ api, namespace }) {
const masterHistoryType = (router && router.mode) || defaultHistoryType;
modifyRoutesWithAttachMode({
api,
namespace,
routes,
masterHistoryType,
base: base || '/',
namespace,
});
return routes;

View File

@ -0,0 +1,11 @@
<template>
<MicroApp name="{{{microAppName}}}" base="{{{base}}}" masterHistoryType="{{{masterHistoryType}}}" cacheName="{{{cacheName}}}"> </MicroApp>
</template>
<script>
// eslint-disable-next-line import/extensions
import { MicroApp } from './MicroApp';
export default {
components: { MicroApp },
};
</script>

View File

@ -1,6 +0,0 @@
// eslint-disable-next-line import/extensions
import { MicroApp } from './MicroApp';
export function getMicroAppRouteComponent({ key, appName, base, masterHistoryType, routeProps, cacheName }) {
return <MicroApp key={key} base={base} masterHistoryType={masterHistoryType} name={appName} cacheName={cacheName} {...routeProps} />;
}

View File

@ -1,7 +1,8 @@
import assert from 'assert';
import { lodash } from '@fesjs/utils';
import { readFileSync } from 'fs';
import { join } from 'path';
import { lodash } from '@fesjs/utils';
import vitePluginQiankun from 'vite-plugin-qiankun';
import { qiankunStateFromMainModelNamespace } from '../constants';
const namespace = 'plugin-qiankun/micro';
@ -19,24 +20,21 @@ export default function (api) {
enableBy: () => isSlaveEnable(api),
});
if (api.builder.name === 'vite') {
// 处理
} else {
api.modifyDefaultConfig((memo) => {
const initialMicroOptions = {
devSourceMap: true,
...JSON.parse(process.env.INITIAL_QIANKUN_MIRCO_OPTIONS || '{}'),
...JSON.parse(process.env.INITIAL_QIANKUN_MICRO_OPTIONS || '{}'),
...(memo.qiankun || {}).micro,
};
const modifiedDefaultConfig = {
...memo,
qiankun: {
...memo.qiankun,
slave: initialMicroOptions,
micro: initialMicroOptions,
},
};
const shouldNotModifyDefaultBase = api.userConfig.qiankun?.slave?.shouldNotModifyDefaultBase ?? initialMicroOptions.shouldNotModifyDefaultBase;
const shouldNotModifyDefaultBase = api.userConfig.qiankun?.micro?.shouldNotModifyDefaultBase ?? initialMicroOptions.shouldNotModifyDefaultBase;
if (!shouldNotModifyDefaultBase) {
modifiedDefaultConfig.router.base = `/${api.pkg.name}`;
}
@ -45,14 +43,10 @@ export default function (api) {
});
const absRuntimePath = join(namespace, 'runtime.js');
const absLifecyclesPath = join(namespace, 'lifecycles.js');
const absLifecyclePath = join(namespace, 'lifecycle.js');
const absMicroOptionsPath = join(namespace, 'slaveOptions.js');
const absPublicPath = join(namespace, 'publicPath.js');
const absModelPath = join(namespace, 'qiankunModel.js');
// 更改public path
api.addEntryImportsAhead(() => [{ source: `@@/${absPublicPath}` }]);
api.register({
key: 'addExtraModels',
fn: () => {
@ -77,22 +71,12 @@ export default function (api) {
});
api.writeTmpFile({
path: absLifecyclesPath,
content: Mustache.render(readFileSync(join(__dirname, 'runtime/lifecycles.tpl'), 'utf-8'), {
path: absLifecyclePath,
content: Mustache.render(readFileSync(join(__dirname, 'runtime/lifecycle.tpl'), 'utf-8'), {
HAS_PLUGIN_MODEL,
}),
});
api.writeTmpFile({
path: absPublicPath,
content: `
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
window.public_path = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
`,
});
api.writeTmpFile({
path: absMicroOptionsPath,
content: `
@ -112,6 +96,66 @@ export default function (api) {
api.addRuntimePlugin(() => `@@/${absRuntimePath}`);
if (api.builder.name === 'vite') {
// 处理
api.modifyBundleConfig((memo) => {
assert(api.pkg.name, 'You should have name in package.json');
memo.plugins.push(
vitePluginQiankun(api.pkg.name, {
useDevMode: api.config.qiankun?.micro?.useDevMode,
}),
);
return memo;
});
api.addEntryImports(() => ({
source: `vite-plugin-qiankun/dist/helper`,
specifier: '{ renderWithQiankun, qiankunWindow }',
}));
api.addEntryImports(() => ({
source: `@@/${absLifecyclePath}`,
specifier:
'{ genBootstrap as qiankun_genBootstrap, genMount as qiankun_genMount, genUnmount as qiankun_genUnmount, genUpdate as qiankun_genUpdate }',
}));
api.addEntryCode(
() => `
const bootstrap = qiankun_genBootstrap(clientRender, app);
const mount = qiankun_genMount('#${api.config.mountElementId}');
const unmount = qiankun_genUnmount();
const update = qiankun_genUpdate();
renderWithQiankun({
bootstrap,
mount,
update,
unmount,
})
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
bootstrap().then(mount);
}
`,
);
} else {
const absPublicPath = join(namespace, 'publicPath.js');
// 更改public path
api.addEntryImportsAhead(() => [{ source: `@@/${absPublicPath}` }]);
api.onGenerateFiles(() => {
api.writeTmpFile({
path: absPublicPath,
content: `
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
window.public_path = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
`,
});
});
api.chainWebpack((config) => {
assert(api.pkg.name, 'You should have name in package.json');
config.output.libraryTarget('umd').library(`${api.pkg.name}-[name]`);
@ -119,9 +163,9 @@ export default function (api) {
});
api.addEntryImports(() => ({
source: `@@/${absLifecyclesPath}`,
source: `@@/${absLifecyclePath}`,
specifier:
'{ genMount as qiankun_genMount, genBootstrap as qiankun_genBootstrap, genUnmount as qiankun_genUnmount, genUpdate as qiankun_genUpdate }',
'{ genBootstrap as qiankun_genBootstrap, genMount as qiankun_genMount, genUnmount as qiankun_genUnmount, genUpdate as qiankun_genUpdate }',
}));
api.addEntryCode(

View File

@ -1,5 +1,5 @@
import { createMemoryHistory } from '@@/core/coreExports';
import qiankunRender, { clientRenderOptsStack, history as historyConfig } from './lifecycles';
import qiankunRender, { clientRenderOptsStack, history as historyConfig } from './lifecycle';
export const render = oldRender => qiankunRender().then(oldRender);

102
yarn.lock
View File

@ -3788,6 +3788,31 @@ chardet@^0.7.0:
resolved "https://registry.npmmirror.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
cheerio-select@^2.1.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4"
integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==
dependencies:
boolbase "^1.0.0"
css-select "^5.1.0"
css-what "^6.1.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.0.1"
cheerio@^1.0.0-rc.10:
version "1.0.0-rc.12"
resolved "https://registry.npmmirror.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683"
integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==
dependencies:
cheerio-select "^2.1.0"
dom-serializer "^2.0.0"
domhandler "^5.0.3"
domutils "^3.0.1"
htmlparser2 "^8.0.1"
parse5 "^7.0.0"
parse5-htmlparser2-tree-adapter "^7.0.0"
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2, chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@ -4419,6 +4444,17 @@ css-select@^4.1.3, css-select@^4.2.1:
domutils "^2.8.0"
nth-check "^2.0.1"
css-select@^5.1.0:
version "5.1.0"
resolved "https://registry.npmmirror.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
dependencies:
boolbase "^1.0.0"
css-what "^6.1.0"
domhandler "^5.0.2"
domutils "^3.0.1"
nth-check "^2.0.1"
css-tree@^1.1.2, css-tree@^1.1.3:
version "1.1.3"
resolved "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
@ -4427,7 +4463,7 @@ css-tree@^1.1.2, css-tree@^1.1.3:
mdn-data "2.0.14"
source-map "^0.6.1"
css-what@^6.0.1:
css-what@^6.0.1, css-what@^6.1.0:
version "6.1.0"
resolved "https://registry.npmmirror.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
@ -4765,7 +4801,16 @@ dom-serializer@^1.0.1:
domhandler "^4.2.0"
entities "^2.0.0"
domelementtype@^2.0.1, domelementtype@^2.2.0:
dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.2"
entities "^4.2.0"
domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
@ -4784,6 +4829,13 @@ domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.2.2, domhandler@^4.3.1:
dependencies:
domelementtype "^2.2.0"
domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"
domutils@^2.5.2, domutils@^2.8.0:
version "2.8.0"
resolved "https://registry.npmmirror.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
@ -4793,6 +4845,15 @@ domutils@^2.5.2, domutils@^2.8.0:
domelementtype "^2.2.0"
domhandler "^4.2.0"
domutils@^3.0.1:
version "3.0.1"
resolved "https://registry.npmmirror.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c"
integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.1"
dot-case@^3.0.4:
version "3.0.4"
resolved "https://registry.npmmirror.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
@ -4905,6 +4966,11 @@ entities@^3.0.1, entities@~3.0.1:
resolved "https://registry.npmmirror.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
entities@^4.2.0, entities@^4.3.0, entities@^4.4.0:
version "4.4.0"
resolved "https://registry.npmmirror.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174"
integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==
envinfo@^7.7.3, envinfo@^7.8.1:
version "7.8.1"
resolved "https://registry.npmmirror.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
@ -6253,6 +6319,16 @@ htmlparser2@^7.1.2:
domutils "^2.8.0"
entities "^3.0.1"
htmlparser2@^8.0.1:
version "8.0.1"
resolved "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010"
integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.2"
domutils "^3.0.1"
entities "^4.3.0"
http-deceiver@^1.2.7:
version "1.2.7"
resolved "https://registry.npmmirror.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
@ -8473,6 +8549,14 @@ parse5-htmlparser2-tree-adapter@^6.0.0:
dependencies:
parse5 "^6.0.1"
parse5-htmlparser2-tree-adapter@^7.0.0:
version "7.0.0"
resolved "https://registry.npmmirror.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1"
integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==
dependencies:
domhandler "^5.0.2"
parse5 "^7.0.0"
parse5@6.0.1, parse5@^6.0.1:
version "6.0.1"
resolved "https://registry.npmmirror.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
@ -8483,6 +8567,13 @@ parse5@^5.1.1:
resolved "https://registry.npmmirror.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178"
integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==
parse5@^7.0.0:
version "7.1.2"
resolved "https://registry.npmmirror.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32"
integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==
dependencies:
entities "^4.4.0"
parseurl@~1.3.2, parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@ -10747,6 +10838,13 @@ vite-plugin-monaco-editor@^1.0.10:
resolved "https://registry.npmmirror.com/vite-plugin-monaco-editor/-/vite-plugin-monaco-editor-1.1.0.tgz#a6238c2e13d5e98dd54a1bc51f6f189325219de3"
integrity sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==
vite-plugin-qiankun@^1.0.15:
version "1.0.15"
resolved "https://registry.npmmirror.com/vite-plugin-qiankun/-/vite-plugin-qiankun-1.0.15.tgz#862bb6935c50db31536cf322e13f3bf59e1adace"
integrity sha512-0QB0Wr8Eu/LGcuJAfuNXDb7BAFDszo3GCxq4bzgXdSFAlK425u1/UGMxaDEBVA1uPFrLsZPzig83Ufdfl6J45A==
dependencies:
cheerio "^1.0.0-rc.10"
vite-plugin-windicss@^1.8.3:
version "1.8.8"
resolved "https://registry.npmmirror.com/vite-plugin-windicss/-/vite-plugin-windicss-1.8.8.tgz#ff1adf7d1a1c38634c77a4c0125fa730d16138e7"