@@ -2,7 +2,14 @@ import assert from 'assert';
22import { join , isAbsolute } from 'path' ;
33import type { Adapter } from '@vanilla-extract/css' ;
44import { transformCss } from '@vanilla-extract/css/transformCss' ;
5- import type { ModuleNode , UserConfig as ViteUserConfig } from 'vite' ;
5+ import {
6+ type ModuleNode ,
7+ type UserConfig as ViteUserConfig ,
8+ type ViteDevServer ,
9+ createServer ,
10+ createServerModuleRunner ,
11+ } from 'vite' ;
12+ import { type ModuleRunner , EvaluatedModules } from 'vite/module-runner' ;
613
714import {
815 cssFileFilter ,
@@ -89,6 +96,11 @@ const createModuleScanner = () => {
8996 return scanModule ;
9097} ;
9198
99+ type Context = {
100+ server : ViteDevServer ;
101+ runner : ModuleRunner ;
102+ } ;
103+
92104const createViteServer = async ( {
93105 root,
94106 identifiers,
@@ -97,11 +109,10 @@ const createViteServer = async ({
97109} : Required <
98110 Pick < CreateCompilerOptions , 'root' | 'identifiers' | 'viteConfig' >
99111> &
100- Pick < CreateCompilerOptions , 'enableFileWatcher' > ) => {
112+ Pick < CreateCompilerOptions , 'enableFileWatcher' > ) : Promise < Context > => {
101113 const pkg = getPackageInfo ( root ) ;
102- const vite = await import ( 'vite' ) ;
103114
104- const server = await vite . createServer ( {
115+ const server = await createServer ( {
105116 ...viteConfig ,
106117 // The vite-node server should not rewrite imported asset URLs within VE stylesheets.
107118 // Doing so interferes with Vite's resolution and bundling of these assets at build time.
@@ -111,6 +122,7 @@ const createViteServer = async ({
111122 // Don't include HTML middlewares
112123 appType : 'custom' ,
113124 server : {
125+ preTransformRequests : false ,
114126 middlewareMode : viteConfig . server ?. middlewareMode ,
115127 hmr : false ,
116128 watch : enableFileWatcher ? viteConfig . server ?. watch : null ,
@@ -129,7 +141,12 @@ const createViteServer = async ({
129141 assetsInlineLimit : viteConfig . build ?. assetsInlineLimit ,
130142 } ,
131143 ssr : {
132- noExternal : true ,
144+ // `createServerModuleRunner` evaluates modules as ESM (`AsyncFunction`). Forcing every
145+ // dependency through the SSR transform (`noExternal: true`) executes arbitrary CJS in that
146+ // context (`module is not defined`). Externalize `node_modules` by default and only pull
147+ // Vanilla Extract packages through Vite.
148+ external : true ,
149+ noExternal : [ / ^ @ v a n i l l a - e x t r a c t \/ / , / ^ @ e m o t i o n \/ / ] ,
133150 } ,
134151 plugins : [
135152 {
@@ -169,36 +186,18 @@ const createViteServer = async ({
169186 // this is need to initialize the plugins
170187 await server . pluginContainer . buildStart ( { } ) ;
171188
172- const { ViteNodeRunner } = await import ( 'vite-node/client' ) ;
173- const { ViteNodeServer } = await import ( 'vite-node/server' ) ;
174-
175- const node = new ViteNodeServer ( server ) ;
176-
177- class ViteNodeRunnerWithContext extends ViteNodeRunner {
178- cssAdapter : Adapter | undefined ;
179-
180- prepareContext ( context : Record < string , any > ) : Record < string , any > {
181- return {
182- ...super . prepareContext ( context ) ,
183- [ globalAdapterIdentifier ] : this . cssAdapter ,
184- } ;
185- }
186- }
187-
188- const runner = new ViteNodeRunnerWithContext ( {
189- root,
190- base : server . config . base ,
191- fetchModule ( id ) {
192- return node . fetchModule ( id ) ;
193- } ,
194- resolveId ( id , importer ) {
195- return node . resolveId ( id , importer ) ;
196- } ,
189+ const ssr = server . environments . ssr ;
190+ const runner = createServerModuleRunner ( ssr , {
191+ hmr : false ,
192+ sourcemapInterceptor : false ,
197193 } ) ;
198194
199195 if ( enableFileWatcher ) {
200196 server . watcher . on ( 'change' , ( filePath ) => {
201- runner . moduleCache . invalidateDepTree ( [ filePath ] ) ;
197+ const mod = runner . evaluatedModules . getModuleById ( filePath ) ;
198+ if ( mod ) {
199+ runner . evaluatedModules . invalidateModule ( mod ) ;
200+ }
202201 } ) ;
203202 }
204203
@@ -407,12 +406,20 @@ export const createCompiler = ({
407406
408407 const { fileExports, cssImports, watchFiles, lastInvalidationTimestamp } =
409408 await lock ( async ( ) => {
410- runner . cssAdapter = cssAdapter ;
411-
412- const fileExports = ( await runner . executeFile ( filePath ) ) as Record <
413- string ,
414- unknown
415- > ;
409+ const cache = new EvaluatedModules ( ) ;
410+ runner . evaluatedModules = cache ;
411+
412+ const globalForAdapter = globalThis as typeof globalThis &
413+ Record < typeof globalAdapterIdentifier , Adapter | undefined > ;
414+ globalForAdapter [ globalAdapterIdentifier ] = cssAdapter ;
415+
416+ let fileExports : Record < string , unknown > ;
417+ try {
418+ fileExports =
419+ await runner . import < Record < string , unknown > > ( filePath ) ;
420+ } finally {
421+ delete globalForAdapter [ globalAdapterIdentifier ] ;
422+ }
416423
417424 const moduleId = normalizePath ( filePath ) ;
418425 const moduleNode = server . moduleGraph . getModuleById ( moduleId ) ;
@@ -517,9 +524,13 @@ export const createCompiler = ({
517524 async unstable_invalidateAllModules ( ) {
518525 const { server, runner } = await vitePromise ;
519526
520- for ( const [ key ] of runner . moduleCache . entries ( ) ) {
521- if ( ! key . includes ( 'node_modules' ) ) {
522- runner . moduleCache . delete ( key ) ;
527+ const evaluatedIds = runner . evaluatedModules . idToModuleMap . keys ( ) ;
528+ for ( const id of evaluatedIds ) {
529+ if ( ! id . includes ( 'node_modules' ) ) {
530+ const mod = runner . evaluatedModules . getModuleById ( id ) ;
531+ if ( mod ) {
532+ runner . evaluatedModules . invalidateModule ( mod ) ;
533+ }
523534 }
524535 }
525536
@@ -545,9 +556,13 @@ export const createCompiler = ({
545556 } ;
546557 } ,
547558 async close ( ) {
548- const { server } = await vitePromise ;
559+ const { server, runner } = await vitePromise ;
549560
550- await server . close ( ) ;
561+ try {
562+ await runner . close ( ) ;
563+ } finally {
564+ await server . close ( ) ;
565+ }
551566 } ,
552567 getAllCss ( ) {
553568 let allCss = '' ;
0 commit comments