CC 4.0 授權

本節的內容衍生自以下連結的內容,並受 CC BY 4.0 授權條款約束。

如果沒有特別說明,以下內容可以假設是基於原始內容進行修改和刪除的結果。

模組方法

本節涵蓋了所有在 Rspack 編譯的程式碼中可用的方法。當使用 Rspack 打包您的應用程式時,您可以從各種模組語法樣式中選擇,包括 ES6、CommonJS。

雖然 Rspack 支援多種模組語法,我們建議為了保持一致性並避免奇怪的行為/錯誤,採用單一的語法。

實際上,當最近的父級 package.json 檔案包含一個值為 "module""commonjs""type" 欄位時,Rspack 會強制執行對 .mjs 檔案、.cjs 檔案或 .js 檔案的建議。在您繼續閱讀之前,請注意這些強制執行。

  • .mjs.js 在 package.json 中帶有 "type": "module"
    • 不允許使用 CommonJS,例如,您不能使用 requiremodule.exportsexports
    • 匯入時需要檔案副檔名,例如,您應該使用 import './src/App.mjs' 而不是 import './src/App'(您可以使用 Rule.resolve.fullySpecified 停用此強制執行)
  • .cjs.js 在 package.json 中帶有 "type": "commonjs"
    • import 和 export 皆不可用

Rspack 原生支援 ES6 模組語法,您可以使用靜態 importexportimport() 語法。

警告

請記住,您可能仍然需要 SWC 或 Babel 來處理其他 ES6+ 功能。

import

靜態 import 另一個模組的 export

import MyModule from './my-module.js';
import { NamedExport } from './other-module.js';

您也可以 import Data URI

import 'data:text/javascript;charset=utf-8;base64,Y29uc29sZS5sb2coJ2lubGluZSAxJyk7';
import {
  number,
  fn,
} from 'data:text/javascript;charset=utf-8;base64,ZXhwb3J0IGNvbnN0IG51bWJlciA9IDQyOwpleHBvcnQgY29uc3QgZm4gPSAoKSA9PiAiSGVsbG8gd29ybGQiOw==';

export

將任何內容匯出為 default 或具名 export。

// Named exports
export var Count = 5;
export function Multiply(a, b) {
  return a * b;
}

// Default export
export default {
  // Some data...
};

動態 import()

function import(path: string): Promise;

動態載入模組。對 import() 的呼叫被視為分割點,這表示請求的模組及其子模組會被分割到一個單獨的區塊中。

if (module.hot) {
  import('lodash').then(_ => {
    // Do something with lodash (a.k.a '_')...
  });
}
警告

此功能在內部依賴 Promise。如果您在較舊的瀏覽器中使用 import(),請記得使用諸如 es6-promisepromise-polyfill 之類的 polyfill 來 shim Promise

import() 中的動態表達式

無法使用完全動態的 import 語句,例如 import(foo)。因為 foo 可能會是系統或專案中任何檔案的任何路徑。

import() 必須至少包含關於模組位置的一些資訊。捆綁可以限定在特定的目錄或檔案集中,以便當您使用動態表達式時 - 每個可能在 import() 呼叫中請求的模組都會被包含進來。例如,import(./locale/${language}.json) 將會導致 ./locale 目錄中的每個 .json 檔案被捆綁到新的區塊中。在執行階段,當變數 language 被計算出來後,任何像 english.jsongerman.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
});

魔法註解

Rspack/Webpack 特定

內嵌註解以使功能運作。通過在 import 中新增註解,我們可以執行諸如命名區塊或選擇不同模式等操作。有關這些魔法註解的完整列表,請參閱下面的程式碼,以及這些註解的作用說明。

// 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}`
);
webpackIgnore
  • 類型: boolean

當設定為 true 時,停用動態 import 解析。

警告

請注意,將 webpackIgnore 設定為 true 會選擇不進行程式碼分割。

webpackMode
  • 類型: "eager" | "lazy" | "weak" | "lazy-once"

可以指定解析動態 import 的不同模式。支援以下選項

  • 'lazy' (預設):為每個 import() 的模組產生一個可延遲載入的區塊。
  • 'lazy-once':產生一個單一的可延遲載入區塊,可以滿足所有對 import() 的呼叫。該區塊將在第一次呼叫 import() 時提取,後續對 import() 的呼叫將使用相同的網路回應。請注意,這僅在部分動態語句的情況下才有意義,例如 import("./locales/${language}.json"),其中有多個模組路徑可能會被請求。
  • 'eager':不產生額外的區塊。所有模組都包含在目前的區塊中,並且不會進行額外的網路請求。仍會返回一個 Promise,但它已經被解析。與靜態 import 相比,模組直到呼叫 import() 時才會執行。
  • 'weak':如果模組函式已通過其他方式載入(例如,另一個區塊匯入了它或載入了一個包含該模組的腳本),則會嘗試載入該模組。仍會返回一個 Promise,但只有在區塊已經在客戶端時才會成功解析。如果模組不可用,則 Promise 將被拒絕。永遠不會執行網路請求。這對於通用渲染很有用,當所需的區塊總是在初始請求中手動提供(嵌入在頁面中)時,但當應用程式導航將觸發最初未提供的 import 時則不適用。
webpackPrefetch
  • 類型
    • number:區塊預提取優先順序
    • booleanfalse 表示不預提取,true 表示優先順序為 0

告知瀏覽器此資源未來可能用於某些導航,詳情請參閱預取/預載模組

webpackPreload
  • 類型
    • number:區塊預載優先級
    • booleanfalse 表示不預載,true 表示優先級為 0

告知瀏覽器此資源可能在當前導航期間需要,詳情請參閱預取/預載模組

webpackChunkName
  • 類型:: string

新區塊的名稱。

webpackFetchPriority
  • 類型:: "low" | "high" | "auto"

為特定的動態導入設定 fetchPriority。也可以使用 module.parser.javascript.dynamicImportFetchPriority 選項為所有動態導入設定全域預設值。

webpackInclude
  • 類型:: Regexp

一個在導入解析期間會進行匹配的正規表示式。只有符合此正規表示式的模組才會被打包

webpackExclude
  • 類型:: Regexp

一個在導入解析期間會進行匹配的正規表示式。任何符合此正規表示式的模組都不會被打包

資訊

請注意,webpackIncludewebpackExclude 選項不會干擾前綴。例如:./locale

webpackExports
  • 類型:: string | string[]

告知 webpack 僅打包動態 import() 的模組中指定的輸出。它可以減少區塊的輸出大小。

CommonJS

Rspack 也原生支援 CommonJS 語法,您可以使用 requiremodule.exports 方法。

require

同步從另一個模組檢索輸出。

require(dependency: string);

require.resolve

同步檢索模組的 ID。建議將其視為不透明的值,只能與 require.cache[id]__webpack_require__(id) 一起使用(最好避免這種用法)。

require.resolve(dependency: string);
警告

模組 ID 的類型可以是數字或字串,具體取決於 optimization.moduleIds 設定。

require.cache

多次要求同一個模組只會導致一個模組執行和一個輸出。因此,執行階段存在一個快取。從此快取中移除值會導致新的模組執行和新的輸出。

var d1 = require('dependency');
require('dependency') === d1;
delete require.cache[require.resolve('dependency')];
require('dependency') !== d1;

require.context

Rspack/Webpack 特定

require.context 是 webpack 特有的函式,可讓您動態要求一組模組。

您可以在程式碼中使用 require.context,Rspack 將在建置過程中解析並引用匹配的模組。

提示

require.context 的傳回值與 import.meta.webpackContext 相同。我們建議使用功能更強大的 import.meta.webpackContext

  • 類型
function requireContext(
  /**
   * A directory to search.
   */
  directory: string,
  /**
   * Whether subdirectories should be searched.
   * @default true
   */
  includeSubdirs?: boolean,
  /**
   * A regular expression to match files.
   * @default /^\.\/.*$/ (any file)
   */
  filter?: RegExp,
  /**
   * Module loading mode.
   * @default 'sync'
   */
  mode?: 'sync' | 'eager' | 'weak' | 'lazy' | 'lazy-once',
): Context;
  • 範例
// Create a context, with files from the test directory that
// can be required with a request ending with `.test.js`.
const context = require.context('./test', false, /\.test\.js$/);
// Create a context with all files in the parent folder and
// descending folders ending with `.stories.js`.
const context = require.context('../', true, /\.stories\.js$/);
// If mode is set to 'lazy', the underlying modules will be loaded asynchronously
const context = require.context('./locales', true, /\.json$/, 'lazy');
提示

Rspack 使用靜態分析來解析編譯期間 require.context 的參數。因此,參數必須是字面值

例如,filter 的值不能是變數,也不能是 new RegExp() 產生的值。它只能是一個正規表示式字面值。

require.ensure

Rspack/Webpack 特定
提示

require.ensure() 是 rspack/webpack 特有的,已被 import() 取代。

將給定的 dependencies 分割到一個單獨的捆綁包中,該捆綁包將以非同步方式載入。當使用 CommonJS 模組語法時,這是動態載入 dependencies 的唯一方法。這意味著,此程式碼可以在執行中執行,只有在滿足特定條件時才會載入相依性。

警告

此功能在內部依賴 Promise。如果您在較舊的瀏覽器中使用 require.ensure,請記得使用 polyfill(例如 es6-promisepromise-polyfill)來填補 Promise。

  • 類型
function requireEnsure(
  /**
   * An array of strings declaring all modules required for the code in the callback to execute.
   */
  dependencies: String[],
  /**
   * A function that webpack will execute once the dependencies are loaded.
   * An implementation of the require function is sent as a parameter to this function.
   * The function body can use this to further require() modules it needs for execution
   */
  callback: function(require),
  /**
   * A function that is executed when webpack fails to load the dependencies.
   */
  errorCallback?: function(error),
  /**
   * A name given to the chunk created by this particular require.ensure().
   * By passing the same chunkName to various require.ensure() calls,
   * we can combine their code into a single chunk, resulting in only one bundle that the browser must load.
   */
  chunkName?: String
): Context;
  • 範例
var a = require('normal-dep');

if (module.hot) {
  require.ensure(['b'], function (require) {
    var c = require('c');

    // Do something special...
  });
}

資料 URI 模組

Rspack 支援使用 importrequire 語法導入資料 URI 模組。

import

import DataURI from 'data:text/javascript,export default 42';

require

require('data:text/javascript,module.exports = 42');

此外,也支援 Base64 編碼的請求

const {
  number,
  fn,
} = require('data:text/javascript;charset=utf-8;base64,ZXhwb3J0IGNvbnN0IG51bWJlciA9IDQyOwpleHBvcnQgZnVuY3Rpb24gZm4oKSB7CiAgcmV0dXJuICJIZWxsbyB3b3JsZCI7Cn0=');
提示

資料 URI 模組可以用作實現虛擬模組的方法,例如與 Loader 結合以在執行階段動態載入自訂模組。