Skip to content

Commit 58a1afd

Browse files
authored
feat: improve support rsc with rspack (#6931)
1 parent a649794 commit 58a1afd

File tree

8 files changed

+243
-304
lines changed

8 files changed

+243
-304
lines changed

.changeset/early-drinks-repeat.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@modern-js/uni-builder': patch
3+
---
4+
5+
feat: improve support rsc with rspack
6+
feat: 完善 rspack 下对 rsc 的支持

.changeset/two-guests-argue.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@modern-js/runtime': patch
3+
'@modern-js/runtime-utils': patch
4+
---
5+
6+
feat: Add response APIs to support setting response headers, status codes, and redirects
7+
feat: 添加一些响应的 API,可以设置响应头,状态码,及重定向

packages/cli/uni-builder/src/shared/rsc/plugins/rsc-server-plugin.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import type Webpack from 'webpack';
2-
import {
3-
type Compilation,
4-
Module,
5-
type ModuleGraph,
6-
NormalModule,
7-
} from 'webpack';
2+
import { type Compilation, NormalModule } from 'webpack';
83
import {
94
type ServerManifest,
105
type ServerReferencesMap,

packages/cli/uni-builder/src/shared/rsc/plugins/rspack-rsc-client-plugin.ts

+20-21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
/**
2-
* The plugin is developing, ignore it now
3-
*/
41
import path from 'path';
52
import type Webpack from 'webpack';
63
import type { Module } from 'webpack';
@@ -38,11 +35,9 @@ export class RspackRscClientPlugin {
3835
apply(compiler: Webpack.Compiler): void {
3936
const {
4037
EntryPlugin,
41-
// AsyncDependenciesBlock,
4238
RuntimeGlobals,
4339
RuntimeModule,
4440
WebpackError,
45-
// dependencies: { ModuleDependency, NullDependency },
4641
sources: { RawSource },
4742
} = compiler.webpack;
4843

@@ -52,20 +47,10 @@ export class RspackRscClientPlugin {
5247
styles: [],
5348
};
5449

55-
// class ClientReferenceDependency extends ModuleDependency {
56-
// override get type(): string {
57-
// return `client-reference`;
58-
// }
59-
// }
60-
6150
const getEntryModule = (compilation: Webpack.Compilation): Module[] => {
6251
const entryModules: Webpack.Module[] = [];
6352

6453
for (const [, entryValue] of compilation.entries.entries()) {
65-
// const entryDependency = entryValue.dependencies.find(
66-
// dependency => dependency.constructor.name === `EntryDependency`,
67-
// );
68-
6954
const entryDependency = entryValue.dependencies[0];
7055

7156
if (!entryDependency) {
@@ -100,16 +85,18 @@ export class RspackRscClientPlugin {
10085
) => {
10186
const promises = [];
10287
[...this.clientReferencesMap.keys()].forEach((resourcePath, index) => {
103-
const dependency = EntryPlugin.createDependency(resourcePath, {
104-
name: resourcePath,
105-
});
10688
const entries = compilation.entries.entries();
10789

10890
for (const [entryName, entry] of entries) {
91+
const runtimeName = entry.options.runtime || entryName;
10992
if (hasExtension(entryName)) {
11093
continue;
11194
}
11295

96+
const dependency = EntryPlugin.createDependency(resourcePath, {
97+
name: resourcePath,
98+
});
99+
113100
promises.push(
114101
new Promise((resolve, reject) => {
115102
compilation.addInclude(
@@ -122,6 +109,9 @@ export class RspackRscClientPlugin {
122109
if (error) {
123110
reject(error);
124111
} else {
112+
compilation.moduleGraph
113+
.getExportsInfo(module!)
114+
.setUsedInUnknownWay(runtimeName);
125115
this.dependencies.push(dependency);
126116
resolve(undefined);
127117
}
@@ -147,6 +137,9 @@ export class RspackRscClientPlugin {
147137
if (error) {
148138
reject(error);
149139
} else {
140+
compilation.moduleGraph
141+
.getExportsInfo(module!)
142+
.setUsedInUnknownWay(undefined);
150143
this.dependencies.push(dependency);
151144
resolve(undefined);
152145
}
@@ -226,9 +219,15 @@ export class RspackRscClientPlugin {
226219

227220
compilation.hooks.processAssets.tap(RspackRscClientPlugin.name, () => {
228221
const clientManifest: ClientManifest = {};
229-
const { chunkGraph, moduleGraph, modules } = compilation;
230-
231-
for (const module of modules) {
222+
const { chunkGraph, moduleGraph } = compilation;
223+
224+
// use dependencies, not modules
225+
// so that the bundler can get the moduleId if the dependency points to a different module when optimizing like concat modules.
226+
for (const dependency of this.dependencies) {
227+
const module = moduleGraph.getModule(dependency);
228+
if (!module) {
229+
continue;
230+
}
232231
const resourcePath = module.nameForCondition();
233232

234233
const clientReferences = resourcePath

packages/cli/uni-builder/src/shared/rsc/plugins/rspack-rsc-server-plugin.ts

+37-54
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
/**
2-
* The plugin is developing, ignore it now
3-
*/
41
import type Webpack from 'webpack';
52
import type { Compilation, ModuleGraph, NormalModule } from 'webpack';
63
import {
@@ -25,13 +22,12 @@ export interface ModuleExportsInfo {
2522
readonly exportName: string;
2623
}
2724

28-
const resourcePath2Entries = new Map<
29-
string,
30-
{
31-
entryName: string;
32-
entryPath: string;
33-
}[]
34-
>();
25+
export interface EntryInfo {
26+
readonly entryName: string;
27+
readonly entryPath: string;
28+
}
29+
30+
const resourcePath2Entries = new Map<string, EntryInfo[]>();
3531
export class RscServerPlugin {
3632
private clientReferencesMap: ClientReferencesMap = new Map();
3733
private serverReferencesMap: ServerReferencesMap = new Map();
@@ -41,29 +37,47 @@ export class RscServerPlugin {
4137
private styles: Set<string>;
4238
constructor(options: RscServerPluginOptions) {
4339
this.styles = new Set();
44-
4540
this.serverManifestFilename =
4641
options?.serverManifestFilename || `react-server-manifest.json`;
47-
4842
this.entryPath2Name = options?.entryPath2Name || new Map();
4943
}
5044

45+
private isValidModule(module: NormalModule): boolean {
46+
return Boolean(module?.resource);
47+
}
48+
49+
private hasValidEntries(
50+
entries: EntryInfo[] | undefined,
51+
): entries is EntryInfo[] {
52+
return Boolean(entries && entries.length > 0);
53+
}
54+
55+
private getEntryNameFromIssuer(issuer: NormalModule): string | undefined {
56+
return issuer.resource
57+
? this.entryPath2Name.get(issuer.resource)
58+
: undefined;
59+
}
60+
61+
private createEntryFromIssuer(
62+
issuer: NormalModule,
63+
entryName: string,
64+
): EntryInfo {
65+
return { entryName, entryPath: issuer.resource };
66+
}
67+
5168
private findModuleEntries(
5269
module: NormalModule,
5370
compilation: Compilation,
54-
resourcePath2Entries: Map<
55-
string,
56-
Array<{ entryName: string; entryPath: string }>
57-
>,
71+
resourcePath2Entries: Map<string, EntryInfo[]>,
5872
visited = new Set<string>(),
59-
): Array<{ entryName: string; entryPath: string }> {
60-
if (!module?.resource || visited.has(module.resource)) {
73+
): EntryInfo[] {
74+
if (!this.isValidModule(module) || visited.has(module.resource)) {
6175
return [];
6276
}
6377
visited.add(module.resource);
6478

6579
const currentEntries = resourcePath2Entries.get(module.resource);
66-
if (currentEntries && currentEntries?.length > 0) {
80+
if (this.hasValidEntries(currentEntries)) {
6781
return currentEntries;
6882
}
6983

@@ -78,15 +92,13 @@ export class RscServerPlugin {
7892
resourcePath2Entries,
7993
visited,
8094
);
81-
if (issuerEntries.length > 0) {
95+
if (this.hasValidEntries(issuerEntries)) {
8296
return issuerEntries;
8397
}
8498

85-
if (issuer.resource) {
86-
const entryName = this.entryPath2Name.get(issuer.resource);
87-
if (entryName) {
88-
return [{ entryName, entryPath: issuer.resource }];
89-
}
99+
const entryName = this.getEntryNameFromIssuer(issuer);
100+
if (entryName) {
101+
return [this.createEntryFromIssuer(issuer, entryName)];
90102
}
91103

92104
return [];
@@ -96,38 +108,9 @@ export class RscServerPlugin {
96108
const {
97109
EntryPlugin,
98110
WebpackError,
99-
// dependencies: { NullDependency },
100-
// util: {
101-
// runtime: { getEntryRuntime },
102-
// },
103111
sources: { RawSource },
104-
// RuntimeGlobals,
105112
} = compiler.webpack;
106113

107-
// class ServerReferenceDependency extends NullDependency {
108-
// override get type(): string {
109-
// return `server-reference`;
110-
// }
111-
// }
112-
113-
// ServerReferenceDependency.Template = class ServerReferenceDependencyTemplate extends (
114-
// NullDependency.Template
115-
// ) {
116-
// override apply(
117-
// _dependency: ServerReferenceDependency,
118-
// _source: Webpack.sources.ReplaceSource,
119-
// { runtimeRequirements }: { runtimeRequirements: Set<string> },
120-
// ) {
121-
// runtimeRequirements.add(RuntimeGlobals.moduleId);
122-
// }
123-
// };
124-
125-
// function hasServerReferenceDependency(module: Webpack.Module): boolean {
126-
// return module.dependencies.some(
127-
// dependency => dependency instanceof ServerReferenceDependency,
128-
// );
129-
// }
130-
131114
const includeModule = async (
132115
compilation: Webpack.Compilation,
133116
resource: string,

0 commit comments

Comments
 (0)