|
webpack多页面开发与懒加载hash解决方案
之前讨论了webpack的hash与chunkhash的区别以及各自的应用场景,如果是常规单页面应用的话,上篇文章提供的方案是没有问题的。但是前端项目复杂多变,应对复杂多页面项目时,我们不得不继续踩webpack的hash坑。
在进入正文之前先解释一下所谓的常规单页面和复杂多页面是什么意思。
这两个并非专业术语,而是笔者实在想不出更恰当的说法了,见谅。
1.项目类型
1.1常规单页面项目
常规单页面符合以下条件:
可以存在多个主js文件和css文件;
每个js文件都是同步打包的,也就是说不存在与主文件相关联的懒加载文件。
与主文件关联的懒加载文件指的是逻辑与主文件完全无关的js文件,这类文件不参与主文件打包。比如主文件main.js中有以下代码:
window.onload=function(){
varscript=document.createElement(''script'');
script.src=''//static.daojia.com/bi.js'';
document.head.appendChild(script);
}
其中bi.js的内部逻辑与main.js为任何关联,它对于main.js来说就是一个字符串而已。
与之相对应的是与主文件有逻辑关系的模块文件,比如以下代码:
window.onload=function(){
require.ensure([],function(require){
require(''./part.a.js'');
},''a'');
}
其中part.a.js是懒加载模块,以上源码经编译会生成独立的part文件,由main.js按需加载。
1.2复杂多页面项目
复杂多页面项目符合以下条件:
存在与主文件相关联的懒加载模块文件;
存在多个主js文件。
那么这种类型的项目复杂度在哪呢?如何应用webpack去解决hash问题?
2.懒加载的hash解决方案
上篇文章webpack的hash与chunkhash的区别以及各自的应用场景提到应该使用chunkhash结合webpack-md5-plugin作为js文件hash解决方案。这种方案在应对所有模块均同步编译的场景是没有问题的,但是请大家首先考虑下文的场景。
2.1应用场景
入口文件main.app.js的代码如下:
import''../style/main.app.scss'';
importfn_dfrom''./part.d.js'';
console.log(''main'');
window.onload=function(){
require.ensure([],(require)=>{
require(''./part.a.js'');
});
}
异步模块part.a.js代码如下:
importfn_dfrom''./part.d.js'';
console.log(''parta'');
setTimeout(()=>{
require.ensure([],(require)=>{
require(''./part.b.js'');
});
},10000);
异步模块part.b.js代码如下:
importfn_cfrom''./part.c.js'';
importfn_dfrom''./part.d.js'';
console.log(''partb'');
使用webpack将以上源代码进行编译,输出以下文件:
main.app.[chunkhash].js:主文件;
part.a.[chunkhash].js:异步模块a;
part.b.[chunkhash].js:异步模块b;
main.app.[chunkhash].css:样式文件。
截止到目前是没有问题的,现在,请大家想象一下:如果我们修改了part.a.js源码,编译的结果文件哪些文件的hash改变了?
首先可以肯定的是part.a.[chunkhash].js的hash值会改变,那么其他文件呢?
答案是:只有part.a.[chunkhash].js的hash改变了,其余文件的hash都与修改前一致。
那么这种结果是否合理呢?
在回答这个问题之前,我们首先了解一下webpackruntime是如何加载异步模块的。请看以下代码:
varhead=document.getElementsByTagName(''head'')[0];
varscript=document.createElement(''script'');
script.type=''text/javascript'';
script.charset=''utf-8'';
script.async=true;
script.src=__webpack_require__.p+"js/part/part."+({
"1":"a",
"2":"b"
}[chunkId]||chunkId)+"."+{
"1":"f5ea7d95",
"2":"b93662b0"
}[chunkId]+".js";
head.appendChild(script);
上述代码是编译生成的main.app.[chunkhash].js中实现懒加载的逻辑,原理就是大家熟知的动态生成
| | |