Webpack4 配置 Resolve
Webpack
在啓動後會從webpack.config.js
配置文件中的enter
屬性指定的入口模塊出發找出所有依賴的模塊,Resolve 的作用就是:配置 Webpack 如何尋找模塊所對應的文件。resolve 屬性的值是一個對象。該對象常用的屬性有: modules、extensions、alias、...
, 其中modules
是配置尋找模塊的根目錄;extensions
是配置搜索模塊的後綴名(搜索模塊時按照從左往右的順序搜索對應的後綴名模塊);alias
是給模塊對應路勁單獨起一個別名。
簡單的使用案例:
webpack.config.js
const path = require('path');
module.exports = {
entry: {
app: ['./src/main.js']
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist'),
},
module: {
rules: [
{
...
}
]
},
plugins: [
.....
],
// 1.配置 webpack 尋找模塊的規則
resolve: {
modules: [ // 尋找模塊的根目錄,array 類型,默認以 node_modules 爲根目錄
'node_modules',
path.resolve(__dirname, 'app')
],
extensions: ['.js', '.json', '.jsx', '.css'], // 模塊的後綴名
alias: { // 模塊別名配置,用於映射模塊
// 把 'module' 映射 'new-module',同樣的 'module/path/file' 也會被映射成 'new-module/path/file'
'module': 'new-module',
// 使用結尾符號 $ 後,把 'only-module' 映射成 'new-module',
// 但是不像上面的,'module/path/file' 不會被映射成 'new-module/path/file'
'only-module$': 'new-module',
}
},
};
1.配置-modules
resolve.modules
配置 Webpack 去哪些目錄下尋找第三方模塊,默認是隻會去 node_modules
目錄下尋找。 有時你的項目裏會有一些模塊會大量被其它模塊依賴和導入,由於其它模塊的位置分佈不定,針對不同的文件都要去計算被導入模塊文件的相對路徑, 這個路徑有時候會很長,就像這樣 import '../../../components/button'
這時你可以利用 modules
配置項優化,假如那些被大量導入的模塊都在 ./src/components
目錄下,把 modules
配置成
resolve: {
modules:['./src/components','node_modules']
}
新建一個項目
|-- src
| |-- components
| | `-- Button.js
| |-- index.html
| `-- main.js
`-- webpack.config.js
webpack.config.js
const path = require('path');
module.exports = {
entry: './main.js',
output: {
path: path.resolve(__dirname, './dist'),
},
// 1.配置模塊的查找規則
resolve: {
// 2.導入 require('Button'),會先在components下查找,然後再到node_modules下查找
// 相對路徑是相對於webpack.config.js文件所在的路勁
modules:['./src/components','node_modules']
},
};
Button.js
const Button = {
render:()=>{
console.log('我是一個 button 組件')
}
}
export default Button
main.js
// 1.引入components文件夾中的Button組件
let Button=require('Button') // 改button會先到components下查找,然再到node_modules文件夾下查找導入
// Button.default :是拿到Button的對象
console.log(Button.default)
console.log(Button.default.render())
index.html
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="app"></div>
<!--導入 Webpack 輸出的 JavaScript 文件-->
<script src="../dist/main.js"></script>
</body>
</html>
在項目的根目錄執行webpack --mode development
, 打開index.html查看打包後的main.js文件如下
// 1.引入components文件夾中的Button組件
let Button=__webpack_require__(/*! Button */ "./src/components/Button.js") // 改button會先到components下查找,然再到node_modules文件夾下查找導入
// Button.default :是拿到Button的對象
console.log(Button.default)
console.log(Button.default.render())
從這個打包後的結果可以得出結論:
當在webpack.config.js
中配置了resolve.modules:['./src/components','node_modules']
, 那麼當你通過 let Button=require('Button')'
導入時,會先到components下查找,再到node_modules文件夾下查找,在components找到後會把路徑替換成了 let Button=require('./src/components/Button.js')'
2.配置-extensions
上面在執行let Button=require('Button')
的時候,爲什麼不用寫文件的擴展名也可以導入?爲什麼不是let Button=require('Button.js')
這樣導入?其實這兩種寫法都可以。
因爲在導入語句沒帶文件後綴時,Webpack 會自動帶上後綴後去嘗試訪問文件是否存在。 resolve.extensions
就是專門用於配置在嘗試過程中用到的後綴列表,它的默認值如下:
resolve: {
extensions: ['.js', '.json']
}
也就是說當遇到 require('Button')
這樣的導入語句時,Webpack 會先去尋找 Button.js
文件,如果該文件不存在就去尋找 Button.json
文件, 如果還是找不到就報錯。
假如你想讓 Webpack 優先使用目錄下的 TypeScript 文件,可以這樣配置:
resolve: {
extensions: ['.ts', '.js', '.json']
}
webpack.config.js
const path = require('path');
module.exports = {
entry: './main.js',
output: {
path: path.resolve(__dirname, './dist'),
},
// 1.配置模塊的查找規則
resolve: {
modules:['./src/components','node_modules'],
// 3.導入語句沒帶文件後綴時,Webpack會自動帶上後綴後去嘗試訪問文件是否存在,專門用於配置在嘗試過程中用到的後綴列表
extensions: ['.js', '.json']
},
};
3.配置-alias
resolve.alias
配置項通過別名來把原導入路徑映射成一個新的導入路徑。例如使用以下配置:
// Webpack alias 配置
resolve:{
alias:{
utils: './src/utils/'
}
}
當你通過 let Http = require('utils/Http')
導入時,實際上被 alias
等價替換成了 let Http = require('./src/utils/Http')
。
以上 alias 配置的含義是把導入語句裏的 utils關鍵字替換成
./src/utils/`。
項目的目錄結構
|-- src
| |-- components
| | `-- Button.js
| |-- utils
| | `-- Http.js
| |-- index.html
| `-- main.js
`-- webpack.config.js
webpack.config.js
const path = require('path');
module.exports = {
entry: './main.js',
output: {
path: path.resolve(__dirname, './dist'),
},
// 1.配置模塊的查找規則
resolve: {
// 2.導入 require('Button'),會先在components下查找,然後再到node_modules下查找
modules:['./src/components','node_modules'],
// 3.導入語句沒帶文件後綴時,Webpack會自動帶上後綴後去嘗試訪問文件是否存在,專門用於配置在嘗試過程中用到的後綴列表
extensions: ['.js', '.json'],
// 4.給指定的路徑起一個別名,下面給 ./src/utils 路徑起一個 別名叫 utils
alias:{
utils: './src/utils' // key是別名,value是路徑:'./src/utils/' 或者 './src/utils' 寫法都可以
}
},
};
Http.js
const Http = {
get:()=>{
console.log('發送get請求')
}
}
export default Http
main.js
// 1.引入components文件夾中的Button組件
let Button=require('Button')
console.log(Button.default)
Button.default.render()
//2.導入 http 工具類(沒有配置alias的用法)
// let Http = require('./src/utils/Http')
//2.導入 http 工具類(配置alias的用法,utils === ./src/utils )
// let Http = require('utils/Http')
Http.default.get()
結論:
當在webpack.config.js
中配置了resolve.alias
配置項,就可以通過別名來把原導入路徑映射成一個新的導入路徑。例如: let Http = require('utils/Http')
導入時,實際上被 alias
等價替換成了 let Http = require('./src/utils/Http')