【webpack】webpack 的编译主流程
相关文章
- webpack 的编译主流程
- webpack 配置文件
- webpack 配置参数
- 如何使用sourcemap
- 自定义loader
- 自定义plugin
- 实现静态资源的离线缓存
- 如何优化webpack配置
webpack 的编译主流程
一、解析配置文件
解析配置文件是 Webpack 编译过程中的第一步,它负责读取和解析项目中的 webpack 配置文件,通常是 webpack.config.js 文件。在配置文件中,开发者可以定义入口文件、输出文件、模块解析规则、插件配置等信息,以指导 Webpack 如何进行打包构建。
定位配置文件:
Webpack 会首先尝试在项目根目录下查找配置文件,默认的配置文件名称是 webpack.config.js,如果存在则会加载该文件作为配置文件。
解析配置文件:
一旦找到配置文件,Webpack 将会加载并解析该文件,获取其中的配置信息。
配置文件可以是 CommonJS 模块、ES Module 或者是一个导出为配置对象的 JavaScript 文件,Webpack 会根据文件的导出方式进行解析。
合并配置项:
Webpack 内部会将默认配置和用户配置进行合并,以形成最终的配置对象。
如果用户未提供某些配置项,Webpack 将会使用默认配置项来填充缺失的部分。
验证配置项:
Webpack 会对最终的配置对象进行验证,确保配置项的正确性和有效性。
如果配置项存在错误或不合法,Webpack 将会抛出相应的错误信息,指导开发者进行修复。
输出最终配置:
最终,Webpack 会输出经过解析和合并的最终配置对象,作为构建过程的配置参数。
这个配置对象将被用于后续的模块解析、打包和输出文件等过程。
二、创建 Compiler 对象
在 Webpack 中,Compiler 是核心编译器,负责管理整个编译过程,包括读取配置、解析模块、应用加载器和插件、生成输出文件等。创建 Compiler 对象是 Webpack 编译过程中的第一个关键步骤。
初始化 Compiler 对象
根据解析得到的配置信息,Webpack 将会创建一个 Compiler 对象。Compiler 对象是 Webpack 编译过程的核心,它包含了 Webpack 的所有配置和功能,负责管理整个编译过程。
创建 Compiler 实例
Webpack 使用 webpack 模块导出的 createCompiler 方法来创建 Compiler 实例。这个方法接收一个配置对象作为参数,包含了从配置文件中解析得到的各项配置信息。
初始化插件系统
在创建 Compiler 实例时,Webpack 会初始化插件系统,即初始化 this.hooks 对象。this.hooks 对象包含了一系列的钩子(Hook),Webpack 在编译过程中的各个阶段会触发这些钩子,开发者可以通过插件来监听这些钩子,并在合适的时机执行自定义的逻辑。
应用内置插件
在初始化插件系统的过程中,Webpack 会自动应用一些内置插件,用于处理入口文件、处理模块、生成输出文件等。这些内置插件包含了 Webpack 的一些基本功能,如 EntryOptionPlugin、ModuleKindPlugin、CompilationPlugin 等。
应用用户配置的插件
在初始化插件系统后,Webpack 还会根据配置文件中的插件配置,加载和应用用户配置的插件。这些插件包含了用户自定义的一些功能和优化逻辑,如代码分割、资源优化、自定义输出等。
返回 Compiler 实例
创建完 Compiler 实例后,Webpack 将会将这个实例返回给调用者,作为整个编译过程的核心对象。开发者可以通过 Compiler 实例来触发编译过程,监听编译过程中的各个阶段,并执行相应的逻辑。
三、开始编译
Webpack 的编译过程从创建 Compiler 对象开始,然后执行编译过程,包括编译阶段(compilation)和打包阶段(bundle)。下面详细说明开始编译的过程:
创建 Compilation 对象
在开始编译时,Webpack 会创建一个 Compilation 对象,表示一次编译过程。Compilation 包含了当前编译过程中的所有信息,如入口模块、依赖关系、资源文件、编译结果等。
触发 compile 钩子
在创建 Compilation 对象后,Webpack 会触发 beforeCompile 钩子,通知插件开始编译过程。插件可以监听这个钩子,在编译开始前执行一些预处理操作。
编译模块
Webpack 根据入口模块开始递归地编译项目中的所有模块。在编译过程中,Webpack 首先会根据模块的路径和模块解析规则,找到模块对应的文件,然后使用加载器加载模块文件,将模块内容传递给加载器进行处理。
应用 Loader
加载器根据配置中的 Loader 规则,对模块内容进行转换处理。加载器可以对模块内容进行预处理、转换、优化等操作,使得模块能够被正确地打包和使用。加载器处理完模块后,将处理结果返回给 Webpack。
生成模块代码
在加载器处理完模块后,Webpack 将会生成模块对应的代码。对于 JavaScript 模块,Webpack 会将模块内容转换成抽象语法树(AST),然后根据依赖关系和模块之间的引用关系生成模块代码。
构建依赖图
在编译过程中,Webpack 会构建一个模块之间的依赖图,表示各个模块之间的依赖关系。这个依赖图会被用于确定模块的加载顺序、生成打包文件等。
触发 compilation 钩子
在编译过程中,Webpack 会在合适的时机触发 compilation 钩子,通知插件编译过程中的各个阶段。插件可以监听这些钩子,在编译过程中执行自定义的逻辑。
处理完所有模块
当所有模块都经过加载器处理并生成了对应的代码后,编译过程就完成了。此时,Webpack 将会触发 this.hooks.finishModules 钩子,通知插件编译完成。
四、输出编译结果
确定输出路径和文件名
在输出编译结果之前,Webpack 首先会根据配置文件中的输出路径和文件名规则确定生成的打包文件应该输出到哪个目录以及使用什么文件名。
触发 emit 钩子
在开始输出编译结果之前,Webpack 会触发 emit 钩子,通知插件即将生成输出文件。插件可以监听这个钩子,在输出文件生成前执行一些额外的操作。
生成输出文件
Webpack 将会根据生成的打包内容和输出文件的路径,将打包文件写入到指定的目录中。生成输出文件的过程会涉及文件系统的读写操作,Webpack 会将打包文件内容写入到指定的文件中。
触发 afterEmit 钩子
在输出文件生成后,Webpack 会触发 afterEmit 钩子,通知插件输出文件已经生成。插件可以监听这个钩子,在输出文件生成后执行一些额外的操作,如生成额外的文件、发送通知等。
输出编译结果
最后,Webpack 将生成的打包文件输出到指定的目录中,完成整个编译过程。开发者可以在输出目录中找到生成的打包文件,用于部署和使用。