Skip to content

Commit 548c70b

Browse files
authored
Support mixing static and dynamic RSCs (#10093)
1 parent 1e6f4b3 commit 548c70b

File tree

60 files changed

+634
-275
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+634
-275
lines changed

packages/bundlers/default/src/DefaultBundler.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1856,7 +1856,9 @@ function getEntryByTarget(
18561856
context.value.isEntry &&
18571857
context.value.target != null,
18581858
);
1859-
targets.get(context.value.target.distDir).set(node.value, context.value);
1859+
targets
1860+
.get(context.value.target.loc?.filePath ?? context.value.target.distDir)
1861+
.set(node.value, context.value);
18601862
actions.skipChildren();
18611863
return node;
18621864
},

packages/configs/default/index.json

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"@parcel/transformer-worklet",
99
"..."
1010
],
11+
"react-static:*": ["@parcel/transformer-react-static", "..."],
1112
"*.mdx": [
1213
// For backward compatibility, include the old transformer
1314
// so it is used if already installed in the project.
@@ -69,6 +70,7 @@
6970
"*.{jpg,jpeg,png}": ["@parcel/optimizer-image"]
7071
},
7172
"packagers": {
73+
"react-static:*.html": "@parcel/packager-react-static",
7274
"*.{html,xhtml}": "@parcel/packager-html",
7375
"*.css": "@parcel/packager-css",
7476
"*.{js,mjs,cjs}": "@parcel/packager-js",

packages/configs/default/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"parcelDependencies": {
5555
"@parcel/optimizer-data-url": "2.13.3",
5656
"@parcel/packager-raw-url": "2.13.3",
57+
"@parcel/packager-react-static": "2.13.3",
5758
"@parcel/packager-ts": "2.13.3",
5859
"@parcel/packager-xml": "2.13.3",
5960
"@parcel/transformer-coffeescript": "2.13.3",
@@ -64,6 +65,7 @@
6465
"@parcel/transformer-jsonld": "2.13.3",
6566
"@parcel/transformer-less": "2.13.3",
6667
"@parcel/transformer-pug": "2.13.3",
68+
"@parcel/transformer-react-static": "2.13.3",
6769
"@parcel/transformer-sass": "2.13.3",
6870
"@parcel/transformer-stylus": "2.13.3",
6971
"@parcel/transformer-sugarss": "2.13.3",

packages/configs/react-static/index.json

-7
This file was deleted.

packages/configs/react-static/package.json

-21
This file was deleted.

packages/core/core/src/PackagerRunner.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ export default class PackagerRunner {
203203
bundleConfigs: Map<string, Config>,
204204
): Promise<void> {
205205
let name = nullthrows(bundle.name);
206-
let plugin = await this.config.getPackager(name);
206+
let plugin = await this.config.getPackager(name, bundle.pipeline);
207207
await this.loadPluginConfig(
208208
bundleGraph,
209209
bundle,
@@ -405,7 +405,10 @@ export default class PackagerRunner {
405405
bundle,
406406
});
407407

408-
let packager = await this.config.getPackager(bundle.name);
408+
let packager = await this.config.getPackager(
409+
bundle.name,
410+
internalBundle.pipeline,
411+
);
409412
let {name, resolveFrom, plugin} = packager;
410413
let measurement;
411414
try {
@@ -691,8 +694,8 @@ export default class PackagerRunner {
691694

692695
async getDevDepHashes(bundle: InternalBundle): Promise<string> {
693696
let name = nullthrows(bundle.name);
694-
let packager = await this.config.getPackager(name);
695-
let optimizers = await this.config.getOptimizers(name);
697+
let packager = await this.config.getPackager(name, bundle.pipeline);
698+
let optimizers = await this.config.getOptimizers(name, bundle.pipeline);
696699

697700
let key = `${packager.name}:${fromProjectPathRelative(
698701
packager.resolveFrom,

packages/core/core/src/ParcelConfig.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,21 @@ export default class ParcelConfig {
259259

260260
async getPackager(
261261
filePath: FilePath,
262+
pipeline: ?string,
262263
): Promise<LoadedPlugin<Packager<mixed, mixed>>> {
264+
// If a pipeline is specified, but it doesn't exist in the optimizers config, ignore it.
265+
// Pipelines for bundles come from their entry assets, so the pipeline likely exists in transformers.
266+
if (pipeline) {
267+
let prefix = pipeline + ':';
268+
if (!Object.keys(this.packagers).some(glob => glob.startsWith(prefix))) {
269+
pipeline = null;
270+
}
271+
}
272+
263273
let packager = this.matchGlobMap(
264274
toProjectPathUnsafe(filePath),
265275
this.packagers,
276+
pipeline,
266277
);
267278
if (!packager) {
268279
throw await this.missingPluginError(
@@ -363,9 +374,13 @@ export default class ParcelConfig {
363374
);
364375
}
365376

366-
matchGlobMap<T>(filePath: ProjectPath, globMap: {|[Glob]: T|}): ?T {
377+
matchGlobMap<T>(
378+
filePath: ProjectPath,
379+
globMap: {|[Glob]: T|},
380+
pipeline?: ?string,
381+
): ?T {
367382
for (let pattern in globMap) {
368-
if (this.isGlobMatch(filePath, pattern)) {
383+
if (this.isGlobMatch(filePath, pattern, pipeline)) {
369384
return globMap[pattern];
370385
}
371386
}

packages/core/core/src/requests/TargetRequest.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,11 @@ export class TargetResolver {
329329
}
330330

331331
let serve = this.options.serveOptions;
332-
if (serve && targets.length > 0) {
332+
if (
333+
serve &&
334+
targets.length > 0 &&
335+
targets.every(t => BROWSER_ENVS.has(t.env.context))
336+
) {
333337
// In serve mode, we only support a single browser target. If the user
334338
// provided more than one, or the matching target is not a browser, throw.
335339
if (targets.length > 1) {
@@ -357,7 +361,10 @@ export class TargetResolver {
357361

358362
// Explicit targets were not provided. Either use a modern target for server
359363
// mode, or simply use the package.json targets.
360-
if (this.options.serveOptions) {
364+
if (
365+
this.options.serveOptions &&
366+
targets.every(t => BROWSER_ENVS.has(t.env.context))
367+
) {
361368
// In serve mode, we only support a single browser target. Since the user
362369
// hasn't specified a target, use one targeting modern browsers for development
363370
let distDir = toProjectPath(

packages/core/core/test/TargetRequest.test.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,9 @@ describe('TargetResolver', () => {
12411241
});
12421242

12431243
assert.deepEqual(
1244-
await targetResolver.resolve(COMMON_TARGETS_FIXTURE_PATH),
1244+
await targetResolver.resolve(
1245+
path.join(__dirname, 'fixtures/default-serve'),
1246+
),
12451247
[
12461248
{
12471249
name: 'default',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"foo": "dist/foo/index.js",
3+
"bar": "dist/browser/index.js",
4+
"engines": {
5+
"node": ">= 8.0.0"
6+
},
7+
"targets": {
8+
"foo": {
9+
"engines": {
10+
"browsers": ["last 1 version"]
11+
},
12+
"sourceMap": {
13+
"inlineSources": true
14+
}
15+
},
16+
"bar": {
17+
"engines": {
18+
"browsers": ["last 1 version"]
19+
},
20+
"publicUrl": "/assets"
21+
}
22+
}
23+
}

packages/core/integration-tests/test/contentHashing.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('content hashing', function () {
3333
'utf8',
3434
);
3535
let filename = html.match(
36-
/<link rel="stylesheet" href="[/\\]{1}(index\.[a-f0-9]+\.css)">/,
36+
/<link rel="stylesheet" href="[/\\]{1}(input\.[a-f0-9]+\.css)">/,
3737
)[1];
3838
assert(await outputFS.exists(path.join(distDir, filename)));
3939

@@ -45,7 +45,7 @@ describe('content hashing', function () {
4545

4646
html = await outputFS.readFile(path.join(distDir, 'index.html'), 'utf8');
4747
let newFilename = html.match(
48-
/<link rel="stylesheet" href="[/\\]{1}(index\.[a-f0-9]+\.css)">/,
48+
/<link rel="stylesheet" href="[/\\]{1}(input\.[a-f0-9]+\.css)">/,
4949
)[1];
5050
assert(await outputFS.exists(path.join(distDir, newFilename)));
5151

@@ -89,11 +89,11 @@ describe('content hashing', function () {
8989

9090
it('should generate the same hash for the same distDir inside separate projects', async () => {
9191
let a = await _bundle(
92-
path.join(__dirname, 'integration/hash-distDir/a/index.html'),
92+
path.join(__dirname, 'integration/hash-distDir/a/entry.html'),
9393
{sourceMaps: true},
9494
);
9595
let b = await _bundle(
96-
path.join(__dirname, 'integration/hash-distDir/b/index.html'),
96+
path.join(__dirname, 'integration/hash-distDir/b/entry.html'),
9797
{sourceMaps: true},
9898
);
9999

@@ -105,7 +105,7 @@ describe('content hashing', function () {
105105

106106
let aJS = aBundles.find(bundle => bundle.type === 'js');
107107
let bJS = bBundles.find(bundle => bundle.type === 'js');
108-
assert(/index\.[a-f0-9]*\.js/.test(path.basename(aJS.filePath)));
108+
assert(/entry\.[a-f0-9]*\.js/.test(path.basename(aJS.filePath)));
109109
assert.equal(aJS.name, bJS.name);
110110
});
111111
});

packages/core/integration-tests/test/html.js

+9-10
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,9 @@ describe('html', function () {
373373
'utf8',
374374
);
375375
assert(
376-
/<link rel="stylesheet" href="[/\\]{1}index\.[a-f0-9]+\.css">/.test(html),
376+
/<link rel="stylesheet" href="[/\\]{1}html-css\.[a-f0-9]+\.css">/.test(
377+
html,
378+
),
377379
);
378380
});
379381

@@ -402,7 +404,7 @@ describe('html', function () {
402404
'utf8',
403405
);
404406
assert(
405-
/<html>\s*<link rel="stylesheet" href="[/\\]{1}index\.[a-f0-9]+\.css">\s*<body>/.test(
407+
/<html>\s*<link rel="stylesheet" href="[/\\]{1}html-css-head\.[a-f0-9]+\.css">\s*<body>/.test(
406408
html,
407409
),
408410
);
@@ -502,7 +504,7 @@ describe('html', function () {
502504
);
503505

504506
assert(
505-
/^<link rel="stylesheet" href="[/\\]index\.[a-f0-9]+\.css">\s*<script type="module" src="[/\\]index\.[a-f0-9]+\.js"><\/script>\s*<h1>Hello/m.test(
507+
/^<link rel="stylesheet" href="[/\\]html-css-optional-elements\.[a-f0-9]+\.css">\s*<script type="module" src="[/\\]html-css-optional-elements\.[a-f0-9]+\.js"><\/script>\s*<h1>Hello/m.test(
506508
html,
507509
),
508510
);
@@ -539,14 +541,15 @@ describe('html', function () {
539541

540542
assert.equal(
541543
html.match(
542-
/<link rel="stylesheet" href="[/\\]{1}index\.[a-f0-9]+?\.css">/g,
544+
/<link rel="stylesheet" href="[/\\]{1}html-css-multi\.[a-f0-9]+?\.css">/g,
543545
).length,
544546
1,
545547
);
546548

547549
assert.equal(
548-
html.match(/<script type="module" src="[/\\]{1}index\.[a-f0-9]+?\.js">/g)
549-
.length,
550+
html.match(
551+
/<script type="module" src="[/\\]{1}html-css-multi\.[a-f0-9]+?\.js">/g,
552+
).length,
550553
2,
551554
);
552555
});
@@ -2141,10 +2144,6 @@ describe('html', function () {
21412144
type: 'js',
21422145
assets: ['esmodule-helpers.js', 'shared.js'],
21432146
},
2144-
{
2145-
type: 'js',
2146-
assets: ['esmodule-helpers.js', 'shared.js'],
2147-
},
21482147
{
21492148
name: 'index.html',
21502149
type: 'html',

packages/core/integration-tests/test/output-formats.js

+7-5
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ describe('output formats', function () {
10071007
'utf8',
10081008
);
10091009

1010-
assert(html.includes('<script type="module" src="/index'));
1010+
assert(html.includes('<script type="module" src="/esm-browser'));
10111011

10121012
let entry = await outputFS.readFile(
10131013
b
@@ -1049,7 +1049,7 @@ describe('output formats', function () {
10491049
'utf8',
10501050
);
10511051

1052-
assert(html.includes('<script type="module" src="/index'));
1052+
assert(html.includes('<script type="module" src="/esm-browser'));
10531053

10541054
let entry = await outputFS.readFile(
10551055
b
@@ -1081,8 +1081,8 @@ describe('output formats', function () {
10811081
'utf8',
10821082
);
10831083

1084-
assert(html.includes('<script type="module" src="/index'));
1085-
assert(html.includes('<link rel="stylesheet" href="/index'));
1084+
assert(html.includes('<script type="module" src="/esm-browser-css'));
1085+
assert(html.includes('<link rel="stylesheet" href="/esm-browser-css'));
10861086

10871087
let entry = await outputFS.readFile(
10881088
b
@@ -1137,7 +1137,9 @@ describe('output formats', function () {
11371137
'utf8',
11381138
);
11391139

1140-
assert(html.includes('<script type="module" src="/index'));
1140+
assert(
1141+
html.includes('<script type="module" src="/esm-browser-split-bundle'),
1142+
);
11411143
assert(html.includes('<script type="importmap"'));
11421144

11431145
let bundles = b.getBundles();

0 commit comments

Comments
 (0)