微前端 micro-app 搭建
微前端 micro-app 搭建
官网:https://zeroing.jd.com/docs.html#/zh-cn/configure
环境:
主应用:vue2,名称:cde-railfore
子应用:vue3,名称:cde-standard,vite 搭建,参考:https://www.cnblogs.com/1285026182YUAN/p/17823873.html
各语言框架 demo 案例:
主应用配置
1. 主应用安装插件
yarn add @micro-zoe/micro-app pnpm add @micro-zoe/micro-app npm i @micro-zoe/micro-app
2. 在应用入口main.js 中引入并启动 micro-app。
import microApp from '@micro-zoe/micro-app' microApp.start({ destroy: true })
3. 创建页面page1,承载子页面 ,配置子项目的地址路由,参考:https://zeroing.jd.com/docs.html#/zh-cn/configure
<template> <div class="container"> <micro-app name="my-app-page1" url="http://localhost:5173/stand" disableSandbox inline></micro-app> </div> </template>
子应用配置
path 是子应用路由地址。非严格匹配,/login/* 都指向 SubApp 页面。使用 vue-router@4.x 时写法为:'/login/:page*'。history 路由,Vite 子应用使用 hash 路由,避免一些可能出现的问题。 子应用如果是 Vue3,在初始化时路由时,createWebHashHistory 不要传入参数,如下:
import { createRouter, createWebHashHistory, createWebHistory, } from "vue-router"; export const routes = [ { path: "/", redirect: "/login", }, { name: "login", path: "/login", component: () => import("@/pages/login.vue"), }, { name: "index", path: "/index", component: () => import("@/pages/index.vue"), }, ]; const router = createRouter({ // scrollBehavior: () => ({ left: 0, top: 0 }), history: createWebHashHistory(), // // history: createWebHistory(), // routes, }); router.beforeEach((to, from, next) => { next(); }); export default router;
import { join } from 'path'
import { writeFileSync } from 'fs'
function VitePluginMicroApp() {
(function () {
let basePath = "";
return {
name: "vite:micro-app",
apply: "build",
configResolved(config) {
basePath = `${config.base}${config.build.assetsDir}/`;
},
writeBundle(options, bundle) {
for (const chunkName in bundle) {
if (Object.prototype.hasOwnProperty.call(bundle, chunkName)) {
const chunk = bundle[chunkName];
if (chunk.fileName && chunk.fileName.endsWith(".js")) {
chunk.code = chunk.code.replace(
/(from|import\()(\s*['"])(\.\.?\/)/g,
(all, $1, $2, $3) => {
return all.replace($3, new URL($3, basePath));
}
);
const fullPath = join(options.dir, chunk.fileName);
writeFileSync(fullPath, chunk.code);
}
}
}
},
};
})();
}
export default VitePluginMicroApp;
3. 修改配置文件:vite.config.ts
1. 导入插件并配置公共资源基础路径
2. 项目输出到 dist/stand/ 目录
import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import { resolve } from "path"; import VitePluginMicroApp from "./vite-plugin-micro-app"; export default defineConfig({ base: `${ process.env.NODE_ENV === "production" ? "http://stand.procde.cn" : "" }/stand/`, // base: "/stand/", plugins: [vue(), VitePluginMicroApp()], resolve: { alias: { "@": resolve(__dirname, "./src"), }, extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"], }, server: { port: 5173, }, build: { outDir: "dist/stand/", }, });
if (window.__MICRO_APP_ENVIRONMENT__) {
__webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__;
}
5. 修改容器元素 id
当多个vite子应用同时渲染时,必须修改容器元素的id值,确保每个子应用容器元素id的唯一性,否则无法正常渲染。
修改 index.html 中容器元素的 id 值
<body>
<div id="my-vite-app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
6. 使用新的 id 渲染,修改 main.ts
import { createApp } from "vue";
import "./common.scss";
import App from "./App.vue";
import router from "@/router/index";
import { createPinia } from "pinia";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import http from "./utils/request.js";
const app = createApp(App);
app.use(router);
app.use(createPinia());
app.use(ElementPlus);
app.use(http);
app.mount("#my-vite-app");
7. 静态资源
图片等静态资源需要使用绝对地址,可以使用 new URL('../assets/logo.png', import.meta.url).href 等方式获取资源的全链接地址。
主应用配置
修改 main.js 中的启动配置
microApp.start({ // shadowDOM: true, // 默认值false destroy: true, plugins: { modules: { // appName即应用的name值 "my-app-page12": [{ loader(code) { if (process.env.NODE_ENV === 'development') { // 这里 basename 需要和子应用vite.config.js中base的配置保持一致 code = code.replace(/(from|import)(\s*['"])(\/stand\/)/g, all => { return all.replace('/stand/', 'http://localhost:5173/stand/') }) } return code } }], 'appname-vite': [ { loader(code) { if (process.env.NODE_ENV === 'development') { // 这里 /basename/ 需要和子应用vite.config.js中base的配置保持一致 code = code.replace(/(from|import)(\s*['"])(\/child\/vite\/)/g, all => { return all.replace('/child/vite/', 'http://localhost:4007/child/vite/') }) } return code } } ], } } })
这些标记字段应与上面配置的一 一对应,否则会报错。
报错现像:
Uncaught TypeError: Failed to resolve module specifier "/stand/node_modules/vite/dist/client/env.mjs". Invalid relative url or base scheme isn't hierarchical.
page1:1 Uncaught TypeError: Failed to resolve module specifier "/stand/src/utils/public-path.js". Invalid relative url or base scheme isn't hierarchical.
配置完成。
引用:https://zeroing.jd.com/docs.html#/zh-cn/configure
引用:https://www.jianshu.com/p/65b81afc0cb5
引用:https://micro-zoe.github.io/micro-app/docs.html#/zh-cn/framework/vite
引用:https://blog.csdn.net/outsider76557/article/details/129687164

浙公网安备 33010602011771号