说明
2018年初在上家公司做新编辑器V2.0版本时,需要我用webpack实现多页面打包和页面嵌套显示的功能(见下方案例)。由于当时不了解webpack,但是任务面前我只能赶鸭子上架,加班加点地在网上搜寻各种实现方法,虽然费了几个小时但最终还是磕磕绊绊地实现了功能(现在回忆一下,还是能回想起当时实现了功能的那一刻自己内心的舒畅和开心哈哈~~)
最近在学习webpack,今天终于把当初的这个配置原理也学习了解了!然后还专门去找到当初的配置代码再看了一遍,才发现并没有那么难,但是当初不了解配置原理,只知道生搬硬套网上的相关配置代码,所以费时费力哎。
为了记录下这个挺有意义的事儿,所以有了今天这篇文章~
说明
单页面:整个应用只有一个html页面。react、vue都是单页面应用。
多页面:整个应用里有多个html页面。
案例
需求1:现在需要有两个页面:首页、编辑器页。两个页面独立互不相关,有各自的业务逻辑等。但这两个页面又都在一个项目中开发。
我的解决思路:使用webpack进行多页面打包。
需求2:显示效果:首页里嵌套编辑器页面。
我的解决思路:在首页项目里使用<iframe src="" />
来实现嵌套,跨页面通信可以使用H5的window.postMessage()
。
webpack主要配置
entry
plugins
中的HtmlWebpackPlugin()
。
具体配置
module.exports = {
mode: "development",
entry: {
// entry为object时,默认打包输出的文件名为键值+'.js'
index: "./src/index.js",
+ editor: "./src/editor.js"
},
// 打包输出配置
output: {
filename: "[name].js", // index.js、editor.js
path: path.resolve(__dirname, "dist")
},
// 插件
plugins: [
new CleanWebpackPlugin(),
// 打包完成后基于template生成html页面,并自动引入打包后对应的js
new HtmlWebpackPlugin({
template: "./src/index.html", // 基于这个模板生成html文件
+ filename: "index.html", // 打包生成的html的文件名
+ chunks: ["index"] // index.html引入打包后的index.js
}),
+ new HtmlWebpackPlugin({
template: "./src/index.html",
filename: "editor.html",
chunks: ["editor"] // editor.html引入打包后的editor.js。chunks告诉插件要引用entry里面的哪几个入口,各个模块引入自己所需的js
}),
new webpack.HotModuleReplacementPlugin() // 使用热模块更新插件
]
};
打包后生成的文件夹:
|- dist ("分发"代码)
|- index.html
|- index.js
|- editor.html
|- editor.js
|- src ("源代码")
|- index.js (webpack打包入口文件1)
|- editor.js (webpack打包入口文件2)
|- index.html(模板)
|- node_modules (模块依赖)
|- package.json
|- webpack.config.js
分析
- 由于两个html页面各自引用不同的js,所以有两个不同的js文件,则需要我们配置两个入口文件。
- 打包后将生成两个js文件:index.js、editor.js。
- 需要生成几个html文件,就配置几个
HtmlWebpackPlugin
对象。所以我们要new 2个HtmlWebpackPlugin()
。 - webpack将基于"./src/index.html"模板打包生成2个html,生成的html文件名分别叫index.html、editor.html。且index.html引入打包后的index.js,editor.html引入打包后的editor.js。
- 现在我们重新启动服务,分别打开
http://localhost:1992/index.html
、http://localhost:1992/editor.html
页面,即可看到两个html页面都分别显示出来啦。 - 还需要在首页里嵌套编辑器页面。则在index项目的某个组件里使用
<iframe src="editor.html" />
嵌套即可啦。
// react
class App extends Component {
render() {
return (
<iframe src="editor.html" />
);
}
}
export default App;
批判锋芒犀利,直指问题症结所在。
作者以简洁明了的语言,传达了深刻的思想和情感。