Skip to content

Commit 85fe814

Browse files
committed
Inline cssesc dependency
1 parent c432ff3 commit 85fe814

File tree

10 files changed

+121
-20
lines changed

10 files changed

+121
-20
lines changed

.changeset/polite-rats-allow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@vanilla-extract/css': patch
3+
---
4+
5+
Inline `cssesc` dependency to fix CJS interop issues in certain Vite apps

packages/css/package.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@
119119
"@emotion/hash": "^0.9.0",
120120
"@vanilla-extract/private": "workspace:^",
121121
"css-what": "^6.1.0",
122-
"cssesc": "^3.0.0",
123122
"csstype": "^3.0.7",
124123
"dedent": "^1.5.3",
125124
"deep-object-diff": "^1.1.9",
@@ -128,8 +127,5 @@
128127
"media-query-parser": "^2.0.2",
129128
"modern-ahocorasick": "^1.0.0",
130129
"picocolors": "^1.0.0"
131-
},
132-
"devDependencies": {
133-
"@types/cssesc": "^3.0.0"
134130
}
135131
}

packages/css/src/cssesc.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Modified from https://github.com/mathiasbynens/cssesc/blob/cb894eb42f27c8d3cd793f16afe35b3ab38000a1/src/cssesc.js
2+
// Does not support globally overriding options
3+
4+
interface Options {
5+
escapeEverything: boolean;
6+
isIdentifier: boolean;
7+
quotes: string;
8+
wrap: boolean;
9+
}
10+
11+
const regexAnySingleEscape = /[ -,\.\/:-@\[-\^`\{-~]/;
12+
const regexSingleEscape = /[ -,\.\/:-@\[\]\^`\{-~]/;
13+
const regexExcessiveSpaces =
14+
/(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g;
15+
16+
const defaultOptions: Options = {
17+
escapeEverything: false,
18+
isIdentifier: false,
19+
quotes: 'single',
20+
wrap: false,
21+
};
22+
23+
// https://mathiasbynens.be/notes/css-escapes#css
24+
export const cssesc = (string: string, options: Partial<Options>) => {
25+
options = { ...defaultOptions, ...options };
26+
27+
if (options.quotes != 'single' && options.quotes != 'double') {
28+
options.quotes = 'single';
29+
}
30+
const quote = options.quotes == 'double' ? '"' : "'";
31+
const isIdentifier = options.isIdentifier;
32+
33+
const firstChar = string.charAt(0);
34+
let output = '';
35+
let counter = 0;
36+
const length = string.length;
37+
while (counter < length) {
38+
const character = string.charAt(counter++);
39+
let codePoint = character.charCodeAt(0);
40+
let value;
41+
// If it’s not a printable ASCII character…
42+
if (codePoint < 0x20 || codePoint > 0x7e) {
43+
if (codePoint >= 0xd800 && codePoint <= 0xdbff && counter < length) {
44+
// It’s a high surrogate, and there is a next character.
45+
const extra = string.charCodeAt(counter++);
46+
if ((extra & 0xfc00) == 0xdc00) {
47+
// next character is low surrogate
48+
codePoint = ((codePoint & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
49+
} else {
50+
// It’s an unmatched surrogate; only append this code unit, in case
51+
// the next code unit is the high surrogate of a surrogate pair.
52+
counter--;
53+
}
54+
}
55+
value = '\\' + codePoint.toString(16).toUpperCase() + ' ';
56+
} else {
57+
if (options.escapeEverything) {
58+
if (regexAnySingleEscape.test(character)) {
59+
value = '\\' + character;
60+
} else {
61+
value = '\\' + codePoint.toString(16).toUpperCase() + ' ';
62+
}
63+
} else if (/[\t\n\f\r\x0B]/.test(character)) {
64+
value = '\\' + codePoint.toString(16).toUpperCase() + ' ';
65+
} else if (
66+
character == '\\' ||
67+
(!isIdentifier &&
68+
((character == '"' && quote == character) ||
69+
(character == "'" && quote == character))) ||
70+
(isIdentifier && regexSingleEscape.test(character))
71+
) {
72+
value = '\\' + character;
73+
} else {
74+
value = character;
75+
}
76+
}
77+
output += value;
78+
}
79+
80+
if (isIdentifier) {
81+
if (/^-[-\d]/.test(output)) {
82+
output = '\\-' + output.slice(1);
83+
} else if (/\d/.test(firstChar)) {
84+
output = '\\3' + firstChar + ' ' + output.slice(1);
85+
}
86+
}
87+
88+
// Remove spaces after `\HEX` escapes that are not followed by a hex digit,
89+
// since they’re redundant. Note that this is only possible if the escape
90+
// sequence isn’t preceded by an odd number of backslashes.
91+
output = output.replace(regexExcessiveSpaces, function ($0, $1, $2) {
92+
if ($1 && $1.length % 2) {
93+
// It’s not safe to remove the space, so don’t.
94+
return $0;
95+
}
96+
// Strip the space.
97+
return ($1 || '') + $2;
98+
});
99+
100+
if (!isIdentifier && options.wrap) {
101+
return quote + output + quote;
102+
}
103+
return output;
104+
};

packages/css/src/style.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import cssesc from 'cssesc';
1+
import { cssesc } from './cssesc';
22
import dedent from 'dedent';
33
import deepmerge from 'deepmerge';
44

packages/css/src/transformCss.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getVarName } from '@vanilla-extract/private';
2-
import cssesc from 'cssesc';
2+
import { cssesc } from './cssesc';
33
import AhoCorasick from 'modern-ahocorasick';
44

55
import type {

packages/css/src/validateSelector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { parse } from 'css-what';
2-
import cssesc from 'cssesc';
2+
import { cssesc } from './cssesc';
33
import dedent from 'dedent';
44

55
// https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript

packages/css/src/vars.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
MapLeafNodes,
88
CSSVarFunction,
99
} from '@vanilla-extract/private';
10-
import cssesc from 'cssesc';
10+
import { cssesc } from './cssesc';
1111

1212
import { Tokens, NullableTokens, ThemeVars } from './types';
1313
import { validateContract } from './validateContract';

packages/integration/src/compiler.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ const createViteServer = async ({
111111
ssr: {
112112
noExternal: true,
113113
},
114+
build: {
115+
rollupOptions: {
116+
external: ['cssesc'],
117+
},
118+
},
114119
plugins: [
115120
{
116121
name: 'vanilla-extract-externalize',

packages/vite-plugin/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ export function vanillaExtractPlugin({
106106
config(_userConfig, _configEnv) {
107107
configEnv = _configEnv;
108108
return {
109+
optimizeDeps: {
110+
include: ['@vanilla-extract/css > cssesc'],
111+
},
109112
ssr: {
110113
external: [
111114
'@vanilla-extract/css',

pnpm-lock.yaml

Lines changed: 0 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)