首页 文章详情

不小心将 Webpack 升级后我搞定了微前端。

勾勾的前端世界 | 1001 2021-01-19 18:34 0 0 0
UniSMS (合一短信)

嗨,我是你稳定更新、持续输出的勾勾。



今天项目升级的时候,把 Webpack 升级了一个版本。瞬间让我囧大了,你懂的,我就不说了。反正给我一顿操作啊,终于摆平了。


再梳理项目的时候,我用 Webpack 新版本的模块联邦还真实现了应用程序和应用程序之间的引用。一个微前端的雏形就出现了!


借这个机会,刚好把 Webpack 的微前端实现流程介绍一下。


创建两个应用


既然是应用和应用之间的引用,所以我们就创建两个项目,一个叫 app,一个叫 slide。


app 项目的配置文件 webpack.config.js 内容如下:

//app/webpack.config.jsconst path = require("path")const HtmlWebpackPlugin = require("html-webpack-plugin")//微前端的模块const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;module.exports = {    mode:"development",    devtool:false,    entry:"./src/index.js",    output:{       filename:"build.js",       path: path.resolve(__dirname,"dist")    },    devServer:{        contentBase: path.join(__dirname, 'dist'),        port:8081    },    module:{        rules:[            {                test:/\.js$/,                exclude:/node_modules/,                use:{                    loader:"babel-loader"                }            }        ]    },    plugins:[        new HtmlWebpackPlugin({            title:"webpack5",            template:"./public/index.html"        }),        new ModuleFederationPlugin({            name:"remote",            // library:{type:"var",name:"remote"},            filename:"remoteEntry.js",            exposes:{  //导出                "./App":"./src/App.js"            }        })    ]
}


Slide 项目的配置文件 webpack.config.js 内容如下:

const path = require("path")const HtmlWebpackPlugin = require("html-webpack-plugin")// 模块联邦const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;module.exports = {    mode:"development",    devtool:false,    entry:"./src/index.js",    output:{        filename:"build.js",       path: path.resolve(__dirname,"dist")    },    devServer:{        contentBase: path.join(__dirname, 'dist'),        port:3000    },    module:{        rules:[            {                test:/\.js$/,                exclude:/node_modules/,                use:{                    loader:"babel-loader"                }            }        ]    },    plugins:[        new HtmlWebpackPlugin({            title:"webpack5",            template:"./public/index.html"        }),        new ModuleFederationPlugin({            name:"slide",            library:{type:"var",name:"slide"},            remotes:{                "remote":"remote@http://127.0.0.1:8081/remoteEntry.js"            }        })    ]
}


重点


在 ModuleFederationPlugin 实例化的时候传入参数 options 的字段说明。


  • name 模块名

  • library 目前看到的用法有 { type: "var" } { type: "commonjs-module" },可以用来指定模块的使用规范

  • remotes 需要依赖的模块名

  • exposes 暴露出的模块,可以有多个

  • shared app 打包暴露模块时,不会将 shared 打包,是两个应用的共享依赖,比如 react vue 等


注意:library 是对外导出的一种规范,前端使用 {type:"var"}。在引入的应用程序中这个字段不要加哈,不然会不显示内容,而被引入模块可以加上。


还有就是 exposes 和 remotes 的字段小伙伴们也要注意。


  • exposes 的暴露字段要写上 ./name

  • remotes 的字段跟暴露模块的 name 保持一致,里面别名的定义也要一致


最后,两个应用同时启动,就会发现最终你要的应用就把其他应用的模块也引入进来了(●'◡'●)。


喜欢的小伙伴可以 fork 去(ง •_•)ง。

https://github.com/cuiweijun/moduleFederation


推荐阅读:

腾讯QQ偷我浏览记录到底想干嘛。

Webpack 究竟解决了什么问题?

是我 Web 端配不上阿里了。

前端人因为 Vue3 的 Ref-sugar 提案打起来了!


点点“”和“在看”,保护头发,减少bug。

good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter