此區段涵蓋 webpack 編譯程式碼中所有可用的方法。當使用 webpack 將應用程式打包時,您可以從各種模組語法樣式中挑選,包括 ES6、CommonJS 和 AMD。
雖然 webpack 支援多種模組語法,但我們建議遵循單一語法以確保一致性並避免奇怪的行為/錯誤。實際上,當最近的父級 package.json
檔案包含值為 "module"
或 "commonjs"
的 "type"
欄位時,webpack 會強制執行 .mjs
檔案、.cjs
檔案或 .js
檔案的建議。請在繼續閱讀前注意這些強制執行
package.json
中的 .mjs
或 .js
,並具有 "type": "module"
require
、module.exports
或 exports
import './src/App.mjs'
而不是 import './src/App'
(您可以使用 Rule.resolve.fullySpecified
停用此強制執行)package.json
中的 .cjs
或 .js
,並具有 "type": "commonjs"
import
和 export
都不可用package.json
中的 .wasm
,並具有 "type": "module"
webpack 版本 2 原生支援 ES6 模組語法,表示您可以使用 import
和 export
,而不需要像 babel 這樣的工具來處理這些語法。請注意,您可能仍需要 babel 來使用其他 ES6+ 功能。webpack 支援下列方法
靜態 import
另一個模組的 export
。
import MyModule from './my-module.js';
import { NamedExport } from './other-module.js';
您也可以 import
資料 URI
import 'data:text/javascript;charset=utf-8;base64,Y29uc29sZS5sb2coJ2lubGluZSAxJyk7';
import {
number,
fn,
} from 'data:text/javascript;charset=utf-8;base64,ZXhwb3J0IGNvbnN0IG51bWJlciA9IDQyOwpleHBvcnQgY29uc3QgZm4gPSAoKSA9PiAiSGVsbG8gd29ybGQiOw==';
將任何內容作為 default
或命名 export 匯出。
// Named exports
export var Count = 5;
export function Multiply(a, b) {
return a * b;
}
// Default export
export default {
// Some data...
};
function(string 路徑):Promise
動態載入模組。呼叫 import()
會被視為分割點,表示要求的模組及其子模組會分割到一個獨立的區塊中。
if (module.hot) {
import('lodash').then((_) => {
// Do something with lodash (a.k.a '_')...
});
}
無法使用完全動態的匯入陳述式,例如 import(foo)
。因為 foo
可能是系統或專案中任何檔案的任何路徑。
import()
必須包含模組所在位置的一些資訊。套件可以限制在特定目錄或檔案組,以便在使用動態表達式時 - 每個模組都可能在 import()
呼叫時請求,並包含在內。例如,import(`./locale/${language}.json`)
會導致 ./locale
目錄中的每個 .json
檔案都套件到新的區塊中。在執行階段,當變數 language
已計算完成時,任何檔案(例如 english.json
或 german.json
)都可供使用。
// imagine we had a method to get language from cookies or other storage
const language = detectVisitorLanguage();
import(`./locale/${language}.json`).then((module) => {
// do something with the translations
});
內嵌註解可讓功能運作。透過在匯入中新增註解,我們可以執行命名區塊或選擇不同模式等動作。如需這些魔術註解的完整清單,請參閱下列程式碼,以及這些註解執行的動作說明。
// Single target
import(
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
/* webpackExports: ["default", "named"] */
/* webpackFetchPriority: "high" */
'module'
);
// Multiple possible targets
import(
/* webpackInclude: /\.json$/ */
/* webpackExclude: /\.noimport\.json$/ */
/* webpackChunkName: "my-chunk-name" */
/* webpackMode: "lazy" */
/* webpackPrefetch: true */
/* webpackPreload: true */
`./locale/${language}`
);
import(/* webpackIgnore: true */ 'ignored-module.js');
webpackIgnore
設為 true
時,停用動態匯入剖析。
webpackChunkName
新區塊的名稱。自 webpack 2.6.0 起,已支援在給定字串中使用 [index]
和 [request]
佔位符,分別表示遞增的數字或實際解析的檔案名稱。新增此註解將使我們的獨立區塊命名為 [my-chunk-name].js,而不是 [id].js。
webpackFetchPriority
針對特定動態載入設定 fetchPriority
。也可以使用 module.parser.javascript.dynamicImportFetchPriority
選項,為所有動態載入設定全域預設值。
import(
/* webpackFetchPriority: "high" */
'path/to/module'
);
webpackMode
自 webpack 2.6.0 起,可以指定不同的模式來解析動態載入。支援下列選項
'lazy'
(預設):針對每個 import()
ed 模組產生可延遲載入的區塊。'lazy-once'
:產生單一可延遲載入的區塊,可滿足所有對 import()
的呼叫。此區塊會在第一次呼叫 import()
時擷取,後續對 import()
的呼叫會使用相同的網路回應。請注意,這僅在部分動態陳述的情況下才有意義,例如 import(`./locales/${language}.json`)
,其中有多個模組路徑可能被要求。'eager'
:不產生額外的區塊。所有模組都包含在目前的區塊中,且不會產生其他網路要求。仍會傳回 Promise
,但已解析。與靜態載入不同,模組不會在呼叫 import()
之前執行。'weak'
:如果模組函式已透過其他方式載入 (例如,其他區塊載入它,或載入包含該模組的指令碼),則嘗試載入模組。仍會傳回 Promise
,但只有當區塊已存在於客戶端時,才會成功解析。如果模組不可用,則 Promise
會被拒絕。絕不會執行網路要求。當必要的區塊總是手動提供於初始要求 (嵌入在頁面中) 時,這對於通用呈現很有用,但對於應用程式導覽會觸發未在初始提供載入的情況則不然。webpackPrefetch
告訴瀏覽器此資源未來可能需要用於某些導覽。查看指南以取得更多關於 webpackPrefetch 運作方式 的資訊。
webpackPreload
告訴瀏覽器此資源可能需要在目前導覽期間使用。查看指南以取得更多關於 webpackPreload 運作方式 的資訊。
webpackInclude
在匯入解析期間會比對的正規表示式。只有比對成功的模組才會打包。
webpackExclude
在匯入解析期間會比對的正規表示式。任何比對成功的模組都不會打包。
webpackExports
:告訴 webpack 只打包動態 import()
ed 模組指定的 exports。它可以減少區塊的輸出大小。自 webpack 5.0.0-beta.18 起提供。
CommonJS 的目標是為瀏覽器外的 JavaScript 指定一個生態系統。webpack 支援下列 CommonJS 方法
require(dependency: String);
同步擷取其他模組的輸出。編譯器會確保相依性在輸出套件中可用。
var $ = require('jquery');
var myModule = require('my-module');
也可以為 require
啟用神奇註解,詳情請參閱 module.parser.javascript.commonjsMagicComments
。
require.resolve(dependency: String);
同步擷取模組的 ID。編譯器會確保相依性在輸出套件中可用。建議將其視為不透明值,只能與 require.cache[id]
或 __webpack_require__(id)
搭配使用(最好避免這種用法)。
有關更多資訊,請參閱 module.id
。
多次 require 同一個模組只會執行一次模組,只會輸出一次。因此執行階段存在快取。從這個快取中移除值會導致新的模組執行和新的輸出。
var d1 = require('dependency');
require('dependency') === d1;
delete require.cache[require.resolve('dependency')];
require('dependency') !== d1;
// in file.js
require.cache[module.id] === module;
require('./file.js') === module.exports;
delete require.cache[module.id];
require.cache[module.id] === undefined;
require('./file.js') !== module.exports; // in theory; in praxis this causes a stack overflow
require.cache[module.id] !== module;
require.ensure(
dependencies: String[],
callback: function(require),
errorCallback: function(error),
chunkName: String
)
將指定的 dependencies
分割到一個獨立的套件中,並非同步載入。當使用 CommonJS 模組語法時,這是動態載入依賴項目的唯一方法。也就是說,這段程式碼可以在執行期間執行,僅在符合特定條件時載入 dependencies
。
var a = require('normal-dep');
if (module.hot) {
require.ensure(['b'], function (require) {
var c = require('c');
// Do something special...
});
}
以下參數依上述順序提供支援
dependencies
:宣告 callback
中執行程式碼所需所有模組的字串陣列。callback
:Webpack 在載入依賴項後執行的函式。require
函式的實作會作為參數傳送給此函式。函式主體可以使用此函式進一步 require()
執行所需的模組。errorCallback
:Webpack 無法載入依賴項時執行的函式。chunkName
:給予此特定 require.ensure()
建立的區塊名稱。透過將相同的 chunkName
傳遞給各種 require.ensure()
呼叫,我們可以將其程式碼合併成單一區塊,只產生瀏覽器必須載入的一個套件。非同步模組定義 (AMD) 是一種 JavaScript 規格,定義了撰寫和載入模組的介面。Webpack 支援下列 AMD 方法
define([name: String], [dependencies: String[]], factoryMethod: function(...))
如果提供了 dependencies
,則會使用每個依賴項的匯出(按相同順序)呼叫 factoryMethod
。如果未提供 dependencies
,則會使用 require
、exports
和 module
呼叫 factoryMethod
(為了相容性!)。如果此函式傳回一個值,則此值會由模組匯出。編譯器會確保每個依賴項都可用。
define(['jquery', 'my-module'], function ($, myModule) {
// Do something with $ and myModule...
// Export a function
return function doSomething() {
// ...
};
});
define(value: !Function)
這將匯出提供的 value
。這裡的 value
可以是任何東西,除了函式之外。
define({
answer: 42,
});
require(dependencies: String[], [callback: function(...)])
類似於 require.ensure
,這會將指定的 dependencies
分割成一個獨立的套件,並會非同步載入。會使用 dependencies
陣列中每個依賴項的匯出呼叫 callback
。
require(['b'], function (b) {
var c = require('c');
});
內部的 LabeledModulesPlugin
讓您可以在模組中使用下列方法來匯出和需要
匯出給定的 value
。標籤可以在函數宣告或變數宣告之前出現。函數名稱或變數名稱是匯出值之下的識別碼。
export: var answer = 42;
export: function method(value) {
// Do something...
};
讓所有從依賴項的匯出在目前的範圍中可用。require
標籤可以在字串之前出現。依賴項必須使用 export
標籤匯出值。無法使用 CommonJS 或 AMD 模組。
some-dependency.js
export: var answer = 42;
export: function method(value) {
// Do something...
};
require: 'some-dependency';
console.log(answer);
method(...);
除了上述的模組語法之外,Webpack 也允許一些自訂的 Webpack 專屬方法
require.context(
(directory: String),
(includeSubdirs: Boolean) /* optional, default true */,
(filter: RegExp) /* optional, default /^\.\/.*$/, any file */,
(mode: String) /* optional, 'sync' | 'eager' | 'weak' | 'lazy' | 'lazy-once', default 'sync' */
);
使用路徑到 directory
指定一整組依賴項,includeSubdirs
選項,更精細地控制所包含模組的 filter
,以及定義載入方式的 mode
。稍後可以解析底層模組
var context = require.context('components', true, /\.html$/);
var componentA = context.resolve('componentA');
如果 mode
設為 'lazy'
,底層模組將會非同步載入
var context = require.context('locales', true, /\.json$/, 'lazy');
context('localeA').then((locale) => {
// do something with locale
});
可用模式及其行為的完整清單說明在 import()
文件中。
require.include((dependency: String));
包含 dependency
而不用執行它。這可以用來最佳化模組在輸出區塊中的位置。
require.include('a');
require.ensure(['a', 'b'], function (require) {
/* ... */
});
require.ensure(['a', 'c'], function (require) {
/* ... */
});
這將會產生下列輸出
file.js
和 a
b
c
沒有 require.include('a')
,它會在兩個匿名區塊中重複。
類似於 require.resolve
,但這不會將 module
拉入套件中。它被認為是「弱」依賴項。
if (__webpack_modules__[require.resolveWeak('module')]) {
// Do something when module is available...
}
if (require.cache[require.resolveWeak('module')]) {
// Do something when module was loaded before...
}
// You can perform dynamic resolves ("context")
// similarly to other require/import methods.
const page = 'Foo';
__webpack_modules__[require.resolveWeak(`./page/${page}`)];
如果模組來源包含無法靜態分析的需要,則會發出關鍵依賴項警告。
範例程式碼
someFn(require);
require.bind(null);
require(variable);