single-spa的簡單介紹與遇到的問題小結

其實原本應該寫個介紹的,可是我看到其餘的文章寫得很完善了,因此就來寫寫我在其中遇到的一些問題就行了。css

安裝single-spa請看沉末的這篇文章html

背景

簡單介紹下背景吧~前端

爲何要用single-spa呢,是由於公司的項目須要拆項目了,這個時候就須要知道微前端的概念了,那麼什麼是微前端呢。vue

微前端服務

微前端架構是一種相似於微服務的架構,由ThoughtWorks 2016年提出,它將微服務的理念應用於瀏覽器端,即將 Web 應用由單一的單體應用轉變爲多個小型前端應用聚合爲一的應用。

由此帶來的變化是,這些前端應用能夠獨立運行、獨立開發、獨立部署。node

在項目中是運用single-spa去搭建微前端框架的,在搭建框架以前,咱們須要知道兩個知識點,什麼是single-spaimportmapwebpack

single-spa

single-spa是一個用於前端微服務化的JavaScript前端解決方案。git

特色:github

  • (兼容各類技術棧)在同一個頁面中使用多種技術框架(React, Vue, AngularJS, Angular, Ember等任意技術框架),而且不須要刷新頁面.
  • (無需重構現有代碼)使用新的技術框架編寫代碼,現有項目中的代碼無需重構.
  • (更優的性能)每一個獨立模塊的代碼可作到按需加載,不浪費額外資源.

每一個獨立模塊可獨立運行.web

importmap

咱們先來看兩段代碼vue-cli

import moment from 'moment';
import 'http://momentjs.com/downloads/moment.js';

在一個文件中咱們寫入如上代碼,顯然第一行是沒法正常運行的,第二行是能夠正常運行的,但若是咱們想要第一行正常運行的話,importmap就能夠粉墨登場啦。只須要在html文件書寫以下:

<script type="importmap">
    {
        "imports": {
            "moment": "https://momentjs.com/downloads/moment.js",
        }
    }
</script>

就能夠了。

可是如今瀏覽器並不支持,想要讓它支持的話,須要引入system.js

<script type="systemjs-importmap">
    {
        "imports": {
            "moment": "https://momentjs.com/downloads/moment.js",
        }
    }
</script>
<script src="https://cdn.jsdelivr.net/npm/systemjs/dist/system.js"></script>

而在single-spa的使用過程當中,咱們須要用importmap在根項目中引入全部的模塊文件和子項目,從而在其他項目中能夠進行模塊的引用,就像上面說的那樣,能夠把moment想象成一個子項目。

single-spa用於將項目打包爲可引用的模塊。

其餘的就很少加介紹了,具體能夠看原做者@Joel Denning發的視頻,須要🔬上網。

遇到的問題

怎麼打開importmap的插件

在瀏覽器的console中輸入

localStorage.setItem('devtools', true);

這個小可愛就出現了。

子項目打包

在微服務的組件引用中,因爲運用cdn引入,所以文件須要打包成單一的js文件,而vue-cli3-service(文件路徑位於node_modules/_@vue_cli-service@4.3.1@@vue/cli-service/lib/config, 並無找到github地址)內置了一些webpack配置,在子項目的打包過程當中須要把某些配置關掉,而且將其打包成支持system.js的文件,咱們須要作以下事情:

  • 將項目打包成可引入的文件
  • 去除代碼分割的配置 (代碼分割會生成chunk-vendors文件)
  • 去除mini-css-extract-plugin(該插件會將組件中的css抽離出來)

代碼以下

> vue.config.js

process.env.VUE_CLI_CSS_SHADOW_MODE = true; // 去除將css從js分出去的配置

module.exports = {
    chainWebpack: config => {
        config.optimization.delete('splitChunks') // 關閉代碼分割
        config.output
            .filename('app.js')
            .library('@[library]/[sub-project]')
            .libraryTarget('amd') // 打包方式
            .end()
    }
    ...
}

可是上面都是屁話。。。。這些事情其實只要一個插件就能夠解決了,原做者寫了vue-cli-plugin-single-spa這個插件,直接安裝便可。

npm install vue-cli-plugin-single-spa -D

子項目的文件路徑404了

通過如上的過程打包以後,打包後的文件爲/dist/js/app.js,在原做者寫的插件中,改寫文件路徑以下:

就能夠了。

假如仍是404,可能項目被打包到了不一樣的路徑,須要打開子項目的tab在瀏覽器中查看文件地址。

element-ui 圖標顯示不出

須要注意的是vue-cli-plugin-single-spa這個插件並無處理文字等靜態資源,所以儘管npm run build沒有顯示靜態資源被打包成單獨的文件,事實上其仍是被打包成了靜態文件了。解決這個問題最好的方法是把element-ui轉化爲cdn引入的而不是經過node_module引入的。

渲染錯項目

明明指向的是項目A,可是卻渲染成了項目B。

插件中配置的文件路徑錯了,可能A項目是8080端口配置成了8081端口,在多項目開發的時候尤爲容易出現該問題。

怎麼實現兩欄佈局右邊可切換項目

以前的我天真得覺得能夠將子項目變成一個router的組件直接引入,但事實上是實現不了的。因爲項目的耦合程度過大,依賴於各個插件,是沒法將其打包成一個組件的。因此其實質上是兩個並排的DOM節點。可是咱們能夠實現一個假的效果。

在菜單欄的router中設置,

{
    path: '/',
    component: Home,
    name: 'home',
    redirect: '/sub-project',
    children: [{
      path: 'sub-project/*',
      name: 'sub-project',
    }]
  },

爲何要加星號呢,是爲了解決另外一個問題,不加通配符的話會致使navbar沒法正常匹配,若是sub-project具備一些router轉換的話。

爲了在子項目中能匹配相應的router,須要設置

base: 'sub-project'

接着在菜單欄中設置浮動,右邊margin相應的寬度就能夠了。

更多

從0實現一個single-spa的前端微服務

single-spa

vue-microfrontends
用微前端的方式搭建類單頁應用以上就是我遇到的問題,喜歡能夠給一個小小的贊,謝謝~

相關文章
相關標籤/搜索