记录学习微前端
技术栈
- lerna
- qiankun
- vue
- tailwind
lerna
管理具有多个独立包的 JavaScript 项目的工具。
优点
- 模块化:每个子应用可以作为一个单独的包,这样可以确保每个子应用的代码独立、可重用,并且可以独立开发和发布。
- 代码共享:如果你的子应用之间有一些共享的组件或库,Lerna 可以帮助你创建一个公共的包,所有子应用都可以引用这个公共包。
初始化
安装
bash
npm install lerna -g
初始化lerna
bash
lerna init
创建packages文件 之后管理的包都放在此处
创建主应用
为了实现keepalive我这里还是使用vue2. 使用vuecli去创建vue2项目。
在需要渲染子应用的地方添加
vue
<div id="sub-container"></div>
- sub-container:为应用渲染节点
vue
load() {
const apps = registerMicroApps([
{
name: "cust",
entry: "//localhost:3002",
container: "#sub-container",
activeRule: "/cust-vue",
},
{
name: "user",
entry: "//localhost:3001",
container: "#sub-container",
activeRule: "/user-vue",
props: {
changeRouter: (path) => {
console.log(path);
this.$router.push(path);
},
menus: menus.menus,
store,
},
},
]);
console.log(apps);
// 启动 qiankun
start({
sandbox: { strictStyleIsolation: true },
});
},
- registerMicroApps、start来自qiankun库
- name:子应用名称(唯一)
- entry:子应用入口
- container:渲染节点
- activeRule:触发渲染子应用前缀
- props:向子应用传递的属性
创建子应用
依然是vue2
修改webpack配置
js
const { defineConfig } = require("@vue/cli-service");
const packageName = require("./package.json").name;
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
port: 3001,
headers: {
"Access-Control-Allow-Origin": "*",
},
},
configureWebpack: {
output: {
library: `${packageName}-[name]`,
libraryTarget: "umd",
chunkLoadingGlobal: `webpackJsonp_${packageName}`,
},
},
});
在src下新建public-path.js注入全局变量
js
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
在main.js中加入生命周期代码
js
let router = null;
let instance = null;
function render(props = {}) {
const { container, store: mainStore, changeRouter, menus } = props;
Vue.prototype.$changeRouter = changeRouter;
if (mainStore) {
store.replaceState({
...store.state,
...mainStore.state,
});
store.subscribe((mutation) => {
mainStore.commit(mutation.type, mutation.payload);
});
}
Vue.use(ElementUI);
let routeList = [];
if (menus) {
routeList = routes.filter((route) => {
return menus.some((menu) => {
return menu.path === route.path;
});
});
}
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? "/user-vue/" : "/",
mode: "history",
store,
routes: routeList,
});
if (!window.__CACHE_INSTANCE_BY_QIAN_KUN_FOR_VUE__) {
// 第一次加载时,创建 Vue 实例
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector("#app") : "#app");
} else {
const cachedInstance = window.__CACHE_INSTANCE_BY_QIAN_KUN_FOR_VUE__;
// 让当前路由在最初的 Vue 实例上可用
router.apps.push(...cachedInstance.$router.apps);
instance = new Vue({
router,
render: () => cachedInstance._vnode, // 从最初的 Vue 实例上获得 _vnode
});
// 缓存最初的 Vue 实例
instance.cachedInstance = cachedInstance;
router.onReady(() => {
const { fullPath } = router.currentRoute;
const { fullPath: oldFullPath } = cachedInstance.$router.currentRoute;
// 当前路由的 fullPath 和上一次卸载时不一致,则切换至新路由
if (fullPath !== oldFullPath) {
cachedInstance.$router.replace(fullPath);
}
});
instance.$mount(container ? container.querySelector("#app") : "#app");
}
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
console.log("[vue] vue app bootstraped");
}
export async function mount(props) {
console.log("[vue] props from main framework", props);
render(props);
}
export async function unmount() {
console.log("[vue] vue app unmount");
const cachedInstance = instance.cachedInstance || instance;
window.__CACHE_INSTANCE_BY_QIAN_KUN_FOR_VUE__ = cachedInstance;
const cachedNode = cachedInstance._vnode;
cachedNode.data.keepAlive = true;
cachedNode.data.hook.destroy(cachedNode);
if (instance.cachedInstance) {
instance.$destroy();
instance = null;
}
router = null;
}
添加公用包css
使用lerna创建共用库
bash
lerna create common-style
具体结构如下
安装tailwindcss并初始化创建配置文件
bash
npm install -D tailwindcss
npx tailwindcss init
修改配置文件
js
/** @type {import('tailwindcss').Config} */
module.exports = {
// content: ["./src/**/*.{html,js}"],
content: ["../../packages/**/src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
}
- 这样我们在修改主应用和子应用代码的时候都能检测到修改重新输出新的css文件
在input.css中添加代码
css
@tailwind base;
@tailwind components;
@tailwind utilities;
bash
npx tailwindcss -i ./input.css -o ./output.css --watch
在common-style.js中导出output.css
javascript
export * from "./output.css";
其他包引入公用库: 例如在主应用中引入
json
//主应用package.json中添加依赖
"dependencies": {
"common-style":"0.0.0"//你的版本号
}
执行安装命令
js
yarn install
在需要使用的地方引入
js
import "common-style"
待续。。。