导航菜单

  • 0.api
  • 0.Async
  • 0.module
  • 1.ES2015
  • 2.Promise
  • 3.Node
  • 4.NodeInstall
  • 5.REPL
  • 6.NodeCore
  • 7.module&NPM
  • 8.Encoding
  • 9.Buffer
  • 10.fs
  • 11.Stream-1
  • 11.Stream-2
  • 11.Stream-3
  • 11.Stream-4
  • 12-Network-2
  • 12.NetWork-3
  • 12.Network-1
  • 13.tcp
  • 14.http-1
  • 14.http-2
  • 15.compress
  • 16.crypto
  • 17.process
  • 18.yargs
  • 19.cache
  • 20.action
  • 21.https
  • 22.cookie
  • 23.session
  • 24.express-1
  • 24.express-2
  • 24.express-3
  • 24.express-4
  • 25.koa-1
  • 26.webpack-1-basic
  • 26.webpack-2-optimize
  • 26.webpack-3-file
  • 26.webpack-4.tapable
  • 26.webpack-5-AST
  • 26.webpack-6-sources
  • 26.webpack-7-loader
  • 26.webpack-8-plugin
  • 26.webpack-9-hand
  • 26.webpack-10-prepare
  • 28.redux
  • 28.redux-jwt-back
  • 28.redux-jwt-front
  • 29.mongodb-1
  • 29.mongodb-2
  • 29.mongodb-3
  • 29.mongodb-4
  • 29.mongodb-5
  • 29.mongodb-6
  • 30.cms-1-mysql
  • 30.cms-2-mysql
  • 30.cms-3-mysql
  • 30.cms-4-nunjucks
  • 30.cms-5-mock
  • 30.cms-6-egg
  • 30.cms-7-api
  • 30.cms-8-roadhog
  • 30.cms-9-yaml
  • 30.cms-10-umi
  • 30.cms-12-dva
  • 30.cms-13-dva-ant
  • 30.cms-14-front
  • 30.cms-15-deploy
  • 31.dva
  • 31.cms-13-dva-antdesign
  • 33.redis
  • 34.unittest
  • 35.jwt
  • 36.websocket-1
  • 36.websocket-2
  • 38.chat-api-1
  • 38.chat-api-2
  • 38.chat-3
  • 38.chat-api-3
  • 38.chat
  • 38.chat2
  • 38.chat2
  • 39.crawl-0
  • 39.crawl-1
  • 39.crawl-2
  • 40.deploy
  • 41.safe
  • 42.test
  • 43.nginx
  • 44.enzyme
  • 45.docker
  • 46.elastic
  • 47.oauth
  • 48.wxpay
  • index
  • 52.UML
  • 53.design
  • index
  • 54.linux
  • 57.ts
  • 56.react-ssr
  • 58.ts_react
  • 59.ketang
  • 59.ketang2
  • 61.1.devops-linux
  • 61.2.devops-vi
  • 61.3.devops-user
  • 61.4.devops-auth
  • 61.5.devops-shell
  • 61.6.devops-install
  • 61.7.devops-system
  • 61.8.devops-service
  • 61.9.devops-network
  • 61.10.devops-nginx
  • 61.11.devops-docker
  • 61.12.devops-jekins
  • 61.13.devops-groovy
  • 61.14.devops-php
  • 61.15.devops-java
  • 61.16.devops-node
  • 61.17.devops-k8s
  • 62.1.react-basic
  • 62.2.react-state
  • 62.3.react-high
  • 62.4.react-optimize
  • 62.5.react-hooks
  • 62.6.react-immutable
  • 62.7.react-mobx
  • 62.8.react-source
  • 63.1.redux
  • 63.2.redux-middleware
  • 63.3.redux-hooks
  • 63.4.redux-saga
  • 63.5.redux-saga-hand
  • 64.1.router
  • 64.2.router-connected
  • 65.1.typescript
  • 65.2.typescript
  • 65.3.typescript
  • 65.4.antd
  • 65.4.definition
  • 66-1.vue-base
  • 66-2.vue-component
  • 66-3.vue-cli3.0
  • 66-4.$message组件
  • 66-5.Form组件
  • 66-6.tree
  • 66-7.vue-router-apply
  • 66-8.axios-apply
  • 66-9.vuex-apply
  • 66-10.jwt-vue
  • 66-11.vue-ssr
  • 66-12.nuxt-apply
  • 66-13.pwa
  • 66-14.vue单元测试
  • 66-15.权限校验
  • 67-1-network
  • 68-2-wireshark
  • 7.npm2
  • 69-hooks
  • 70-deploy
  • 71-hmr
  • 72.deploy
  • 73.import
  • 74.mobile
  • 75.webpack-1.文件分析
  • 75.webpack-2.loader
  • 75.webpack-3.源码流程
  • 75.webpack-4.tapable
  • 75.webpack-5.prepare
  • 75.webpack-6.resolve
  • 75.webpack-7.loader
  • 75.webpack-8.module
  • 75.webpack-9.chunk
  • 75.webpack-10.asset
  • 75.webpack-11.实现
  • 76.react_optimize
  • 77.ts_ketang_back
  • 77.ts_ketang_front
  • 78.vue-domdiff
  • 79.grammar
  • 80.tree
  • 81.axios
  • 82.1.react
  • 82.2.react-high
  • 82.3.react-router
  • 82.4.redux
  • 82.5.redux_middleware
  • 82.6.connected
  • 82.7.saga
  • 82.8.dva
  • 82.8.dva-source
  • 82.9.roadhog
  • 82.10.umi
  • 82.11.antdesign
  • 82.12.ketang-front
  • 82.12.ketang-back
  • 83.upload
  • 84.graphql
  • 85.antpro
  • 86.1.uml
  • 86.2.design
  • 87.postcss
  • 88.react16-1
  • 89.nextjs
  • 90.react-test
  • 91.react-ts
  • 92.rbac
  • 93.tsnode
  • 94.1.JavaScript
  • 94.2.JavaScript
  • 94.3.MODULE
  • 94.4.EventLoop
  • 94.5.文件上传
  • 94.6.https
  • 94.7. nginx
  • 95.1. react
  • 95.2.react
  • 96.1.react16
  • 96.2.fiber
  • 96.3.fiber
  • 97.serverless
  • 98.websocket
  • 100.1.react-basic
  • 101.1.monitor
  • 101.2.monitor
  • 102.java
  • 103.1.webpack-usage
  • 103.2.webpack-bundle
  • 103.3.webpack-ast
  • 103.4.webpack-flow
  • 103.5.webpack-loader
  • 103.6.webpack-tapable
  • 103.7.webpack-plugin
  • 103.8.webpack-optimize1
  • 103.9.webpack-optimize2
  • 103.10.webpack-hand
  • 103.11.webpack-hmr
  • 103.11.webpack5
  • 103.13.splitChunks
  • 103.14.webpack-sourcemap
  • 103.15.webpack-compiler1
  • 103.15.webpack-compiler2
  • 103.16.rollup.1
  • 103.16.rollup.2
  • 103.16.rollup.3
  • 103.16.vite.basic
  • 103.16.vite.source
  • 103.16.vite.plugin
  • 103.16.vite.1
  • 103.16.vite.2
  • 103.17.polyfill
  • 104.1.binary
  • 104.2.binary
  • 105.skeleton
  • 106.1.react
  • 106.2.react_hooks
  • 106.3.react_router
  • 106.4.redux
  • 106.5.redux_middleware
  • 106.6.connected-react-router
  • 106.6.redux-first-history
  • 106.7.redux-saga
  • 106.8.dva
  • 106.9.umi
  • 106.10.ketang
  • 106.11.antdesign
  • 106.12.antpro
  • 106.13.router-6
  • 106.14.ssr
  • 106.15.nextjs
  • 106.16.1.cms
  • 106.16.2.cms
  • 106.16.3.cms
  • 106.16.4.cms
  • 106.16.mobx
  • 106.17.fomily
  • 107.fiber
  • 108.http
  • 109.1.webpack_usage
  • 109.2.webpack_source
  • 109.3.dll
  • 110.nest.js
  • 111.xstate
  • 112.Form
  • 113.redux-saga
  • 114.react+typescript
  • 115.immer
  • 116.pro5
  • 117.css-loader
  • 118.1.umi-core
  • 119.2.module-federation
  • 119.1.module-federation
  • 120.create-react-app
  • 121.react-scripts
  • 122.react-optimize
  • 123.jsx-runtime
  • 124.next.js
  • 125.1.linux
  • 125.2.linux-vi
  • 125.3.linux-user
  • 125.4.linux-auth
  • 125.5.linux-shell
  • 125.6.linux-install
  • 125.7.linux-system
  • 125.8.linux-service
  • 125.9.linux-network
  • 125.10.nginx
  • 125.11.docker
  • 125.12.ci
  • 125.13.k8s
  • 125.14.k8s
  • 125.15.k8s
  • 125.16.k8s
  • 126.11.react-1
  • 126.12.react-2
  • 126.12.react-3
  • 126.12.react-4
  • 126.12.react-5
  • 126.12.react-6
  • 126.12.react-7
  • 126.12.react-8
  • 127.frontend
  • 128.rollup
  • 129.px2rem-loader
  • 130.health
  • 131.hooks
  • 132.keepalive
  • 133.vue-cli
  • 134.react18
  • 134.2.react18
  • 134.3.react18
  • 135.function
  • 136.toolkit
  • 137.lerna
  • 138.create-vite
  • 139.cli
  • 140.antd
  • 141.react-dnd
  • 142.1.link
  • 143.1.gulp
  • 143.2.stream
  • 143.3.gulp
  • 144.1.closure
  • 144.2.v8
  • 144.3.gc
  • 145.react-router-v6
  • 146.browser
  • 147.lighthouse
  • 148.1.basic
  • 148.2.basic
  • 148.3.basic
  • 148.4.basic
  • 148.5.basic
  • 149.1.vite
  • 149.2.vite
  • 149.3.vite
  • 149.4.vite
  • 150.react-window
  • 151.react-query
  • 152.useRequest
  • 153.transition
  • 154.emotion
  • 155.1.formily
  • 155.2.formily
  • 155.3.formily
  • 155.3.1.mobx.usage
  • 155.3.2.mobx.source
  • 156.vue-loader
  • 103.11.mf
  • 157.1.react18
  • 158.umi4
  • 159.rxjs
  • 159.rxjs2
  • 160.bff
  • 161.zustand
  • 162.vscode
  • 163.emp
  • 164.cors
  • 1.基础知识
    • 1.1 EMP
    • 1.2 Module Federation
      • 1.2.1 动机
      • 1.2.2 概念
      • 1.2.3 配置参数
    • 1.3 webpack-chain
      • 1.3.1 use.js
      • 1.3.2 webpack-chain\index.js
      • 1.3.3 ChainedMap.js
      • 1.3.4 ChainedSet.js
      • 1.3.5 Chainable.js
      • 1.3.6 Output.js
    • 1.4 其它工具
  • 2.EMP2启动
  • 3.实现init
    • 3.1 安装依赖
    • 3.2 package.json
    • 3.3 bin\zmp6.js
    • 3.4 cli\index.js
    • 3.5 cli\init.js
  • 4.实现dev
    • 4.1 bin\zmp6.js
    • 4.2 cli\dev.js
    • 4.3 config\index.js
    • 4.4 template\index.html

1.基础知识 #

1.1 EMP #

  • emp2是一个用于构建企业级微前端应用的框架。它允许您将大型前端应用程序分解为独立的、可独立开发、部署和维护的模块。这种模块化方法提高了可维护性和可扩展性,同时降低了开发复杂性

1.2 Module Federation #

1.2.1 动机 #

  • Module Federation的动机是为了不同开发小组间共同开发一个或者多个应用
  • 应用将被划分为更小的应用块,一个应用块,可以是比如头部导航或者侧边栏的前端组件,也可以是数据获取逻辑的逻辑组件
  • 每个应用块由不同的组开发
  • 应用或应用块共享其他其他应用块或者库

1.2.2 概念 #

  • 使用Module Federation时,每个应用块都是一个独立的构建,这些构建都将编译为容器
  • 容器可以被其他应用或者其他容器应用
  • 一个被引用的容器被称为remote, 引用者被称为host,remote暴露模块给host, host则可以使用这些暴露的模块,这些模块被成为remote模块

1.2.3 配置参数 #

字段 类型 含义
name string 必传值,即输出的模块名,被远程引用时路径为${name}/${expose}
filename string 指定导出的 remoteEntry 文件的名称。这个文件包含了模块联邦的运行时和引导代码
remotes object 定义其他应用程序的引用映射。这个参数是一个对象,键是别名,值是远程应用的 URL。当我们想在当前应用中引用其他应用的模块时,可以使用这个别名
exposes object 定义当前应用要暴露给其他应用的模块。这个参数是一个对象,键是别名,值是模块的相对路径。别名将用于其他应用在引用该模块时
shared object 定义哪些模块应该在应用程序之间共享。这个参数可以是一个数组,包含共享模块的名称,或者是一个对象,包含共享模块的名称及其配置选项。共享模块可以避免重复加载,从而减少应用的体积和加载时间

1.3 webpack-chain #

  • webpack-chain是一个用于创建和修改 Webpack 配置的 Node.js 库。它提供了一种直观的链式 API,允许您以可读的方式构建复杂的 Webpack 配置 这个库的主要目的是让您可以通过链式方法调用轻松地对 Webpack 配置进行更改,而无需直接操作配置对象。这使得配置更加可读和易于维护。以下是 webpack-chain 的一些主要特性
    • 链式 API:webpack-chain 使用了流行的链式 API 设计模式,允许您通过链式方法调用轻松地修改 Webpack 配置。这种设计模式提高了代码的可读性和维护性
    • 命名规则和插件:您可以为规则和插件分配名称,稍后可以轻松地修改它们。这可以帮助您组织和管理配置中的各个部分

1.3.1 use.js #

// 导入 'webpack-chain' 模块,它是一个构造函数,用于创建配置 API
const Config = require('./webpack-chain');
// 实例化一个新的配置 API 对象
const config = new Config();
// 使用链式 API 修改配置
config
    // 添加一个入口点
    .entry('index')
    // 为入口点添加文件路径
    .add('src/index.js')
    // 结束对当前入口点的操作并返回 config 实例
    .end()
    // 修改输出设置
    .output
    // 设置输出目录
    .path('dist')
    // 设置输出文件名
    .filename('[name].bundle.js');
// 将配置转换为 webpack 可以使用的配置对象
const options = config.toConfig();
// 打印配置对象
console.log(options);

/**
{
  entry: { index: [ 'src/index.js' ] },
  output: { path: 'dist', filename: '[name].bundle.js' }
}
 */

1.3.2 webpack-chain\index.js #

chain\webpack-chain\index.js

const ChainedMap = require('./ChainedMap');
const ChainedSet = require('./ChainedSet');
const Output = require('./Output');
class Config extends ChainedMap {
    constructor(parent) {
        super(parent);
        this.entryPoints = new ChainedMap(this);
        this.output = new Output(this);
    }
    entry(name) {
        return this.entryPoints.getOrCompute(name, () => new ChainedSet(this));
    }
    toConfig() {
        const entryPoints = this.entryPoints.entries();
        return {
            entry: Object.keys(entryPoints).reduce(
                (acc, key) =>
                    Object.assign(acc, { [key]: entryPoints[key].values() }),
                {},
            ),
            output: this.output.entries()
        }
    }
}
module.exports = Config;

1.3.3 ChainedMap.js #

chain\webpack-chain\ChainedMap.js

const Chainable = require('./Chainable');
class ChainedMap extends Chainable {
    constructor(parent) {
        super(parent);
        this.store = new Map();
    }
    extend(methods) {
        this.shorthands = methods;
        methods.forEach((method) => {
            this[method] = (value) => this.set(method, value);
        });
        return this;
    }
    getOrCompute(key, fn) {
        if (!this.has(key)) {
            this.set(key, fn());
        }
        return this.get(key);
    }
    has(key) {
        return this.store.has(key);
    }
    set(key, value) {
        this.store.set(key, value);
        return this;
    }
    get(key) {
        return this.store.get(key);
    }
    entries() {
        const entries = [...this.store].reduce((acc, [key, value]) => {
            acc[key] = value;
            return acc;
        }, {});
        return entries;
    }
}
module.exports = ChainedMap

1.3.4 ChainedSet.js #

chain\webpack-chain\ChainedSet.js

const Chainable = require('./Chainable');
class ChainedSet extends Chainable {
    constructor(parent) {
        super(parent);
        this.store = new Set();
    }
    add(value) {
        this.store.add(value);
        return this;
    }
    values() {
        return [...this.store];
    }
}
module.exports = ChainedSet;

1.3.5 Chainable.js #

chain\webpack-chain\Chainable.js

class Chainable {
    constructor(parent) {
        this.parent = parent;
    }
    end() {
        return this.parent;
    }
};
module.exports = Chainable;

1.3.6 Output.js #

chain\webpack-chain\Output.js

const ChainedMap = require('./ChainedMap');
module.exports = class extends ChainedMap {
    constructor(parent) {
        super(parent);
        this.extend([
            'path',
            'filename'
        ]);
    }
};

1.4 其它工具 #

  • @babel/core: Babel的核心编译器,用于将ES6+代码转换为向后兼容的JavaScript版本
  • @babel/preset-env: Babel预设,根据目标环境自动确定需要的Babel插件和polyfills
  • @babel/preset-react: Babel预设,用于转换React JSX语法为普通的JavaScript
  • babel-loader: Webpack加载器,允许使用Babel和Webpack一起转换JavaScript文件
  • commander: 一个功能强大的命令行界面库,用于创建Node.js命令行应用
  • fs-extra: 一个扩展了Node.js内置fs模块的库,提供额外的文件系统相关功能
  • git-promise: 一个用于在Node.js中处理Git命令的简单Promise封装库
  • html-webpack-plugin: 一个Webpack插件,用于简化HTML文件的创建,以便为你的bundle提供服务
  • inquirer: 一个交互式命令行用户界面的集合,用于在Node.js中创建自定义的命令行界面
  • nanospinner: 一个轻量级的命令行spinner库,用于在命令行中显示加载进度
  • webpack: 一个用于现代JavaScript应用程序的静态模块打包工具
  • webpack-chain: 一个流畅的API,用于编程地配置Webpack
  • webpack-cli: Webpack的命令行工具,用于在命令行中运行Webpack
  • webpack-dev-server: 一个开发服务器,使用热模块替换(HMR)提供实时重新加载功能
  • axios: 一个基于Promise的HTTP客户端库,用于浏览器和Node.js中进行AJAX请求

2.EMP2启动 #

npm i -g @efox/emp
emp init -d https://static.docs-hub.com/template_1680930323773.json
emp dev

3.实现init #

3.1 安装依赖 #

npm install @babel/core @babel/preset-env @babel/preset-react babel-loader commander fs-extra git-promise html-webpack-plugin inquirer nanospinner webpack webpack-chain webpack-cli webpack-dev-server axios --save

3.2 package.json #

package.json

{
    "bin": {
        "zmp6": "./bin/zmp6.js"
    }
}

3.3 bin\zmp6.js #

bin\zmp6.js

// 声明一个 Node.js 脚本,并指定使用的解释器
#!/usr/bin/env node
// 引入 commander 库,用于处理命令行参数和选项
const program = require('commander');
// 引入 package.json 文件,以获取版本号等信息
const pkg = require('../package.json');
// 引入自定义的 CLI 模块
const cli = require('../cli');
// 设置版本号,并添加一个用于显示版本号的选项
program.version(pkg.version, '-v, --version').usage('<command> [options]');
// 添加 init 命令,用于初始化项目
program.command('init')
    .description('初始化项目')
    .option('-d, --data [data]', 'JSON数据 http地址或者文件路径相对、绝对路径')
    .action((options) => {
        cli.exec('init', options);
    });
// 添加 dev 命令,用于启动开发服务器
program.command('dev')
    .description('Dev Server')
    .action(async (options) => {
        console.log('dev', options);
    });
// 解析命令行参数
program.parse(process.argv);

3.4 cli\index.js #

cli\index.js

// 定义一个名为 ZMPScript 的类
class ZMPScript {
    // 定义一个名为 exec 的异步方法,接受两个参数:name 和 options
    async exec(name, options) {
        // 使用 require 动态加载指定名称的模块(文件),并调用其 setup 方法,传递 options 参数
        await require(`./${name}`).setup(options);
    }
}
// 创建一个 ZMPScript 类的实例,并导出该实例
module.exports = new ZMPScript();

3.5 cli\init.js #

cli\init.js

// 导入依赖模块
const { createSpinner } = require('nanospinner');
const git = require('git-promise');
const fs = require('fs-extra');
const path = require('path');
const axios = require('axios');

// 定义项目模板的URL
const templates = {
    'remote': `https://gitee.com/zhufengpeixun/remote.git`,
    'host': `https://gitee.com/zhufengpeixun/host.git`,
};

// 定义 Init 类
class Init {
    templates = templates
    // 检查传入的URL是否是HTTP地址,并返回数据
    async checkData(url) {
        if (/^http(s)?:\/\/.+/.test(url)) {
            const { data } = await axios.get(url);
            return data;
        } else {
            const filepath = path.join(process.cwd(), url);
            this.templates = require(filepath);
        }
    }
    // 设置模板
    async setup(options) {
        if (typeof options.data === 'string') {
            const data = await this.checkData(options.data);
            if (data) {
                this.templates = data;
            }
        }
        await this.selectTemplate();
    }
    // 选择模板
    async selectTemplate() {
        const inquirer = await (await import('inquirer')).default;
        let answers = await inquirer.prompt([{
            type: 'input',
            name: 'name',
            message: '请输入项目名:',
            default: function () {
                return 'zmp-project';
            }
        }, {
            type: 'list',
            name: 'template',
            message: '请选择模板:',
            choices: Object.keys(this.templates)
        }]);
        let downLoadUrl = this.templates[answers.template];
        const downLoadName = answers.name;
        await this.downloadRepo(downLoadUrl, downLoadName);
    }
    // 下载仓库
    async downloadRepo(repoPath, localPath) {
        const spinner = createSpinner().start();
        spinner.start({ text: `[downloading]\n` });
        await git(`clone ${repoPath} ./${localPath}`);
        fs.removeSync(`./${localPath}/.git`);
        spinner.success({
            text: ` cd ${localPath} && npm i && npm run dev`
        });
    }
}
// 导出 Init 类的实例
module.exports = new Init();

4.实现dev #

4.1 bin\zmp6.js #

bin\zmp6.js

#!/usr/bin/env node
const program = require('commander');
const pkg = require('../package.json');
const cli = require('../cli');
program.version(pkg.version, '-v, --version').usage('<command> [options]');
program.command('init')
    .description('初始化项目')
    .option('-d, --data [data]', 'JSON数据 http地址或者文件路径相对、绝对路径')
    .action((options) => {
        cli.exec('init', options);
    });
program.command('dev')
    .description('Dev Server')
    .action(async (options) => {
+        cli.exec('dev',options);
    });
program.parse(process.argv);

4.2 cli\dev.js #

cli\dev.js

// 引入 webpack-dev-server 模块
const WebpackDevServer = require('webpack-dev-server'); 
// 引入 webpack 模块
const webpack = require('webpack'); 
 // 引入 getConfig 方法,用于获取 webpack 配置
const { getConfig } = require('../config');
class devServer {
    // 定义异步的 setup 方法
  async setup() { 
        // 调用 setServer 方法来设置服务器
    await this.setServer();
  }
    // 定义异步的 setServer 方法
  async setServer() { 
        // 通过 getConfig 方法获取 webpack 配置
    const config = getConfig(); 
        // 使用 webpack 函数创建一个编译器实例
    const compiler = webpack(config); 
        // 创建一个新的 webpack-dev-server 实例,传入 devServer 配置和编译器实例
    this.server = new WebpackDevServer(config.devServer, compiler); 
        // 启动 webpack-dev-server
    this.server.start(); 
  }
}
// 导出 devServer 类的一个实例
module.exports = new devServer(); 

4.3 config\index.js #

config\index.js

// 引入 path、webpack 和 WebpackChain 模块
const path = require('path');
const webpack = require('webpack');
const WebpackChain = require('webpack-chain');
// 导出 defineConfig 函数,接收一个配置对象并返回它
exports.defineConfig = (config) => {
    return config;
}
// 导出 getConfig 函数,返回经过处理后的 webpack 配置对象
exports.getConfig = () => {
    // 创建一个 webpack-chain 实例
    const webpackChain = new WebpackChain();
    // 解析 emp-config.js 配置文件,并获取其导出值
    const configPath = path.resolve(process.cwd(), 'emp-config.js');
    const configExport = require(configPath);
    // 对默认配置进行处理,如将 server 属性提取到 devServer 属性中
    const config = processDefault(configExport);
    // 将处理后的配置与 webpack-chain 实例合并
    webpackChain.merge(config);
    // 将合并后的 webpack-chain 实例转换成 webpack 配置对象并返回
    return webpackChain.toConfig();
}
// 处理默认配置的函数,返回处理后的配置对象
function processDefault(configExport) {
    // 将 server 属性提取到 devServer 属性中
    const devServer = configExport.server || {};
    delete configExport.server;
    // 将 empShare 属性的值作为 mfOptions 的一部分,并将 empShare 属性删除
    const mfOptions = {
        filename: "emp.js",
        ...configExport.empShare
    }
    delete configExport.empShare;
    // 返回处理后的配置对象
    return {
        context: process.cwd(),
        mode: 'development',
        devtool: false,
        devServer,
        plugin: {
            html: {
                plugin: require('html-webpack-plugin'),
                args: [{
                    template: path.join(__dirname, '../template/index.html')
                }]
            },
            mf: {
                plugin: webpack.container.ModuleFederationPlugin,
                args: [mfOptions]
            }
        },
        module: {
            rule: {
                compile: {
                    test: /\.js$/,
                    exclude: [/node_modules/],
                    use: {
                        'babel-loader': {
                            loader: require.resolve('babel-loader'),
                            options: {
                                presets: [
                                    require.resolve('@babel/preset-env'),
                                    require.resolve('@babel/preset-react')
                                ]
                            }
                        }
                    }
                }
            }
        },
        ...configExport,
    }
}

4.4 template\index.html #

template\index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
</head>
<body>
    <div id="emp-root"></div>
</body>
</html>

访问验证

请输入访问令牌

Token不正确,请重新输入