Skip to content

Commit 4e5ba05

Browse files
authored
Fix Vite HMR issue, remove devStyleRuntime option (#422)
1 parent 221d8ed commit 4e5ba05

File tree

6 files changed

+69
-24
lines changed

6 files changed

+69
-24
lines changed

.changeset/curvy-otters-develop.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@vanilla-extract/vite-plugin': patch
3+
---
4+
5+
Fix HMR for pre-existing CSS
6+
7+
Previously, styles would not hot reload correctly when returning to a previously cached version

.changeset/ten-forks-explain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@vanilla-extract/vite-plugin': major
3+
---
4+
5+
Remove the `devStyleRuntime` option

fixtures/features/src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,10 @@ function render() {
1414
}
1515

1616
render();
17+
18+
// Uncomment to enable HMR with Vite
19+
// if (import.meta.hot) {
20+
// import.meta.hot.accept('./features.css', () => {
21+
// render();
22+
// });
23+
// }

fixtures/themed/src/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ import { button, container, opacity } from './styles.css';
55
import { shadow } from './shared.css';
66
import testNodes from '../test-nodes.json';
77

8+
// Uncomment to get HMR for Vite working
9+
// if (import.meta.hot) {
10+
// import.meta.hot.accept(
11+
// ['./themes.css', './styles.css', './shared.css'],
12+
// () => {
13+
// render();
14+
// },
15+
// );
16+
// }
17+
818
const inlineTheme = assignInlineVars(vars, {
919
colors: {
1020
backgroundColor: 'orange',

packages/vite-plugin/src/index.ts

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,41 @@
11
import path from 'path';
2-
import type { Plugin, ResolvedConfig } from 'vite';
2+
import type { Plugin, ResolvedConfig, ViteDevServer } from 'vite';
33
import { normalizePath } from 'vite';
44
import outdent from 'outdent';
55
import {
66
cssFileFilter,
77
processVanillaFile,
88
compile,
9-
hash,
109
getPackageInfo,
1110
IdentifierOption,
1211
addFileScope,
1312
stringifyFileScope,
1413
parseFileScope,
1514
} from '@vanilla-extract/integration';
1615

16+
const styleUpdateEvent = (fileId: string) =>
17+
`vanilla-extract-style-update:${fileId}`;
18+
1719
interface Options {
1820
identifiers?: IdentifierOption;
19-
20-
/**
21-
* Which CSS runtime to use when running `vite serve`.
22-
* @default 'vite'
23-
*/
24-
devStyleRuntime?: 'vite' | 'vanilla-extract';
2521
}
26-
export function vanillaExtractPlugin({
27-
identifiers,
28-
devStyleRuntime = 'vite',
29-
}: Options = {}): Plugin {
22+
export function vanillaExtractPlugin({ identifiers }: Options = {}): Plugin {
3023
let config: ResolvedConfig;
3124
let packageInfo: ReturnType<typeof getPackageInfo>;
32-
let useRuntime = false;
25+
let server: ViteDevServer;
3326
const cssMap = new Map<string, string>();
3427

3528
let virtualExt: string;
3629

3730
return {
3831
name: 'vanilla-extract',
3932
enforce: 'pre',
33+
configureServer(_server) {
34+
server = _server;
35+
},
4036
config(_userConfig, env) {
41-
useRuntime =
42-
devStyleRuntime === 'vanilla-extract' && env.command === 'serve';
43-
44-
const include = useRuntime ? ['@vanilla-extract/css/injectStyles'] : [];
37+
const include =
38+
env.command === 'serve' ? ['@vanilla-extract/css/injectStyles'] : [];
4539

4640
return {
4741
optimizeDeps: { include },
@@ -57,7 +51,7 @@ export function vanillaExtractPlugin({
5751
configResolved(resolvedConfig) {
5852
config = resolvedConfig;
5953

60-
virtualExt = `.vanilla.${useRuntime ? 'js' : 'css'}?hash=`;
54+
virtualExt = `.vanilla.${config.command === 'serve' ? 'js' : 'css'}`;
6155

6256
packageInfo = getPackageInfo(config.root);
6357
},
@@ -78,7 +72,7 @@ export function vanillaExtractPlugin({
7872

7973
const css = cssMap.get(fileScopeId)!;
8074

81-
if (!useRuntime) {
75+
if (!server) {
8276
return css;
8377
}
8478

@@ -87,10 +81,16 @@ export function vanillaExtractPlugin({
8781
return outdent`
8882
import { injectStyles } from '@vanilla-extract/css/injectStyles';
8983
90-
injectStyles({
84+
const inject = (css) => injectStyles({
9185
fileScope: ${JSON.stringify(fileScope)},
92-
css: ${JSON.stringify(css)}
93-
})
86+
css
87+
});
88+
89+
inject(${JSON.stringify(css)});
90+
91+
import.meta.hot.on('${styleUpdateEvent(fileScopeId)}', (css) => {
92+
inject(css);
93+
});
9494
`;
9595
}
9696

@@ -132,10 +132,26 @@ export function vanillaExtractPlugin({
132132
identifiers ?? (config.mode === 'production' ? 'short' : 'debug'),
133133
serializeVirtualCssPath: ({ fileScope, source }) => {
134134
const fileId = stringifyFileScope(fileScope);
135+
const id = `${fileId}${virtualExt}`;
136+
137+
if (server && cssMap.has(fileId) && cssMap.get(fileId) !== source) {
138+
const { moduleGraph } = server;
139+
const module = moduleGraph.getModuleById(id);
140+
141+
if (module) {
142+
moduleGraph.invalidateModule(module);
143+
}
144+
145+
server.ws.send({
146+
type: 'custom',
147+
event: styleUpdateEvent(fileId),
148+
data: source,
149+
});
150+
}
135151

136152
cssMap.set(fileId, source);
137153

138-
return `import "${fileId}${virtualExt}${hash(source)}";`;
154+
return `import "${id}";`;
139155
},
140156
});
141157
},

test-helpers/src/startFixture/vite.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export const startViteFixture = async (
4242
configFile: false,
4343
root,
4444
logLevel: 'error',
45-
plugins: [vanillaExtractPlugin({ devStyleRuntime: 'vanilla-extract' })],
45+
plugins: [vanillaExtractPlugin()],
4646
server: {
4747
port,
4848
force: true,

0 commit comments

Comments
 (0)