在 vue/cli 中使用 Module Federation

前言

webpack5 的新特性,分模塊共同開發

  • 所需環境: webpack v5 以上,由於我們用的是 vue-cli,所以需要升級 @vue/cli 到 v5 以上版本。
  • 任何框架都可以使用

動機

多個獨立的構建可以組成一個應用程序,這些獨立的構建之間不應該存在依賴關係,因此可以單獨開發和部署它們。

這通常被稱作微前端,但並不僅限於此。

底層概念

我們分爲本地模塊、遠程模塊。

其中本地模塊即爲普通模塊,是當前構建的一部分;而遠程模塊不屬於當前構建,並在運行時從所謂的容器加載。

加載遠程模塊被認爲是異步操作。當使用遠程模塊時,這些異步操作將被放置在遠程模塊和入口之間的下一個chunk的加載操作中。如果沒有chunk加載操作,就不能使用遠程模塊。

chunk的加載操作通常是通過調用import()實現的,但也支持像 require.ensure或require([...])之類的舊語法。

容器是由容器入口創建的,該入口暴露了對特定模塊的異步訪問。暴露的訪問分爲兩個步驟:

步驟1:加載模塊(異步的)

步驟2:執行模塊(同步的)

步驟1將在chunk加載期間完成。步驟2將在與其他(本地和遠程)的模塊交錯執行期間完成。這樣一來,執行順序不受模塊從本地轉換爲遠程或從遠程轉爲本地的影響。

容器可以嵌套使用,容器可以使用來自其他容器的模塊。容器之間也可以循環依賴。


使用只需以下幾個步驟

home 項目

// vue.config.js
module.exports = {
  publicPath: 'http://localhost:8084/',

  chainWebpack: (config) => {
    config
      .plugin('module-federation-plugin')
      .use(require('webpack').container.ModuleFederationPlugin, [{
        name: "home", // 模塊名稱
        filename: "remoteEntry.js",
        exposes: { // 對外暴露的組件
          './HelloWorld': './src/components/HelloWorld.vue'
        },
    }])
  },

  devServer: {
    port: 8084,
    hot: true,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers":
        "X-Requested-With, content-type, Authorization",
    }
  }
}

app 項目

// vue.config.js
module.exports = {
  publicPath: 'http://localhost:8085/',

  chainWebpack: (config) => {
    config
      .plugin('module-federation-plugin')
      .use(require('webpack').container.ModuleFederationPlugin, [{
        name: "app",
        remotes: { // 導入
          home: 'home@http://localhost:8084/remoteEntry.js',
        },
    }])
  },

  devServer: {
    port: 8085,
    hot: true,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers":
        "X-Requested-With, content-type, Authorization",
    }
  }
}
// 使用 home 項目裏面的組件
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="1111"/>
  </div>
</template>

<script>
export default {
  name: 'App',
  components: {
    HelloWorld: () => import('home/HelloWorld')
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>


體驗地址

cd home && yarn && yarn serve
cd app && yarn && yarn serve

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章