Webpack高级应用篇(四):模块解析(Module Resolution)
目錄
- webpack 中的解析規則
- 絕對路徑
- 相對路徑
- 模塊路徑
- 解析(Resolve)
- resolve.alias
- resolve.extensions
- 外部擴展(Externals)
- externals
resolver 是一個幫助尋找模塊絕對路徑的庫。 一個模塊可以作為另一個模塊的依賴模塊,然后被后者引用,如下:
import foo from 'path/to/module'; // 或者 require('path/to/module');所依賴的模塊可以是來自應用程序的代碼或第三方庫。 resolver 幫助 webpack 從每個 require/import 語句中,找到需要引入到 bundle 中的模塊代碼。 當打包模塊時,webpack 使用 enhanced-resolve 來解析文件路徑。
webpack 中的解析規則
使用 enhanced-resolve,webpack 能解析三種文件路徑:
絕對路徑
import '/home/me/file';import 'C:\\Users\\me\\file';由于已經獲得文件的絕對路徑,因此不需要再做進一步解析。
相對路徑
import '../src/file1'; import './file2';這種情況下,使用 import 或 require 的資源文件所處的目錄,被認為是上下文目錄。 在import/require 中給定的相對路
徑,enhanced-resolve 會拼接此上下文路徑,來生成模塊的絕對路徑(path.resolve(__dirname, RelativePath)) 。 這也是我們在寫代碼時最常用的方式之一,另一種最常用的方式則是模塊路徑。
模塊路徑
import 'module'; import 'module/lib/file';也就是在 resolve.modules 中指定的所有目錄檢索模塊(node_modules里的模塊已經被默認配置了)。 你可以通過配置別名的方式來替
換初始模塊路徑, 具體請參照下面 resolve.alias 配置選項。
解析(Resolve)
object
resolve.alias
上文中提到我們可以通過 resolve.alias 來自定義配置模塊路徑。現在我們來實現一下:
首先,我們 src 目錄下新建一個 utils 文件夾,并新建一個 add.js 文件,對外暴露出一個add函數。
// src/utils/add.js export default function add(a, b){ return a + b; }然后我們在src/index.js中基于相對路徑引用并使用它:
import add from './utils/add'; console.log(add);運行項目并且沒有報錯。 這時我們期望能用 @/utils/add 的方式去引用它,于是我們這樣寫了:
import add from '@/utils/add'; console.log(add(a,b));很明顯它會報錯,因為webpack會將其當做一個模塊路徑來識別———所以無法找到 @ 這個模塊。 這時,我們配置下resolve:
// webpack.config.js const path = require('path'); module.exports = {//... resolve: {alias: {"@": path.resolve(__dirname, './src')},}, };如代碼所示,我們將 src 文件夾的絕對路徑配置為一個模塊路徑,起一個別名為 @。 重啟服務發現,代碼跑起來了。模塊識別成功了。
resolve.extensions
[string] = ['.js', '.json', '.wasm']
上述代碼中我們發現,只需要 import add from '@utils/add, webpack就可以幫我們找到add.js。 事實上,這與import add from ‘@utils/add.js’ 的效果是一致的。 為什么會這樣? 原來webpack的內置解析器已經默認定義好了一些 文件/目錄 的路徑解析規則。 比如當我們
import utils from './utils';utils是一個文件目錄而不是模塊(文件),但webpack在這種情況下默認幫我們添加了后綴/index.js,從而將此相對路徑指向到utils里的 index.js 。 這是webpack解析器默認內置好的規則。 那么現在有一個問題: 當utils文件夾下同時擁有add.js add.json時,@utils/add會指向誰呢?
@utils/add.json
{ "name": "add" }我們發現仍然指向到add.js。 當我們刪掉add.js,會發現此時的引入的add變成了一個json對象。 上述現象似乎表明了這是一個默認
配置的優先級的問題。 而webpack對外暴露了配置屬性: resolve.extensions , 它的用法形如:
// webpack.config.js module.exports = {//... resolve: {extensions: ['.js', '.json', '.wasm'],}, };webpack會按照數組順序去解析這些后綴名,對于同名的文件,webpack總是會先解析列在數組首位的后綴名的文件。
外部擴展(Externals)
externals 配置選項提供了「從輸出的 bundle 中排除依賴」的方法。相反,所創建的 bundle 依賴于那些存在于用戶環境(consumer’s environment)中的依賴。此功能通常對 library 開發人員來說是最有用的,然而也會有各種各樣的應用程序用到它。
externals
string [string] object function RegExp
有時候我們為了減小 bundle 的體積或者想要讓我們寫的npm組件/類庫依賴用戶環境,防止將某些 import 的包(package)打包到 bundle
中,而是在運行時(runtime)再去從外部獲取這些擴展依賴(external dependencies),這時我們可以用到外部擴展(Externals)
例如,從 CDN 引入 jQuery,而不是把它打包:
index.html
<scriptsrc="https://code.jquery.com/jquery-3.1.0.js"integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="crossorigin="anonymous" ></script>webpack.config.js
module.exports = {//...externals: {jquery: 'jQuery',}, };其中 jquery 是暴露給你內部代碼使用的模塊名;jQuery 是外部環境存在的模塊名
這樣就剝離了那些不需要改動的依賴模塊,換句話,下面展示的代碼還可以正常運行:
import $ from 'jquery';$('.my-element').animate(/* ... */);未完待續~
總結
以上是生活随笔為你收集整理的Webpack高级应用篇(四):模块解析(Module Resolution)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL如何从字符串截取指定字符(LEFT
- 下一篇: 3-5年经验Java开发面试题精选