本节内容派生于以下链接指向的内容 ,并遵守 CC BY 4.0 许可证的规定。
以下内容如果没有特殊声明,可以认为都是基于原内容的修改和删减后的结果。
当使用 Rspack 打包应用程序时,你可以选择多种模块语法风格,包括 ES6、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 原生支持 ES6 模块语法,可以使用静态的 import
、export
和 import()
语法。
如果使用其他的 ES6+ 特性,仍然需要引入 SWC / Babel 进行转换。
静态 import
另一个模块的 export
。
你还可以 import
Data URI:
将任何内容作为默认导出或具名导出。
动态加载模块。对 import()
的调用被视为分割点,这意味着请求的模块及其子模块被拆分成单独的 chunk。
此功能内部依赖于 Promise
。如果你在旧版浏览器中使用 import()
,请记得使用类似于 es6-promise
或 promise-polyfill
的 polyfill 来模拟 Promise
。
无法使用完全动态的导入语句,例如 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'
(默认值):为每个 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)中会保存一份缓存。删除此缓存,则会产生新的模块执行和新的导出。
Rspack 支持使用 import
和 require
语法导入 Data URI 模块。
import
require
除此之外,还支持了 Base64 编码:
Data URI 模块可以被用作虚拟模块(Virtual Modules)的实现方式,如:配合 loader 完成运行时动态加载自定义模块。
除了上述的模块方法之外,Rspack 还支持一些 webpack 特有的方法。
require.context
是 webpack 特有的一个函数,它允许你动态地 require 一组模块。
你可以在代码中使用 require.context
,Rspack 将在构建时进行解析并引用匹配的模块。
require.context
的返回值与 import.meta.webpackContext 相同,我们推荐使用 import.meta.webpackContext
,它的功能更加强大。
Rspack 在编译时,会通过静态分析来解析 require.context
的参数,因此参数必须是字面量。
例如,filter
的值不允许传入一个变量,也不允许传入 new RegExp()
生成的值,只能是一个正则表达式字面量。