Webpack 多页面打包
先说一下前提,大部分情况的web 项目有个单独登录页面的需求,这个页面的前端路由、前端用户状态都是和登陆后的主页面分开的,为了安全性(登录页不应包含主页的逻辑代码,虽然是混淆压缩的)和登录页加载速度。 这边还得提到一些基本概念:
-
页面程序的生命周期, 目前流行的SPA 单页面程序,只要刷新页面,实际上Vuex store 都重置了,除了还停留在当前路由之外,其他前端状态都回到了程序最开始的状态。
-
多页面程序,类似于把登录界面和主页面分开为两个 html 文件入口的架构。每个html 文件中引入了js、css ,js中包含了前端路由的配置,app 的第三方vendor和业务模块,可能分为好几个js 文件。
例如封面图所示:多页面打包output 出好几个模块,每个模块一个js 文件,有login.js,app.js,还有vendor.js (没有显示在图中),0.js 是app.js 引用的一个懒加载模块(按需加载),也是单独打包的。这样可以让登录页只引用vendor.js 和 login.js, 提高首页的响应能力
具体配置
具体webpack 配置如下,比较简单。
// webpack.base.conf.js
module.exports = {
entry: {
// 写多个入口,每个入口实例化 new Vue({ el: '#app' })
app: './src/main.js',
login: './src/login.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
// webpack.prod.conf.js
// 关键的在prod 的配置中,利用HtmlWebpackPlugin 插件输出多个 html 作为不同app 的入口,包含对应的 js chunks
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'auto',
// 关键的是这里,配置这个html 包含 login 相关的模块
chunks: ['manifest', 'vendor', 'login'],
}),
// 继续再配置一个主页面的html 文件输出
new HtmlWebpackPlugin({
filename: 'app.html',
template: 'index.html',
inject: true,
// 配置这个html 包含 app 相关模块
chunks: ['manifest', 'vendor', 'app'],
chunksSortMode: 'dependency',
}),
放到 github上了,需要的直接copy 下webpack配置和 程序入口 main.js, login.js
实际上login.js 和app.js 这两个程序可以共享一些第三方模块,大部分情况下依赖的第三方模块是不完全相同的。所以最理想的结果是打包出共享的vendor.js ,然后再打包出每个入口单独依赖的vendor_login.js 和vendor_app.js,这样就可以把vendor_app.js 从最开始的vendor.js 中拆分出去,提高首屏时间。
在路由表中配置,懒加载模块还有一个优化打包的方面: 避免webpack tree Shaking 失败而打包无用模块。
也就是采用 import 具体模块文件的方式,替代import from index 的方式来实现确定性引入模块,实现在bundle.js 排除 index 文件中其他未引入的文件。具体参考上一篇总结
打包出的js 模块写在最后
之前碰到一个很烦的情况,有个bug 需要在页面跳转之前或刚进入页面的时候打断点。。。找了半天,发现 Chrome 浏览器可以在debugger 中对所有页面跳转的事件打breakPoints,而且可以跨页面。不同于debugger 关键字或者在source 中对某一行进行 debug,该功能特别适用于多页面跳转的debug
Chrome debugger
网友评论