IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> webpack5 之 ModuleFederationPlugin 联邦组件 -> 正文阅读

[JavaScript知识库]webpack5 之 ModuleFederationPlugin 联邦组件

Webpack 5 增加了一个新的功能 “模块联邦”,它允许多个 webpack 构建一起工作。从运行时的角度来看,多个构建的模块将表现得像一个巨大的连接模块图。从开发者的角度来看,模块可以从指定的远程构建中导入,并以最小的限制来使用。

多个独立的构建可以组成一个应用程序,这些独立的构建之间不应该存在依赖关系,因此可以单独开发和部署它们。这通常被称作微前端,但并不仅限于此。

在这里插入代码片Webpack5 模块联邦让 Webpack 达到了线上 Runtime 的效果,让代码直接在项目间利用 CDN 直接共享,不再需要本地安装 Npm 包、构建再发布了! 我们知道 Webpack 可以通过 DLL 或者 Externals 做代码共享时 Common Chunk, 但不同应用和项目间这个任务就变得困难了,我们几乎无法在项目之间做到按需热插拔。

模块联邦可以将一个应用的包应用于另一个应用,同时具备整体应用一起打包的公共依赖抽取能力。

APP1

components/uploadFile.vue

// 正常封装 vue 组件即可(此处仅为示例)
<template>
  <div class="upload_wrap">
    <el-upload>示例上传组件</el-upload>
  </div>
</template>

components/index.js

// 导出所有组件
import uploadFile from './uploadFile/uploadFile' // 上传文件
export {
  uploadFile
}

vue.config.js

const { defineConfig } = require('@vue/cli-service')
const ModuleFederationPlugin =
  require('webpack').container.ModuleFederationPlugin

// 根据不同环境配置不同 publicPath
let publicPath
if (process.env.NODE_ENV === 'development') {
  // 开发环境
  publicPath = 'http://localhost:9001' // webpack 公共路径
} else if (process.env.VUE_APP_CURRENTMODE === 'test') {
  // 测试环境
  publicPath = '测试环境域名/xlt-ms-component-library'
} else if (process.env.VUE_APP_CURRENTMODE === 'prod') {
  // 正式环境
  publicPath = '正式环境域名/xlt-ms-component-library'
}

module.exports = defineConfig({
  transpileDependencies: true,
  publicPath: publicPath,
  lintOnSave: process.env.NODE_ENV === 'development',
  configureWebpack: {
    plugins: [
      new ModuleFederationPlugin({
        name: 'remoteEntry',
        filename: 'remoteEntry.js',

        exposes: {
          // 组件
          './components': './src/components/index',
          // 这里可以添加其他资源,例如js、css等
          ...
        }
        // shared: require("./package.json").dependencies,
      })
    ]
  },
  devServer: {
    port: 9001
  },
  chainWebpack: (config) => {
    config.optimization.delete('splitChunks')
  }
})

APP2(第一种使用方法,webpack 配置引用)

vue.config.js (配置加载远程库)

const { defineConfig } = require('@vue/cli-service')
const ModuleFederationPlugin =
	require('webpack').container.ModuleFederationPlugin

// 根据不同环境配置不同的远程 URL
let remoteUrl
if (process.env.NODE_ENV === 'development') {
	// 开发环境
	remoteUrl = 'http://localhost:9001'
} else if (process.env.VUE_APP_CURRENTMODE === 'test') {
	// 测试环境
	remoteUrl = '测试域名/xlt-ms-component-library'
} else if (process.env.VUE_APP_CURRENTMODE === 'prod') {
	// 正式环境
	remoteUrl = '正式域名/xlt-ms-component-library'
}

module.exports = defineConfig({
	publicPath: '/fangliang-ms',
	transpileDependencies: true,
	lintOnSave: process.env.NODE_ENV === 'development',
	configureWebpack: {
		plugins: [
			new ModuleFederationPlugin({
				name: 'clitest',
				filename: 'remoteEntry.js',
				remotes: {
					// 加载远程库
					remoteEntry: `remoteEntry@${remoteUrl}/remoteEntry.js`
				}
			})
		]
	}
})

views/uploadFile.vue (页面使用示例)

<template>
  <uploadFile />
</template>
<script>
  // 此处引用可以放在一个公共 js 文件内引用并全部加导出
  import { uploadFile } from 'remoteEntry/components'
  export default {
    components: {
      uploadFile
    }
  }
</script>

APP2(第二种使用方法 动态引用)

vue.config.js

不做配置引用

utils/moduleFederationPlugin.js

import Vue from 'vue'
import baseURL from '@/env.js'
// 动态加载远程 js 文件
const useDynamicScript = (url) => {
  return new Promise((resolve, reject) => {
    const element = document.createElement('script')
    element.src = url
    element.type = 'text/javascript'
    element.async = true
    element.onload = (e) => {
      resolve(true)
    }
    element.onerror = () => {
      reject(false)
    }
    document.head.appendChild(element)
  })
}
// 加载组件
const loadComponent = (scope, module) => {
  return async () => {
    // 初始化共享作用域。使用此版本和所有远程提供的已知模块填充它
    await __webpack_init_sharing__('default')
    const container = window[scope] // 或者到别的地方去拿容器
    // 初始化容器,它可以提供共享模块
    await container.init(__webpack_share_scopes__.default)
    const factory = await window[scope].get(module)
    const Module = factory()
    return Module
  }
}
// 处理联邦组件所有导出项
export const moduleFederationPlugin = () => {
  return new Promise(async (resolve, reject) => {
    if (!window.EcRootMs) {
      // 加载远程库 TODO: 后期放在 npm 包内
      await useDynamicScript(`${baseURL.remoteUrl}?date=${Date.now()}`) // 远程模块地址
      const components = await loadComponent('remoteEntry', './components')()
      const views = await loadComponent('remoteEntry', './views')()
      // 全局注册所有组件
      Object.keys({ ...components, ...views }).forEach(key => {
        Vue.component(`xlt${key}`, components[key])
      })
      // 加载远程 css 文件
      await loadComponent('remoteEntry', './publicStyle')()
      // 加载公共js方法
      const publicJs = await loadComponent('remoteEntry', './publicJs')()
      // 加载公共路由
      const remoteRouter = await loadComponent('remoteEntry', './remoteRouter')()
      // 挂在到 window 对象上
      window.EcRootMs = {
        publicJs,
        remoteRouter
      }
    }
    resolve(true)
  })
}

main.js (此处仅为示例,因为加载远程组件为异步加载,在使用远程库的时候必须在其加载完成)

// 例如 setRem 在 main.js 文件内调用,此时远程库是异步,window上不一定有此方法,所以放在 promise 回调之后调用
moduleFederationPlugin().then(async res => {
  // px转rem
  window.EcRootMs.publicJs.setRem() // 初始化
  const router = await routerRoot()
  new Vue({
    router,
    store,
    render: (h) => h(App)
  }).$mount('#app')
})
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 18:03:56  更:2022-05-24 18:05:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:49:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码