JS打包与代码分割
参考来源:https://github.com/ruanyf/webpack-demos#demo01-entry-file-source
后面的代码:https://github.com/947133297/lwj-webpack-demo
打包AMD和commonJS模块
webpack默认支持这两种模块的打包
amd.js
define('amd',function(){
return {
data:'content from amd module'
}
});
commonJS.js
module.exports = {
data:'content from commonjs module'
}
配置文件
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
入口文件
var amd = require('./js-module/amd');
var com = require('./js-module/commomJS');
console.log(amd);
console.log(com);
运行结果:可正常输出这两个模块,网络请求只有一个bundle.js,可见这两个模块的内容都打包进了一个js文件中

chunk(这里的理解偏颇)
entry chunk :包含了 webpackJsonp、__webpack_require__ 的定义 ,__webpack_require__.e用于以promise方式加载依赖后执行组件的代码(入口文件的代码),如:

normal chunk:包含了入口文件所需的模块的代码,里面调用了webpackJsonp来注册依赖,如:

多组件代码抽取
如果多个组件中有相同的代码,每个组件都都像上个例子那样完全打包一份,那虽然减少了网络访问次数,但可能导致无谓的流量消耗,因为多个模块是可以共用代码的
全局JS:
把要复用的部分抽取到一个额外的全局js中,然后手动引入这个js,其他组件中直接使用这个js即可,如:
module.exports = {
entry: {
bundle1:'./main1.js',
bundle2:'./main2.js'
},
output: {
filename: '[name].js'
}
};
// main1.js
console.log('组件1获取数据' + data);
//main2.js
console.log('组件2获取数据' + data);
//commonData.js:
var data = 'this is common data';
index.html:
<html>
<script src="commonData.js"></script>
<body>
<script type="text/javascript" src="bundle1.js"></script>
<script type="text/javascript" src="bundle2.js"></script>
</body>
</html>
有没有办法不全局,而且可以使多个组件共用呢?这个需求可唯一推测出只能使用js模块,但是以上测试中,发现使用模块的话,会完全打包进去,以至于不能实现代码复用。其他webpack提供一个require.ensure可以实现模块的不打包,从而达到复用的目的
require.ensure
对以上代码进行改造:
// commonData.js
exports.data = 'this is common data'; // mian1.js
require.ensure(['./commonData'], function(require) {
var m = require('./commonData');
console.log('组件1获取数据' + m.data);
}); //main2.js
require.ensure(['./commonData'], function(require) {
var m = require('./commonData');
console.log('组件2获取数据' + m.data);
}); //index.html
<html>
<body>
<script type="text/javascript" src="bundle1.js"></script>
<script type="text/javascript" src="bundle2.js"></script>
</body>
</html>
运行结果一样。只不过这次实现了代码复用:

以上效果的另外一种实现方式,是使用 bundle-loader ,语法不同但效果一样就不再举例了
源码分析:
bundle1、2.js中包含了webpackJsonp、__webpack_require__以及这个函数对象的一系列方法,以及对应入口文件的执行代码
__webpack_require__.e 函数:用于根据模块id来获取模块,返回一个promise。往header上写一个script标签,这个标签onload的时候,也就是这个新增script中的webpackJsonp函数执行完了,就触发promise的resolve方法(执行了对应入口文件的代码)
补充测试:
模块1和2ensure了一个文件,模块3ensure了另一个文件。则会额外生成0.js和1.js。也就是说多少个文件被ensure,就会额外生成多少个文件(名字从0开始计算),重复ensure不会额外生成文件,而是复用之前的
与ensure具有相同功能的是import。这两者都用于动态代码分割,如果使用import的话需要注意promise的兼容,可以使用响应的垫片库来处理,简单的import使用,可以参考仓库中的demo5
CommonsChunkPlugin
代码抽取还可以用这个插件来实现,测试代码如下:
抽取依赖
// 配置文件
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
module.exports = {
entry: {
bundle1: './main1.js',
bundle2: './main2.js'
},
output: {
filename: '[name].js'
},
plugins: [
new CommonsChunkPlugin('chunkInit')
]
} // main1.js
require('./com');
require('./comm2'); var data = 'this is differenet1 '; //main2.js
require('./com');
require('./comm2'); var data = 'this is differenet2 '; //com.js
exports.data = '这里存放的是公共代码' //comm2.js
exports.data = '这里存放的是公共代码2' //index.html
<html>
<body>
<script src="chunkInit.js"></script>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</body>
</html>
运行结果:
会生成一个chunkinit.js文件(这个名字是我们在new 插件的时候指定的),这个文件中包含了webpackJsonp、__webpack_require__以及这个函数对象的一系列方法以及被依赖的模块的代码,也就是说require进来的东西并不是动态加载的,而且直接写到了这个chunkinit.js文件中。而两个bundle文件调用了webpackjsonP函数,里面的回调函数中执行了对应入口文件的代码
可见,这个插件实现的功能和require.ensure都是代码抽取,但两者本质上不同:
组件的初始化定义:包含了webpackJsonp、__webpack_require__以及这个函数对象的一系列方法
ensure:动态加载代码,抽取的是被依赖的代码,多个组件的初始化定义也还是重复的
插件:非动态加载代码,抽取的是多个组件的初始化定义到一个文件中,并且里面写好了被依赖的模块代码
以上两个组件都引用了两个相同的依赖,所以这两个依赖都放到了chuninit中。测试发现,多个组件中相同的依赖会被放到chunkinti中,而差异的部分则放到对应的bundle中,也就是说bundle中可能同时出现出现被依赖的模块代码以及对应的入口文件的代码
使用jquery
回顾以下:jq这个库兼容amd和commonJS的导入方式,require.ensure可以以不打包的形式导入一个库
有了以上的理解,怎么使用jq就很好想象了,以下使用ensure来导入,同样的理解使用上面的插件来导入应该也是可行的
require.ensure(['./jquery-3.2.1.min'], function(require) {
var jq = require('./jquery-3.2.1.min');
jq('body').attr('c2','true');
});
运行结果正常。
JS打包与代码分割的更多相关文章
- requirejs 多页面,多js 打包代码,requirejs多对多打包【收藏】
这段代码来自 http://stackoverflow.com/questions/20583812/grunt-requirejs-optimizer-for-a-multi-app-project ...
- requirejs 多页面,多js 打包代码,requirejs多对多打包
这段代码来自 http://stackoverflow.com/questions/20583812/grunt-requirejs-optimizer-for-a-multi-app-project ...
- 【grunt整合版】30分钟学会使用grunt打包前端代码
grunt 是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于:① 压缩文件② 合并文件③ 简单语法检查 对于其他用法,我还不太清楚,我们这里简单介绍下grunt的压缩.合并文件,初学, ...
- 【grunt第二弹】30分钟学会使用grunt打包前端代码(02)
前言 上一篇博客,我们简单的介绍了grunt的使用,一些基础点没能覆盖,我们今天有必要看看一些基础知识 [grunt第一弹]30分钟学会使用grunt打包前端代码 配置任务/grunt.initCon ...
- webpack练手项目之easySlide(二):代码分割(转)
在上一篇 webpack练手项目之easySlide(一):初探webpack 中我们一起为大家介绍了webpack的基本用法,使用webpack对前端代码进行模块化打包. 但是乍一看webpack ...
- 使用grunt打包前端代码
grunt 是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于:① 压缩文件② 合并文件③ 简单语法检查 对于其他用法,我还不太清楚,我们这里简单介绍下grunt的压缩.合并文件,初学, ...
- 【grunt整合版】 30分钟学会使用grunt打包前端代码
grunt 是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于:① 压缩文件② 合并文件③ 简单语法检查 对于其他用法,我还不太清楚,我们这里简单介绍下grunt的压缩.合并文件,初学, ...
- 30分钟学会使用grunt打包前端代码【mark】
grunt 是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于:① 压缩文件② 合并文件③ 简单语法检查 对于其他用法,我还不太清楚,我们这里简单介绍下grunt的压缩.合并文件,初学, ...
- 【grunt整合版】学会使用grunt打包前端代码
grunt 是一套前端自动化工具,一个基于nodeJs的命令行工具,一般用于:① 压缩文件② 合并文件③ 简单语法检查 对于其他用法,我还不太清楚,我们这里简单介绍下grunt的压缩.合并文件,初学, ...
随机推荐
- Linux系统配置文件
ubuntu系统: ~/.bashrc:该文件保存终端的文本,颜色等各类设置 ~/.bash_history:保存用户运行过的命令 ~:表示home目录 /etc/matb:该文件保存所有挂载分区的文 ...
- Jquery | 基础 | 慕课网 | 类选择器
原生getElementsByClassName()函数的实现代码与jQuery实现代码的比较: <!DOCTYPE html> <html> <head> < ...
- Hdu 2089 不要62 (数位dp入门题目)
题目链接: Hdu 2089 不要62 题目描述: 给一个区间 [L, R] ,问区间内不含有4和62的数字有多少个? 解题思路: 以前也做过这个题目,但是空间复杂度是n.如果数据范围太大就GG了.今 ...
- django 相关问题
和数据库的连接 session的实现 django app开发步骤 python环境准备 数据库安装 model定义 url mapping定义 view定义 template定义 如何查看数据库里的 ...
- 137 Single Number II 数组中除了一个数外,其他的数都出现了三次,找出这个只出现一次的数
给定一个整型数组,除了一个元素只出现一次外,其余每个元素都出现了三次.求出那个只出现一次的数.注意:你的算法应该具有线性的时间复杂度.你能否不使用额外的内存来实现?详见:https://leetcod ...
- asp.net MVC 错误信息“没有为该对象定义无参数的构造函数”请求各位大神帮忙!
在做一个登录的功能,没有用MVC自己生成的identity代码,仿照别人的代码写出了以后出现错误. 错误信息如下: 代码如下: 求各位asp.net大神支招,网上找了资料最终也没解决这个问题.
- JVM初探
### JVM分为类的加载生命周期和gc垃圾回收两个大的方面#####首先是类的生命周期, 类的加载: --> 记载字节码 ---> 这个过程有类的加载起参与,双亲委托机制() --> ...
- PMP项目管理学习笔记(4)——项目整合管理
六个整合管理过程. 1.制定项目章程 一个新项目要完成的第一件事,就是项目章程的制定.这是授权你开展工作的文档.不过并不总是需要你介入,通常情况下会由赞助人交给你.如果没有项目章程,你就没有权利告诉你 ...
- asp.net mvc 5 微信接入VB版 - 接入认证
微信接入官方文档是php的,网上被抄好几遍的代码是c#的,就是没vb的.今天我把这个坑填了,做vb版的接入认证. 首先是照着开发文档把微信接入的模型写好.在Models文件夹新建一个Model Pub ...
- ECharts是我接触过的最优秀的可视化工具,也是进步最快的软件,希望它早日成为世界级的开源项目。
ECharts的广泛网址: http://echarts.baidu.com/doc/example.html 零编程玩转图表: http://tushuo.baidu.com/?qq-pf-to=p ...