webpack4.X之EntryOptionPlugin流程书写

EntryOptionPlugin为Webpack挂载内置插件入口的核心代码,EntryOptionPlugin会解析传给 webpack 的配置中的 entry 属性

lib下新建WebpackOptionsApply.js,EntryOptionPlugin.js,SingleEntryPlugin.js

WebpackOptionsApply.js


const EntryOptionPlugin=require('./EntryOptionPlugin')

class WebpackOptionsApply {
    process(options, compiler){
        new EntryOptionPlugin().apply(compiler)
        compiler.hooks.entryOption.call(options.context,options.entry)
    }
}
module.exports=WebpackOptionsApply

webpack.js

/**
 * 
 */
const Compiler = require('./Compiler') //自动导包插件
const NodeEnvironmentPlugin = require('./node/NodeEnvironmentPlugin')
const WebpackOptionsApply=require('./WebpackOptionsApply')
const webpack = function (options) {
  //根据run.js options为webpack.config.js
  // 01 实例化 compiler 对象
  let compiler = new Compiler(options.context) //获取当前项目所在的绝对路径 options.context
  compiler.options = options

  // 02 初始化 NodeEnvironmentPlugin(让compiler具体文件读写能力)
  new NodeEnvironmentPlugin().apply(compiler)

  // 03 挂载所有 plugins 插件至 compiler 对象身上 (compiler就相当于贯穿整个编译过程的,在整个编译过程中到处埋雷)
  if (options.plugins && Array.isArray(options.plugins)) {
    for (const plugin of options.plugins) {
      plugin.apply(compiler)
    }
  }

  // 04 挂载所有 webpack 内置的插件(入口)
   compiler.options = new WebpackOptionsApply().process(options, compiler);

  // 05 返回 compiler 对象即可
  return compiler
}

module.exports = webpack

EntryOptionPlugin.js

const SingleEntryPlugin = require("./SingleEntryPlugin")

const itemToPlugin = function (context, item, name) {
  return new SingleEntryPlugin(context, item, name)
}

class EntryOptionPlugin {
  apply(compiler) {
    compiler.hooks.entryOption.tap('EntryOptionPlugin', (context, entry) => {
      itemToPlugin(context, entry, "main").apply(compiler)
    })
  }
}

module.exports = EntryOptionPlugin

SingleEntryPlugin.js


class SingleEntryPlugin {
    constructor(context, entry, name) {
      this.context = context
      this.entry = entry
      this.name = name
    }
  
    apply(compiler) {
      compiler.hooks.make.tapAsync('SingleEntryPlugin', (compilation, callback) => {
        const { context, entry, name } = this
        console.log("make 钩子监听执行了~~~~~~")
        // compilation.addEntry(context, entry, name, callback)
      })
    }
  }
  
  module.exports = SingleEntryPlugin
  

Compiler.js

const {
  Tapable,
  AsyncSeriesHook,
  SyncBailHook
} = require('tapable')

class Compiler extends Tapable {
  constructor(context) {
    super()
    this.context = context
    this.hooks = {
      done: new AsyncSeriesHook(["stats"]),
      entryOption:new SyncBailHook(["context","entry"]),
            beforeCompile: new AsyncSeriesHook(["params"]),
            compile: new SyncHook(["params"]),
            make: new AsyncParallelHook(["compilation"]),
            afterCompile: new AsyncSeriesHook(["compilation"]),
    }
  }
  run(callback) {
    callback(null, {
      toJson() {
        return {
          entries: [],  // 当前次打包的入口信息
          chunks: [],  // 当前次打包的 chunk 信息
          modules: [],  // 模块信息
          assets: [], // 当前次打包最终生成的资源
        }
      }
    })
  }
}

module.exports = Compiler

后续进行总流程梳理~~~~~

posted on 2021-03-28 15:13  メSerendipity  阅读(332)  评论(0编辑  收藏  举报

导航