diff --git a/.changeset/gold-trainers-sing.md b/.changeset/gold-trainers-sing.md new file mode 100644 index 000000000..e936bf8ed --- /dev/null +++ b/.changeset/gold-trainers-sing.md @@ -0,0 +1,5 @@ +--- +'@vanilla-extract/css': patch +--- + +Fix spaces in debug IDs for variable names. diff --git a/.changeset/hungry-ties-judge.md b/.changeset/hungry-ties-judge.md new file mode 100644 index 000000000..686d057d4 --- /dev/null +++ b/.changeset/hungry-ties-judge.md @@ -0,0 +1,16 @@ +--- +'@vanilla-extract/css': minor +--- + +Support excluding file names from `generateIdentifier` output. This is available by passing a newly-added options object rather than a string. + +**Example usage** + +```ts +import { generateIdentifier } from '@vanilla-extract/css'; + +const identifier = generateIdentifier({ + debugId, + debugFileName: false, +}); +``` diff --git a/.changeset/popular-seas-relate.md b/.changeset/popular-seas-relate.md new file mode 100644 index 000000000..71420dbd1 --- /dev/null +++ b/.changeset/popular-seas-relate.md @@ -0,0 +1,5 @@ +--- +'@vanilla-extract/css': patch +--- + +Fix file name prefix in debug names when file extension is `.cjs` or `.mjs`. diff --git a/packages/css/src/identifier.test.ts b/packages/css/src/identifier.test.ts index 93d9f5f98..3ef01d6ef 100644 --- a/packages/css/src/identifier.test.ts +++ b/packages/css/src/identifier.test.ts @@ -3,26 +3,58 @@ import { generateIdentifier } from './identifier'; describe('identifier', () => { beforeAll(() => { - setFileScope('test'); + setFileScope('path/to/file.css.ts'); }); afterAll(() => { endFileScope(); }); - it(`should create a valid identifier`, () => { + it(`should ignore file scopes without a file extension when creating a path prefix`, () => { + setFileScope('test'); expect(generateIdentifier(undefined)).toMatchInlineSnapshot(`"skkcyc0"`); + endFileScope(); + }); + + it(`should create a valid identifier`, () => { + expect(generateIdentifier(undefined)).toMatchInlineSnapshot( + `"file__18bazsm0"`, + ); }); it('should create a valid identifier with a debug id', () => { expect(generateIdentifier('debug')).toMatchInlineSnapshot( - `"debug__skkcyc1"`, + `"file_debug__18bazsm1"`, ); }); it('should create a valid identifier with a debug id with whitespace', () => { expect(generateIdentifier('debug and more')).toMatchInlineSnapshot( - `"debug_and_more__skkcyc2"`, + `"file_debug_and_more__18bazsm2"`, ); }); + + describe('options object', () => { + it(`should create a valid identifier`, () => { + expect(generateIdentifier({})).toMatchInlineSnapshot(`"file__18bazsm3"`); + }); + + it('should create a valid identifier with a debug id and with file name debugging explicitly enabled', () => { + expect( + generateIdentifier({ debugId: 'debug', debugFileName: true }), + ).toMatchInlineSnapshot(`"file_debug__18bazsm4"`); + }); + + it('should create a valid identifier with a debug id and without file name debugging', () => { + expect( + generateIdentifier({ debugId: 'debug', debugFileName: false }), + ).toMatchInlineSnapshot(`"debug__18bazsm5"`); + }); + + it('should create a valid identifier without a debug ID or file name', () => { + expect( + generateIdentifier({ debugFileName: false }), + ).toMatchInlineSnapshot(`"_18bazsm6"`); + }); + }); }); diff --git a/packages/css/src/identifier.ts b/packages/css/src/identifier.ts index da4431b43..5dfe5b1ad 100644 --- a/packages/css/src/identifier.ts +++ b/packages/css/src/identifier.ts @@ -3,23 +3,46 @@ import hash from '@emotion/hash'; import { getIdentOption } from './adapter'; import { getAndIncrementRefCounter, getFileScope } from './fileScope'; -function getDevPrefix(debugId: string | undefined) { +function getDevPrefix({ + debugId, + debugFileName, +}: { + debugId?: string; + debugFileName: boolean; +}) { const parts = debugId ? [debugId.replace(/\s/g, '_')] : []; - const { filePath } = getFileScope(); - const matches = filePath.match( - /(?[^\/\\]*)?[\/\\]?(?[^\/\\]*)\.css\.(ts|js|tsx|jsx)$/, - ); + if (debugFileName) { + const { filePath } = getFileScope(); + + const matches = filePath.match( + /(?[^\/\\]*)?[\/\\]?(?[^\/\\]*)\.css\.(ts|js|tsx|jsx|cjs|mjs)$/, + ); - if (matches && matches.groups) { - const { dir, file } = matches.groups; - parts.unshift(file && file !== 'index' ? file : dir); + if (matches && matches.groups) { + const { dir, file } = matches.groups; + parts.unshift(file && file !== 'index' ? file : dir); + } } return parts.join('_'); } -export function generateIdentifier(debugId: string | undefined) { +interface GenerateIdentifierOptions { + debugId?: string; + debugFileName?: boolean; +} + +export function generateIdentifier(debugId?: string): string; +export function generateIdentifier(options?: GenerateIdentifierOptions): string; +export function generateIdentifier( + arg?: string | GenerateIdentifierOptions, +): string { + const { debugId, debugFileName = true } = { + ...(typeof arg === 'string' ? { debugId: arg } : null), + ...(typeof arg === 'object' ? arg : null), + }; + // Convert ref count to base 36 for optimal hash lengths const refCount = getAndIncrementRefCounter().toString(36); const { filePath, packageName } = getFileScope(); @@ -31,7 +54,7 @@ export function generateIdentifier(debugId: string | undefined) { let identifier = `${fileScopeHash}${refCount}`; if (getIdentOption() === 'debug') { - const devPrefix = getDevPrefix(debugId); + const devPrefix = getDevPrefix({ debugId, debugFileName }); if (devPrefix) { identifier = `${devPrefix}__${identifier}`; diff --git a/packages/css/src/vars.ts b/packages/css/src/vars.ts index d124b1626..915e1839a 100644 --- a/packages/css/src/vars.ts +++ b/packages/css/src/vars.ts @@ -5,29 +5,20 @@ import { MapLeafNodes, CSSVarFunction, } from '@vanilla-extract/private'; -import hash from '@emotion/hash'; import cssesc from 'cssesc'; import { Tokens, NullableTokens, ThemeVars } from './types'; -import { getAndIncrementRefCounter, getFileScope } from './fileScope'; import { validateContract } from './validateContract'; -import { getIdentOption } from './adapter'; +import { generateIdentifier } from './identifier'; export function createVar(debugId?: string): CSSVarFunction { - // Convert ref count to base 36 for optimal hash lengths - const refCount = getAndIncrementRefCounter().toString(36); - const { filePath, packageName } = getFileScope(); - const fileScopeHash = hash( - packageName ? `${packageName}${filePath}` : filePath, + const cssVarName = cssesc( + generateIdentifier({ + debugId, + debugFileName: false, + }), + { isIdentifier: true }, ); - const varName = - getIdentOption() === 'debug' && debugId - ? `${debugId}__${fileScopeHash}${refCount}` - : `${fileScopeHash}${refCount}`; - - const cssVarName = cssesc(varName.match(/^[0-9]/) ? `_${varName}` : varName, { - isIdentifier: true, - }); return `var(--${cssVarName})` as const; }