@vanilla-extract/vite-plugin 5.2.3-vite-environment-20260407054241 → 5.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,13 +2,47 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var path = require('path');
6
5
  var compiler = require('@vanilla-extract/compiler');
7
6
  var integration = require('@vanilla-extract/integration');
7
+ var path = require('path');
8
+
9
+ // Vite wraps module ids that aren't valid browser import specifiers with
10
+ // `/@id/` in dev mode. The leading slash is sometimes already stripped.
11
+ const viteIdPrefix = /^\/?@id\//;
12
+ // Vite emits posix separators and sometimes prefixes a Windows drive letter
13
+ // with a slash, e.g. a resolved id like `/C:/...`.
14
+ const slashPrefixedDrive = /^\/([a-zA-Z]:\/)/;
15
+ // A Windows drive path (`C:/...`) is unambiguously a real absolute path
16
+ // unlike a posix `/...` path, which may be an SSR root-relative id.
17
+ const windowsAbsolutePathRegex = /^[a-zA-Z]:\//;
18
+ const isWindowsAbsolutePath = filePath => windowsAbsolutePathRegex.test(filePath);
19
+ const isAbsolutePath = filePath => path.posix.isAbsolute(filePath) || isWindowsAbsolutePath(filePath);
20
+
21
+ // Strip Vite's `@id/` wrapper and any slash it prefixes onto a Windows drive.
22
+ const unwrapViteId = id => {
23
+ const unwrapped = id.replace(viteIdPrefix, '').replace(slashPrefixedDrive, '$1');
8
24
 
9
- function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
25
+ // If unwrapping didn't yield an absolute path, the `@id/` prefix wasn't a
26
+ // path wrapper, so keep the original id.
27
+ return isAbsolutePath(unwrapped) ? unwrapped : id;
28
+ };
29
+ const getAbsoluteId = ({
30
+ filePath,
31
+ root
32
+ }) => {
33
+ const resolvedId = unwrapViteId(filePath);
34
+ if (
35
+ // A Windows drive path is always a real absolute path.
36
+ isWindowsAbsolutePath(resolvedId) || resolvedId.startsWith(root) ||
37
+ // In monorepos the absolute path is outside of `root`, so we check they
38
+ // share a filesystem root. Vite paths always use posix separators.
39
+ path.posix.isAbsolute(resolvedId) && resolvedId.split(path.posix.sep)[1] === root.split(path.posix.sep)[1]) {
40
+ return integration.normalizePath(resolvedId);
41
+ }
10
42
 
11
- var path__default = /*#__PURE__*/_interopDefault(path);
43
+ // In SSR mode we can have root-relative paths like `/app/styles.css.ts`.
44
+ return integration.normalizePath(path.posix.join(root, resolvedId));
45
+ };
12
46
 
13
47
  const PLUGIN_NAMESPACE = 'vite-plugin-vanilla-extract';
14
48
  const virtualExtCss = '.vanilla.css';
@@ -39,23 +73,11 @@ function vanillaExtractPlugin({
39
73
  let server;
40
74
  let packageName;
41
75
  let compiler$1;
76
+ let compilerReady;
42
77
  let isBuild;
43
78
  const vitePromise = import('vite');
44
79
  const transformedModules = new Set();
45
80
  const getIdentOption = () => identifiers ?? (config.mode === 'production' ? 'short' : 'debug');
46
- const getAbsoluteId = filePath => {
47
- let resolvedId = filePath;
48
- if (filePath.startsWith(config.root) ||
49
- // In monorepos the absolute path will be outside of config.root, so we check that they have the same root on the file system
50
- // Paths from vite are always normalized, so we have to use the posix path separator
51
- path__default["default"].isAbsolute(filePath) && filePath.split(path__default["default"].posix.sep)[1] === config.root.split(path__default["default"].posix.sep)[1]) {
52
- resolvedId = filePath;
53
- } else {
54
- // In SSR mode we can have paths like /app/styles.css.ts
55
- resolvedId = path__default["default"].join(config.root, filePath);
56
- }
57
- return integration.normalizePath(resolvedId);
58
- };
59
81
 
60
82
  /**
61
83
  * Custom invalidation function that takes a chain of importers to invalidate. If an importer is a
@@ -87,6 +109,60 @@ function vanillaExtractPlugin({
87
109
  }
88
110
  }
89
111
  };
112
+ const initializeCompiler = async () => {
113
+ var _configForViteCompile;
114
+ const {
115
+ loadConfigFromFile
116
+ } = await vitePromise;
117
+ let configForViteCompiler;
118
+
119
+ // The user has a vite config file
120
+ if (config.configFile) {
121
+ const configFile = await loadConfigFromFile({
122
+ command: config.command,
123
+ mode: config.mode,
124
+ isSsrBuild: configEnv.isSsrBuild
125
+ }, config.configFile);
126
+ configForViteCompiler = configFile === null || configFile === void 0 ? void 0 : configFile.config;
127
+ }
128
+ // The user is using a vite-based framework that has a custom config file
129
+ else {
130
+ configForViteCompiler = config.inlineConfig;
131
+ }
132
+ const viteConfig = {
133
+ ...configForViteCompiler,
134
+ plugins: (_configForViteCompile = configForViteCompiler) === null || _configForViteCompile === void 0 || (_configForViteCompile = _configForViteCompile.plugins) === null || _configForViteCompile === void 0 ? void 0 : _configForViteCompile.flat().filter(isPluginObject).filter(withUserPluginFilter({
135
+ mode: config.mode,
136
+ pluginFilter
137
+ }))
138
+ };
139
+ compiler$1 = compiler.createCompiler({
140
+ root: config.root,
141
+ identifiers: getIdentOption(),
142
+ cssImportSpecifier: fileIdToVirtualId,
143
+ viteConfig,
144
+ enableFileWatcher: !isBuild
145
+ });
146
+ };
147
+
148
+ /**
149
+ * Lazily creates the compiler, memoizing the initialization promise.
150
+ *
151
+ * `buildStart` kicks this off eagerly, but `transform` also awaits it. This
152
+ * matters because `transform` can run before `buildStart` has finished
153
+ * creating the compiler when another plugin emits an additional entry whose
154
+ * module graph is transformed concurrently (e.g. a module federation plugin
155
+ * exposing a module as its own chunk). Without awaiting, `transform` would
156
+ * bail and leave the `.css.ts` untransformed, producing runtime `style()`
157
+ * calls that throw "Styles were unable to be assigned to a file".
158
+ */
159
+ const ensureCompiler = () => {
160
+ if (unstable_mode === 'transform') {
161
+ return Promise.resolve();
162
+ }
163
+ compilerReady ?? (compilerReady = initializeCompiler());
164
+ return compilerReady;
165
+ };
90
166
  return [{
91
167
  name: `${PLUGIN_NAMESPACE}-inline-dev-css`,
92
168
  apply: (_, {
@@ -131,41 +207,7 @@ function vanillaExtractPlugin({
131
207
  },
132
208
  async buildStart() {
133
209
  // Ensure we re-use the compiler instance between builds, e.g. in watch mode
134
- if (unstable_mode !== 'transform' && !compiler$1) {
135
- var _configForViteCompile;
136
- const {
137
- loadConfigFromFile
138
- } = await vitePromise;
139
- let configForViteCompiler;
140
-
141
- // The user has a vite config file
142
- if (config.configFile) {
143
- const configFile = await loadConfigFromFile({
144
- command: config.command,
145
- mode: config.mode,
146
- isSsrBuild: configEnv.isSsrBuild
147
- }, config.configFile);
148
- configForViteCompiler = configFile === null || configFile === void 0 ? void 0 : configFile.config;
149
- }
150
- // The user is using a vite-based framework that has a custom config file
151
- else {
152
- configForViteCompiler = config.inlineConfig;
153
- }
154
- const viteConfig = {
155
- ...configForViteCompiler,
156
- plugins: (_configForViteCompile = configForViteCompiler) === null || _configForViteCompile === void 0 || (_configForViteCompile = _configForViteCompile.plugins) === null || _configForViteCompile === void 0 ? void 0 : _configForViteCompile.flat().filter(isPluginObject).filter(withUserPluginFilter({
157
- mode: config.mode,
158
- pluginFilter
159
- }))
160
- };
161
- compiler$1 = compiler.createCompiler({
162
- root: config.root,
163
- identifiers: getIdentOption(),
164
- cssImportSpecifier: fileIdToVirtualId,
165
- viteConfig,
166
- enableFileWatcher: !isBuild
167
- });
168
- }
210
+ await ensureCompiler();
169
211
  },
170
212
  buildEnd() {
171
213
  // When using the rollup watcher, we don't want to close the compiler after every build.
@@ -196,10 +238,21 @@ function vanillaExtractPlugin({
196
238
  identOption
197
239
  });
198
240
  }
241
+
242
+ // `transform` can run before `buildStart` has finished creating the
243
+ // compiler (e.g. when another plugin emits an additional entry whose
244
+ // module graph is transformed concurrently). Await the memoized
245
+ // initialization rather than bailing, which would leave this `.css.ts`
246
+ // untransformed. `ensureCompiler` is memoized, so this is a no-op once
247
+ // the compiler exists.
248
+ await ensureCompiler();
199
249
  if (!compiler$1) {
200
250
  return null;
201
251
  }
202
- const absoluteId = getAbsoluteId(validId);
252
+ const absoluteId = getAbsoluteId({
253
+ filePath: validId,
254
+ root: config.root
255
+ });
203
256
  const {
204
257
  source,
205
258
  watchFiles
@@ -246,14 +299,21 @@ function vanillaExtractPlugin({
246
299
  });
247
300
  },
248
301
  resolveId(source) {
249
- var _compiler4;
250
302
  const [validId, query] = source.split('?');
251
303
  if (!isVirtualId(validId)) return;
252
- const absoluteId = getAbsoluteId(validId);
253
- if ( // We should always have CSS for a file here.
254
- // The only valid scenario for a missing one is if someone had written
255
- // a file in their app using the .vanilla.js/.vanilla.css extension
256
- (_compiler4 = compiler$1) !== null && _compiler4 !== void 0 && _compiler4.getCssForFile(virtualIdToFileId(absoluteId))) {
304
+ const absoluteId = getAbsoluteId({
305
+ filePath: validId,
306
+ root: config.root
307
+ });
308
+ if (!compiler$1) return;
309
+
310
+ // The only valid scenario for a missing CSS entry is if someone had
311
+ // written a file in their app using the .vanilla.js/.vanilla.css
312
+ // extension, or the file produced no CSS output.
313
+ const {
314
+ css
315
+ } = compiler$1.getCssForFile(virtualIdToFileId(absoluteId));
316
+ if (css) {
257
317
  // Keep the original query string for HMR.
258
318
  return absoluteId + (query ? `?${query}` : '');
259
319
  }
@@ -261,11 +321,16 @@ function vanillaExtractPlugin({
261
321
  load(id) {
262
322
  const [validId] = id.split('?');
263
323
  if (!isVirtualId(validId) || !compiler$1) return;
264
- const absoluteId = getAbsoluteId(validId);
324
+ const absoluteId = getAbsoluteId({
325
+ filePath: validId,
326
+ root: config.root
327
+ });
265
328
  const {
266
329
  css
267
330
  } = compiler$1.getCssForFile(virtualIdToFileId(absoluteId));
268
- return css;
331
+ if (css) {
332
+ return css;
333
+ }
269
334
  }
270
335
  }];
271
336
  }
@@ -2,13 +2,47 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var path = require('path');
6
5
  var compiler = require('@vanilla-extract/compiler');
7
6
  var integration = require('@vanilla-extract/integration');
7
+ var path = require('path');
8
+
9
+ // Vite wraps module ids that aren't valid browser import specifiers with
10
+ // `/@id/` in dev mode. The leading slash is sometimes already stripped.
11
+ const viteIdPrefix = /^\/?@id\//;
12
+ // Vite emits posix separators and sometimes prefixes a Windows drive letter
13
+ // with a slash, e.g. a resolved id like `/C:/...`.
14
+ const slashPrefixedDrive = /^\/([a-zA-Z]:\/)/;
15
+ // A Windows drive path (`C:/...`) is unambiguously a real absolute path
16
+ // unlike a posix `/...` path, which may be an SSR root-relative id.
17
+ const windowsAbsolutePathRegex = /^[a-zA-Z]:\//;
18
+ const isWindowsAbsolutePath = filePath => windowsAbsolutePathRegex.test(filePath);
19
+ const isAbsolutePath = filePath => path.posix.isAbsolute(filePath) || isWindowsAbsolutePath(filePath);
20
+
21
+ // Strip Vite's `@id/` wrapper and any slash it prefixes onto a Windows drive.
22
+ const unwrapViteId = id => {
23
+ const unwrapped = id.replace(viteIdPrefix, '').replace(slashPrefixedDrive, '$1');
8
24
 
9
- function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
25
+ // If unwrapping didn't yield an absolute path, the `@id/` prefix wasn't a
26
+ // path wrapper, so keep the original id.
27
+ return isAbsolutePath(unwrapped) ? unwrapped : id;
28
+ };
29
+ const getAbsoluteId = ({
30
+ filePath,
31
+ root
32
+ }) => {
33
+ const resolvedId = unwrapViteId(filePath);
34
+ if (
35
+ // A Windows drive path is always a real absolute path.
36
+ isWindowsAbsolutePath(resolvedId) || resolvedId.startsWith(root) ||
37
+ // In monorepos the absolute path is outside of `root`, so we check they
38
+ // share a filesystem root. Vite paths always use posix separators.
39
+ path.posix.isAbsolute(resolvedId) && resolvedId.split(path.posix.sep)[1] === root.split(path.posix.sep)[1]) {
40
+ return integration.normalizePath(resolvedId);
41
+ }
10
42
 
11
- var path__default = /*#__PURE__*/_interopDefault(path);
43
+ // In SSR mode we can have root-relative paths like `/app/styles.css.ts`.
44
+ return integration.normalizePath(path.posix.join(root, resolvedId));
45
+ };
12
46
 
13
47
  const PLUGIN_NAMESPACE = 'vite-plugin-vanilla-extract';
14
48
  const virtualExtCss = '.vanilla.css';
@@ -39,23 +73,11 @@ function vanillaExtractPlugin({
39
73
  let server;
40
74
  let packageName;
41
75
  let compiler$1;
76
+ let compilerReady;
42
77
  let isBuild;
43
78
  const vitePromise = import('vite');
44
79
  const transformedModules = new Set();
45
80
  const getIdentOption = () => identifiers ?? (config.mode === 'production' ? 'short' : 'debug');
46
- const getAbsoluteId = filePath => {
47
- let resolvedId = filePath;
48
- if (filePath.startsWith(config.root) ||
49
- // In monorepos the absolute path will be outside of config.root, so we check that they have the same root on the file system
50
- // Paths from vite are always normalized, so we have to use the posix path separator
51
- path__default["default"].isAbsolute(filePath) && filePath.split(path__default["default"].posix.sep)[1] === config.root.split(path__default["default"].posix.sep)[1]) {
52
- resolvedId = filePath;
53
- } else {
54
- // In SSR mode we can have paths like /app/styles.css.ts
55
- resolvedId = path__default["default"].join(config.root, filePath);
56
- }
57
- return integration.normalizePath(resolvedId);
58
- };
59
81
 
60
82
  /**
61
83
  * Custom invalidation function that takes a chain of importers to invalidate. If an importer is a
@@ -87,6 +109,60 @@ function vanillaExtractPlugin({
87
109
  }
88
110
  }
89
111
  };
112
+ const initializeCompiler = async () => {
113
+ var _configForViteCompile;
114
+ const {
115
+ loadConfigFromFile
116
+ } = await vitePromise;
117
+ let configForViteCompiler;
118
+
119
+ // The user has a vite config file
120
+ if (config.configFile) {
121
+ const configFile = await loadConfigFromFile({
122
+ command: config.command,
123
+ mode: config.mode,
124
+ isSsrBuild: configEnv.isSsrBuild
125
+ }, config.configFile);
126
+ configForViteCompiler = configFile === null || configFile === void 0 ? void 0 : configFile.config;
127
+ }
128
+ // The user is using a vite-based framework that has a custom config file
129
+ else {
130
+ configForViteCompiler = config.inlineConfig;
131
+ }
132
+ const viteConfig = {
133
+ ...configForViteCompiler,
134
+ plugins: (_configForViteCompile = configForViteCompiler) === null || _configForViteCompile === void 0 || (_configForViteCompile = _configForViteCompile.plugins) === null || _configForViteCompile === void 0 ? void 0 : _configForViteCompile.flat().filter(isPluginObject).filter(withUserPluginFilter({
135
+ mode: config.mode,
136
+ pluginFilter
137
+ }))
138
+ };
139
+ compiler$1 = compiler.createCompiler({
140
+ root: config.root,
141
+ identifiers: getIdentOption(),
142
+ cssImportSpecifier: fileIdToVirtualId,
143
+ viteConfig,
144
+ enableFileWatcher: !isBuild
145
+ });
146
+ };
147
+
148
+ /**
149
+ * Lazily creates the compiler, memoizing the initialization promise.
150
+ *
151
+ * `buildStart` kicks this off eagerly, but `transform` also awaits it. This
152
+ * matters because `transform` can run before `buildStart` has finished
153
+ * creating the compiler when another plugin emits an additional entry whose
154
+ * module graph is transformed concurrently (e.g. a module federation plugin
155
+ * exposing a module as its own chunk). Without awaiting, `transform` would
156
+ * bail and leave the `.css.ts` untransformed, producing runtime `style()`
157
+ * calls that throw "Styles were unable to be assigned to a file".
158
+ */
159
+ const ensureCompiler = () => {
160
+ if (unstable_mode === 'transform') {
161
+ return Promise.resolve();
162
+ }
163
+ compilerReady ?? (compilerReady = initializeCompiler());
164
+ return compilerReady;
165
+ };
90
166
  return [{
91
167
  name: `${PLUGIN_NAMESPACE}-inline-dev-css`,
92
168
  apply: (_, {
@@ -131,41 +207,7 @@ function vanillaExtractPlugin({
131
207
  },
132
208
  async buildStart() {
133
209
  // Ensure we re-use the compiler instance between builds, e.g. in watch mode
134
- if (unstable_mode !== 'transform' && !compiler$1) {
135
- var _configForViteCompile;
136
- const {
137
- loadConfigFromFile
138
- } = await vitePromise;
139
- let configForViteCompiler;
140
-
141
- // The user has a vite config file
142
- if (config.configFile) {
143
- const configFile = await loadConfigFromFile({
144
- command: config.command,
145
- mode: config.mode,
146
- isSsrBuild: configEnv.isSsrBuild
147
- }, config.configFile);
148
- configForViteCompiler = configFile === null || configFile === void 0 ? void 0 : configFile.config;
149
- }
150
- // The user is using a vite-based framework that has a custom config file
151
- else {
152
- configForViteCompiler = config.inlineConfig;
153
- }
154
- const viteConfig = {
155
- ...configForViteCompiler,
156
- plugins: (_configForViteCompile = configForViteCompiler) === null || _configForViteCompile === void 0 || (_configForViteCompile = _configForViteCompile.plugins) === null || _configForViteCompile === void 0 ? void 0 : _configForViteCompile.flat().filter(isPluginObject).filter(withUserPluginFilter({
157
- mode: config.mode,
158
- pluginFilter
159
- }))
160
- };
161
- compiler$1 = compiler.createCompiler({
162
- root: config.root,
163
- identifiers: getIdentOption(),
164
- cssImportSpecifier: fileIdToVirtualId,
165
- viteConfig,
166
- enableFileWatcher: !isBuild
167
- });
168
- }
210
+ await ensureCompiler();
169
211
  },
170
212
  buildEnd() {
171
213
  // When using the rollup watcher, we don't want to close the compiler after every build.
@@ -196,10 +238,21 @@ function vanillaExtractPlugin({
196
238
  identOption
197
239
  });
198
240
  }
241
+
242
+ // `transform` can run before `buildStart` has finished creating the
243
+ // compiler (e.g. when another plugin emits an additional entry whose
244
+ // module graph is transformed concurrently). Await the memoized
245
+ // initialization rather than bailing, which would leave this `.css.ts`
246
+ // untransformed. `ensureCompiler` is memoized, so this is a no-op once
247
+ // the compiler exists.
248
+ await ensureCompiler();
199
249
  if (!compiler$1) {
200
250
  return null;
201
251
  }
202
- const absoluteId = getAbsoluteId(validId);
252
+ const absoluteId = getAbsoluteId({
253
+ filePath: validId,
254
+ root: config.root
255
+ });
203
256
  const {
204
257
  source,
205
258
  watchFiles
@@ -246,14 +299,21 @@ function vanillaExtractPlugin({
246
299
  });
247
300
  },
248
301
  resolveId(source) {
249
- var _compiler4;
250
302
  const [validId, query] = source.split('?');
251
303
  if (!isVirtualId(validId)) return;
252
- const absoluteId = getAbsoluteId(validId);
253
- if ( // We should always have CSS for a file here.
254
- // The only valid scenario for a missing one is if someone had written
255
- // a file in their app using the .vanilla.js/.vanilla.css extension
256
- (_compiler4 = compiler$1) !== null && _compiler4 !== void 0 && _compiler4.getCssForFile(virtualIdToFileId(absoluteId))) {
304
+ const absoluteId = getAbsoluteId({
305
+ filePath: validId,
306
+ root: config.root
307
+ });
308
+ if (!compiler$1) return;
309
+
310
+ // The only valid scenario for a missing CSS entry is if someone had
311
+ // written a file in their app using the .vanilla.js/.vanilla.css
312
+ // extension, or the file produced no CSS output.
313
+ const {
314
+ css
315
+ } = compiler$1.getCssForFile(virtualIdToFileId(absoluteId));
316
+ if (css) {
257
317
  // Keep the original query string for HMR.
258
318
  return absoluteId + (query ? `?${query}` : '');
259
319
  }
@@ -261,11 +321,16 @@ function vanillaExtractPlugin({
261
321
  load(id) {
262
322
  const [validId] = id.split('?');
263
323
  if (!isVirtualId(validId) || !compiler$1) return;
264
- const absoluteId = getAbsoluteId(validId);
324
+ const absoluteId = getAbsoluteId({
325
+ filePath: validId,
326
+ root: config.root
327
+ });
265
328
  const {
266
329
  css
267
330
  } = compiler$1.getCssForFile(virtualIdToFileId(absoluteId));
268
- return css;
331
+ if (css) {
332
+ return css;
333
+ }
269
334
  }
270
335
  }];
271
336
  }
@@ -1,6 +1,44 @@
1
- import path from 'path';
2
1
  import { createCompiler } from '@vanilla-extract/compiler';
3
2
  import { normalizePath, getPackageInfo, cssFileFilter, transform } from '@vanilla-extract/integration';
3
+ import { posix } from 'path';
4
+
5
+ // Vite wraps module ids that aren't valid browser import specifiers with
6
+ // `/@id/` in dev mode. The leading slash is sometimes already stripped.
7
+ const viteIdPrefix = /^\/?@id\//;
8
+ // Vite emits posix separators and sometimes prefixes a Windows drive letter
9
+ // with a slash, e.g. a resolved id like `/C:/...`.
10
+ const slashPrefixedDrive = /^\/([a-zA-Z]:\/)/;
11
+ // A Windows drive path (`C:/...`) is unambiguously a real absolute path
12
+ // unlike a posix `/...` path, which may be an SSR root-relative id.
13
+ const windowsAbsolutePathRegex = /^[a-zA-Z]:\//;
14
+ const isWindowsAbsolutePath = filePath => windowsAbsolutePathRegex.test(filePath);
15
+ const isAbsolutePath = filePath => posix.isAbsolute(filePath) || isWindowsAbsolutePath(filePath);
16
+
17
+ // Strip Vite's `@id/` wrapper and any slash it prefixes onto a Windows drive.
18
+ const unwrapViteId = id => {
19
+ const unwrapped = id.replace(viteIdPrefix, '').replace(slashPrefixedDrive, '$1');
20
+
21
+ // If unwrapping didn't yield an absolute path, the `@id/` prefix wasn't a
22
+ // path wrapper, so keep the original id.
23
+ return isAbsolutePath(unwrapped) ? unwrapped : id;
24
+ };
25
+ const getAbsoluteId = ({
26
+ filePath,
27
+ root
28
+ }) => {
29
+ const resolvedId = unwrapViteId(filePath);
30
+ if (
31
+ // A Windows drive path is always a real absolute path.
32
+ isWindowsAbsolutePath(resolvedId) || resolvedId.startsWith(root) ||
33
+ // In monorepos the absolute path is outside of `root`, so we check they
34
+ // share a filesystem root. Vite paths always use posix separators.
35
+ posix.isAbsolute(resolvedId) && resolvedId.split(posix.sep)[1] === root.split(posix.sep)[1]) {
36
+ return normalizePath(resolvedId);
37
+ }
38
+
39
+ // In SSR mode we can have root-relative paths like `/app/styles.css.ts`.
40
+ return normalizePath(posix.join(root, resolvedId));
41
+ };
4
42
 
5
43
  const PLUGIN_NAMESPACE = 'vite-plugin-vanilla-extract';
6
44
  const virtualExtCss = '.vanilla.css';
@@ -31,23 +69,11 @@ function vanillaExtractPlugin({
31
69
  let server;
32
70
  let packageName;
33
71
  let compiler;
72
+ let compilerReady;
34
73
  let isBuild;
35
74
  const vitePromise = import('vite');
36
75
  const transformedModules = new Set();
37
76
  const getIdentOption = () => identifiers ?? (config.mode === 'production' ? 'short' : 'debug');
38
- const getAbsoluteId = filePath => {
39
- let resolvedId = filePath;
40
- if (filePath.startsWith(config.root) ||
41
- // In monorepos the absolute path will be outside of config.root, so we check that they have the same root on the file system
42
- // Paths from vite are always normalized, so we have to use the posix path separator
43
- path.isAbsolute(filePath) && filePath.split(path.posix.sep)[1] === config.root.split(path.posix.sep)[1]) {
44
- resolvedId = filePath;
45
- } else {
46
- // In SSR mode we can have paths like /app/styles.css.ts
47
- resolvedId = path.join(config.root, filePath);
48
- }
49
- return normalizePath(resolvedId);
50
- };
51
77
 
52
78
  /**
53
79
  * Custom invalidation function that takes a chain of importers to invalidate. If an importer is a
@@ -79,6 +105,60 @@ function vanillaExtractPlugin({
79
105
  }
80
106
  }
81
107
  };
108
+ const initializeCompiler = async () => {
109
+ var _configForViteCompile;
110
+ const {
111
+ loadConfigFromFile
112
+ } = await vitePromise;
113
+ let configForViteCompiler;
114
+
115
+ // The user has a vite config file
116
+ if (config.configFile) {
117
+ const configFile = await loadConfigFromFile({
118
+ command: config.command,
119
+ mode: config.mode,
120
+ isSsrBuild: configEnv.isSsrBuild
121
+ }, config.configFile);
122
+ configForViteCompiler = configFile === null || configFile === void 0 ? void 0 : configFile.config;
123
+ }
124
+ // The user is using a vite-based framework that has a custom config file
125
+ else {
126
+ configForViteCompiler = config.inlineConfig;
127
+ }
128
+ const viteConfig = {
129
+ ...configForViteCompiler,
130
+ plugins: (_configForViteCompile = configForViteCompiler) === null || _configForViteCompile === void 0 || (_configForViteCompile = _configForViteCompile.plugins) === null || _configForViteCompile === void 0 ? void 0 : _configForViteCompile.flat().filter(isPluginObject).filter(withUserPluginFilter({
131
+ mode: config.mode,
132
+ pluginFilter
133
+ }))
134
+ };
135
+ compiler = createCompiler({
136
+ root: config.root,
137
+ identifiers: getIdentOption(),
138
+ cssImportSpecifier: fileIdToVirtualId,
139
+ viteConfig,
140
+ enableFileWatcher: !isBuild
141
+ });
142
+ };
143
+
144
+ /**
145
+ * Lazily creates the compiler, memoizing the initialization promise.
146
+ *
147
+ * `buildStart` kicks this off eagerly, but `transform` also awaits it. This
148
+ * matters because `transform` can run before `buildStart` has finished
149
+ * creating the compiler when another plugin emits an additional entry whose
150
+ * module graph is transformed concurrently (e.g. a module federation plugin
151
+ * exposing a module as its own chunk). Without awaiting, `transform` would
152
+ * bail and leave the `.css.ts` untransformed, producing runtime `style()`
153
+ * calls that throw "Styles were unable to be assigned to a file".
154
+ */
155
+ const ensureCompiler = () => {
156
+ if (unstable_mode === 'transform') {
157
+ return Promise.resolve();
158
+ }
159
+ compilerReady ?? (compilerReady = initializeCompiler());
160
+ return compilerReady;
161
+ };
82
162
  return [{
83
163
  name: `${PLUGIN_NAMESPACE}-inline-dev-css`,
84
164
  apply: (_, {
@@ -123,41 +203,7 @@ function vanillaExtractPlugin({
123
203
  },
124
204
  async buildStart() {
125
205
  // Ensure we re-use the compiler instance between builds, e.g. in watch mode
126
- if (unstable_mode !== 'transform' && !compiler) {
127
- var _configForViteCompile;
128
- const {
129
- loadConfigFromFile
130
- } = await vitePromise;
131
- let configForViteCompiler;
132
-
133
- // The user has a vite config file
134
- if (config.configFile) {
135
- const configFile = await loadConfigFromFile({
136
- command: config.command,
137
- mode: config.mode,
138
- isSsrBuild: configEnv.isSsrBuild
139
- }, config.configFile);
140
- configForViteCompiler = configFile === null || configFile === void 0 ? void 0 : configFile.config;
141
- }
142
- // The user is using a vite-based framework that has a custom config file
143
- else {
144
- configForViteCompiler = config.inlineConfig;
145
- }
146
- const viteConfig = {
147
- ...configForViteCompiler,
148
- plugins: (_configForViteCompile = configForViteCompiler) === null || _configForViteCompile === void 0 || (_configForViteCompile = _configForViteCompile.plugins) === null || _configForViteCompile === void 0 ? void 0 : _configForViteCompile.flat().filter(isPluginObject).filter(withUserPluginFilter({
149
- mode: config.mode,
150
- pluginFilter
151
- }))
152
- };
153
- compiler = createCompiler({
154
- root: config.root,
155
- identifiers: getIdentOption(),
156
- cssImportSpecifier: fileIdToVirtualId,
157
- viteConfig,
158
- enableFileWatcher: !isBuild
159
- });
160
- }
206
+ await ensureCompiler();
161
207
  },
162
208
  buildEnd() {
163
209
  // When using the rollup watcher, we don't want to close the compiler after every build.
@@ -188,10 +234,21 @@ function vanillaExtractPlugin({
188
234
  identOption
189
235
  });
190
236
  }
237
+
238
+ // `transform` can run before `buildStart` has finished creating the
239
+ // compiler (e.g. when another plugin emits an additional entry whose
240
+ // module graph is transformed concurrently). Await the memoized
241
+ // initialization rather than bailing, which would leave this `.css.ts`
242
+ // untransformed. `ensureCompiler` is memoized, so this is a no-op once
243
+ // the compiler exists.
244
+ await ensureCompiler();
191
245
  if (!compiler) {
192
246
  return null;
193
247
  }
194
- const absoluteId = getAbsoluteId(validId);
248
+ const absoluteId = getAbsoluteId({
249
+ filePath: validId,
250
+ root: config.root
251
+ });
195
252
  const {
196
253
  source,
197
254
  watchFiles
@@ -238,14 +295,21 @@ function vanillaExtractPlugin({
238
295
  });
239
296
  },
240
297
  resolveId(source) {
241
- var _compiler4;
242
298
  const [validId, query] = source.split('?');
243
299
  if (!isVirtualId(validId)) return;
244
- const absoluteId = getAbsoluteId(validId);
245
- if ( // We should always have CSS for a file here.
246
- // The only valid scenario for a missing one is if someone had written
247
- // a file in their app using the .vanilla.js/.vanilla.css extension
248
- (_compiler4 = compiler) !== null && _compiler4 !== void 0 && _compiler4.getCssForFile(virtualIdToFileId(absoluteId))) {
300
+ const absoluteId = getAbsoluteId({
301
+ filePath: validId,
302
+ root: config.root
303
+ });
304
+ if (!compiler) return;
305
+
306
+ // The only valid scenario for a missing CSS entry is if someone had
307
+ // written a file in their app using the .vanilla.js/.vanilla.css
308
+ // extension, or the file produced no CSS output.
309
+ const {
310
+ css
311
+ } = compiler.getCssForFile(virtualIdToFileId(absoluteId));
312
+ if (css) {
249
313
  // Keep the original query string for HMR.
250
314
  return absoluteId + (query ? `?${query}` : '');
251
315
  }
@@ -253,11 +317,16 @@ function vanillaExtractPlugin({
253
317
  load(id) {
254
318
  const [validId] = id.split('?');
255
319
  if (!isVirtualId(validId) || !compiler) return;
256
- const absoluteId = getAbsoluteId(validId);
320
+ const absoluteId = getAbsoluteId({
321
+ filePath: validId,
322
+ root: config.root
323
+ });
257
324
  const {
258
325
  css
259
326
  } = compiler.getCssForFile(virtualIdToFileId(absoluteId));
260
- return css;
327
+ if (css) {
328
+ return css;
329
+ }
261
330
  }
262
331
  }];
263
332
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanilla-extract/vite-plugin",
3
- "version": "5.2.3-vite-environment-20260407054241",
3
+ "version": "5.2.4",
4
4
  "description": "Zero-runtime Stylesheets-in-TypeScript",
5
5
  "main": "dist/vanilla-extract-vite-plugin.cjs.js",
6
6
  "module": "dist/vanilla-extract-vite-plugin.esm.js",
@@ -16,13 +16,13 @@
16
16
  "author": "SEEK",
17
17
  "license": "MIT",
18
18
  "dependencies": {
19
- "@vanilla-extract/compiler": "^0.7.1-vite-environment-20260407054241",
19
+ "@vanilla-extract/compiler": "^0.7.1",
20
20
  "@vanilla-extract/integration": "^8.0.10"
21
21
  },
22
22
  "devDependencies": {
23
- "vite": "^7.0.0 || ^8.0.0"
23
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
24
24
  },
25
25
  "peerDependencies": {
26
- "vite": "^7.0.0 || ^8.0.0"
26
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
27
27
  }
28
28
  }