webpack4.X之complier方法的实现及make前流程回顾

一.complier方法的实现

complier贯穿整个打包的流程,具体执行顺序如下:

1.newCompilationParams 方法调用,返回 params,normalModuleFactory

2.上述的操作是为了获取parms

3.接着调用了 beforeCompile 钩子监听,在它的回调中又触发了 compile监听

4.调用newCompilation 方法,传入了上面的 params,返回了complilation

5.调用了一个 createNewCompilation(Compilation.js)

6.上述操作完成之后就可以触发make 钩子监听

complier.js 具体代码如下:

//Compiler.js
const {
  Tapable,
  AsyncSeriesHook,
  SyncBailHook,
  SyncHook,
  AsyncParallelHook
} = require('tapable')
const NormalModuleFactory=require("./NormalModuleFactory")
const Compilation=require('./Compilation')
class Compiler extends Tapable {
  constructor(context) {
    super()
    this.context = context
    this.hooks = {
      done: new AsyncSeriesHook(["stats"]),
      entryOption:new SyncBailHook(["context","entry"]),
      beforeRun: new AsyncSeriesHook(["compiler"]),
      run: new AsyncSeriesHook(["compiler"]),
      thisCompilation: new SyncHook(["compilation", "params"]),
      compilation: new SyncHook(["compilation", "params"]),
            beforeCompile: new AsyncSeriesHook(["params"]),
            compile: new SyncHook(["params"]),
            make: new AsyncParallelHook(["compilation"]),
            afterCompile: new AsyncSeriesHook(["compilation"])
    }
  }
  run(callback) {
    console.log('run 方法执行了~~~~~')
    //创建finalCallback
    const finalCallback=function(){
      //对callback进行调用
      callback(err,stats)
    }
    const onCompiled=function(err,compilation){
      console.log('onComplied~~~~~')
      //调用finalCallback
      finalCallback(err,{
        toJson(){
          return{
            entries: [],  // 当前次打包的入口信息
            chunks: [],  // 当前次打包的 chunk 信息
            modules: [],  // 模块信息
            assets: [], // 当前次打包最终生成的资源 
          }
        }
      })
    }
    //仿照源码调用异步钩子callAsync
    this.hooks.beforeRun.callAsync(this,(err)=>{
      this.hooks.run.callAsync(this,(err)=>{
        this.compile(onCompiled)
      })
    })
  }
  //compile方法
  compile(callback){
      const params=this.newCompilationParams()
      this.hooks.beforeRun.callAsync(params,(err)=>{
        this.hooks.compile.call(params)
        const compilation=this.newCompilation(params)
        this.hooks.make.callAsync(compilation,(err)=>{
          console.log('make钩子触发了~~~~~')
          callback()
        })
      })
  }
  //定义params然后return
  newCompilationParams(){
    const params={
      normalModuleFactory : new NormalModuleFactory()
    }
    return params
  }

  newCompilation(params){
    const compilation=this.createCompilation()
  }

  createCompilation(){
    return new Compilation(this)
  }
}

module.exports = Compiler

二.make前流程回顾(执行编译前做了哪些事情)

    一.步骤

  1.实例化 complier 对象(它会贯穿整个webpack工作的过程)

  2.由 compiler 调用 run 方法

 二.compiler 实例化操作

  1 compiler 继承 tapable,因此它具备钩子的操作能力(监听事件,触发事件,webpack是一个事件流)

  2 在实例化了complier对象之后就往它的身上挂载很多属性,其中 NodeEnvironmentPlugin 这个操作就让它具备了文件读写的能力(我们模拟时采用的是 node 自带的 fs模块)

       3 具备了 fs 操作能力之后又将 plugins 中的插件都挂载到了complier对象身上

       4 将内部默认的插件与 compiler建立关系,其中 EntryOptionPlugin 处理了入口模块的 id

       5 在实例化 compiler 的时候只是监听了 make 钩子(SingleEntryPlugin)

   5-1 在 SingleEntryPlugin 模块的 apply 方法中有二个钩子

   5-2 其中 complilation 钩子就是让 compilation 具备了利用 normalModuleFactory 工厂创建了一个普通模块的能力

           5-3 因为它就是利用一个自己创建的模块来加载需要被打包的模块

           5-4 其中 make 钩子 在complier.run的时候被触发,走到这里就意味着某个模块执行打包之前的所有准备工作就完成了

           5-5 addEntry 方法调用()
   三. run方法 执行

     01 run 方法里就是一堆钩子按照顺序触发(beforeRun run compile)

     02 compile 方法执行

    1 准备参数

               2 触发beforeCompile

               3 将第一步的参数传给一个函数,开始创建一个 compilation (newCompilation)

     4 在调用 newCompilation 方法的内部

      -调用了 createCompilation

      -触发了 this.compilation 钩子 和 complilation 钩子的监听

         03 当创建了 compilation 对象之后就触发了make钩子

         04 当我们触发 make 钩子监听的时候,将compilation 对象传递了过去

   四. 总结

  1 实例化 complier

  2 调用 compile 方法

       3 newCompilation

       4 实例化了一个 compilation对象(它和compiler是有关系的)

       5 触发make 监听

       6 addEntry 方法(这个时候就带着 context name entry) 就奔着编译去了

 

 

posted on 2021-04-10 21:59  メSerendipity  阅读(267)  评论(0编辑  收藏  举报

导航