resolve.alias
用于给模块路径指定别名。vue
为何要给模块路径取别名呢?node
假设在咱们的源码中有以下 import
语句:webpack
import BaseModel from '../../../../common/BaseModel'; export default class ProductModel extends BaseModel { // some code here }
那么每次引入 BaseModel
的时候,极可能都会面临着写很长一堆 ../../../../
的问题,并且若是没有编辑器的智能提示,很容易少写(或者多写)一层 ../
。web
此时就能够在 webpack 配置中为 BaseModel
指定一个别名:正则表达式
{ // some other configs resolve: { alias: { common: require('path').resolve(__dirname, '../src/common') } } // some other configs }
这样一来,引入 BaseModel
的代码就变成下面这样了:数组
import BaseModel from 'common/BaseModel';
另一种场景,就是去掉路径中的无心义的一层(站在使用者角度来讲无心义)。好比安装了 vue
模块以后,若是不作任何配置,引入 vue
的代码看起来是这样的:babel
import Vue from 'vue/dist/vue.esm.js';
看起来多多少少会以为别扭,并且还很差调整成不一样的版本(开发时用 vue.esm.js
,发布的时候用 vue.runtime.js
)。编辑器
此时在 webpack 中加上不一样环境的别名:ui
{ // some other configs resolve: { alias: { vue$: process.env.NODE_ENV === 'production' ? 'vue/dist/vue.runtime.js' : 'vue/dist/vue.esm.js' } } // some other configs }
看起来就优雅不少了。code
那么 alias
的原理是怎么样的呢?
配置了 alias
以后,在 webpack 解析引入(经过 import 或者 require )的模块的时候,会先将源码中的模块路径中匹配 alias 里 key 的部分替换成 value 部分,再作查找。
好比源码中有以下引入语句:
import Test1 from 'xyz/file';
alias
中有以下配置:
{ // some other configs resolve: { alias: { xyz: './dir' } } // some other configs }
在解析路径的时候,会先将 xyz
替换成 ./dir
,那么以前的 import
语句就至关于:
import Test1 from './dir/file.js';
而后 webpack 再基于 ./dir/file.js
去查找须要引入的模块。
固然,也能够配置绝对路径:
{ // some other configs resolve: { alias: { xyz: require('path').resolve(__dirname, '../dir') } } // some other configs }
依然按照以前先替换后解析的流程执行。
另外,alias
还有一种特殊的语法:key 的末尾带一个 $ 字符,表示精确匹配。
假设有下面 alias
配置:
{ // some other configs resolve: { alias: { xyz$: 'xyz/dir' } } // some other configs }
对于:
import 'xyz/file.js';
这种 import
语句,就没法匹配上这条 alias
规则。
而:
import 'xyz';
才能匹配上。
更多 alias
的匹配示例,参考官网文档。
能够经过 resolveLoader.modules
配置在哪些目录下查找 loader
,默认是在 node_modules
目录下查找。
那么问题就来了,这个默认的 node_modules
指的是哪里的 node_modules
目录呢?换句话说,这里的 node_modules
目录对应的绝对路径是怎么构造的?
webpack 会以当前进程目录( process.cwd()
)开始,逐层往上查找 node_modules
目录,若是查到根目录,还没找到,就抛出错误。这与 Node 查找 node_modules
目录的行为是一致的,只不过 Node 是从当前模块所在目录开始查找的。
对于其余的相对目录配置,查找逻辑与默认的 node_modules
同样
对于绝对路径,就直接找这个路径对应的目录了。
权威说明,可参考官网文档。
找到 resolveLoader.modules
的具体目录以后,就按照配置的顺序去查找 loader
了。
假设有以下配置:
{ // some other configs resolveLoader: { modules: ['loaders1', 'loaders2'] } // some other configs }
若是当前进程目录是 /a/b/c
,如今要查找 babel-loader
,就会按照以下顺序查找:
/a/b/c/loaders1/babel-loader/... /a/b/c/loaders2/babel-loader/... /a/b/loaders1/babel-loader/... /a/b/loaders2/babel-loader/... /a/loaders1/babel-loader/... /a/loaders2/babel-loader/... /loaders1/babel-loader/... /loaders2/babel-loader/...
注:上述示例省略号后面的内容根据其余配置肯定,具体参看官网文档,此处不赘述。
Rule
中的 test
、 include
、 exclude
的值都是 Condition
实例。
Condition
实例可使下面的某一种值:
Condition
实例组成的数组。and
、 or
或者 not
)。对于 Rule.test
,值只能是一个正则表达式或者一个正则表达式数组。
对于 Rule.include
,值只能是一个字符串或者一个字符串数组。
Rule.exclude
的值和 Rule.include
同样。
更详细的描述,参考官网文档。
因此,Rule.include
和 Rule.exclude
配置都会使用绝对路径。
entry 中配置的相对路径,是相对于 process.cwd()
去查找的。
必须配置成一个绝对路径。
plugins
和 presets
路径babelrc 中 plugins
和 presets
配置的相对路径是相对于待转换文件解析的。
好比在转换 /a/b/c/d.js
模块的时候,查找 babel-plugin-veui
的顺序是:
/a/b/c/node_modules/babel-plugin-veui/... /a/b/node_modules/babel-plugin-veui/... /a/node_modules/babel-plugin-veui/... /node_modules/babel-plugin-veui/...
presets
的解析逻辑与 plugins
一致。