Webpack按需加载打包chunk命名的方法


Posted in Javascript onSeptember 22, 2019

前言

最近,遇到复杂h5页面开发,为了优化H5首屏加载速度,想到使用按需加载的方式,减少首次加载的JavaScript文件体积,于是将处理过程在这里记录一下,涉及到的主要是以下三点:

  • 使用Webpack如何做按需加载
  • filename和chunkFilename的区别
  • 如何命名chunk的名称(webpackChunkName)

1 使用Webpack如何做按需加载

大家都知道Webpack是现在流行的前端打包编译工具,通过模块之间的依赖关系,将代码打包组织到一起。Webpack目前已经到v4.x,不同版本版支持按需加载的方式不同,主要有两种:

  • webpack1.x 中提供了 require.ensure()
  • webpack2.x 中提供了 import()

require.ensure()

// 举例
require.ensure([], function(require){
 require('b');
});

webpack 在编译时,会静态地解析代码中的 require.ensure(),同时将[模块b] 添加到一个分开的 chunk 当中。这个新的 chunk 会被 webpack 通过 jsonp 来按需加载。

为什么说到是静态分析,我们可以看到下面的require.ensure语法,第二个参数callback就是一个回调函数。其中需要注意的是,这个回调函数有一个参数require,通过这个require就可以在回调函数内按需引入其他模块。==值得注意的是,虽然这个require是回调函数的参数"module",理论上可以换其他名称,但是实际上是不能换的,否则webpack就无法静态分析的时候处理它。==

require.ensure(
 dependencies: String[], 
 callback: function(require){
  require('module');
 }, 
 errorCallback: function(error){}, 
 chunkName: String
)

import()

要注意的是import() 函数不同于import命令,import 是 ECMAScript 6 Module 的语法,import 是静态执行,这里不多说,可以去看import 命令。

import(specifier)

上面代码中,import函数的参数specifier,指定所要加载的模块的位置,而且==specifier可以是一个方法,动态的生成模块路径==。import命令能够接受什么参数,import()函数就能接受什么参数,两者区别主要是后者为动态加载。

import()函数是 ECMAScript Stage 3 草案阶段的语法;用于完成动态加载即运行时加载,可以用在任何地方。import()函数 返回的是一个 Promise。类似于 CommonJs 的 require() ,区别主要是前者是异步加载,后者是同步加载。

import的应用场景有以下三种 (参考自ECMAScript 6 入门):

  • 按需加载。import()可以在需要的时候,再加载某个模块
  • 条件加载。import()可以放在if代码块,根据不同的情况,加载不同的模块。
  • 动态的模块路径。import()允许模块路径动态生成。

用法大致如下:

import('./myModule.js')
 .then(myModule => {
  console.log(myModule.default);
 });

小结

目前我们用的比较多的是import来做按需加载,模块路径可以动态生成,更适合现在的应用场景。

filename和chunkFilename的区别

能够打包之后,我们会发现打包出来的chunk的路径和命名是极其简单的1,2,3...这样子的数字,对于我们要定制路径和名字的话,就会涉及到filename和chunkFilename。

  • output.filename 决定了每个入口(entry) 输出 bundle 的名称。
  • output.chunkFilename 决定了非入口(non-entry) chunk 文件的名称。

常用的Webpack配置如下

module.exports = {
 //...
 output: {
  filename: '[name].[hash].bundle.js',
  chunkFilename: '[name].[hash].chunk.js',
 }
};

filename和chunkFilename对应的结果可以由以下参数拼接或者返回:

模板 描述
[hash] 模块标识符(module identifier)的 hash
[chunkhash] chunk 内容的 hash
[name] 模块名称
[id] 模块标识符(module identifier)
[query] 模块的 query,例如,文件名 ? 后面的字符串
[function] 方法,可以返回一个filename字符串

不同的是chunkFilename我们不能想filename中的name那样,可以在entry中定义。也就是说对于chunkFilename,默认[id]和[name]是一样的,那么如何自定义name呢?

如何命名chunk的名称

只能说哪里有压迫,哪里就会有反抗,chunkFileName不能灵活自定义,这谁能忍,于是便有了/* webpackChunkName: "" */,号称是Magic Comments(魔术注释法)。

Webpack通过增加内联注释来告诉运行时,该有怎样的行为。通过向import中添加注释,我们可以执行诸如命名chunk或选择不同模式之类的操作。

这里着重讲一下webpackChunkName,它其实就是对chunkFilename定义时[name]值的改写,/* webpackChunkName: "hello" */,意味着[name]等于hello。

于是上面的代码就会按照下面的方式来写,打包出来的chunk文件将会出现在plugins文件夹下,名字叫myModule.a2d1d5d8e7d5d4d4d4se.chunk.js。

import(/* webpackChunkName: "plugins/myModule" */
  './myModule.js')
  .then(myModule => {
    console.log(myModule.default);
  });

更多的魔术注释,请参考Webpack官方文档。

结束了

到此为止,我们已经可以将代码打包到多个文件,每个chunk可以独立命名,是的就是这样。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript 回调函数详解
Nov 11 Javascript
jQuery中removeData()方法用法实例
Dec 27 Javascript
JQuery radio(单选按钮)操作方法汇总
Apr 15 Javascript
基于JavaScript实现类似于百度学术高级检索功能
Mar 02 Javascript
教你用javascript实现随机标签云效果_附代码
Mar 16 Javascript
微信小程序三级联动地址选择器的实例代码
Jul 12 Javascript
javascript 跨域问题以及解决办法
Jul 17 Javascript
详解A标签中href=""的几种用法
Aug 20 Javascript
BootStrap数据表格实例代码
Sep 13 Javascript
Vue打包部署到Nginx时,css样式不生效的解决方式
Aug 03 Javascript
vue 数据遍历筛选 过滤 排序的应用操作
Nov 17 Javascript
JS中锚点链接点击平滑滚动并自由调整到顶部位置
Feb 06 Javascript
jquery.tagsinput.js实现记录checkbox勾选的顺序
Sep 21 #jQuery
vue2.0+SVG实现音乐播放圆形进度条组件
Sep 21 #Javascript
js+springMVC 提交数组数据到后台的实例
Sep 21 #Javascript
jquery弹窗时禁止body滚动条滚动的例子
Sep 21 #jQuery
vue实现文件上传读取及下载功能
Nov 17 #Javascript
layer弹出框确定前验证:弹出消息框的方法(弹出两个layer)
Sep 21 #Javascript
vue配置nprogress实现页面顶部进度条
Sep 21 #Javascript
You might like
windows下apache搭建php开发环境
2015/08/27 PHP
PHP排序二叉树基本功能实现方法示例
2018/05/26 PHP
php求斐波那契数的两种实现方式【递归与递推】
2019/09/09 PHP
PHP基于ip2long实现IP转换整形
2020/12/11 PHP
jquery 插件 任意位置浮动固定层
2008/12/25 Javascript
javascript重复绑定事件造成的后果说明
2013/03/02 Javascript
javaScript函数中执行C#代码中的函数方法总结
2013/08/07 Javascript
js使浏览器窗口最大化实现代码(适用于IE)
2013/08/07 Javascript
Lua表达式和控制结构学习笔记
2014/12/15 Javascript
js面向对象之公有、私有、静态属性和方法详解
2015/04/17 Javascript
JavaScript 轮播图和自定义滚动条配合鼠标滚轮分享代码贴
2016/10/28 Javascript
微信小程序 中wx.chooseAddress(OBJECT)实例详解
2017/03/31 Javascript
浅谈node的事件机制
2017/10/09 Javascript
详解使用React全家桶搭建一个后台管理系统
2017/11/04 Javascript
基于vue v-for 循环复选框-默认勾选第一个的实现方法
2018/03/03 Javascript
D3.js实现简洁实用的动态仪表盘的示例
2018/04/04 Javascript
JS逻辑运算符短路操作实例分析
2018/07/09 Javascript
js判断复选框是否选中的方法示例【基于jQuery】
2019/10/10 jQuery
[01:35]2014DOTA2西雅图邀请赛 专访狐狸妈青春献给刀塔
2014/07/08 DOTA
[00:59]DOTA2荣耀之路1:Doom is back!weapon X!
2018/05/22 DOTA
python中while循环语句用法简单实例
2015/05/07 Python
Python工程师面试题 与Python Web相关
2016/01/14 Python
Python连接DB2数据库
2016/08/27 Python
python编写Logistic逻辑回归
2020/12/30 Python
解决python中遇到字典里key值为None的情况,取不出来的问题
2018/10/17 Python
浅谈pycharm的xmx和xms设置方法
2018/12/03 Python
Python嵌套式数据结构实例浅析
2019/03/05 Python
Python安装Flask环境及简单应用示例
2019/05/03 Python
基于CSS3实现立方体自转效果
2016/03/01 HTML / CSS
HTML5 语义化结构化规范化
2008/10/17 HTML / CSS
美国从事品牌鞋类零售的连锁店:Famous Footwear
2016/08/25 全球购物
Ariat英国官网:为世界顶级马术运动员制造最优质的鞋类和服装
2020/02/14 全球购物
Linux的主要特性
2016/09/03 面试题
工程力学专业毕业生求职信
2013/10/06 职场文书
小学同学聚会感言
2015/07/30 职场文书
elasticSearch-api的具体操作步骤讲解
2021/06/28 Java/Android