Skip to content

Commit 2b7b90f

Browse files
authored
fix(rsc): keep server stylesheet link for hmr and avoid injecting css via client js (#841)
1 parent eab0a16 commit 2b7b90f

File tree

3 files changed

+24
-47
lines changed

3 files changed

+24
-47
lines changed

packages/plugin-rsc/e2e/basic.test.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -733,16 +733,26 @@ function defineTest(f: Fixture) {
733733
})
734734

735735
async function expectNoDuplicateServerCss(page: Page) {
736-
// check only manually inserted stylesheet link exists
737-
await expect(page.locator('link[rel="stylesheet"]')).toHaveCount(3)
738-
for (const locator of await page
739-
.locator('link[rel="stylesheet"]')
740-
.all()) {
741-
await expect(locator).toHaveAttribute(
742-
'data-precedence',
743-
'test-style-manual-link',
744-
)
745-
}
736+
// verify duplicate client-reference style link are removed
737+
await expect(
738+
page.locator(
739+
'link[rel="stylesheet"][data-precedence="vite-rsc/client-reference"]',
740+
),
741+
).toHaveCount(0)
742+
await expect(
743+
page
744+
.locator(
745+
'link[rel="stylesheet"][data-precedence="vite-rsc/importer-resources"]',
746+
)
747+
.nth(0),
748+
).toBeAttached()
749+
await expect(
750+
page
751+
.locator(
752+
'link[rel="stylesheet"][data-precedence="test-style-manual-link"]',
753+
)
754+
.nth(0),
755+
).toBeAttached()
746756
}
747757

748758
test('no duplicate server css', async ({ page }) => {

packages/plugin-rsc/src/plugin.ts

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ window.__vite_plugin_react_preamble_installed__ = true;
10131013
const ssrCss = document.querySelectorAll("link[rel='stylesheet']");
10141014
import.meta.hot.on("vite:beforeUpdate", () => {
10151015
ssrCss.forEach(node => {
1016-
if (node.dataset.precedence?.startsWith("vite-rsc/")) {
1016+
if (node.dataset.precedence?.startsWith("vite-rsc/client-references")) {
10171017
node.remove();
10181018
}
10191019
});
@@ -2103,13 +2103,7 @@ function vitePluginRscCss(
21032103
if (this.environment.mode === 'dev') {
21042104
const result = collectCss(server.environments.rsc!, importer)
21052105
const cssHrefs = result.hrefs.map((href) => href.slice(1))
2106-
const jsHrefs = [
2107-
`@id/__x00__${toCssVirtual({ id: importer, type: 'rsc-browser' })}`,
2108-
]
2109-
const deps = assetsURLOfDeps(
2110-
{ css: cssHrefs, js: jsHrefs },
2111-
manager,
2112-
)
2106+
const deps = assetsURLOfDeps({ css: cssHrefs, js: [] }, manager)
21132107
return generateResourcesCode(
21142108
serializeValueWithRuntime(deps),
21152109
manager,
@@ -2128,20 +2122,6 @@ function vitePluginRscCss(
21282122
`
21292123
}
21302124
}
2131-
if (parsed?.type === 'rsc-browser') {
2132-
assert(this.environment.name === 'client')
2133-
assert(this.environment.mode === 'dev')
2134-
const importer = parsed.id
2135-
const result = collectCss(server.environments.rsc!, importer)
2136-
let code = result.ids
2137-
.map((id) => id.replace(/^\0/, ''))
2138-
.map((id) => `import ${JSON.stringify(id)};\n`)
2139-
.join('')
2140-
// ensure hmr boundary at this virtual since otherwise non-self accepting css
2141-
// (e.g. css module) causes full reload
2142-
code += `if (import.meta.hot) { import.meta.hot.accept() }\n`
2143-
return code
2144-
}
21452125
},
21462126
hotUpdate(ctx) {
21472127
if (this.environment.name === 'rsc') {
@@ -2153,10 +2133,6 @@ function vitePluginRscCss(
21532133
server.environments.rsc!,
21542134
`\0` + toCssVirtual({ id: mod.id, type: 'rsc' }),
21552135
)
2156-
invalidteModuleById(
2157-
server.environments.client,
2158-
`\0` + toCssVirtual({ id: mod.id, type: 'rsc-browser' }),
2159-
)
21602136
}
21612137
}
21622138
}
@@ -2174,7 +2150,7 @@ function vitePluginRscCss(
21742150
.forEach((node) => {
21752151
if (
21762152
node instanceof HTMLElement &&
2177-
node.dataset.precedence?.startsWith('vite-rsc/')
2153+
node.dataset.precedence?.startsWith('vite-rsc/client-reference')
21782154
) {
21792155
node.remove()
21802156
}
@@ -2234,15 +2210,6 @@ function generateResourcesCode(depsCode: string, manager: RscPluginManager) {
22342210
href: href,
22352211
}),
22362212
),
2237-
// js is only for dev to forward css import on browser to have hmr
2238-
...deps.js.map((href: string) =>
2239-
React.createElement('script', {
2240-
key: 'js:' + href,
2241-
type: 'module',
2242-
async: true,
2243-
src: href,
2244-
}),
2245-
),
22462213
RemoveDuplicateServerCss &&
22472214
React.createElement(RemoveDuplicateServerCss, {
22482215
key: 'remove-duplicate-css',

packages/plugin-rsc/src/plugins/shared.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
type CssVirtual = {
22
id: string
3-
type: 'ssr' | 'rsc' | 'rsc-browser'
3+
type: 'ssr' | 'rsc'
44
}
55

66
export function toCssVirtual({ id, type }: CssVirtual) {

0 commit comments

Comments
 (0)