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