webpack 源码研究导读

145 阅读2分钟

在研究WEBPACK 源码时想了些什么,首先想到的是阅读每一个文件,再查过查资料改变了一些想法,可以通过阅读webpack 的四个大部分,例:入口,加载器,插件,输出。

webpack 入口

  • webpack 大约有以下几种
    // 第一种
    entry: "***.js"
    // 第二种
    entry: ["**.js"]
    // 第三种
    entry: async () => {
        // 这里面可以加载JS文件实现异步操作
        return "***.js"  
    }

在阅读源码时可以参照以上的方式进行webpack 运行逻辑整理

webpack 加载器

  • webpack css-loader 加载器
    // 加载器配置示例
    {
        // 静态CSS加载
        test: /\.css$/i,
        use: [{ loader: MiniCssExtractPlugin.loader, options: { publicPath: './' } }, 'css-loader', 'postcss-loader'],// 'clear-print',
    }
    // 加载器示例 
    module.exports = function(/** @type {string} */ source){
        source = source.replace(/console.log\([^)]+[\)];?/,'')
        return source;
    }

以上示例中介绍了 .css 加载器的用法,在加载器中会对所有的 导入的.css 进行读取,然后在加载器中进行逻辑处理,最后将处理后的字符串返回给 webpack 使用。 以上就是加载器的基本原理

webpack 插件(plus)

  • webpack 与加载器类型
class ClearPrint {
    /**
     * @param {any} doneCallback
     * @param {any} failCallback
     */
    constructor(doneCallback, failCallback){
        this.doneCallback = doneCallback;
    }
    /**
     * @param {{ hooks: { emit: { tapAsync: (arg0: string, arg1: (compilation: any, callback: any) => void) => void; }; }; }} compiler
     */
    apply(compiler){
        compiler.hooks.emit.tapAsync('ClearPrint',(/** @type {{ assets: { [x: string]: { _value: any; }; }; }} */ compilation,/** @type {() => void} */ callback)=>{
            for(let key in compilation.assets){
                let str = compilation.assets[key]._value;
                compilation.assets[key]._value = str.replace(/console.log\([^)]+[\)];?/,'');
            }
            callback();
            // @ts-ignore
            this.doneCallback && this.doneCallback()
        })
    }
}

module.exports = ClearPrint;

与加载器不同的是 插件(plus) 能够在webpack 运行的各个介阶定义勾子,如上例所示,插件监听的是 emit 钩子,它在 Webpack 生成文件并写入 output 目录 之前执行

webpack 输出

  • webpack 中输出可以插件定义输入也能通过 output 定义输入,主入口文件的输出只能由 output 定义
  output: {
      filename: '**.js',
      path: path.resolve(basePath, "web"),
      publicPath: "/",
      chunkFilename: "**.js",
      clean: true,
  },

上例中定义了输出主入口文件的名称输出路径,默认输出路和戏,检出文件名,以及打包是否清除原目录文件。

上面介绍了webpack 中的四个大部分,在源码研究中会陆续输入,webpack 优化,以及对webpack 功能进行增改,例优化hot 功能,定义复杂一些的插件。