本节内容派生于以下链接指向的内容 ,并遵守 CC BY 4.0 许可证的规定。
以下内容如果没有特殊声明,可以认为都是基于原内容的修改和删减后的结果。
当使用 Rspack 打包应用程序时,你可以选择多种模块语法风格,包括 ES modules 和 CommonJS。
尽管 Rspack 支持多种模块语法,但我们还是建议尽量使用一致的语法,以此避免一些奇怪的行为和 bug。
事实上,当距离最近的 package.json
文件中 "type" 字段值为 "module"
或 "commonjs"
时,Rspack 会对 .mjs
文件、.cjs
文件或.js
文件进行对应的处理:
.mjs
,或者 package.json
中 "type": "module"
且后缀为 .js
时:
require
,module.exports
或 exports
import './src/App.mjs'
,而非 import './src/App'
.cjs
,或者 package.json
中 "type": "commonjs"
且后缀为 .js
时:
import
和 export
Rspack 原生支持 ES modules 语法,可以使用静态的 import
、export
和 import()
语法。
如果使用其他的 ES6+ 特性,你仍然需要引入 SWC 或 Babel 进行转换。
静态 import
另一个模块的 export
。
你还可以 import
Data URI:
将任何内容作为默认导出或具名导出。
动态加载模块,参考 Dynamic import 了解更多。
对 import()
的调用被视为分割点,这意味着请求的模块及其子模块被拆分成单独的 chunk。
此功能内部依赖于 Promise
。如果你在旧版浏览器中使用 import()
,请记得使用类似于 core-js, es6-promise 或 promise-polyfill 的 polyfill 来模拟 Promise
。
import()
无法使用完全动态的导入语句,例如 import(foo)
。因为 foo
可能是系统或项目中任何文件的任何路径。
import()
必须至少包含一些关于模块所在位置的信息。可以将打包限制在特定目录或一组文件中,这样当你使用动态表达式时,在 import()
调用中可能被请求的每个模块都会被包括进来。
例如,import(./locale/${language}.json)
会将 ./locale
目录中的每个 .json
文件都被打包进新的代码块。在运行时,一旦变量 language
被计算出来,任何像 english.json
或 german.json
这样的文件都将可供使用。
通过向 import 语句添加注释,我们可以实现「指定 chunk 名称」或「设置加载模式」等操作。有关这些魔法注释的完整列表,请参见下面的代码,以及对这些注释功能的解释。
boolean
设置为 true 时,禁用动态导入解析。
当 webpackIgnore 为 true 时,不会将代码分离成为独立的 chunk。
"eager" | "lazy" | "weak" | "lazy-once"
'lazy'
可以指定以不同的模式解析动态导入。支持以下选项:
'lazy'
(默认值):为每个 import()
导入的模块生成一个可延迟加载(lazy-loadable)的 chunk。'lazy-once'
:生成一个可以满足所有 import()
调用的单个可延迟加载(lazy-loadable)的 chunk。此 chunk 将在第一次 import()
时调用时获取,随后的 import()
则使用相同的网络响应。注意,这种模式仅在部分动态语句中有意义,例如 import("./locales/${language}.json")
,其中可能含有多个被请求的模块路径。'eager'
:不会生成额外的 chunk。所有的模块都被当前的 chunk 引入,并且没有额外的网络请求。但是仍会返回一个 resolved 状态的 Promise。与静态导入相比,在调用 import()
完成之前,该模块不会被执行。'weak'
:尝试加载模块,如果该模块函数已经以其他方式加载,(即另一个 chunk 导入过此模块,或包含模块的脚本被加载)。仍会返回 Promise, 但是只有在客户端上已经有该 chunk 时才会成功解析。如果该模块不可用,则返回 rejected 状态的 Promise,且网络请求永远都不会执行。当需要的 chunks 始终在(嵌入在页面中的)初始请求中手动提供,而不是在应用程序导航在最初没有提供的模块导入的情况下触发,这对于通用渲染(SSR)是非常有用的。number
: 预取优先级boolean
: false
表示不预取, true
表示预取并且优先级是 0
告诉浏览器将来可能需要该资源来进行某些导航跳转,详情请查看预取/预载模块。
number
: 预载优先级boolean
: false
表示不预载, true
表示预载并且优先级是 0
告诉浏览器在当前导航期间可能需要该资源,详情请查看预取/预载模块。
string
指定新 chunk 的名称。
"low" | "high" | "auto"
为指定的动态导入设置 fetchPriority
。也可以通过使用 module.parser.javascript.dynamicImportFetchPriority
选项为所有动态导入设置全局默认值。
Regexp
在导入解析时匹配的正则表达式。只有匹配的模块才会被打包。
Regexp
在导入解析时匹配的正则表达式。只有匹配的模块不会被打包。
请注意,webpackInclude
和 webpackExclude
选项不会影响前缀。例如:./locale
。
string | string[]
使 Rspack 在处理该动态 import()
模块时仅打包指定的导出。这样可以降低 chunk 的产物体积。
Rspack 也支持 CommonJS
语法,可以使用 require
和 module.exports
语法。
以同步的方式引入其他模块。
以同步的方式获取模块的 ID。可视为只能与 require.cache[id] 或 webpack_require(id) 配合使用(最好避免这种用法)。
模块 ID 的类型可以是 number
或 string
,具体取决于 optimization.moduleIds
配置。
多处引用同一模块,最终只会产生一次模块执行和一次导出。所以,会在运行时(runtime)中会保存一份缓存。删除此缓存,则会产生新的模块执行和新的导出。
require.context
允许你动态地 require 一组模块。
你可以在代码中使用 require.context
,Rspack 将在构建时进行解析并引用匹配的模块。
require.context
的返回值与 import.meta.webpackContext 相同,我们推荐使用 import.meta.webpackContext
,它的功能更加强大。
Rspack 在编译时,会通过静态分析来解析 require.context
的参数,因此参数必须是字面量。
例如,filter
的值不允许传入一个变量,也不允许传入 new RegExp()
生成的值,只能是一个正则表达式字面量。
require.ensure()
基本已经被 import()
取代.
将给定 dependencies
单独打包,并异步加载。当使用 CommonJS 语法的时候,这是唯一动态加载依赖的方式。同时,这个 API 也可以用于运行时,只有在满足某些条件时才会加载依赖。
该特性内部依赖于 Promise。 如果你在旧的浏览器上使用 require.ensure
, 最好加入 polyfill es6-promise 或 promise-polyfill。
Rspack 支持使用 import
和 require
语法导入 Data URI 模块。
import
require
除此之外,还支持了 Base64 编码:
Data URI 模块可以被用作虚拟模块(Virtual Modules)的实现方式,如:配合 loader 完成运行时动态加载自定义模块。