Dev: a stylesheet shared by the entry and a lazy component moves after the lazy component's styles
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- Medio día
- Aptitud para principiantes
- 62/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- css, javascript, typescript
- Área
- build-system, frontend
Línea de trabajo
The dedupe logic is in devStylePatch in src/dev-manifest.ts, on the line that picks ssr from o and el by data-asset. Reproduce with the issue's App/Button/Page files and check the link tags in the hydrated head. Done means .corner resolves to absolute in dev, the stylesheet order matches vite build, and editing button.css still hot-updates while the page is open.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
In start-mode dev, a stylesheet that both the entry graph and a lazy component import ends up after the lazy component's own stylesheets. Production keeps it before them. Rules of equal specificity then resolve the other way in dev: a lazy page's override of a shared component's style loses.
Versions: @solidjs/[email protected], [email protected], @solidjs/[email protected], [email protected].
Reproduction
// vite.config.ts
import { defineConfig } from 'vite';
import solid from '@solidjs/vite-plugin';
export default defineConfig({
plugins: [solid({ start: { app: 'src/App.tsx' }, ssr: true })],
});
// src/App.tsx
import { lazy, Loading } from 'solid-js';
import { Button } from './Button';
const Page = lazy(() => import('./Page'));
export default function App() {
return (
<main>
<Button>Header button</Button>
<Loading>
<Page />
</Loading>
</main>
);
}
// src/Button.tsx
import type { JSX } from 'solid-js';
import './button.css';
export function Button(props: { class?: string; children: JSX.Element }) {
return <button class={`button ${props.class ?? ''}`}>{props.children}</button>;
}
// src/Page.tsx
import { Button } from './Button';
import './page.css';
export default function Page() {
return (
<div class="panel">
<Button class="corner">Copy</Button>
</div>
);
}
/* src/button.css */
.button {
position: relative;
}
/* src/page.css */
.panel {
position: relative;
height: 200px;
border: 1px solid;
}
/* Same specificity as .button, so it wins only when page.css comes after button.css. */
.corner {
position: absolute;
top: 8px;
right: 8px;
}
Run vite, open the page, and wait for hydration. "Copy" stays in the normal flow instead of the panel's top right corner. vite build + vite preview renders it in the corner.
| style tags in the server HTML | style tags after hydration | .corner |
|
|---|---|---|---|
| dev | button.css, page.css, button.css |
page.css, button.css |
position: relative |
| build | Button-*.css, Page-*.css |
Button-*.css, Page-*.css |
position: absolute |
Cause
The dev shell carries button.css twice, both marked data-asset. The SSR runtime renders the lazy component's styles (button.css, page.css), and the handler then injects the entry graph's styles (button.css again) before </head>.
devStylePatch (src/dev-manifest.ts) dedupes the two by data-vite-dev-id. It removes o, the tag found by querySelectorAll, whenever o is data-asset:
var ssr=o.hasAttribute("data-asset")?o:el.hasAttribute("data-asset")?el:null;
When both twins are SSR'd, the observer handles the later tag as el, so o is the earlier one and it is removed. The copy that survives sits after page.css.
Suggested fix
When both twins are SSR'd, drop the later one, so the stylesheet keeps the first position the shell gave it:
var ssr=o.hasAttribute("data-asset")&&el.hasAttribute("data-asset")?(o.compareDocumentPosition(el)&4?el:o):o.hasAttribute("data-asset")?o:el.hasAttribute("data-asset")?el:null;
With that line patched into the repro's copy of the plugin, the hydrated order is button.css, page.css and .corner is absolute, as in the build. Editing button.css with the page open still hot-updates it.
Not emitting entry styles that the shell already carries would fix it as well. Moving the entry styles ahead of the lazy ones does not: in the larger app where I first saw this, the shared stylesheets still ended up after the lazy ones.
- Lenguaje dominante
- TypeScript
- Estrellas
- 522
- Forks
- 73
- Merge medio
- 1 d 8 h
- PR fusionados (30 d)
- 31
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de solidjs/solid-vite-plugin
-
Vitest config is dropped when test.server.deps.external already lists solid-jsPosiblemente ocupada @RaphaelFakhri la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
solidjs/solid-vite-plugin#454 ·
Los mantenedores suelen responder en 1 día
-
Test environment detection doesn't consider Vitest workspacesPosiblemente ocupada @carloitaben la tomó hace 58 días. Abierto1.x
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
solidjs/solid-vite-plugin#205 · 1 comentario · 2 reacciones ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 56/100
solidjs/solid-vite-plugin#456 ·
Los mantenedores suelen responder en 1 día
-
serverFunctions.components (dev): server-functions client is duplicated when @solidjs/web is in optimizeDeps.exclude, so post-boot server components resolve to undefinedPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 58/100
solidjs/solid-vite-plugin#428 ·
Los mantenedores suelen responder en 1 día
-
[3.0.0-next.50 / next] Dev with a host-owned SSR environment: the first server-function call after startup, a restart or a new "use server" file waits a fixed 1 sPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 58/100
solidjs/solid-vite-plugin#427 ·
Los mantenedores suelen responder en 1 día
Todos los issues de solidjs/solid-vite-plugin
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
jessepollak/home#2223 ·
Los mantenedores suelen responder en 1 día
-
grep fixture corpus test follows the corpus's loop symlink under the receipt runner (fails on main)Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
code-yeongyu/senpi#3756 ·
Los mantenedores suelen responder en 1 día
-
org:external package:deepagents priority:triage topic:memory topic:middleware type:bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
langchain-ai/deepagents#7059 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 92/100
osmlab/name-suggestion-index#12992 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
hemilabs/ui-monorepo#2506 ·
Los mantenedores suelen responder en 1 día