Webpack4 配置 Resolve

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')

源碼下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章