webpack | 青训营笔记

94 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的的第19天。

今天已经是进入青训营学习的第三周的第二天了,从加入青训营到现在,我跟着青训营的课程一路坚持了下来,从简单的前端三件套html、css和JavaScript到现在的react、ndoejs等前端技术,我一步一步在进行学习和理解,可以看到,青训营前端场的知识体系还是比较完善的,而且需要一定的基础才能够进行更加深入的提高,对于我这种前端小白来说,即使有些知识听不懂,我还是有一定的收获的,并且能跟着前沿的师资进行同步学习,并且有很多的小伙伴一起参加这种活动,这种学习的氛围还是很不错的。

上周课程重点内容

  • Web开发安全
  • Http使用指南
  • 前端开发调试
  • TypeScript入门
  • 响应式系统React
  • NodeJs
  • webpack

在前端工程化日趋复杂的今天,模块打包工具在我们的开发中起到了越来越重要的作用,其中webpack就是最热门的打包工具之一。

说到webpack,可能很多小伙伴会觉得既熟悉又陌生,熟悉是因为几乎在每一个项目中我们都会用上它,又因为webpack复杂的配置和五花八门的功能感到陌生。尤其当我们使用诸如umi.js之类的应用框架还帮我们把webpack配置再封装一层的时候,webpack的本质似乎离我们更加遥远和深不可测了。

当面试官问你是否了解webpack的时候,或许你可以说出一串耳熟能详的webpack loaderplugin的名字,甚至还能说出插件和一系列配置做按需加载和打包优化,那你是否了解他的运行机制以及实现原理呢,那我们今天就一起探索webpack的能力边界,尝试了解webpack的一些实现流程和原理,拒做API工程师。

![image.png](p6-juejin.byteimg.com/tos-cn-i-k3…

你知道webpack的作用是什么吗?

从官网上的描述我们其实不难理解,webpack的作用其实有以下几点:

  • 模块打包。可以将不同模块的文件打包整合在一起,并且保证它们之间的引用正确,执行有序。利用打包我们就可以在开发的时候根据我们自己的业务自由划分文件模块,保证项目结构的清晰和可读性。
  • 编译兼容。在前端的“上古时期”,手写一堆浏览器兼容代码一直是令前端工程师头皮发麻的事情,而在今天这个问题被大大的弱化了,通过webpackLoader机制,不仅仅可以帮助我们对代码做polyfill,还可以编译转换诸如.less, .vue, .jsx这类在浏览器无法识别的格式文件,让我们在开发的时候可以使用新特性和新语法做开发,提高开发效率。
  • 能力扩展。通过webpackPlugin机制,我们在实现模块化打包和编译兼容的基础上,可以进一步实现诸如按需加载,代码压缩等一系列功能,帮助我们进一步提高自动化程度,工程效率以及打包输出的质量。

说一下模块打包运行原理?

如果面试官问你Webpack是如何把这些模块合并到一起,并且保证其正常工作的,你是否了解呢?

首先我们应该简单了解一下webpack的整个打包流程:

  • 1、读取webpack的配置参数;
  • 2、启动webpack,创建Compiler对象并开始解析项目;
  • 3、从入口文件(entry)开始解析,并且找到其导入的依赖模块,递归遍历分析,形成依赖关系树;
  • 4、对不同文件类型的依赖模块文件使用对应的Loader进行编译,最终转为Javascript文件;
  • 5、整个过程中webpack会通过发布订阅模式,向外抛出一些hooks,而webpack的插件即可通过监听这些关键的事件节点,执行插件任务进而达到干预输出结果的目的。

其中文件的解析与构建是一个比较复杂的过程,在webpack源码中主要依赖于compilercompilation两个核心对象实现。

compiler对象是一个全局单例,他负责把控整个webpack打包的构建流程。 compilation对象是每一次构建的上下文对象,它包含了当次构建所需要的所有信息,每次热更新和重新构建,compiler都会重新生成一个新的compilation对象,负责此次更新的构建过程。

而每个模块间的依赖关系,则依赖于AST语法树。每个模块文件在通过Loader解析完成之后,会通过acorn库生成模块代码的AST语法树,通过语法树就可以分析这个模块是否还有依赖的模块,进而继续循环执行下一个模块的编译解析。

最终Webpack打包出来的bundle文件是一个IIFE的执行函数。