Entry: 入口,执行构建的输入Module: 模块,在Webpack里一切皆模块,Webpack会从Entry开始,递归找出所有依赖的模块Chunk: 代码块,一个Chunk由多个模块合成,用于代码合并和分割Loader: 模块转换器,用于将模块的源内容按照需求转换成新内容Plugin: 扩展插件,在构建流程中的特定时机会广播对应的事件,插件可以监听这些事件,做出对应的事情Webpack的运行流程是一个串行的过程,从启动开始依次是:
Shell语句中读取与合并参数,得出最终参数Compiler对象,加载所有配置的插件,通过执行对象的run方法开始编译Entry找出所有入口文件Loader对模块递归的进行编译Chunk,再将每个Chunk转换成一个单独的文件加入输出列表,这是修改输出内容的最后机会在以上过程中,Webpack会在特定的时间广播特定的事件,插件在监听到特定事件后可以执行对应的逻辑,并且可以调用Webpack提供的API改变Webpack的运行结果。
整体构建流程可以分为以下三大阶段:
Plugin,实例化CompilerEntry开始,针对每个Module串行调用对应Loader去编译内容,并依据Module之间的依赖关系,递归的进行编译处理Module组合成Chunk,然后转换成文件,输出到文件系统build时,只执行上述阶段一次。监听模式下,将不断的执行编译,输出阶段
在模块化编程中,开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为模块。
Webpack模块能够以各种方式表达他们的依赖关系,例如:
ES6``import语句CommonJS``require()语句AMD``define和require语句css/sass/less文件中的@import语句url(...))或HTML文件(<img src=...>)中的图片链接(image url)以处理SCSS文件为例:
一个Loader的职责是单一的,只负责一种转换。一个源文件需要多次转换,需要配置多个Loader。在调用多个Loader时,执行顺序是从后往前依次执行
Loader就是一个函数,获取处理前的内容,返回处理后的内容
Loader的options直接return可以返回原内容转换后的内容,返回其他内容需要用到this.callback函数:
此外,由于Source Map生产很耗时,通常在开发环境下才生成。因此可以通过this.sourceMapAPI来配置是否生成Source Map。
异步转换流程如下:
对于二进制数据,需要将exports.raw = ture:
可以通过this.cacheable()方法设置是否缓存计算结果,默认是开启的
API | 简介 |
|---|---|
this.context | 当前处理的文件所在目录,以/src/main.js为例,为/src |
this.resoure | 当前处理的完整请求路径,包括query string,例如/src/main.js?name=1 |
this.resourePath | 当前处理文件的路径,例如/src/main.js |
this.resoureQuery | 当前处理文件的query string |
this.target | Webpack中配置的Target |
this.loadModule(request: string, callback: function(err, source, sourceMap, ast)) | Loader在处理一个文件时,需要加入依赖时,用于获取对应文件的处理结果 |
this.addDependency(file: string) | 为当前处理的文件添加依赖。其依赖文件发生变化时,会重新调用loader处理该文件 |
this.addContextDependency(directory: string) | 将整个目录加入到正在处理的文件依赖中 |
this.clearDependencies() | 清除当前处理文件的多有依赖 |
| `this.emitFile(name: string, content: Buffer | string, sourceMap)` |
开发Plugin最常用的两个对象就是Compiler和Compilation,他们是Plugin和Webpack之间的桥梁。
Compiler包含所有配置信息(options、loaders和plugins等),在Webpack启动时被实例化,全局唯一。代表了整个Webpack从启动到关闭的生命周期Compilation包含当前的模块资源、编译生成资源和变化的文件等。在开发模式下,每当有文件变化时,就有一次新的Compilation被创建。代表了一次编译过程Webpack通过Tapable来组织构建的事件流。Webpack中许多对象(包括Compiler和Compilation)都继承自Tapable。
Tapable暴露了tap, tapAsync和tapPromise方法。可以使用这些方法,注入自定义的构建步骤,这些步骤将在整个编译过程中不同时机触发。
都自Tapable,可以广播和监听事件:
每个插件的Compiler和Compilation对象都是同一个引用。修改Compiler和Compilation对象上的属性就会影响后面的插件。有些事件是异步的,插件处理完成时调用回调函数通知Webpack,才能进入下一个流程。
Plugin主要通过监听Webpack在运行的生命周期中广播的特定事件,在合适的时机通过Webpack提供的API做出对应的处理,改变输出结果
一个Plugin就是一个类,具体写法如下:
Webpack启动后,读取配置过程中会初始化插件实例。在初始化compiler对象之后,在调用插件的apply方法,为实例传入compiler对象。插件实例在获取到compiler对象后,通过
compiler.plugin(event: string, callback: function(compilation))监听Webpack广播的事件,通过compiler对象去操作Webpack
插件可以用来修改输出文件和增加输出文件,甚至提升Webpack性能
emit事件发生时,代表源文件的转换和组装已经完成,可以读取到最终输出的资源、代码块、模块及其依赖,并修改输出资源的内容
SSE