Module Resolution(模块解析)1
解析器(resolver)是通过绝对路径帮助定位一个模块的库。一个模块可以被另一个模块当做依赖引入,如下:
import foo from 'path/to/module'
// or
require('path/to/module')
依赖的模块可以来自项目代码,也可以是第三方库。解析器帮助webpack为每个require
/import
声明找到需要引入bundle里的模块。在打包模块的时候Webpack使用enhanced-resolve来解析文件路径。
Webpack中的解析规则
使用enhanced-resolve
,webpack能够解析三种类型的文件路径:
绝对路径
import "/home/me/file";
import "C:\\Users\\me\\file";
我们已经有了文件的绝对路径,不再需要更多的解析操作。
相对路径
import "../src/file1";
import "./file2";
这种情况下,import
或require
所在的资源文件目录就是上下文目录。import
或require
里指定的相对路径和上下文路径连接生成这个模块的绝对路径。
模块路径
import "module";
import "module/lib/file";
Webpack会在resolve.modules
指定的所有目录中搜索模块。你可以通过resolve.alias
配置选项建立别名,从而用另外的路径来替换原始的模块路径。
一旦基于上述规则解析了路径,解析器检查路径是否指向了文件或目录。如果路径指向了一个文件:
- 如果路径有文件扩展名,那么这个文件会直接被打包引入;
- 否则,通过
resolve.extensions
选项解析文件扩展名,它会告诉解析器哪些扩展名(比如.js
,.jsx
)是可解析的。
如果路径指向一个目录,那么采取以下步骤来找到正确的文件和正确的扩展名:
- 如果目录包含
package.json
文件,那么resolve.mainFields
配置选项指定的字段会被按顺序查找,在package.json
里面这样的第一个字段决定了文件路径。 - 如果没有
package.json
或者resolve.mainFields
没有返回有效的路径,resolve.mainFiles
配置选项指定的文件名会被按顺序查找,看看import/require
目录是否能匹配文件名。 - 文件扩展名以类似的方式解析,使用
resolve.extensions
选项。
根据你的build target,webpack为这些选项提供了合理的默认值。
解析loaders
跟文件解析遵从一样的规则。不过resolveLoader
配置选项可以用来给loaders不同的解析规则。
缓存
每次文件系统访问都被缓存,所以对同个文件的多个并行或串行请求更快执行。在观察模式,只有修改过的文件才会从缓存移除。如果关闭观察模式,缓存则会在每次编译开始前清除。
查阅Resolve API来获取更多关于上面提到的配置选项信息。
1. https://webpack.js.org/concepts/module-resolution/ ↩