# 介绍

# 准备工作

在学习vue-cli怎么配置webpack之前我们先学习一个插件webpack-chain,为啥要学习这个插件呢,因为vue-cli中就是用这个插件来修改webpack的配置的

我这里就不细说这个插件了,大家看一个看一下官网,传送门

# 整体流程

在聊webpack每一块具体是怎么配置之前我们先来看一下vue-cli修改webpack配置的一个整体流程

webpack的配置有两部分组成:

  1. configureWebpack: webpack的原始配置
  2. chainWebpack: 通过webpack-chain配置的webpack配置

每一个部分都存放在各自的队列里:

  1. configureWebpack的配置存在webpackRawConfigFns
  2. chainWebpack的配置存在webpackChainFns

在我们调用vue-cli-serve serve的时候,会先实例化Service的类,类的构造函数里会调用初始化方法,初始化方法会先把那些插件修改webpack的方法push到配置的队列里,然后再把用户自定义的webpack配置push到配置的队列里,详细见源码:

 // apply plugins.
    this.plugins.forEach(({ id, apply }) => {
      if (this.pluginsToSkip.has(id)) return
      apply(new PluginAPI(id, this), this.projectOptions)
    })

    // apply webpack configs from project config file
    if (this.projectOptions.chainWebpack) {
      this.webpackChainFns.push(this.projectOptions.chainWebpack)
    }
    if (this.projectOptions.configureWebpack) {
      this.webpackRawConfigFns.push(this.projectOptions.configureWebpack)
    }
1
2
3
4
5
6
7
8
9
10
11
12
13

然后再执行serve命令,执行serve命令后就会把webpack配置进行合并处理,最终生成webpack真正需要的配置

  resolveChainableWebpackConfig () {
    const chainableConfig = new Config()
    // apply chains
    this.webpackChainFns.forEach(fn => fn(chainableConfig))
    return chainableConfig
  }

  resolveWebpackConfig (chainableConfig = this.resolveChainableWebpackConfig()) {
    if (!this.initialized) {
      throw new Error('Service must call init() before calling resolveWebpackConfig().')
    }
    // get raw config
    let config = chainableConfig.toConfig()
    const original = config
    // apply raw config fns
    this.webpackRawConfigFns.forEach(fn => {
      if (typeof fn === 'function') {
        // function with optional return value
        const res = fn(config)
        if (res) config = merge(config, res)
      } else if (fn) {
        // merge literal values
        config = merge(config, fn)
      }
    })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25