webapck 是现代javaScript应用程序的静态模块打包器。它会在内部从一个或多个入口点出发构建一个依赖关系图,然后将您项目中所需的每个模块组合成一个或多个bundles,这些bundles是用于提供内容的静态资产。
—— webpack 官网
webpack 就像一条生产线,要经过一系列的处理流程后才能将源文件转换成bundles。这条生产线上的每个处理流程的职责都是单一的,多个流程之间有存在依赖关系,只有完成当前处理后才能进入下一个流程去处理。插件就像是一个插入到生产线中某个节点的功能,在特定的时机对生产线上的内容做个性化处理。 webpack 通过Tapable来组织这条复杂的生产线。Tapable是webpack 自行维护的一个插件库,它暴露了一些hooks Class用以创建hooks。webpack在运行过程中会广播事件,插件只需要提前订阅这些事件就能加入到这条生产线中,去改变生产线的运作。webpack的事件流机制保证了插件的有序性,使得整个系统扩展性很好。——《深入浅出 webpack》
流程
初始化:从配置文件和webpack cli中读取与合并参数,注册插件,实例化Compiler并执行Compiler.run()来触发编译工作。编译:对入口模块及其依赖的模块进行静态解析并使用相应loader进行递归编译。输出:将转换后的模块根据代码分离规则组合成chunks,然后根据输出配置等确定并输出bundles。- 若开启监听模式,当监听到文件变化时,会创建新的编译流程。
配置
context基础目录,字符串格式,默认使用Node.js进程的当前工作目录。entry入口,字符串/对象/数组/函数格式,用于webpack查找开始构建的地方。mode模式,字符串格式,用以告知webpack 使用相应模式的内置优化。output输出,对象格式,用以指示webpack 如何去输出、以及哪里输出你的「bundle、asset和其他你所打包或使用webpack 载入的任何内容」。module模块,对象格式,用以配置相关规则和loader来匹配处理项目中不同类型的模块。resolve解析,对象格式,用以设置模块如何被解析,如extensions、alias。optimization优化,对象格式,用于设置webpack的优化配置项,如minimize,minimizer,splitChunks等。plugins插件,数组格式,用以使用hooks来自定义webpack构建过程。devServer开发服务器,对象格式,可用于快速开发应用程序。cache缓存,布尔值/对象格式,缓存生成的模块和chunk,来改善构建速度。devtoolDevtool,字符串/false格式,用以控制生成及如何生成source map。targets构建目标,字符串/数组/false格式,为多种环境或target构建编译。watch监听,布尔值格式,当开启监听且文件变化时,webpack会重新编译。externals外部拓展,字符串/对象格式/函数格式/正则表达式/数组格式,可用来防止将某些import的包打包到bundle中,而是在运行时再去从外部获取这些外部依赖。performance性能提示,对象格式,用来配置如何展示性能提示。nodeNode,false/对象格式,用以配置是否 polyfill 或mock 某些Node.js q全局变量。statsStats,对象/字符串,让你更精确地控制bundle的错误、告警、输出信息是否显示。experiments实验特性,对象格式,在webpack v5推出的新API,赋能给用户去开启并试用一些实验的特性,如css => 启用原生支持css,futuredefaults => 为许多 webpack 4 api 启用后向兼容层,并发出弃用警告。others其他选项,格式不定,webpack的其他设置项,如:bail => 在第一个错误时抛出失败结果等。
loader
plugin
性能优化
请查阅webpack的性能优化
常见问题
1、如何解决循环依赖问题?答:
- 对于
Commonjs、ESModule模块规范,其执行遇到循环依赖时会先将被循环依赖的脚本导出对象的未完成副本给到造成循环依赖的脚本,待造成循环依赖的脚本执行完成后再将导出对象给到被循环依赖的脚本。