WebPack运行流程

74 阅读1分钟

1.Compiler编译器

  • 创建Compiler实例
  • Compiler负责监听文件变化并触发编译流程
const webpack = require('webpack');
const compiler = webpack({
    // webpack配置
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    }
})

2.Compilation编译

  • 由Compiler触发生成Compilation实例
  • 负责整个打包过程的资源生成
compiler.hooks.compilation.tap('MyPlugin', (compilation)=> {
    // 处理compilation事件
    compilation.hooks.optimize.tap('MyPlugin', ()=>{
        // 资源优化
    })
})

3.Chunk区块

  • 将模块按特定规则组织成代码块
  • 处理代码分割&按需加载
module.exports = {
    optimization: {
        splitChunks: {
            chunks: 'all',
            minSize: 2000,
            minChunks: 1
        }
    }
}

4.Parse解析器

  • 解析模块代码,生成AST(抽象语法树)
  • 分析模块依赖关系
module.exports = {
    module: {
        rules: [{
            test: /\.js$/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env']
                }
            }
        }]
    }
}

5.Module&Dependency处理

  • Module:管理模块信息
  • Dependency: 处理模块间的依赖关系
// 处理模块依赖
import { sum } from './math';
// webpack会自动解析依赖关系

6.Template模板

  • 基于Compilation数据生成最终代码
  • 负责输出文件的生成
module.exports = {
    output: {
        filename; '[name].[contenthash].js',
        path: path.resolve(__dirname, 'dist')
    }
}

纠正与补充

image.png

  • 流程箭头方向有误:
    1. Chunk和Parser的关系:
      • 图中显示Chunk直接传递给Parser,但实际上Parser是从模块(Module)中解析依赖,而非直接处理Chunk
      • Parser的输入是Module
    2. Dependency的箭头方向:
      • 图中Dependency的箭头只想Parser,但实际上Dependency是由Parser解析模块时生成的
      • Parser箭头应该指向Dependency
    3. Template的位置:
      • 图中Template直接连接Chunk,但Template实际上是基于Compilation的数据生成输出文件。
      • Template输入是Compilation
  • 修正后的流程图:
      1. Compiler -> 2. Compilation -> 3. Module -> 4. Parser -> 5. Dependency -> 6. Chunk -> 7. Template -> 输出文件

完整Webpack配置示例

const path = require('path');  

module.exports = {  
  mode: 'development',  
  // 入口配置
  entry: './src/index.js',  
  // 输出配置
  output: {  
    path: path.resolve(__dirname, 'dist'),  
    filename: '[name].[contenthash].js'  
  },  
  // Loader处理
  module: {  
    rules: [  
      {  
        test: /\.js$/,  
        use: 'babel-loader'  
      },  
      {  
        test: /\.css$/,  
        use: ['style-loader', 'css-loader']  
      }  
    ]  
  },  
  // 插件使用
  plugins: [  
    new HtmlWebpackPlugin({  
      template: './src/index.html'  
    })  
  ],  
  // 代码分割优化
  optimization: {  
    splitChunks: {  
      chunks: 'all'  
    }  
  }  
};