Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b213799
fix(rsc): keep server stylesheet link for hmr
hi-ogawa Sep 12, 2025
e63e354
fix: fix server css module hmr
hi-ogawa Sep 12, 2025
dc4f69e
refactor(rsc): self-accept rsc css module on client environment
hi-ogawa Sep 12, 2025
885ad2a
chore: cleanup
hi-ogawa Sep 12, 2025
2af36d5
chore: comment
hi-ogawa Sep 12, 2025
8992a2f
fix: fix css module on ssr environment
hi-ogawa Sep 12, 2025
394529a
refactor: tweak
hi-ogawa Sep 12, 2025
be3ebfc
Merge branch '09-12-refactor_rsc_self-accept_rsc_css_module_on_client…
hi-ogawa Sep 12, 2025
c61abfe
cleanup
hi-ogawa Sep 12, 2025
4d26189
test: update
hi-ogawa Sep 12, 2025
afe43ce
chore: cleanup
hi-ogawa Sep 12, 2025
19c3067
chore: cleanup
hi-ogawa Sep 12, 2025
2a49b23
Merge branch 'main' into 09-12-fix_rsc_keep_server_stylesheet_link_fo…
hi-ogawa Sep 12, 2025
979cebe
test(rsc): test adding css import works without reload
hi-ogawa Sep 13, 2025
c60f325
Merge branch 'main' into 09-13-test_rsc_test_adding_css_import_works_…
hi-ogawa Sep 13, 2025
818d7f1
test: tweak
hi-ogawa Sep 13, 2025
a0727e6
Merge remote-tracking branch 'origin/09-13-test_rsc_test_adding_css_i…
hi-ogawa Sep 13, 2025
919020c
Merge branch 'main' into 09-12-fix_rsc_keep_server_stylesheet_link_fo…
hi-ogawa Sep 13, 2025
5200b40
Merge branch '09-13-test_rsc_test_adding_css_import_works_without_rel…
hi-ogawa Sep 13, 2025
3661f8d
Merge remote-tracking branch 'origin/09-12-fix_rsc_keep_server_styles…
hi-ogawa Sep 13, 2025
559e3b2
Merge branch 'main' into 09-12-fix_rsc_keep_server_stylesheet_link_fo…
hi-ogawa Sep 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions packages/plugin-rsc/e2e/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -733,16 +733,26 @@ function defineTest(f: Fixture) {
})

async function expectNoDuplicateServerCss(page: Page) {
// check only manually inserted stylesheet link exists
await expect(page.locator('link[rel="stylesheet"]')).toHaveCount(3)
for (const locator of await page
.locator('link[rel="stylesheet"]')
.all()) {
await expect(locator).toHaveAttribute(
'data-precedence',
'test-style-manual-link',
)
}
// verify duplicate client-reference style link are removed
await expect(
page.locator(
'link[rel="stylesheet"][data-precedence="vite-rsc/client-reference"]',
),
).toHaveCount(0)
await expect(
page
.locator(
'link[rel="stylesheet"][data-precedence="vite-rsc/importer-resources"]',
)
.nth(0),
).toBeAttached()
await expect(
page
.locator(
'link[rel="stylesheet"][data-precedence="test-style-manual-link"]',
)
.nth(0),
).toBeAttached()
}

test('no duplicate server css', async ({ page }) => {
Expand Down
39 changes: 3 additions & 36 deletions packages/plugin-rsc/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@ window.__vite_plugin_react_preamble_installed__ = true;
const ssrCss = document.querySelectorAll("link[rel='stylesheet']");
import.meta.hot.on("vite:beforeUpdate", () => {
ssrCss.forEach(node => {
if (node.dataset.precedence?.startsWith("vite-rsc/")) {
if (node.dataset.precedence?.startsWith("vite-rsc/client-references")) {
node.remove();
}
});
Expand Down Expand Up @@ -2103,13 +2103,7 @@ function vitePluginRscCss(
if (this.environment.mode === 'dev') {
const result = collectCss(server.environments.rsc!, importer)
const cssHrefs = result.hrefs.map((href) => href.slice(1))
const jsHrefs = [
`@id/__x00__${toCssVirtual({ id: importer, type: 'rsc-browser' })}`,
]
const deps = assetsURLOfDeps(
{ css: cssHrefs, js: jsHrefs },
manager,
)
const deps = assetsURLOfDeps({ css: cssHrefs, js: [] }, manager)
return generateResourcesCode(
serializeValueWithRuntime(deps),
manager,
Expand All @@ -2128,20 +2122,6 @@ function vitePluginRscCss(
`
}
}
if (parsed?.type === 'rsc-browser') {
assert(this.environment.name === 'client')
assert(this.environment.mode === 'dev')
const importer = parsed.id
const result = collectCss(server.environments.rsc!, importer)
let code = result.ids
.map((id) => id.replace(/^\0/, ''))
.map((id) => `import ${JSON.stringify(id)};\n`)
.join('')
// ensure hmr boundary at this virtual since otherwise non-self accepting css
// (e.g. css module) causes full reload
code += `if (import.meta.hot) { import.meta.hot.accept() }\n`
return code
}
},
hotUpdate(ctx) {
if (this.environment.name === 'rsc') {
Expand All @@ -2153,10 +2133,6 @@ function vitePluginRscCss(
server.environments.rsc!,
`\0` + toCssVirtual({ id: mod.id, type: 'rsc' }),
)
invalidteModuleById(
server.environments.client,
`\0` + toCssVirtual({ id: mod.id, type: 'rsc-browser' }),
)
}
}
}
Expand All @@ -2174,7 +2150,7 @@ function vitePluginRscCss(
.forEach((node) => {
if (
node instanceof HTMLElement &&
node.dataset.precedence?.startsWith('vite-rsc/')
node.dataset.precedence?.startsWith('vite-rsc/client-reference')
) {
node.remove()
}
Expand Down Expand Up @@ -2234,15 +2210,6 @@ function generateResourcesCode(depsCode: string, manager: RscPluginManager) {
href: href,
}),
),
// js is only for dev to forward css import on browser to have hmr
...deps.js.map((href: string) =>
React.createElement('script', {
key: 'js:' + href,
type: 'module',
async: true,
src: href,
}),
),
RemoveDuplicateServerCss &&
React.createElement(RemoveDuplicateServerCss, {
key: 'remove-duplicate-css',
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-rsc/src/plugins/shared.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
type CssVirtual = {
id: string
type: 'ssr' | 'rsc' | 'rsc-browser'
type: 'ssr' | 'rsc'
}

export function toCssVirtual({ id, type }: CssVirtual) {
Expand Down
Loading