From addde783375404c87b513863a585d9ee7bf0e992 Mon Sep 17 00:00:00 2001 From: Sashank Gogula Date: Sat, 10 May 2025 15:12:53 -0700 Subject: [PATCH 1/3] fix fileScope race --- packages/integration/package.json | 3 +- .../src/processVanillaFile.test.ts | 49 ++++++++++++++++++- .../integration/src/processVanillaFile.ts | 31 ++++++------ pnpm-lock.yaml | 3 ++ 4 files changed, 70 insertions(+), 16 deletions(-) diff --git a/packages/integration/package.json b/packages/integration/package.json index 140256ae9..71046b206 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -27,6 +27,7 @@ "mlly": "^1.4.2" }, "devDependencies": { - "@types/babel__core": "^7.20.5" + "@types/babel__core": "^7.20.5", + "@fixtures/sprinkles": "workspace:*" } } diff --git a/packages/integration/src/processVanillaFile.test.ts b/packages/integration/src/processVanillaFile.test.ts index e336ec248..e93aef1a7 100644 --- a/packages/integration/src/processVanillaFile.test.ts +++ b/packages/integration/src/processVanillaFile.test.ts @@ -1,4 +1,7 @@ -import { serializeVanillaModule } from './processVanillaFile'; +import { + processVanillaFile, + serializeVanillaModule, +} from './processVanillaFile'; describe('serializeVanillaModule', () => { test('with plain object exports', () => { @@ -233,3 +236,47 @@ describe('serializeVanillaModule', () => { `); }); }); + +describe('processVanillaFile', () => { + jest.useFakeTimers(); + test('should process vanilla file with correct promise order', async () => { + const serializeVirtualCssPath1 = jest.fn( + ({ source }) => + new Promise((resolve) => { + setTimeout(() => resolve(source), 1); + }), + ); + const serializeVirtualCssPath2 = jest.fn(({ source }) => + Promise.resolve(source), + ); + + const [result] = await Promise.all([ + processVanillaFile({ + source: ` + const __vanilla_filescope__ = require("@vanilla-extract/css/fileScope"); + const { style, globalStyle } = require('@vanilla-extract/css'); + __vanilla_filescope__.setFileScope("dependency.css.ts", "test"); + exports.x = style({ color: 'blue' }); + __vanilla_filescope__.endFileScope(); + __vanilla_filescope__.setFileScope("style1.css.ts", "test"); + exports.y = style([exports.x]); + globalStyle('body ' + exports.y, { color: 'red' }); + __vanilla_filescope__.endFileScope(); + `, + filePath: require.resolve('@fixtures/sprinkles'), + serializeVirtualCssPath: serializeVirtualCssPath1, + }), + processVanillaFile({ + source: ` + const __vanilla_filescope__ = require("@vanilla-extract/css/fileScope"); + __vanilla_filescope__.setFileScope("style2.css.ts", "test"); + __vanilla_filescope__.endFileScope(); + `, + filePath: require.resolve('@fixtures/sprinkles'), + serializeVirtualCssPath: serializeVirtualCssPath2, + }), + jest.runAllTimersAsync(), + ]); + expect(result).toMatch(/.*export var y = .*style1.*/); + }); +}); diff --git a/packages/integration/src/processVanillaFile.ts b/packages/integration/src/processVanillaFile.ts index 41f54056d..aab649e09 100644 --- a/packages/integration/src/processVanillaFile.ts +++ b/packages/integration/src/processVanillaFile.ts @@ -1,5 +1,6 @@ import type { FileScope, Adapter } from '@vanilla-extract/css'; import { transformCss } from '@vanilla-extract/css/transformCss'; +import { removeAdapter, setAdapter } from '@vanilla-extract/css/adapter'; import evalCode from 'eval'; import { stringify } from 'javascript-stringify'; import dedent from 'dedent'; @@ -121,17 +122,33 @@ export async function processVanillaFile({ true, ) as Record; + // We run this code inside eval as jest seems to create a difrerent instance of the adapter file + // for requires executed within the eval and all CSS can be lost. + evalCode( + `const { removeAdapter } = require('@vanilla-extract/css/adapter'); + // Backwards compat with older versions of @vanilla-extract/css + if (removeAdapter) { + removeAdapter(); + } + `, + filePath, + { console, process }, + true, + ); + process.env.NODE_ENV = currentNodeEnv; const cssImports = []; for (const [serialisedFileScope, fileScopeCss] of cssByFileScope) { const fileScope = parseFileScope(serialisedFileScope); + setAdapter(cssAdapter); const css = transformCss({ localClassNames: Array.from(localClassNames), composedClassLists, cssObjs: fileScopeCss, }).join('\n'); + removeAdapter(); const fileName = `${fileScope.filePath}.vanilla.css`; @@ -158,20 +175,6 @@ export async function processVanillaFile({ cssImports.push(virtualCssFilePath); } - // We run this code inside eval as jest seems to create a difrerent instance of the adapter file - // for requires executed within the eval and all CSS can be lost. - evalCode( - `const { removeAdapter } = require('@vanilla-extract/css/adapter'); - // Backwards compat with older versions of @vanilla-extract/css - if (removeAdapter) { - removeAdapter(); - } - `, - filePath, - { console, process }, - true, - ); - const unusedCompositions = composedClassLists .filter(({ identifier }) => !usedCompositions.has(identifier)) .map(({ identifier }) => identifier); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02b89b3cf..5b12e510a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -508,6 +508,9 @@ importers: specifier: ^1.4.2 version: 1.4.2 devDependencies: + '@fixtures/sprinkles': + specifier: workspace:^ + version: link:../../fixtures/sprinkles '@types/babel__core': specifier: ^7.20.5 version: 7.20.5 From 5cee60db4cb9cb2c7a6443c3b3ddf0453a74afb1 Mon Sep 17 00:00:00 2001 From: Sashank Gogula Date: Wed, 14 May 2025 00:45:41 -0700 Subject: [PATCH 2/3] fix pnpm-lock --- pnpm-lock.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5b12e510a..e186666cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -509,7 +509,7 @@ importers: version: 1.4.2 devDependencies: '@fixtures/sprinkles': - specifier: workspace:^ + specifier: workspace:* version: link:../../fixtures/sprinkles '@types/babel__core': specifier: ^7.20.5 From 479dfe8afc3d3e315ec70020fe5e45649b715740 Mon Sep 17 00:00:00 2001 From: Sashank Gogula Date: Wed, 14 May 2025 00:46:01 -0700 Subject: [PATCH 3/3] move removeAdapter eval into adapterBoundSource --- .../integration/src/processVanillaFile.ts | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/packages/integration/src/processVanillaFile.ts b/packages/integration/src/processVanillaFile.ts index aab649e09..69f9aeec6 100644 --- a/packages/integration/src/processVanillaFile.ts +++ b/packages/integration/src/processVanillaFile.ts @@ -111,8 +111,13 @@ export async function processVanillaFile({ process.env.NODE_ENV = originalNodeEnv; const adapterBoundSource = ` - require('@vanilla-extract/css/adapter').setAdapter(__adapter__); + const { setAdapter, removeAdapter } = require('@vanilla-extract/css/adapter'); + setAdapter(__adapter__); ${source} + // Backwards compat with older versions of @vanilla-extract/css + if (removeAdapter) { + removeAdapter(); + } `; const evalResult = evalCode( @@ -122,20 +127,6 @@ export async function processVanillaFile({ true, ) as Record; - // We run this code inside eval as jest seems to create a difrerent instance of the adapter file - // for requires executed within the eval and all CSS can be lost. - evalCode( - `const { removeAdapter } = require('@vanilla-extract/css/adapter'); - // Backwards compat with older versions of @vanilla-extract/css - if (removeAdapter) { - removeAdapter(); - } - `, - filePath, - { console, process }, - true, - ); - process.env.NODE_ENV = currentNodeEnv; const cssImports = [];