Skip to content

Commit 8477ca6

Browse files
authored
feat: add EnableChunkLoadingPlugin.{setEnabled,checkEnabled} (#9092)
1 parent b7688cc commit 8477ca6

File tree

14 files changed

+214
-24
lines changed

14 files changed

+214
-24
lines changed

crates/rspack/src/builder/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2730,23 +2730,23 @@ impl OutputOptionsBuilder {
27302730

27312731
let enabled_chunk_loading_types = f!(self.enabled_chunk_loading_types.take(), || {
27322732
let mut enabled_chunk_loading_types = vec![];
2733-
if let ChunkLoading::Enable(ty) = chunk_loading {
2734-
enabled_chunk_loading_types.push(ty);
2733+
if let ChunkLoading::Enable(ty) = &chunk_loading {
2734+
enabled_chunk_loading_types.push(ty.clone());
27352735
}
2736-
if let ChunkLoading::Enable(ty) = worker_chunk_loading {
2737-
enabled_chunk_loading_types.push(ty);
2736+
if let ChunkLoading::Enable(ty) = &worker_chunk_loading {
2737+
enabled_chunk_loading_types.push(ty.clone());
27382738
}
27392739
for (_, desc) in entry.iter() {
27402740
if let Some(ChunkLoading::Enable(ty)) = &desc.chunk_loading {
2741-
enabled_chunk_loading_types.push(*ty);
2741+
enabled_chunk_loading_types.push(ty.clone());
27422742
}
27432743
}
27442744
enabled_chunk_loading_types
27452745
});
27462746
for ty in enabled_chunk_loading_types.iter() {
27472747
builder_context
27482748
.plugins
2749-
.push(BuiltinPluginOptions::EnableChunkLoadingPlugin(*ty));
2749+
.push(BuiltinPluginOptions::EnableChunkLoadingPlugin(ty.clone()));
27502750
}
27512751

27522752
let enabled_wasm_loading_types = f!(self.enabled_wasm_loading_types.take(), || {

crates/rspack_binding_values/src/compilation/entries.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl EntryOptionsDTO {
5454
#[napi(getter)]
5555
pub fn chunk_loading(&self) -> Either<&str, ()> {
5656
match &self.0.chunk_loading {
57-
Some(c) => Either::A(c.into()),
57+
Some(c) => Either::A(c.as_str()),
5858
None => Either::B(()),
5959
}
6060
}

crates/rspack_core/src/options/output.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,24 +110,24 @@ impl From<ChunkLoading> for String {
110110
}
111111
}
112112

113-
impl From<&ChunkLoading> for &str {
114-
fn from(value: &ChunkLoading) -> Self {
115-
match value {
116-
ChunkLoading::Enable(ty) => ty.into(),
113+
impl ChunkLoading {
114+
pub fn as_str(&self) -> &str {
115+
match self {
116+
ChunkLoading::Enable(ty) => ty.as_str(),
117117
ChunkLoading::Disable => "false",
118118
}
119119
}
120120
}
121121

122122
#[cacheable]
123-
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
123+
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
124124
pub enum ChunkLoadingType {
125125
Jsonp,
126126
ImportScripts,
127127
Require,
128128
AsyncNode,
129129
Import,
130-
// TODO: Custom
130+
Custom(String),
131131
}
132132

133133
impl From<&str> for ChunkLoadingType {
@@ -138,25 +138,26 @@ impl From<&str> for ChunkLoadingType {
138138
"require" => Self::Require,
139139
"async-node" => Self::AsyncNode,
140140
"import" => Self::Import,
141-
_ => unimplemented!("custom chunkLoading in not supported yet"),
141+
_ => Self::Custom(value.to_string()),
142142
}
143143
}
144144
}
145145

146146
impl From<ChunkLoadingType> for String {
147147
fn from(value: ChunkLoadingType) -> Self {
148-
Into::<&str>::into(&value).to_string()
148+
value.as_str().to_string()
149149
}
150150
}
151151

152-
impl From<&ChunkLoadingType> for &str {
153-
fn from(value: &ChunkLoadingType) -> Self {
154-
match value {
152+
impl ChunkLoadingType {
153+
pub fn as_str(&self) -> &str {
154+
match self {
155155
ChunkLoadingType::Jsonp => "jsonp",
156156
ChunkLoadingType::ImportScripts => "import-scripts",
157157
ChunkLoadingType::Require => "require",
158158
ChunkLoadingType::AsyncNode => "async-node",
159159
ChunkLoadingType::Import => "import",
160+
ChunkLoadingType::Custom(value) => value.as_str(),
160161
}
161162
}
162163
}

crates/rspack_plugin_runtime/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,6 @@ pub fn enable_chunk_loading_plugin(loading_type: ChunkLoadingType, plugins: &mut
6767
plugins.push(ImportScriptsChunkLoadingPlugin::default().boxed());
6868
}
6969
ChunkLoadingType::Import => plugins.push(ModuleChunkLoadingPlugin::default().boxed()),
70+
ChunkLoadingType::Custom(_) => (),
7071
}
7172
}

packages/rspack-test-tools/tests/__snapshots__/Config.test.js.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ Object {
209209
}
210210
`;
211211
212+
exports[`config config/builtins/enable-chunk-loading step should pass 1`] = `Chunk loading type "non-existing" is not enabled. EnableChunkLoadingPlugin need to be used to enable this type of chunk loading. This usually happens through the "output.enabledChunkLoadingTypes" option. If you are using a function as entry which sets "chunkLoading", you need to add all potential chunk loading types to "output.enabledChunkLoadingTypes". These types are enabled: custom, import, async-node`;
213+
212214
exports[`config config/chunk-index/available-modules-order-index exported tests should compile 1`] = `
213215
.m {
214216
color: red;

packages/rspack-test-tools/tests/__snapshots__/NewCodeSplitting-config.test.js.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ Object {
209209
}
210210
`;
211211
212+
exports[`new-code-splitting config cases new-code-splitting config cases/builtins/enable-chunk-loading step should pass 1`] = `Chunk loading type "non-existing" is not enabled. EnableChunkLoadingPlugin need to be used to enable this type of chunk loading. This usually happens through the "output.enabledChunkLoadingTypes" option. If you are using a function as entry which sets "chunkLoading", you need to add all potential chunk loading types to "output.enabledChunkLoadingTypes". These types are enabled: custom, import, async-node`;
213+
212214
exports[`new-code-splitting config cases new-code-splitting config cases/chunk-index/available-modules-order-index exported tests should compile 1`] = `
213215
.m {
214216
color: red;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
const foo = 42;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const { rspack } = require("@rspack/core");
2+
3+
/** @type {import("@rspack/core").Configuration} */
4+
module.exports = {
5+
entry: {
6+
main: ["./index.js"]
7+
},
8+
output: {
9+
enabledChunkLoadingTypes: ["import", "async-node"]
10+
},
11+
plugins: [
12+
/** @param {import('@rspack/core').Compiler} compiler */
13+
compiler => {
14+
rspack.javascript.EnableChunkLoadingPlugin.setEnabled(compiler, "custom");
15+
16+
compiler.hooks.initialize.tap("test", () => {
17+
rspack.javascript.EnableChunkLoadingPlugin.checkEnabled(
18+
compiler,
19+
"custom"
20+
);
21+
rspack.javascript.EnableChunkLoadingPlugin.checkEnabled(
22+
compiler,
23+
"import"
24+
);
25+
rspack.javascript.EnableChunkLoadingPlugin.checkEnabled(
26+
compiler,
27+
"async-node"
28+
);
29+
expect(() =>
30+
rspack.javascript.EnableChunkLoadingPlugin.checkEnabled(
31+
compiler,
32+
"non-existing"
33+
)
34+
).toThrowErrorMatchingSnapshot();
35+
});
36+
}
37+
]
38+
};

packages/rspack/etc/core.api.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,13 +1594,23 @@ const ElectronTargetPlugin: {
15941594
};
15951595

15961596
// @public (undocumented)
1597-
const EnableChunkLoadingPlugin: {
1597+
class EnableChunkLoadingPlugin extends EnableChunkLoadingPluginInner {
1598+
// (undocumented)
1599+
apply(compiler: Compiler): void;
1600+
// (undocumented)
1601+
static checkEnabled(compiler: Compiler, type: ChunkLoadingType): void;
1602+
// (undocumented)
1603+
static setEnabled(compiler: Compiler, type: ChunkLoadingType): void;
1604+
}
1605+
1606+
// @public (undocumented)
1607+
const EnableChunkLoadingPluginInner: {
15981608
new (type: string): {
15991609
name: BuiltinPluginName;
16001610
_args: [type: string];
16011611
affectedHooks: "done" | "environment" | "make" | "compile" | "emit" | "afterEmit" | "invalid" | "thisCompilation" | "afterDone" | "compilation" | "normalModuleFactory" | "contextModuleFactory" | "initialize" | "shouldEmit" | "infrastructureLog" | "beforeRun" | "run" | "assetEmitted" | "failed" | "shutdown" | "watchRun" | "watchClose" | "afterEnvironment" | "afterPlugins" | "afterResolvers" | "beforeCompile" | "afterCompile" | "finishMake" | "entryOption" | "additionalPass" | undefined;
1602-
raw(compiler: Compiler_2): BuiltinPlugin;
1603-
apply(compiler: Compiler_2): void;
1612+
raw(compiler: Compiler): BuiltinPlugin;
1613+
apply(compiler: Compiler): void;
16041614
};
16051615
};
16061616

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,75 @@
1+
/**
2+
* The following code is modified based on
3+
* https://github.com/webpack/webpack/blob/3919c84/lib/javascript/EnableChunkLoadingPlugin.js
4+
*
5+
* MIT Licensed
6+
* Author Tobias Koppers @sokra
7+
* Copyright (c) JS Foundation and other contributors
8+
* https://github.com/webpack/webpack/blob/main/LICENSE
9+
*/
10+
111
import { BuiltinPluginName } from "@rspack/binding";
212

13+
import type { ChunkLoadingType, Compiler } from "../exports";
314
import { create } from "./base";
415

5-
export const EnableChunkLoadingPlugin = create(
16+
const EnableChunkLoadingPluginInner = create(
617
BuiltinPluginName.EnableChunkLoadingPlugin,
718
(type: string): string => type
819
);
20+
21+
const enabledTypes: WeakMap<Compiler, Set<ChunkLoadingType>> = new WeakMap();
22+
23+
const getEnabledTypes = (compiler: Compiler): Set<ChunkLoadingType> => {
24+
let set = enabledTypes.get(compiler);
25+
if (set === undefined) {
26+
set = new Set();
27+
enabledTypes.set(compiler, set);
28+
}
29+
return set;
30+
};
31+
32+
export class EnableChunkLoadingPlugin extends EnableChunkLoadingPluginInner {
33+
static setEnabled(compiler: Compiler, type: ChunkLoadingType) {
34+
getEnabledTypes(compiler).add(type);
35+
}
36+
37+
static checkEnabled(compiler: Compiler, type: ChunkLoadingType) {
38+
if (!getEnabledTypes(compiler).has(type)) {
39+
throw new Error(
40+
[
41+
`Chunk loading type "${type}" is not enabled.`,
42+
"EnableChunkLoadingPlugin need to be used to enable this type of chunk loading.",
43+
'This usually happens through the "output.enabledChunkLoadingTypes" option.',
44+
'If you are using a function as entry which sets "chunkLoading", you need to add all potential chunk loading types to "output.enabledChunkLoadingTypes".',
45+
`These types are enabled: ${Array.from(
46+
getEnabledTypes(compiler)
47+
).join(", ")}`
48+
].join(" ")
49+
);
50+
}
51+
}
52+
53+
override apply(compiler: Compiler): void {
54+
const [type] = this._args;
55+
// Only enable once
56+
const enabled = getEnabledTypes(compiler);
57+
if (enabled.has(type)) return;
58+
enabled.add(type);
59+
60+
switch (type) {
61+
// builtin chunk loading types
62+
case "jsonp":
63+
case "import-scripts":
64+
case "require":
65+
case "async-node":
66+
case "import": {
67+
super.apply(compiler);
68+
return;
69+
}
70+
default:
71+
throw new Error(`Unsupported chunk loading type ${type}.
72+
Plugins which provide custom chunk loading types must call EnableChunkLoadingPlugin.setEnabled(compiler, type) to disable this error.`);
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)