Webpack在启动后会从配置的入口模块出发找出所有依赖的模块,resolve用来配置Webpack如何寻找模块对应的文件。

alias

resolve.alias配置项通过别名来将原来导入路径映射成一个新的导入路径。

module.exports = {
  //...
  resolve: {
    alias: {
      Utilities: path.resolve(__dirname, 'src/utilities/'),
      Templates: path.resolve(__dirname, 'src/templates/')
    }
  }
};
1
2
3
4
5
6
7
8
9
// 原来这样访问
import Utility from '../../utilities/utility';
// 现在可以这样访问了
import Utility from 'Utilities/utility';
1
2
3
4

mainFields

有一些第三方模块会针对不同的环境提供多份代码。例如分别提供采用了ES5和ES6的两份代码,这两份代码的位置写在了package.json文件里,代码如下:

{
    "jsnext:main": "es/index.js", // 采用ES6语法的代码入口文件
    "main": "src/index.js" // 采用ES5语法的代码入口文件
}
1
2
3
4

Webpack会根据mainFields的配置去决定优先采用哪份代码,mainFields默认如下:

module.exports = {
  //...
  resolve: {
    mainFields: ['browser', 'main']
  }
};
1
2
3
4
5
6

Webpack会按照数组里的顺序在package.json文件里寻找,只会使用找到的第一个文件。假如我们想优先采用ES6的代码,则可以如下配置:

mainFields: ['jsnext:main', 'browser', 'main']
1

extensions

在导入语句没带文件后缀时,Webpack会自动带上后缀去尝试访问文件是否存在。resolve.extensions用于配置在尝试过程中用到的后缀列表,默认是:

module.exports = {
  //...
  resolve: {
    extensions: ['.ts', '.js', '.json']
  }
};
1
2
3
4
5
6

也就是说,当遇到require('./data')这样的导入语句时,Webpack会先寻找./data.ts文件,如果该文件不存在,就去寻找./data.js文件,如果该文件不存在,就去寻找./data.json文件,如果还是找不到,就报错。

modules

resolve.modules配置Webpack去哪些目录下寻找第三方模块,默认只会去node_modules目录下寻找。有时项目里会有一些模块被其他模块大量依赖和导入,由于其他模块的位置不定,针对不同的文件都要计算被导入的模块文件的相对路径,这个路径有时会很长,就像import '../../../components/button',这就可以利用resolve.modules配置项进行优化。假设那些大量被导入的模块都在./src/components目录下,则进行如下配置即可:

resolve: {
    modules: ['./src/components', 'node_modules']
}
1
2
3

之后可以简单的通过import 'button'导入。

descriptionFiles

resolve.descriptionFiles配置描述第三方模块的文件名称,默认为:package.json。

module.exports = {
  //...
  resolve: {
    descriptionFiles: ['package.json']
  }
};
1
2
3
4
5
6

enforceExtension

resolve.enforceExtension默认值为false,如果被配置为true,则所有导入语句都必须带文件后缀,例如设置之前import './foo'能正常工作,开启后就必须写成import './foo.js'

module.exports = {
  //...
  resolve: {
    enforceExtension: false
  }
};
1
2
3
4
5
6

enforceModuleExtension

resolve.enforceModuleExtensionresolve.enforceExtension的作用类似,但是enforceModuleExtension只对node_modules下的模块生效。enforceModuleExtension通常搭配enforceExtension使用,在enforceExtension: true时,因为安装的第三方模块中大多数导入语句都没有带文件的后缀,所以这时候通过设置enforceModuleExtension: false来兼容第三方模块。

其他配置

Target

Target配置项可以让Webpack构建出针对不同运行环境的代码。 6dce3a03d834d0b06de15680b1221279.png

在设置target: 'node'时,在源代码中导入Node.js原生模块的语句require('fs')将会保留,fs模块的内容不会被打包到Chunk中。

Devtool

devtool配置Webpack如何生成Source Map,默认值是false,即不生成Source Map,若想为构建出的代码生成Source Map以方便调试,可以这样配置:

module.export = {
    devtool: 'source-map'
}
1
2
3

externals

Externals用来告诉Webpack要构建的代码中使用了哪些不用被打包的模块,也就是说这些模板是外部环境提供的,Webpack在打包时可以忽略它们。

有些Javascript运行环境可能内置了一些全局变量或者模块,例如:在HTML的HEAD标签通过以下代码引入jQuery:

<script
  src="https://code.jquery.com/jquery-3.1.0.js"
  integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
  crossorigin="anonymous">
</script>
1
2
3
4
5

这时,全局变量jQuery就会被注入网页的Javascript运行环境里。

如果想在使用模块化的源代码里导入和使用jQuery,可能需要这样:

import $ from 'jquery';

$('.my-element').animate(/* ... */);
1
2
3

构建后我们会发现输出的Chunk里包含的jQuery库的内容,这导致jQuery库出现了两次,浪费加载流量,最好是Chunk里不会包含jQuery库的内容。

Externals配置项就是用于解决这个问题的。通过Externals可以告诉Webpack在Javascript运行环境中已经内置了哪些全局变量,不用将这些全局变量打包到代码中而是直接使用它们。具体配置如下:

module.exports = {
  //...
  externals: {
    jquery: 'jQuery'
  }
};
1
2
3
4
5
6

resolveLoader

resolveLoader配置项用来告诉Webpack如何去寻找Loader,因为在使用Loader时是通过其包名称去引用的,Webpack需要根据配置的Loader包名去找到Loader的实际代码,以调用Loader去处理源文件。默认配置如下:

module.exports = {
  //...
  resolveLoader: {
    // 去哪个目录下寻找Loader
    modules: [ 'node_modules' ],
    // 入口文件的后缀
    extensions: [ '.js', '.json' ],
    // 指明入口文件位置的字段
    mainFields: [ 'loader', 'main' ]
  }
};
1
2
3
4
5
6
7
8
9
10
11