Webpack 在啟動后會從配置的入口模塊出發找出所有依賴的模塊,Resolve 配置 Webpack 如何尋找模塊所對應的文件。 Webpack 內置 JavaScript 模塊化語法解析功能,默認會采用模塊化標准里約定好的規則去尋找,但你也可以根據自己的需要修改默認的規則。
alias
resolve.alias 配置項通過別名來把原導入路徑映射成一個新的導入路徑。例如使用以下配置:
// Webpack alias 配置 resolve:{ alias:{ components: './src/components/' } }
當你通過 import Button from 'components/button 導入時,實際上被 alias
等價替換成了 import Button from './src/components/button' 。
以上 alias 配置的含義是把導入語句里的 components 關鍵字替換成 ./src/components/ 。
這樣做可能會命中太多的導入語句,alias 還支持 $
符號來縮小范圍到只命中以關鍵字結尾的導入語句:
resolve:{ alias:{ 'react$': '/path/to/react.min.js' } }
react$ 只會命中以 react 結尾的導入語句,即只會把 import 'react' 關鍵字替換成 import '/path/to/react.min.js' 。
mainFields
有一些第三方模塊會針對不同環境提供幾分代碼。 例如分別提供采用 ES5 和 ES6 的2份代碼,這2份代碼的位置寫在 package.json 文件里,如下:
{ "jsnext:main": "es/index.js",// 采用 ES6 語法的代碼入口文件 "main": "lib/index.js" // 采用 ES5 語法的代碼入口文件 }
Webpack 會根據 mainFields 的配置去決定優先采用那份代碼, mainFields 默認如下:
mainFields: ['browser', 'main']
Webpack 會按照數組里的順序去 package.json 文件里尋找,只會使用找到的第一個。
假如你想優先采用 ES6 的那份代碼,可以這樣配置:
mainFields: ['jsnext:main', 'browser', 'main']
extensions
在導入語句沒帶文件后綴時,Webpack 會自動帶上后綴后去嘗試訪問文件是否存在。 resolve.extensions 用於配置在嘗試過程中用到的后綴列表,默認是:
extensions: ['.js', '.json']
也就是說當遇到 require('./data') 這樣的導入語句時,Webpack 會先去尋找 ./data.js 文件,如果該文件不存在就去尋找 ./data.json 文件, 如果還是找不到就報錯。
假如你想讓 Webpack 優先使用目錄下的 TypeScript 文件,可以這樣配置:
extensions: ['.ts', '.js', '.json']
modules
resolve.modules 配置 Webpack 去哪些目錄下尋找第三方模塊,默認是只會去 node_modules 目錄下尋找。 有時你的項目里會有一些模塊會大量被其它模塊依賴和導入,由於其它模塊的位置分布不定,針對不同的文件都要去計算被導入模塊文件的相對路徑, 這個路徑有時候會很長,就像這樣 import '../../../components/button' 這時你可以利用 modules 配置項優化,假如那些被大量導入的模塊都在 ./src/components 目錄下,把 modules 配置成
modules:['./src/components','node_modules']
后,你可以簡單通過 import 'button' 導入。
descriptionFiles
resolve.descriptionFiles 配置描述第三方模塊的文件名稱,也就是 package.json 文件。默認如下:
descriptionFiles: ['package.json']
enforceExtension
resolve.enforceExtension 如果配置為 true 所有導入語句都必須要帶文件后綴, 例如開啟前 import './foo' 能正常工作,開啟后就必須寫成 import './foo.js' 。
enforceModuleExtension
enforceModuleExtension 和 enforceExtension 作用類似,但 enforceModuleExtension 只對 node_modules 下的模塊生效。 enforceModuleExtension 通常搭配 enforceExtension 使用,在 enforceExtension:true 時,因為安裝的第三方模塊中大多數導入語句沒帶文件后綴, 所以這時通過配置 enforceModuleExtension:false 來兼容第三方模塊。