Skip to content

Commit e8a6850

Browse files
authored
Load a new Vite config object for the vite-node compiler (#1314)
1 parent 9b4be60 commit e8a6850

File tree

6 files changed

+79
-34
lines changed

6 files changed

+79
-34
lines changed

.changeset/integration-plugins.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@vanilla-extract/integration': minor
3+
---
4+
5+
A Vite config object can be passed to the vite-node compiler via the `viteConfig` option
6+
7+
`viteResolve` and `vitePlugins` options are deprecated and will be removed in a future version.

.changeset/vite-plugin-plugins.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+
Resolve and pass a new copy of the Vite config to the vite-node compiler
6+
7+
Previously, we were passing the same Vite config object to the vite-node compiler. This was causing compatibility issues with other plugins, such as Vitest and Remix.

packages/integration/src/compiler.ts

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import assert from 'assert';
12
import { join, isAbsolute } from 'path';
23
import type { Adapter } from '@vanilla-extract/css';
34
import { transformCss } from '@vanilla-extract/css/transformCss';
4-
import type { ModuleNode, InlineConfig as ViteConfig } from 'vite';
5+
import type { ModuleNode, UserConfig as ViteUserConfig } from 'vite';
56

67
import type { IdentifierOption } from './types';
78
import { cssFileFilter } from './filters';
@@ -47,13 +48,15 @@ const scanModule = (entryModule: ModuleNode) => {
4748
const createViteServer = async ({
4849
root,
4950
identifiers,
50-
viteResolve,
51-
vitePlugins,
52-
}: Required<Omit<CreateCompilerOptions, 'cssImportSpecifier'>>) => {
51+
viteConfig,
52+
}: Required<
53+
Pick<CreateCompilerOptions, 'root' | 'identifiers' | 'viteConfig'>
54+
>) => {
5355
const pkg = getPackageInfo(root);
5456
const vite = await import('vite');
5557

5658
const server = await vite.createServer({
59+
...viteConfig,
5760
configFile: false,
5861
root,
5962
server: {
@@ -66,7 +69,6 @@ const createViteServer = async ({
6669
ssr: {
6770
noExternal: true,
6871
},
69-
resolve: viteResolve,
7072
plugins: [
7173
{
7274
name: 'vanilla-extract-externalize',
@@ -98,7 +100,7 @@ const createViteServer = async ({
98100
}
99101
},
100102
},
101-
...vitePlugins,
103+
...(viteConfig.plugins ?? []),
102104
],
103105
});
104106

@@ -184,21 +186,32 @@ export interface CreateCompilerOptions {
184186
root: string;
185187
cssImportSpecifier?: (filePath: string) => string;
186188
identifiers?: IdentifierOption;
187-
viteResolve?: ViteConfig['resolve'];
188-
vitePlugins?: ViteConfig['plugins'];
189+
viteConfig?: ViteUserConfig;
190+
/** @deprecated */
191+
viteResolve?: ViteUserConfig['resolve'];
192+
/** @deprecated */
193+
vitePlugins?: ViteUserConfig['plugins'];
189194
}
190195
export const createCompiler = ({
191196
root,
192197
identifiers = 'debug',
193198
cssImportSpecifier = (filePath) => filePath + '.vanilla.css',
194-
viteResolve = {},
195-
vitePlugins = [],
199+
viteConfig,
200+
viteResolve,
201+
vitePlugins,
196202
}: CreateCompilerOptions): Compiler => {
203+
assert(
204+
!(viteConfig && (viteResolve || vitePlugins)),
205+
'viteConfig cannot be used with viteResolve or vitePlugins',
206+
);
207+
197208
const vitePromise = createViteServer({
198209
root,
199210
identifiers,
200-
viteResolve,
201-
vitePlugins,
211+
viteConfig: viteConfig ?? {
212+
resolve: viteResolve,
213+
plugins: vitePlugins,
214+
},
202215
});
203216

204217
const processVanillaFileCache = new Map<

packages/vite-plugin/src/index.ts

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from 'path';
33
import type {
44
Plugin,
55
ResolvedConfig,
6-
UserConfig,
6+
ConfigEnv,
77
ViteDevServer,
88
Rollup,
99
} from 'vite';
@@ -33,10 +33,11 @@ export function vanillaExtractPlugin({
3333
unstable_mode: mode = 'emitCss',
3434
}: Options = {}): Plugin {
3535
let config: ResolvedConfig;
36-
let userConfig: UserConfig;
36+
let configEnv: ConfigEnv;
3737
let server: ViteDevServer;
3838
let packageName: string;
3939
let compiler: Compiler | undefined;
40+
const vitePromise = import('vite');
4041

4142
const getIdentOption = () =>
4243
identifiers ?? (config.mode === 'production' ? 'short' : 'debug');
@@ -97,8 +98,8 @@ export function vanillaExtractPlugin({
9798
configureServer(_server) {
9899
server = _server;
99100
},
100-
config(viteUserConfig) {
101-
userConfig = viteUserConfig;
101+
config(_userConfig, _configEnv) {
102+
configEnv = _configEnv;
102103
return {
103104
ssr: {
104105
external: [
@@ -109,30 +110,42 @@ export function vanillaExtractPlugin({
109110
},
110111
};
111112
},
112-
async configResolved(resolvedConfig) {
113-
config = resolvedConfig;
113+
async configResolved(_resolvedConfig) {
114+
config = _resolvedConfig;
114115
packageName = getPackageInfo(config.root).name;
115116

116117
if (mode !== 'transform') {
118+
const { loadConfigFromFile } = await vitePromise;
119+
const configFile = await loadConfigFromFile(
120+
{
121+
command: config.command,
122+
mode: config.mode,
123+
isSsrBuild: configEnv.isSsrBuild,
124+
},
125+
config.configFile,
126+
);
127+
117128
compiler = createCompiler({
118129
root: config.root,
119130
identifiers: getIdentOption(),
120131
cssImportSpecifier: fileIdToVirtualId,
121-
viteResolve: config.resolve,
122-
vitePlugins: userConfig.plugins?.flat().filter(
123-
(plugin) =>
124-
typeof plugin === 'object' &&
125-
plugin !== null &&
126-
'name' in plugin &&
127-
// Prevent an infinite loop where the compiler creates a new instance of the plugin,
128-
// which creates a new compiler, which creates a new instance of the plugin, etc.
129-
plugin.name !== 'vanilla-extract' &&
130-
// Skip Vitest plugins
131-
plugin.name !== 'vitest' &&
132-
!plugin.name.startsWith('vitest:') &&
133-
// Skip Remix because it throws an error if it's not loaded with a config file
134-
plugin.name !== 'remix',
135-
),
132+
viteConfig: {
133+
...configFile?.config,
134+
plugins: configFile?.config.plugins?.flat().filter(
135+
(plugin) =>
136+
typeof plugin === 'object' &&
137+
plugin !== null &&
138+
'name' in plugin &&
139+
// Prevent an infinite loop where the compiler creates a new instance of the plugin,
140+
// which creates a new compiler, which creates a new instance of the plugin, etc.
141+
plugin.name !== 'vanilla-extract' &&
142+
// Skip Remix because it throws an error if it's not loaded with a config file.
143+
// If it _is_ loaded with a config file, it will create an infinite loop because it
144+
// also has a child compiler which uses the same mechanism to load the config file.
145+
// https://github.com/remix-run/remix/pull/7990#issuecomment-1809356626
146+
plugin.name !== 'remix',
147+
),
148+
},
136149
});
137150
}
138151
},

playwright.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { PlaywrightTestConfig, devices } from '@playwright/test';
22

3+
// Prevent Vite from attempting to clear the screen
4+
process.stdout.isTTY = false;
5+
36
const config: PlaywrightTestConfig = {
47
testMatch: '**/*.playwright.ts',
58
updateSnapshots: 'none',

test-helpers/src/startFixture/vite.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'path';
22
import http from 'http';
33

4-
import { createServer, build, InlineConfig } from 'vite';
4+
import type { InlineConfig } from 'vite';
55
import handler from 'serve-handler';
66
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
77
import inspect from 'vite-plugin-inspect';
@@ -54,6 +54,8 @@ export const startViteFixture = async (
5454
},
5555
};
5656

57+
const { createServer, build } = await import('vite');
58+
5759
if (mode === 'development') {
5860
const server = await createServer(config);
5961

0 commit comments

Comments
 (0)