CC 4.0 许可证
本节内容来自以下链接的内容,并受 CC BY 4.0 许可证约束。
除非另有说明,以下内容可以被认为是基于原始内容的修改和删除的结果。
模块方法
本节介绍了使用 Rspack 编译的代码中可用的所有方法。当使用 Rspack 打包您的应用程序时,您可以从多种模块语法样式中进行选择,包括 ES6、CommonJS。
虽然 Rspack 支持多种模块语法,但我们建议您遵循单一语法以保持一致性并避免出现奇怪的行为/错误。
实际上,Rspack 会对 .mjs
文件、.cjs
文件或 .js
文件执行推荐,当它们最近的父 package.json
文件包含一个值为 "module"
或 "commonjs"
的 "type"
字段时。在您继续阅读之前,请注意这些强制措施。
.mjs
或 .js
,在 package.json 中使用 "type": "module"
- 不允许使用 CommonJS,例如,您不能使用
require
、module.exports
或 exports
- 导入时需要文件扩展名,例如,您应该使用 import './src/App.mjs' 而不是 import './src/App'(您可以使用 Rule.resolve.fullySpecified 禁用此强制措施)
.cjs
或 .js
,在 package.json 中使用 "type": "commonjs"
ES6 (推荐)
Rspack 原生支持 ES6 模块语法,您可以使用静态 import
、export
和 import()
语法。
警告
请记住,您可能仍然需要 SWC 或 Babel 来处理其他 ES6+ 功能。
import
静态 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==';
export
导出任何内容作为 default
或命名导出。
// 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 '_')...
});
}
import() 中的动态表达式
无法使用完全动态的导入语句,例如 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
});
Rspack/Webpack 特定
内联注释使功能正常工作。通过向导入添加注释,我们可以做一些事情,例如命名我们的块或选择不同的模式。有关这些魔术注释的完整列表,请参见下面的代码,然后解释这些注释的作用。
// 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
当设置为 true 时,禁用动态导入解析。
警告
请注意,将 webpackIgnore 设置为 true 会选择退出代码拆分。
webpackMode
- 类型:
"eager" | "lazy" | "weak" | "lazy-once"
可以指定用于解析动态导入的不同模式。支持以下选项
'lazy'
(默认):为每个 import()
的模块生成一个延迟加载的块。
'lazy-once'
:生成一个单一的延迟加载的块,可以满足对 import()
的所有调用。该块将在第一次调用 import()
时获取,后续对 import()
的调用将使用相同的网络响应。请注意,这仅在部分动态语句的情况下有意义,例如 import("./locales/${language}.json")
,其中可能请求多个模块路径。
'eager'
:不生成额外的块。所有模块都包含在当前块中,并且不会发出额外的网络请求。仍然会返回一个 Promise,但它已经解析。与静态导入相比,模块直到调用 import()
时才会执行。
'weak'
:如果模块函数已以某种其他方式加载(例如,另一个块导入了它或包含该模块的脚本已加载),则尝试加载该模块。仍然会返回一个 Promise,但仅在块已在客户端上的情况下才会成功解析。如果模块不可用,则 Promise 会被拒绝。永远不会执行网络请求。这在通用渲染中非常有用,因为必需的块始终在初始请求中手动提供(嵌入在页面中),但在应用程序导航将触发未在初始请求中提供的导入的情况下则不适用。
webpackPrefetch
- 类型
number
:块预取优先级
boolean
:false
表示不预取,true
表示优先级为 0
告诉浏览器该资源可能在将来的某些导航中需要,有关更多详细信息,请参见 预取/预加载模块。
webpackPreload
- 类型
number
:块预加载优先级
boolean
:false
表示不预加载,true
表示优先级为 0
告诉浏览器该资源可能在当前导航期间需要,有关更多详细信息,请参见 预取/预加载模块。
webpackChunkName
新块的名称。
webpackFetchPriority
- 类型::
"low" | "high" | "auto"
设置 fetchPriority
用于特定的动态导入。也可以使用 module.parser.javascript.dynamicImportFetchPriority
选项为所有动态导入设置全局默认值。
webpackInclude
一个正则表达式,将在导入解析期间与之匹配。只有与之匹配的模块才会被捆绑。
webpackExclude
一个正则表达式,将在导入解析期间与之匹配。任何与之匹配的模块都不会被捆绑。
信息
请注意,webpackInclude
和 webpackExclude
选项不会干扰前缀。例如:./locale
。
webpackExports
告诉 webpack 只打包动态 import()
模块中指定的导出内容。这可以减小块的输出大小。
CommonJS
Rspack 也原生支持 CommonJS
语法,您可以使用 require
和 module.exports
方法。
require
同步获取来自另一个模块的导出内容。
require(dependency: string);
require.resolve
同步获取模块的 ID。建议将其视为不透明值,只能与 require.cache[id]
或 __webpack_require__(id)
一起使用(最好避免这种用法)。
require.resolve(dependency: string);
警告
模块 ID 的类型可以是数字或字符串,具体取决于 optimization.moduleIds
配置。
require.cache
对同一模块的多次 require
操作只会执行一次模块,并且只会导出一次。因此,运行时存在一个缓存。从该缓存中删除值会导致执行新模块并导出新的内容。
var d1 = require('dependency');
require('dependency') === d1;
delete require.cache[require.resolve('dependency')];
require('dependency') !== d1;
require.context
Rspack/Webpack 特定
require.context
是 webpack 特有的一个函数,允许您动态地 require
一组模块。
您可以在代码中使用 require.context
,Rspack 会在构建过程中解析并引用匹配的模块。
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
的唯一方法。这意味着,此代码可以在执行期间运行,只有在满足特定条件时才会加载依赖项。
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 支持使用 import
和 require
语法导入数据 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 结合以在运行时动态加载自定义模块。