最近,遇到复杂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 入门):

  1. 按需加载。import()可以在需要的时候,再加载某个模块
  2. 条件加载。import()可以放在if代码块,根据不同的情况,加载不同的模块。
  3. 动态的模块路径。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可以独立命名,是的就是这样。

webpack动态加载打包chunk命名的更多相关文章

  1. Unity 利用UGUI打包图集,动态加载sprite资源

    今天做了一个UI界面,这个界面是好友界面,该界面上有若干个好友item. 需要对每个tem的头像对象(image)动态显示对应的头像.尝试利用UGUI的图集来加载,具体实现如下: 1.首先,需要知道S ...

  2. React router动态加载组件-适配器模式的应用

    前言 本文讲述怎么实现动态加载组件,并借此阐述适配器模式. 一.普通路由例子 import Center from 'page/center'; import Data from 'page/data ...

  3. webpack异步加载业务模块

    虽然把我们用到的JS文件全部打包一个可以节省请求数,但如果打包后的JS文件过大,那么也容易出现白屏现象,许多操作失灵.而且一些区域是点到才出现,那么相关的JS其实可以剥离出这个大JS文件外.这就涉及到 ...

  4. javascript模块化以及加载打包

    https://addyosmani.com/writing-modular-js/ 一些术语: 模块:可以理解为一个js文件,就像你以前需要import的那个文件一样:module不一定非要是一个外 ...

  5. 携程Android App插件化和动态加载实践

    携程Android App的插件化和动态加载框架已上线半年,经历了初期的探索和持续的打磨优化,新框架和工程配置经受住了生产实践的考验.本文将详细介绍Android平台插件式开发和动态加载技术的原理和实 ...

  6. Android动态加载jar/dex

    前言 在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优 ...

  7. Webpack模块加载器

    一.介绍 Webpack是德国开发者 Tobias Koppers 开发的模块加载器,它能把所有的资源文件(JS.JSX.CSS.CoffeeScript.Less.Sass.Image等)都作为模块 ...

  8. 携程Android App的插件化和动态加载框架

    携程Android App的插件化和动态加载框架已上线半年,经历了初期的探索和持续的打磨优化,新框架和工程配置经受住了生产实践的考验.本文将详细介绍Android平台插件式开发和动态加载技术的原理和实 ...

  9. Vue(基础七)_webpack(webpack异步加载原理)

    ---恢复内容开始--- 一.前言 1.webpack异步加载原理’                                           2.webpack.ensure原理     ...

随机推荐

  1. 前端常用得CSS代码分享

    前端常用得CSS代码分享 本文首发于公众号:小夭同学,同步更新个人博客:故事影片,转载请署名.代码不断更新中!! 1,垂直居中对齐 .vc { position: absolute; top: 50% ...

  2. shell脚本exercise2

    通过文件里面的网址,判断是否访问成功网址 #!/bin/bash check(){ code=`curl -I -m -o /dev/null -s -w %{http_code} http://$u ...

  3. unity3D 游戏物体同时绑定单击、双击事件

    前言 在unity中我们常用的获取鼠标点击的方法有 在3D场景中,一般用在Update方法中,每一帧调用 void Update(){ )){ Debug.log("鼠标左键点击" ...

  4. 快速理解spark-on-k8s中的external-shuffle-service

    [摘要] external-shuffle-service是Spark里面一个重要的特性,有了它后,executor可以在不同的stage阶段动态改变数量,大大提升集群资源利用率.但是这个特性当前在k ...

  5. 一条数据的HBase之旅,简明HBase入门教程4:集群角色

    [摘要] 本文主要介绍HBase与HDFS的关系,一些关键进程角色,以及在部署上的建议 HBase与HDFS 我们都知道HBase的数据是存储于HDFS里面的,相信大家也都有这么的认知: HBase是 ...

  6. OA项目之mybatis动态查询

    类似于三个条件,可以全部选择,也可以选择几个条件进行查询 Mapper.xml文件: <resultMap type="Employee" id="selAll&q ...

  7. SpringBoot与JPA

    JPA是什么 JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. JPA ...

  8. CodeForces1000A- Codehorses T-shirts

    A. Codehorses T-shirts time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  9. (全国多校重现赛一)F-Senior Pan

    Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory pro ...

  10. Python实现截图功能你肯定不会吧?【面试必学】

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:CyborgLin python实现截图功能. windows环境下.需 ...