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表单常用验证集合
Jan 16 Javascript
谈谈JavaScript中的函数与闭包
Apr 14 Javascript
关闭页面时window.location事件未执行的原因分析及解决方案
Sep 01 Javascript
js实现div弹出层的方法
Nov 20 Javascript
js+jquery实现图片裁剪功能
Jan 02 Javascript
Jquery使用val方法读写value值
May 18 Javascript
详解javascript new的运行机制
Jan 26 Javascript
Bootstrap模态窗口源码解析
Feb 08 Javascript
微信小程序 配置顶部导航条标题颜色的实现方法
Sep 20 Javascript
怎样在vue项目下添加ESLint的方法
May 16 Javascript
javascript实现日历效果
Jun 17 Javascript
使用 JavaScript 制作页面效果
Apr 21 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
PHP中的session永不过期的解决思路及实现方法分享
2011/04/20 PHP
php中使用url传递数组的方法
2015/02/11 PHP
php文件压缩之PHPZip类用法实例
2015/06/18 PHP
在Thinkphp中使用ajax实现无刷新分页的方法
2016/10/25 PHP
详解PHP中的 input属性(隐藏 只读 限制)
2017/08/14 PHP
PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解
2018/04/20 PHP
jQuery 学习第七课 扩展jQuery的功能 插件开发
2010/05/17 Javascript
JS数组的常见用法实例
2015/02/10 Javascript
Jquery全屏相册插件zoomvisualizer具有调节放大与缩小功能
2015/11/02 Javascript
js仿微信语音播放实现思路
2016/12/12 Javascript
Bootstrap下拉菜单更改为悬停(hover)触发的方法
2017/05/24 Javascript
一个简易的js图片轮播效果
2017/07/22 Javascript
JS实现延迟隐藏功能的方法(类似QQ头像鼠标放上展示信息)
2017/12/28 Javascript
vue集成百度UEditor富文本编辑器使用教程
2018/09/21 Javascript
Node.js 获取微信JS-SDK CONFIG的方法示例
2019/05/21 Javascript
[01:05:29]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第二场 1月24日
2021/03/11 DOTA
书单|人生苦短,你还不用python!
2017/12/29 Python
运动检测ViBe算法python实现代码
2018/01/09 Python
Zookeeper接口kazoo实例解析
2018/01/22 Python
浅谈DataFrame和SparkSql取值误区
2018/06/09 Python
python设计微型小说网站(基于Django+Bootstrap框架)
2019/07/08 Python
python支付宝支付示例详解
2019/08/22 Python
浅谈tensorflow模型保存为pb的各种姿势
2020/05/25 Python
sklearn的predict_proba使用说明
2020/06/28 Python
解决Python paramiko 模块远程执行ssh 命令 nohup 不生效的问题
2020/07/14 Python
python批量修改交换机密码的示例
2020/09/22 Python
使用HTML5进行SVG矢量图形绘制的入门教程
2016/02/19 HTML / CSS
html5开发三八女王节表白神器
2018/03/07 HTML / CSS
思想品德自我鉴定
2013/10/12 职场文书
电子商务专业推荐信范文
2013/12/02 职场文书
坎儿井导游词
2015/02/09 职场文书
公司清洁工岗位职责
2015/04/15 职场文书
社会实践单位意见
2015/06/05 职场文书
收入证明申请书
2015/06/12 职场文书
2019年关于小学生课外阅读情况的分析报告
2019/12/02 职场文书
Redis实战高并发之扣减库存项目
2022/04/14 Redis