webpack4.X之核心打包流程

一.webpack打包流程如下图所示:

二.项目的具体目录结构如下:

1.在根目录下创建run.js,代码如下:

//webpack核心代码 引入webpack模块
      let webpack = require('webpack')
      //获取webpack.config的信息
      let options = require('./webpack.config')
      //complier 挂载钩子 处理打包流程
      let compiler = webpack(options)
      //调用run方法 按照某种机制执行打包操作
      compiler.run((err, stats) => {
        console.log(err)
        console.log(stats.toJson({
          entries: true,
          chunks: false,
          modules: false,
          assets: false
        }))
      })

上述代码实际上运行相当于package.json里面的npm run XX 打包操作

二.下面模拟下打包操作,手写下打包逻辑的实现

首先创建lgPack文件夹充当打包的包名,yarn init,在package.json中改变main目录为./lib/webpack.js,

创建lib文件夹,创建webpack.js

2.1从webpack打包流程中,我们可以梳理下webpack.js部分的流程

1.实例化complier对象

2.初始化NodeEnvironmentgPlugin(让compiler具体文件读写能力) 备注:如果要做打包操作,需要对文件处理,打包之后生成一个新的文件

3.挂载所有plugins插件至complier对象身上

4.挂载所有 webpack内置的插件(入口)

5.返回complier对象即可 

出于模块化考虑,创建compiler.js,把complier部分写在complier.js里面 安装tapable,yarn add tapable@版本 -d

在lib下创建node目录,创建complier具有读写能力的NodeEnvironmentPlugin.js

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

run.js修改后的代码如下:

// let webpack = require('./lpPack')
let webpack = require('./lpPack')
let options = require('./webpack.config')

let compiler = webpack(options)

compiler.run((err, stats) => {
  console.log(err)
  console.log(stats.toJson({
    entries: true,
    chunks: false,
    modules: false,
    assets: false
  }))
})

NodeEnvironmentPlugin.js代码如下:

const fs = require('fs')

class NodeEnvironmentPlugin {
  constructor(options) {
    this.options = options || {}
  }

  apply(complier) {
    complier.inputFileSystem = fs
    complier.outputFileSystem = fs
  }
}

module.exports = NodeEnvironmentPlugin

Complier.js代码如下:

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

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

module.exports = Compiler

package.json代码如下:

{
  "name": "wp_h",
  "version": "1.0.0",
  "description": "",
  "main": "./lib/webpack.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "tapable": "^1.1.3",
    "webpack": "^4.45.0",
    "webpack-cli": "^3.3.12"
  }
}

最后在终端中输出node .\run.js就可输出对应的结果。

posted on 2021-03-21 23:51  メSerendipity  阅读(51)  评论(0编辑  收藏  举报

导航