Skip to content
This repository was archived by the owner on Jul 24, 2025. It is now read-only.

Commit f52d870

Browse files
committed
fix: enforce "pre" for builds with SWC plugins (fixes #56)
1 parent 8ad1f6c commit f52d870

File tree

13 files changed

+252
-0
lines changed

13 files changed

+252
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
- Support HMR for MDX (fixes #52)
6+
- Fix: when using plugins, apply SWC before esbuild so that automatic runtime is respected for JSX (fixes #56)
67
- Fix: use jsxImportSource in optimizeDeps
78

89
## 3.1.0
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { expect, test } from "@playwright/test";
2+
import {
3+
setupDevServer,
4+
setupBuildAndPreview,
5+
setupWaitForLogs,
6+
expectColor,
7+
} from "../../utils";
8+
9+
test("Emotion plugin build", async ({ page }) => {
10+
const { testUrl, server } = await setupBuildAndPreview("emotion-plugin");
11+
await page.goto(testUrl);
12+
13+
const button = page.locator("button");
14+
await button.hover();
15+
await expectColor(button, "color", "#646cff");
16+
17+
await button.click();
18+
await expect(button).toHaveText("count is 1");
19+
20+
const code = page.locator("code");
21+
await expectColor(code, "color", "#646cff");
22+
23+
await server.httpServer.close();
24+
});
25+
26+
test("Emotion plugin HMR", async ({ page }) => {
27+
const { testUrl, server, editFile } = await setupDevServer("emotion-plugin");
28+
const waitForLogs = await setupWaitForLogs(page);
29+
await page.goto(testUrl);
30+
await waitForLogs("[vite] connected.");
31+
32+
const button = page.locator("button");
33+
await button.hover();
34+
await expectColor(button, "color", "#646cff");
35+
36+
await button.click();
37+
await expect(button).toHaveText("count is 1");
38+
39+
const code = page.locator("code");
40+
await expectColor(code, "color", "#646cff");
41+
42+
editFile("src/Button.jsx", [
43+
"background-color: #d26ac2;",
44+
"background-color: #646cff;",
45+
]);
46+
await waitForLogs("[vite] hot updated: /src/Button.jsx");
47+
await expect(button).toHaveText("count is 1");
48+
await expectColor(button, "backgroundColor", "#646cff");
49+
50+
editFile("src/App.jsx", ['color="#646cff"', 'color="#d26ac2"']);
51+
await waitForLogs("[vite] hot updated: /src/App.jsx");
52+
await expect(button).toHaveText("count is 1");
53+
await expectColor(button, "color", "#d26ac2");
54+
55+
editFile("src/Button.jsx", ["color: #646cff;", "color: #d26ac2;"]);
56+
await waitForLogs("[vite] hot updated: /src/Button.jsx");
57+
await expect(button).toHaveText("count is 1");
58+
await expectColor(code, "color", "#d26ac2");
59+
60+
await server.close();
61+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + React + TS + Emotion</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/index.jsx"></script>
12+
</body>
13+
</html>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "playground-emotion",
3+
"private": true,
4+
"scripts": {
5+
"dev": "vite",
6+
"build": "vite build",
7+
"preview": "vite preview"
8+
},
9+
"dependencies": {
10+
"@emotion/react": "^11.10.5",
11+
"@emotion/styled": "^11.10.5",
12+
"react": "^18.2.0",
13+
"react-dom": "^18.2.0"
14+
},
15+
"devDependencies": {
16+
"@types/react": "^18.0.27",
17+
"@types/react-dom": "^18.0.10",
18+
"@vitejs/plugin-react-swc": "../../dist",
19+
"@swc/plugin-emotion": "^2.5.41"
20+
}
21+
}
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#root {
2+
max-width: 1280px;
3+
margin: 0 auto;
4+
padding: 2rem;
5+
text-align: center;
6+
}
7+
8+
.logo {
9+
height: 6em;
10+
padding: 1.5em;
11+
will-change: filter;
12+
}
13+
.logo:hover {
14+
filter: drop-shadow(0 0 2em #646cffaa);
15+
}
16+
.logo.emotion:hover {
17+
filter: drop-shadow(0 0 2em #d26ac2aa);
18+
}
19+
20+
.card {
21+
padding: 2em;
22+
}
23+
24+
.read-the-docs {
25+
color: #888;
26+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import "./App.css";
2+
import { Button, StyledCode } from "./Button";
3+
4+
export const App = () => (
5+
<div>
6+
<div>
7+
<a href="https://vitejs.dev" target="_blank" rel="noreferrer">
8+
<img src="/vite.svg" className="logo" alt="Vite logo" />
9+
</a>
10+
<a href="https://emotion.sh/" target="_blank" rel="noreferrer">
11+
<img
12+
src="https://emotion.sh/logo-96x96.png"
13+
className="logo emotion"
14+
alt="Emotion logo"
15+
/>
16+
</a>
17+
</div>
18+
<div className="card">
19+
<Button color="#646cff" />
20+
<p>
21+
Edit <StyledCode>src/Button.tsx</StyledCode> and save to test HMR
22+
</p>
23+
</div>
24+
<p className="read-the-docs">
25+
Click on the Vite and Emotion logos to learn more
26+
</p>
27+
</div>
28+
);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import styled from "@emotion/styled";
2+
import { css } from "@emotion/react";
3+
import { useState } from "react";
4+
5+
// Ensure HMR of styled component alongside other components
6+
export const StyledCode = styled.code`
7+
color: #646cff;
8+
`;
9+
10+
export const Button = ({ color }) => {
11+
const [count, setCount] = useState(0);
12+
13+
return (
14+
<button
15+
css={css`
16+
padding: 10px 16px;
17+
background-color: #d26ac2;
18+
font-size: 20px;
19+
border-radius: 4px;
20+
border: 0px;
21+
&:hover {
22+
color: ${color};
23+
}
24+
`}
25+
onClick={() => setCount(count + 1)}
26+
>
27+
count is {count}
28+
</button>
29+
);
30+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
:root {
2+
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
3+
font-size: 16px;
4+
line-height: 24px;
5+
font-weight: 400;
6+
7+
color-scheme: light dark;
8+
color: rgba(255, 255, 255, 0.87);
9+
background-color: #242424;
10+
11+
font-synthesis: none;
12+
text-rendering: optimizeLegibility;
13+
-webkit-font-smoothing: antialiased;
14+
-moz-osx-font-smoothing: grayscale;
15+
-webkit-text-size-adjust: 100%;
16+
}
17+
18+
body {
19+
margin: 0;
20+
display: flex;
21+
place-items: center;
22+
min-width: 320px;
23+
min-height: 100vh;
24+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { StrictMode } from "react";
2+
import { createRoot } from "react-dom/client";
3+
import { App } from "./App";
4+
import "./index.css";
5+
6+
createRoot(document.getElementById("root")).render(
7+
<StrictMode>
8+
<App />
9+
</StrictMode>,
10+
);

0 commit comments

Comments
 (0)