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
一致。