微前端的實(shí)踐

前端時間打算建立更新下自己的github page杰刽,所以先在gitee上進(jìn)行可實(shí)驗,
開始選用qiankun后來使用single-spa露戒。

主應(yīng)用構(gòu)建

  1. 使用single-spa或者qiankun搭建主應(yīng)用都比較簡單缺谴,只需要配置士修,只要需要配置子應(yīng)用即可。
export const apps: AppConfig[] = [
  {
    name: 'blogs', // app name 需要唯一
    source: {
      scripts: ['/blogs/bundle.js'], //目前只實(shí)現(xiàn)js的加載澈灼,其打包的方式應(yīng)該為umd竞川,具體參考子應(yīng)用的配置
    },
    activeWhen: '/#/blogs', //配置路由,或者自定義返回bool的函數(shù)
    container: '#main', //加載子應(yīng)用的位置
  },
];

如上配置叁熔,參照官網(wǎng)配置即可委乌。

  1. 然后手動實(shí)現(xiàn)一個簡單的loader
export const getAppConfig = (app: AppConfig): RegisterApplicationConfig => {
  return {
    name: app.name,
    app: () => getApp(app),
    activeWhen: app.activeWhen,
    customProps: {
      ...app.customProps,
      container: app.container,
    },
  };
};

const getApp = async (app: AppConfig): Promise<any> => {
  const {
    source: { scripts, styles },
    name,
  } = app;
  if (exports[name]) return exports[name];
  const srcs = await Promise.all(
    scripts.map((script) => fetch(script).then((res) => res.text()))
  );
  // todo:append styles
  srcs.forEach((script) => {
    eval.call(window, script); // 將配置的js進(jìn)行執(zhí)行,獲取到export出來的js
  });
  return exports[name];
};

可能是我使用的qiankun的姿勢不對荣回,上面getApp這一步qiankun已經(jīng)做了遭贸,但是我的加載有問題,所以就放棄了改用了single-spa心软。

window.onload = () => {
  init();// 自定義全局變量
  start();
  apps.forEach((app) => {
    registerApplication(getAppConfig(app));//注冊子應(yīng)用
  });
  // 這里是我自定義的菜單渲染壕吹,即通過配置實(shí)現(xiàn)
  MenuRender(menu, document.getElementById('app-header'));
};

這樣主應(yīng)用就算是搭建起來了。

子應(yīng)用的構(gòu)建

import { createApp } from 'vue';
import App from './App.vue';
import './index.scss';
let app;

/**
 * bootstrap 只會在微應(yīng)用初始化的時候調(diào)用一次删铃,下次微應(yīng)用重新進(jìn)入時會直接調(diào)用 mount 鉤子耳贬,不會再重復(fù)觸發(fā) bootstrap。
 * 通常我們可以在這里做一些全局變量的初始化泳姐,比如不會在 unmount 階段被銷毀的應(yīng)用級別的緩存等效拭。
 */
export async function bootstrap() {}
/**
 * 應(yīng)用每次進(jìn)入都會調(diào)用 mount 方法,通常我們在這里觸發(fā)應(yīng)用的渲染方法
 */
export async function mount(props) {
  app = createApp(App);
  app.mount(props.container);
}
/**
 * 應(yīng)用每次 切出/卸載 會調(diào)用的方法胖秒,通常在這里我們會卸載微應(yīng)用的應(yīng)用實(shí)例
 */
export async function unmount(props) {
  app.unmount(props.container);
}
/**
 * 可選生命周期鉤子缎患,僅使用 loadMicroApp 方式加載微應(yīng)用時生效
 */
export async function update(props) {}

//在本地開發(fā)時的配置
if (!window['__POWERED_BY_QIANKUN__']) {
  const root = document.createElement('div');
  root.setAttribute('id', 'main');
  document.body.append(root);
  const app = createApp(App);
  app.mount('#main');
}

就是這么簡單。

這里還有一個小插曲:使用vue3-alpha開發(fā)的阎肝,按照上面我想著createApp然后在mount和unmount的時候直接調(diào)用即可挤渔,結(jié)果發(fā)現(xiàn)unmount之后mount失敗,后來定位是vue庫的問題风题,然后happy的去提了個issue判导,并提了fix,結(jié)果原來我不是第一個先發(fā)現(xiàn)的沛硅,然后尤大大在另一個issue里面提到眼刃,并不推薦這樣做,建議重新createApp

代碼很簡單摇肌,構(gòu)建也很簡單

  1. 主應(yīng)用的webpack配置,其他的不用說擂红,只說特殊點(diǎn)
devServer: {
    contentBase: './dist',
    hot: true,
    proxy: {
      '/blogs': {
        target: 'http://localhost:1234/',
        pathRewrite: { '^/blogs': '' },
        changeOrigin: true,
      },
    },
  },

其實(shí)主應(yīng)用構(gòu)建不需要什么處理,本地開發(fā)的話围小,加個代理昵骤,使其能獲取到子應(yīng)用的文件

  1. 子應(yīng)用配置可能需要幾個點(diǎn)
  {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              publicPath: '/blogs/', //這里否則資源加載不上
            },
          },
        ],
   },

因為打包出來的js最終是在主應(yīng)用下運(yùn)行的,所以其子應(yīng)用url需要一層轉(zhuǎn)化肯适。

 devtool: 'inline-source-map',

如上变秦,所以其map需要聯(lián)入代碼如果使用map文件會導(dǎo)致map找不到。

output: {
    filename: 'bundle.js',
    library: packageName,
    libraryTarget: 'umd',
  },

使用umd方式框舔,方便外部獲取export蹦玫。

最后一個路由問題

vue-router在single-spa的使用
由于是使用gitpage的所以只能使用hash,最后只好自己手動實(shí)現(xiàn)一個簡單的router來滿足使用刘绣。
簡單來說就是在app.vue中創(chuàng)建一個history并provide下去钳垮。
在實(shí)現(xiàn)的Router組件以及Menu組件中獲取到hostory,然后進(jìn)行push和解析操作额港。具體請直接參考代碼饺窿。

主應(yīng)用
子應(yīng)用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市移斩,隨后出現(xiàn)的幾起案子肚医,更是在濱河造成了極大的恐慌,老刑警劉巖向瓷,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肠套,死亡現(xiàn)場離奇詭異,居然都是意外死亡猖任,警方通過查閱死者的電腦和手機(jī)你稚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刁赖,你說我怎么就攤上這事搁痛。” “怎么了宇弛?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵鸡典,是天一觀的道長。 經(jīng)常有香客問我枪芒,道長彻况,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任舅踪,我火速辦了婚禮纽甘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抽碌。我一直安慰自己悍赢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布咬展。 她就那樣靜靜地躺著泽裳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪破婆。 梳的紋絲不亂的頭發(fā)上涮总,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音祷舀,去河邊找鬼瀑梗。 笑死,一個胖子當(dāng)著我的面吹牛裳扯,可吹牛的內(nèi)容都是我干的抛丽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼饰豺,長吁一口氣:“原來是場噩夢啊……” “哼亿鲜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起冤吨,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤蒿柳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后漩蟆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垒探,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年怠李,在試婚紗的時候發(fā)現(xiàn)自己被綠了圾叼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛤克。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖夷蚊,靈堂內(nèi)的尸體忽然破棺而出构挤,到底是詐尸還是另有隱情,我是刑警寧澤撬码,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布儿倒,位于F島的核電站版保,受9級特大地震影響呜笑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜彻犁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一叫胁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧汞幢,春花似錦驼鹅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仲智,卻和暖如春买乃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钓辆。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工剪验, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人前联。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓功戚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親似嗤。 傳聞我的和親對象是個殘疾皇子啸臀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345