externals
組態選項提供一種從輸出套件中排除相依性的方式。反之,建立的套件依賴於使用者 (任何終端使用者應用程式) 環境中存在的相依性。此功能通常對函式庫開發人員最有幫助,但它有各種應用程式。
字串
物件
函式
正規表示法
[字串、物件、函式、正規表示法]
防止捆綁某些 import
的套件,而是在執行階段擷取這些外部相依性。
例如,要包含 jQuery 從 CDN,而不是將其捆綁
index.html
<script
src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous"
></script>
webpack.config.js
module.exports = {
//...
externals: {
jquery: 'jQuery',
},
};
這會讓任何依賴的模組保持不變,也就是說,下面顯示的程式碼仍然會運作
import $ from 'jquery';
$('.my-element').animate(/* ... */);
在上述的 webpack.config.js
中,externals
下指定的屬性名稱 jquery
表示 import $ from 'jquery'
中的模組 jquery
應從捆綁中排除。為了取代此模組,值 jQuery
將用於擷取全域 jQuery
變數,因為預設的外部函式庫類型為 var
,請參閱 externalsType。
雖然我們在上面顯示了使用外部全域變數的範例,但外部實際上可以採用下列任何一種形式:全域變數、CommonJS、AMD、ES2015 模組,請在 externalsType 中查看更多資訊。
根據 externalsType,這可能是全域變數的名稱(請參閱 'global'
、'this'
、'var'
、'window'
)或模組的名稱(請參閱 amd
、commonjs
、module
、umd
)。
如果您只定義 1 個外部,也可以使用捷徑語法
module.exports = {
//...
externals: 'jquery',
};
等於
module.exports = {
//...
externals: {
jquery: 'jquery',
},
};
您可以使用 ${externalsType} ${libraryName}
語法,為外部指定 外部函式庫類型。它將覆寫在 externalsType 選項中指定的預設外部函式庫類型。
例如,如果外部函式庫是 CommonJS 模組,您可以指定
module.exports = {
//...
externals: {
jquery: 'commonjs jquery',
},
};
module.exports = {
//...
externals: {
subtract: ['./math', 'subtract'],
},
};
subtract: ['./math', 'subtract']
允許您選擇模組的一部分,其中 ./math
是模組,而您的套件只需要 subtract
變數下的子集。
當 externalsType
為 commonjs
時,此範例將轉換為 require('./math').subtract;
而當 externalsType
為 window
時,此範例將轉換為 window["./math"]["subtract"];
與 字串語法 類似,您可以在陣列的第一個項目中使用 ${externalsType} ${libraryName}
語法指定外部函式庫類型,例如
module.exports = {
//...
externals: {
subtract: ['commonjs ./math', 'subtract'],
},
};
module.exports = {
//...
externals: {
react: 'react',
},
// or
externals: {
lodash: {
commonjs: 'lodash',
amd: 'lodash',
root: '_', // indicates global variable
},
},
// or
externals: {
subtract: {
root: ['math', 'subtract'],
},
},
};
此語法用於描述外部函式庫可以提供的各種可能方式。此處的 lodash
可用於 AMD 和 CommonJS 模組系統中的 lodash
,但可用於全域變數形式中的 _
。此處的 subtract
可透過全域 math
物件中的 subtract
屬性取得 (例如 window['math']['subtract']
)。
function ({ context, request, contextInfo, getResolve }, callback)
function ({ context, request, contextInfo, getResolve }) => promise
5.15.0+定義您自己的函式來控制您要從 webpack 外部化的行為可能很有用。例如,webpack-node-externals 會排除 node_modules
目錄中的所有模組,並提供允許套件的選項。
以下是函式可以接收的引數
ctx
(object
):包含檔案詳細資料的物件。ctx.context
(string
):包含匯入的檔案目錄。ctx.request
(string
):正在要求的匯入路徑。ctx.contextInfo
(object
):包含發佈者的資訊 (例如層和編譯器)ctx.getResolve
5.15.0+:取得具有目前解析器選項的解析函式。callback
(function (err, result, type)
):用於指示如何將模組外部化的回呼函式。回呼函式採用三個引數
err
(Error
):用於指出外部化匯入時是否發生錯誤。如果有錯誤,這應該是唯一使用的參數。result
(string
[string]
object
):使用其他外部格式 (string
、[string]
或 object
) 描述外部模組type
(string
):指示模組 外部類型 的選用參數 (如果尚未在 result
參數中指示)。例如,要外部化所有匯入,其中匯入路徑符合正規表示式,您可以執行下列動作
webpack.config.js
module.exports = {
//...
externals: [
function ({ context, request }, callback) {
if (/^yourregex$/.test(request)) {
// Externalize to a commonjs module using the request path
return callback(null, 'commonjs ' + request);
}
// Continue without externalizing the import
callback();
},
],
};
使用不同模組格式的其他範例
webpack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a `commonjs2` module located in `@scope/library`
callback(null, '@scope/library', 'commonjs2');
},
],
};
webpack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a global variable called `nameOfGlobal`.
callback(null, 'nameOfGlobal');
},
],
};
webpack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a named export in the `@scope/library` module.
callback(null, ['@scope/library', 'namedexport'], 'commonjs');
},
],
};
webpack.config.js
module.exports = {
externals: [
function (ctx, callback) {
// The external is a UMD module
callback(null, {
root: 'componentsGlobal',
commonjs: '@scope/components',
commonjs2: '@scope/components',
amd: 'components',
});
},
],
};
與給定正規表示式相符的每個相依性都會從輸出套件中排除。
webpack.config.js
module.exports = {
//...
externals: /^(jquery|\$)$/i,
};
在這種情況下,任何名為 jQuery
的相依性 (不分大小寫) 或 $
都會被外部化。
有時您可能想要使用上述語法組合。這可以用下列方式完成
webpack.config.js
module.exports = {
//...
externals: [
{
// String
react: 'react',
// Object
lodash: {
commonjs: 'lodash',
amd: 'lodash',
root: '_', // indicates global variable
},
// [string]
subtract: ['./math', 'subtract'],
},
// Function
function ({ context, request }, callback) {
if (/^yourregex$/.test(request)) {
return callback(null, 'commonjs ' + request);
}
callback();
},
// Regex
/^(jquery|\$)$/i,
],
};
如需如何使用此組態的更多資訊,請參閱有關 如何撰寫函式庫 的文章。
function
object
依據層級指定外部函式庫。
webpack.config.js
module.exports = {
externals: {
byLayer: {
layer: {
external1: 'var 43',
},
},
},
};
字串 = 'var'
指定外部函式庫的預設類型。amd
、umd
、system
和 jsonp
外部函式庫取決於 output.libraryTarget
設定為相同的值,例如,你只能在 amd
函式庫中使用 amd
外部函式庫。
支援的類型
'amd'
'amd-require'
'assign'
- 與 'var'
相同'commonjs'
'commonjs-module'
'global'
'import'
- 使用 import()
載入原生 EcmaScript 模組(非同步模組)'jsonp'
'module'
'node-commonjs'
'promise'
- 與 'var'
相同,但會等待結果(非同步模組)'self'
'system'
'script'
'this'
'umd'
'umd2'
'var'
'window'
webpack.config.js
module.exports = {
//...
externalsType: 'promise',
};
將外部函式庫的預設類型指定為 'commonjs'
。Webpack 會為模組中使用的外部函式庫產生類似 const X = require('...')
的程式碼。
import fs from 'fs-extra';
webpack.config.js
module.exports = {
// ...
externalsType: 'commonjs',
externals: {
'fs-extra': 'fs-extra',
},
};
將產生類似以下的內容
const fs = require('fs-extra');
請注意,輸出套件中將會有一個 require()
。
將外部函式庫的預設類型指定為 'global'
。Webpack 會在 globalObject
上將外部函式庫讀取為全域變數。
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
webpack.config.js
module.exports = {
// ...
externalsType: 'global',
externals: {
jquery: '$',
},
output: {
globalObject: 'global',
},
};
將產生類似以下的內容
const jq = global['$'];
jq('.my-element').animate(/* ... */);
指定 externals 的預設類型為 'module'
。Webpack 將會為模組中使用的 externals 產生類似 import * as X from '...'
的程式碼。
請務必先啟用 experiments.outputModule
,否則 webpack 將會擲回錯誤。
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
webpack.config.js
module.exports = {
experiments: {
outputModule: true,
},
externalsType: 'module',
externals: {
jquery: 'jquery',
},
};
將產生類似以下的內容
import * as __WEBPACK_EXTERNAL_MODULE_jquery__ from 'jquery';
const jq = __WEBPACK_EXTERNAL_MODULE_jquery__['default'];
jq('.my-element').animate(/* ... */);
請注意輸出套件中將會有一個 import
陳述式。
指定 externals 的預設類型為 'node-commonjs'
。Webpack 將會從 'module'
匯入 createRequire
來建構一個 require 函式,用於載入模組中使用的 externals。
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
webpack.config.js
module.export = {
experiments: {
outputModule: true,
},
externalsType: 'node-commonjs',
externals: {
jquery: 'jquery',
},
};
將產生類似以下的內容
import { createRequire } from 'module';
const jq = createRequire(import.meta.url)('jquery');
jq('.my-element').animate(/* ... */);
請注意輸出套件中將會有一個 import
陳述式。
指定 externals 的預設類型為 'promise'
。Webpack 將會將 external 視為一個全域變數(類似於 'var'
),並對其進行 await
。
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
webpack.config.js
module.exports = {
// ...
externalsType: 'promise',
externals: {
jquery: '$',
},
};
將產生類似以下的內容
const jq = await $;
jq('.my-element').animate(/* ... */);
指定 externals 的預設類型為 'self'
。Webpack 將會將 external 視為 self
物件上的全域變數。
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
webpack.config.js
module.exports = {
// ...
externalsType: 'self',
externals: {
jquery: '$',
},
};
將產生類似以下的內容
const jq = self['$'];
jq('.my-element').animate(/* ... */);
將外部程式碼的預設類型指定為 'script'
。Webpack 會將外部程式碼載入為腳本,並透過 HTML <script>
元素公開預先定義的全球變數。<script>
標籤會在腳本載入後移除。
module.exports = {
externalsType: 'script',
externals: {
packageName: [
'http://example.com/script.js',
'global',
'property',
'property',
], // properties are optional
},
};
如果您不打算指定任何屬性,也可以使用捷徑語法
module.exports = {
externalsType: 'script',
externals: {
packageName: 'global@http://example.com/script.js', // no properties here
},
};
請注意,output.publicPath
不會新增到提供的 URL。
讓我們從 CDN 載入 lodash
webpack.config.js
module.exports = {
// ...
externalsType: 'script',
externals: {
lodash: ['https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js', '_'],
},
};
然後在程式碼中使用它
import _ from 'lodash';
console.log(_.head([1, 2, 3]));
以下是我們如何為上述範例指定屬性的方式
module.exports = {
// ...
externalsType: 'script',
externals: {
lodash: [
'https://cdn.jsdelivr.net/npm/lodash@4.17.19/lodash.min.js',
'_',
'head',
],
},
};
當您 import
lodash
時,本機變數 head
和全域變數 window._
都會公開
import head from 'lodash';
console.log(head([1, 2, 3])); // logs 1 here
console.log(window._.head(['a', 'b'])); // logs a here
將外部程式碼的預設類型指定為 'this'
。Webpack 會將外部程式碼讀取為 this
物件上的全域變數。
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
webpack.config.js
module.exports = {
// ...
externalsType: 'this',
externals: {
jquery: '$',
},
};
將產生類似以下的內容
const jq = this['$'];
jq('.my-element').animate(/* ... */);
將 externals 的預設類型指定為 'var'
。Webpack 會將 external 讀取為全域變數。
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
webpack.config.js
module.exports = {
// ...
externalsType: 'var',
externals: {
jquery: '$',
},
};
將產生類似以下的內容
const jq = $;
jq('.my-element').animate(/* ... */);
將 externals 的預設類型指定為 'window'
。Webpack 會將 external 讀取為 window
物件上的全域變數。
import jq from 'jquery';
jq('.my-element').animate(/* ... */);
webpack.config.js
module.exports = {
// ...
externalsType: 'window',
externals: {
jquery: '$',
},
};
將產生類似以下的內容
const jq = window['$'];
jq('.my-element').animate(/* ... */);
物件
針對特定目標啟用 externals 的預設值。
選項 | 說明 | 輸入類型 |
---|---|---|
electron | 將主程式和預載入內容中常見的 electron 內建模組(例如 electron 、ipc 或 shell )視為 external,並在使用時透過 require() 載入。 | 布林值 |
electronMain | 將主程式內容中的 electron 內建模組(例如 app 、ipc-main 或 shell )視為 external,並在使用時透過 require() 載入。 | 布林值 |
electronPreload | 將預載入內容中的 electron 內建模組(例如 web-frame 、ipc-renderer 或 shell )視為 external,並在使用時透過 require() 載入。 | 布林值 |
electronRenderer | 將呈現器內容中的 electron 內建模組(例如 web-frame 、ipc-renderer 或 shell )視為 external,並在使用時透過 require() 載入。 | 布林值 |
node | 將 node.js 內建模組(例如 fs 、path 或 vm )視為 external,並在使用時透過 require() 載入。 | 布林值 |
nwjs | 將 NW.js 舊版 nw.gui 模組視為外部模組,並在使用時透過 require() 載入。 | 布林值 |
web | 將對 http(s)://... 和 std:... 的參照視為外部參照,並在使用時透過 import 載入。(請注意,這會變更執行順序,因為外部程式碼會在區塊中的任何其他程式碼之前執行)。 | 布林值 |
webAsync | 將對 http(s)://... 和 std:... 的參照視為外部參照,並在使用時透過 async import() 載入。(請注意,此外部類型是一個 async 模組,這會對執行產生各種影響)。 | 布林值 |
請注意,如果您要使用這些與 node.js 相關的預設值來輸出 ES 模組,webpack 會將預設的 externalsType
設定為 node-commonjs
,它會使用 createRequire
來建構一個 require 函式,而不是使用 require()
。
範例
使用 node
預設值不會將內建模組打包,並將它們視為外部模組,並在使用時透過 require()
載入。
webpack.config.js
module.exports = {
// ...
externalsPresets: {
node: true,
},
};