# 07-webpack构建流程

![webpack构建流程.png](https://i.loli.net/2019/11/12/rIHCtwi5pbsPqMg.png)

构建流程中一些核心方法节选。

```javascript
const webpack = (options, callback) => {
    compiler = new Compiler(options.context);
    // WebpackOptionsApply 遍历options初始化了各种插件，订阅了plugin的事件
    compiler.options = new WebpackOptionsApply().process(options, compiler);
    return compiler;
};

// Compiler
class compiler extands Tapable{
    constructor() {
        this.hooks = '定义了各种生命周期的hook'
    }
    run () {
        // before前的工作
        this.compile();
    }
    compile() {
        const compilation = this.newCompilation(params);
    }
}
```

```javascript
class compiler extands Tapable{
    compile() {
        // 创建Module实例
        const params = this.newCompilationParams();
        const compilation = this.newCompilation(params);
    }

    newCompilationParams() {
        return {
            normalModuleFactory: this.createNormalModuleFactory(),
            contextModuleFactory: this.createContextModuleFactory(),
            compilationDependencies: new Set()
        }
    }

    createNormalModuleFactory() {
        const normalModuleFactory = new NormalModuleFactory();
        return normalModuleFactory;
    }
}
```

```javascript
class Compilation  {
    buildModule (module, dependencies) {
        this.hooks.buildModule.call(module);
        module.build();
    }
}

class NormalModule {
    build() {
        // 调用了一个第三方工具 loader-runner
        // 使用loader处理
        runLoaders()

        // AST解析
    }
}
```

```javascript
doBuild(options, compilation, resolver, fs, callback) {
    // 创建loader工作上下文
    const loaderContext = this.createLoaderContext();

    // 调用了一个第三方工具 loader-runner
    // 中间laoder的过程文件流是buffer格式
    runLoaders(options, compilation等各种参数);
}
```

```javascript
const result = this.parser.parse(
    // this._source.source()方法获取的是文件代码
    this._ast || this._source.source(),

    (err, result) => {
        // 处理ast结果，遇到require再递归处理
        handleParseResult(result);
    }
);
```

```javascript
class Compilation {
    seal() {
        buildChunkGraph();
        // optimize配置中的相关参数在下面这些步骤中生效
        this.hooks.optimize.call();
        // ...
    }
}
```

```javascript
seal() {
    this.hooks.beforeHash.call();
    this.createHash();
    this.hooks.afterHash.call();

    this.createModuleAssets();

    this.createChunkAssets();
}
```

```javascript
```

参考：

* [细说 webpack 之流程篇](https://fed.taobao.org/blog/2016/09/10/webpack-flow/)
* [webpack 打包构建流程分析整理](https://www.goyth.com/2018/12/10/webpackFlow/)
* [玩转webpack（一）：webpack的基本架构和构建流程](https://lxzjj.github.io/2017/11/02/%E7%8E%A9%E8%BD%ACwebpack%EF%BC%88%E4%B8%80%EF%BC%89/)
* [玩转webpack（二）：webpack的核心对象](https://lxzjj.github.io/2017/11/08/%E7%8E%A9%E8%BD%ACwebpack%EF%BC%88%E4%BA%8C%EF%BC%89/)
