webpack流程和部分源码解析

  • webpack-cli启动打包流程

    通过convert-argv(node的yargs模块)获取命令行得到运行配置,然后与webpack配置文件整合;
    webpack4 cli独立到webpack-cli模块,增强灵活性,让webpack的调用更便捷;

  • 载入weback核心模块/代码,创建compiler

    创建工作周期hook, 通过make.top() 注册默认内置的插件(toptabel方法)

  • 使用compiler对象编译整个项目

    创建compilation对象存放模块资源,同时创建buildModule方法
    通过buildModule方法执行loader对特殊的文件进行处理

  • 从入口文件开始解析各个模块间的依赖,形成依赖树

    buildModule后,通过acorn库生成模块间的AST
    语法树,找到各模块间的依赖

  • 递归依赖树,将每个模块交给对应的loader处理
  • 合并loader处理的结果,打包到目标disk/自定义文件
webpack-cli部分源码解析

通过yargs去解析命令行参数.

    yargs.parse(process.argv.slice(2), (err, argv, output) => {...}

将命令行参数解析为配置参数对象.

options = require("./utils/convert-argv")(argv);
// convert-argv.js
    if (argv.config) {        /** 判断是否有指定默认配置文件 **/
        const getConfigExtension = function getConfigExtension(configPath) {...} else {
          // 按配置文件规则查找文件
        const defaultConfigFileNames = ["webpack.config", "webpackfile"].join("|");
        const webpackConfigFileRegExp = `(${defaultConfigFileNames})(${extensions.join("|")})`;
        const pathToWebpackConfig = findup(webpackConfigFileRegExp);
  .............................
// 入口文件
compiler = webpack(options);
option可以是对象或者数组,数组即可以多路打包
// 
期间plugin通过compiler访问各个环节,做额外的工作处理;

常用plugin如:
1.打包后文件压缩[ uglifyjs-webpack-plugin ]

  1. 定义html文件输出[ html-webpack-plugin ]
  2. 清空打包前的文件[ clean-webpack-plugin ]
  3. 静态拷贝的文件定义 [copy-webpack-plugin]
  4. 热更新[HotModuleReplacementPlugin]
    ................
    自定义清除注释的plugin
    webpack生命周期
  • complie开始编译
  • make分析入口模块创建对象
  • bind-module构建模块
  • after-complie完成模块构建结束编译
  • emit compilers开始输出生成的assets文件,插件最后的机会修改assets
  • after-emit 输出完成
calss RemoveCommentsPlugin {
  apply(compiler) {
    compiler.hooks.emit.tap('RemoveCommentsPlugin', compilation => {
      for(const name in compilation.assets) {
          if(name.endsWith(".js")){
          const content = compilation.assets[name].source();
          compilation.assets[name] = {
              source: () => content.replace('/\/\/*{2,}\/\s/g', ''),
              length: () => content.replace('/\/\/*{2,}\/\s/g', '').length,
            }
        }
      }
    })
  }
}

你可能感兴趣的:(webpack流程和部分源码解析)