写在webpack源码前面。我已经研究了几周,并在团队中分享了它。我以前从未写过关于师傅的文章。后来觉得师傅比CSDN的文章质量更高,于是转念一想,以后争取每周更新一篇质量更高的文章,期待不断完善。一、webpack的作用Webpack是一个非常重要的前端打包工具。它的主要功能可以用一句话来概括:将基于依赖的代码(包括css、ts、vue、sass)打包成浏览器可以运行的多个bundle。js基于这个目的,webpack必须实现四个东西:基于acorn收集模块依赖;将所有基于loader的文件转换成浏览器可以运行的js,在打包的整个生命周期中做很多事情(基于plugin实现)最后打包(tree-shaking等)成多个bundles.js2,tapable,和acorn贴一段源码,可以看到在整个编译过程中多次出现类似的写法,两次hook之间并没有找到对应的实现代码。钩子里做了什么?这时候就需要引入tapable库2.1Tapable是一个类似NodeJS的EventEmitter的库,主要控制hook函数的发布和订阅,控制webpack的插件系统。webpack的本质就是一系列的插件化操作。hook类型分为四种:1.基本hook2.waterfall:会调用每次tap传入的函数,同时将每个函数的返回值传递给下一个函数3.bail:允许更早exit,当一个tap函数返回任何值时,hook会停止其他函数的执行;4.循环:如果一个函数有返回值,它会循环之前执行的事件。webpack中用的最多的hook是syncHook(同步hook)和AsyncSeriesHook(异步stringLinehook)hook的三种注册方式(包括名字和对应的回调):1.tap:注册同步hook2.tapAsync:注册带有回调回调的异步hook(用得最多的)3.tapPromise:用promisecallbacks注册异步钩子对应的三种调用方式:1.call:调用注册的同步钩子;2.callAsync:用回调回调调用注册的异步钩子3.promise:用promise回调调用注册的异步钩子。看一个例子webpack中间的beforeCompilehook的声明,插件的注册和调用都是基于webpack的各个生命周期hook中声明的插件,实现webpack的全部功能。看webpack的各个声明循环钩子:https://webpack.js.org/api/co...补充一个小点:观察者模式和发布-订阅模式的区别:Observer模式是松耦合的,只有观察者和被观察者(比如一个值的变化,调用一个函数);发布-订阅模式没有耦合,有发布者、订阅者和代理(broker)2.2对于acornacorn是一个库,实现了js的解析,转换成ast,转换后实现依赖收集。3.webpack运行的各个阶段首先来看Compiler和Compilation的区别Compiler对象:包含Webpack环境的所有配置信息,包括options、loaders、plugins信息,这个对象在Webpack启动时实例化,全局唯一,可以简单理解为一个Webpack实例;Compilation对象:包含当前模块资源、编译资源、变化文件等。当Webpack运行在开发模式时,每检测到一个文件变化,就会创建一个新的Compilation。Compilation对象还为插件提供了许多事件回调以进行扩展。Compiler对象也可以通过Compilation来读取。Compiler和Compilation的区别在于:Compiler代表了整个Webpack从启动到关闭的生命周期,而Compilation只是代表了一次新的编译。找了一张网络图,整理了各个进程的依赖关系,通过loader处理代码。make阶段实现了几个关键点:1、webpack的运行是调用compiler.run2。即插件)3.AST基于acron库实现4.Loader处理和依赖收集在make阶段实现5.整个阶段会经历:environment,afterEnvironment,beforeRun,run,beforeCompile,Make,afterCompile等阶段。简单分析webpack源码,大致梳理了大概的流程,但是更详细的流程,还是需要看各个插件的源码
