title: Module bundling author: Gamehu tags: - Module categories: - 前端 date: 2020-03-01 20:23:00 --- 是的这又是一篇搬运文章,谁让我放荡不羁爱打野呢。作者博客地址[Preethi Kasireddy](https://www.preethikasireddy.com/) 之前有聊过一篇关于{% post_link Modules %}的文章,主要讲什么是模块以及为什么需要模块。这篇主要讲怎么捆绑(打包)模块也就是模块使用的深一步探讨。 ### 什么是模块捆绑? 从高层次上讲,模块捆绑只是将一组模块(及其依赖项)按正确顺序拼接到单个文件(或一组文件)中的过程。 ### 为什么需要模块捆绑? 如果项目中使用的模块过多,那么你就需要一个一个的使用script 标签引入到html中去,然后html运行的时候会一个一个的去加载你引入的模块。 {% asset_img waterfall.png from how-to-analyze-a-waterfall-chart %} 像上图那样 one by one 如果用的模块一多,页面的延迟就会过久,用户体验不好。 为了解决这个问题,我们把所有文件捆绑,或“拼接”到一个文件(有时也是一组文件)中,**正是为了减少请求数**。 另一个加速构建操作的常用方法是,“缩减”捆绑后的代码。缩减,是把源代码中不需要的字符(如空格、评论、换行符等等)移除,从而减小了代码的总体积,却不改变其功能。 数据更少,**浏览器处理的时间就更短**,比如经常见到的"xxxmin.js",相比完整版,缩减版小了好多。 ### 捆绑模块有哪些不同的方式? 如果你用的是一种标准模块模式(在 [第一部分](https://medium.freecodecamp.com/javascript-modules-a-beginner-s-guide-783f7d7a5fcc#.y8hs0nsne) 讨论过)来定义模块,比如*IIFE、全局导入*等,其实就是直接拼接和缩减几堆纯 JavaScript 代码,通常则不用借助工具。 但如果你用的是非原生模块系统,浏览器不能像 CommonJS、AMD、甚至原生 ES6 模块格式那样解析,你就需要用专门工具先转化成排列正确、浏览器可识别的代码。这正是 Browserify、RequireJS、Webpack 和其他模块捆绑工具,或模块加载工具粉墨登场的时候。 下面就来过一遍常用的模块捆绑方法: #### Bundling CommonJS [第一部分](https://medium.freecodecamp.com/javascript-modules-a-beginner-s-guide-783f7d7a5fcc#.y8hs0nsne)所知,CommonJS同步加载模块,它对于浏览器是不适用的。 解决此问题其中一个方法是用Browserify。 Browserify是一个为浏览器编译CommonJS模块的工具。 例如,假设您有一个main.js文件,该文件导入一个模块来计算数字数组的平均值: ``` var myDependency = require('myDependency'); var myGrades = [93,95,88,0,91]; var myAverageGrade = myDependency.average(myGrades); ``` 因此,在这种情况下,我们只有一个依赖项(myDependency)。 使用以下命令,Browserify将递归所有必需的模块(从main.js开始)并把它们捆绑到一个名为bundle.js的文件中: ``` browserify main.js -o bundle.js ``` Browserify通过跳入每个***require*** 调用的AST解析来遍历项目的整个依赖关系图来实现此目的。 一旦确定了依存关系的结构,便会将它们按正确的顺序捆绑到一个文件中。当需要使用时,则将***“bundle.js”*** 文件的`