@csszyx/unplugin 0.15.2 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css-mangler.cjs +61 -63
- package/dist/css-mangler.d.cts +31 -2
- package/dist/css-mangler.d.mts +31 -2
- package/dist/css-mangler.mjs +61 -64
- package/dist/index.cjs +3 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +4 -4
- package/dist/next-prebuild.mjs +2 -2
- package/dist/next-turbo-loader.mjs +3 -3
- package/dist/shared/{unplugin.BT7PqYuK.d.cts → unplugin.Bu2rzRtv.d.mts} +41 -4
- package/dist/shared/{unplugin.Bk9o8_RZ.mjs → unplugin.C-oQU1jl.mjs} +1 -1
- package/dist/shared/{unplugin.DK0b4fr7.mjs → unplugin.Ceq-N4jI.mjs} +1 -1
- package/dist/shared/{unplugin.dz3AdzsO.cjs → unplugin.D3yBoTHP.cjs} +310 -66
- package/dist/shared/{unplugin.BxsTa17g.mjs → unplugin.Dx0ngYWw.mjs} +312 -69
- package/dist/shared/{unplugin.BT7PqYuK.d.mts → unplugin.PKo7wFzu.d.cts} +41 -4
- package/dist/shared/{unplugin.DAzgbtuZ.mjs → unplugin.Vn9x8SBP.mjs} +1 -1
- package/dist/vite.cjs +1 -1
- package/dist/vite.d.cts +4 -2
- package/dist/vite.d.mts +3 -1
- package/dist/vite.mjs +3 -3
- package/dist/webpack.cjs +1 -1
- package/dist/webpack.d.cts +4 -2
- package/dist/webpack.d.mts +3 -1
- package/dist/webpack.mjs +3 -3
- package/package.json +15 -9
|
@@ -1732,22 +1732,22 @@ function expandFilePatterns(rootDir, patterns) {
|
|
|
1732
1732
|
return safelistSource.sortStrings(files);
|
|
1733
1733
|
}
|
|
1734
1734
|
|
|
1735
|
-
const BACKSLASH = String.fromCodePoint(92);
|
|
1735
|
+
const BACKSLASH$1 = String.fromCodePoint(92);
|
|
1736
1736
|
function unicodeEscape(hexadecimal) {
|
|
1737
|
-
return `${BACKSLASH}u${hexadecimal}`;
|
|
1737
|
+
return `${BACKSLASH$1}u${hexadecimal}`;
|
|
1738
1738
|
}
|
|
1739
1739
|
function replaceEveryLiteral(value, search, replacement) {
|
|
1740
1740
|
return value.replaceAll(search, () => replacement);
|
|
1741
1741
|
}
|
|
1742
1742
|
function escapeSingleQuotedString(value) {
|
|
1743
|
-
let escaped = replaceEveryLiteral(value, BACKSLASH, BACKSLASH.repeat(2));
|
|
1744
|
-
escaped = replaceEveryLiteral(escaped, "'", `${BACKSLASH}'`);
|
|
1745
|
-
escaped = replaceEveryLiteral(escaped, "\r", `${BACKSLASH}r`);
|
|
1746
|
-
return replaceEveryLiteral(escaped, "\n", `${BACKSLASH}n`);
|
|
1743
|
+
let escaped = replaceEveryLiteral(value, BACKSLASH$1, BACKSLASH$1.repeat(2));
|
|
1744
|
+
escaped = replaceEveryLiteral(escaped, "'", `${BACKSLASH$1}'`);
|
|
1745
|
+
escaped = replaceEveryLiteral(escaped, "\r", `${BACKSLASH$1}r`);
|
|
1746
|
+
return replaceEveryLiteral(escaped, "\n", `${BACKSLASH$1}n`);
|
|
1747
1747
|
}
|
|
1748
1748
|
function escapeDoubleQuotedString(value) {
|
|
1749
|
-
const escaped = replaceEveryLiteral(value, BACKSLASH, BACKSLASH.repeat(2));
|
|
1750
|
-
return replaceEveryLiteral(escaped, '"', `${BACKSLASH}"`);
|
|
1749
|
+
const escaped = replaceEveryLiteral(value, BACKSLASH$1, BACKSLASH$1.repeat(2));
|
|
1750
|
+
return replaceEveryLiteral(escaped, '"', `${BACKSLASH$1}"`);
|
|
1751
1751
|
}
|
|
1752
1752
|
|
|
1753
1753
|
const LINE_SEPARATOR$1 = String.fromCodePoint(8232);
|
|
@@ -1936,6 +1936,81 @@ function removedMangleMapDeliveryMessage() {
|
|
|
1936
1936
|
return "[csszyx] production.mangleMapDelivery has been removed and is ignored. The runtime mangle map is always registered from inside the JS bundle now, on every lane, so the built HTML never carries an executable inline <script> and a strict script-src 'self' policy needs no exception. Delete the option. (`window.__csszyx` is now opt-in through `production.mangleDebugGlobal`.)";
|
|
1937
1937
|
}
|
|
1938
1938
|
|
|
1939
|
+
function utilityStart(className) {
|
|
1940
|
+
let depth = 0;
|
|
1941
|
+
let start = 0;
|
|
1942
|
+
for (let index = 0; index < className.length; index += 1) {
|
|
1943
|
+
const char = className[index];
|
|
1944
|
+
if (char === "[") depth += 1;
|
|
1945
|
+
else if (char === "]") depth = Math.max(0, depth - 1);
|
|
1946
|
+
else if (char === ":" && depth === 0) start = index + 1;
|
|
1947
|
+
}
|
|
1948
|
+
return start;
|
|
1949
|
+
}
|
|
1950
|
+
function compileManglePreserve(entries) {
|
|
1951
|
+
const list = entries ?? [];
|
|
1952
|
+
list.forEach((entry, index) => {
|
|
1953
|
+
if (typeof entry !== "string" || entry.length === 0) {
|
|
1954
|
+
throw new TypeError(
|
|
1955
|
+
`[csszyx] production.manglePreserve[${index}] must be a non-empty string (an exact class name, or a prefix ending in \`*\`); got ${describe(entry)}.`
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1958
|
+
if (entry === "*") {
|
|
1959
|
+
throw new TypeError(
|
|
1960
|
+
"[csszyx] production.manglePreserve must not contain a lone `*`: it would keep every class and silently turn `production.mangle` into a no-op. Name a prefix (`bg-tag-*`) or set `production.mangle: false`."
|
|
1961
|
+
);
|
|
1962
|
+
}
|
|
1963
|
+
});
|
|
1964
|
+
const compiled = list.map((value) => ({
|
|
1965
|
+
value,
|
|
1966
|
+
prefix: value.endsWith("*") ? value.slice(0, -1) : void 0
|
|
1967
|
+
}));
|
|
1968
|
+
const keeps = (entry, className, utilityStartIndex) => entry.prefix === void 0 ? className === entry.value || className.length - utilityStartIndex === entry.value.length && className.startsWith(entry.value, utilityStartIndex) : className.startsWith(entry.prefix) || className.startsWith(entry.prefix, utilityStartIndex);
|
|
1969
|
+
const test = (className) => {
|
|
1970
|
+
if (list.length === 0) return false;
|
|
1971
|
+
const start = utilityStart(className);
|
|
1972
|
+
return compiled.some((entry) => keeps(entry, className, start));
|
|
1973
|
+
};
|
|
1974
|
+
return {
|
|
1975
|
+
entries: list,
|
|
1976
|
+
test,
|
|
1977
|
+
unmatched(census) {
|
|
1978
|
+
if (list.length === 0) return [];
|
|
1979
|
+
const matched = list.map(() => false);
|
|
1980
|
+
let remaining = list.length;
|
|
1981
|
+
for (const className of census) {
|
|
1982
|
+
const start = utilityStart(className);
|
|
1983
|
+
for (let index = 0; index < list.length; index += 1) {
|
|
1984
|
+
if (matched[index] || !keeps(compiled[index], className, start)) continue;
|
|
1985
|
+
matched[index] = true;
|
|
1986
|
+
remaining -= 1;
|
|
1987
|
+
}
|
|
1988
|
+
if (remaining === 0) break;
|
|
1989
|
+
}
|
|
1990
|
+
return list.filter((_, index) => !matched[index]);
|
|
1991
|
+
}
|
|
1992
|
+
};
|
|
1993
|
+
}
|
|
1994
|
+
function describe(value) {
|
|
1995
|
+
if (typeof value === "string") return "an empty string";
|
|
1996
|
+
if (value instanceof RegExp) return `a RegExp (${String(value)})`;
|
|
1997
|
+
return `${typeof value} ${JSON.stringify(value) ?? String(value)}`;
|
|
1998
|
+
}
|
|
1999
|
+
function manglePreserveNoMatchMessage(entries) {
|
|
2000
|
+
const sample = entries.slice(0, 8).join(", ");
|
|
2001
|
+
const noun = entries.length === 1 ? "entry" : "entries";
|
|
2002
|
+
return `[csszyx] production.manglePreserve: ${entries.length} ${noun} matched no csszyx class in this build (${sample}) \u2014 nothing was preserved for them. Check the spelling against the class census; an entry keeps a class only when its name is exact, or when it ends in \`*\` and the class starts with the rest.`;
|
|
2003
|
+
}
|
|
2004
|
+
const TOKEN_CHARACTERS = /^[0-9a-z]+$/i;
|
|
2005
|
+
function mangleExcludeNeverTokenEntries(entries) {
|
|
2006
|
+
return [...entries].filter((entry) => !TOKEN_CHARACTERS.test(entry));
|
|
2007
|
+
}
|
|
2008
|
+
function mangleExcludeNeverTokenMessage(entries) {
|
|
2009
|
+
const sample = entries.slice(0, 8).join(", ");
|
|
2010
|
+
const noun = entries.length === 1 ? "name" : "names";
|
|
2011
|
+
return `[csszyx] production.mangleExclude: ${entries.length} ${noun} can never be a mangle token (${sample}) \u2014 tokens are short base62 strings, so those entries do nothing. To keep a class from being renamed, list it in \`production.manglePreserve\` instead.`;
|
|
2012
|
+
}
|
|
2013
|
+
|
|
1939
2014
|
const MANGLE_RUNTIME_FILE = "mangle-runtime.mjs";
|
|
1940
2015
|
function ensureMangleRuntimeFile(outputDir, globalVarAliasPrefix, exposeDebugGlobal) {
|
|
1941
2016
|
const target = path__default.join(outputDir, MANGLE_RUNTIME_FILE);
|
|
@@ -2185,9 +2260,9 @@ let _hasWarnedTsConfig = false;
|
|
|
2185
2260
|
let _hasWarnedTransformCacheVersion = false;
|
|
2186
2261
|
let _hasWarnedNativeFallback = false;
|
|
2187
2262
|
const _loggedActiveParsers = /* @__PURE__ */ new Set();
|
|
2188
|
-
const requireFromHere = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.
|
|
2263
|
+
const requireFromHere = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.D3yBoTHP.cjs', document.baseURI).href)));
|
|
2189
2264
|
const PLUGIN_VERSION = findPackageVersionFromFile(
|
|
2190
|
-
node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.
|
|
2265
|
+
node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.D3yBoTHP.cjs', document.baseURI).href))),
|
|
2191
2266
|
UNKNOWN_PACKAGE_VERSION
|
|
2192
2267
|
);
|
|
2193
2268
|
const COMPILER_VERSION = findPackageVersionFromModule("@csszyx/compiler", UNKNOWN_PACKAGE_VERSION);
|
|
@@ -2229,39 +2304,136 @@ function shouldWarnMissingTailwindEntry(ownedClassCount, sawTailwindEntry, sawAn
|
|
|
2229
2304
|
function missingTailwindEntryMessage(ownedClassCount) {
|
|
2230
2305
|
return `[csszyx] generated ${ownedClassCount} sz class(es) but found no CSS entry importing "tailwindcss" \u2014 those classes will produce no CSS. Import "tailwindcss" in a CSS file (csszyx auto-injects @source for the generated classes) so Tailwind emits their styles.`;
|
|
2231
2306
|
}
|
|
2232
|
-
function
|
|
2307
|
+
function asciiLower(text) {
|
|
2308
|
+
return text.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
|
|
2309
|
+
}
|
|
2310
|
+
function attributeSelectorPredicates(operator, value) {
|
|
2311
|
+
const eq = (v) => (name) => name === v;
|
|
2312
|
+
const startsWith = (v) => (name) => name.startsWith(v);
|
|
2313
|
+
const endsWith = (v) => (name) => name.endsWith(v);
|
|
2314
|
+
const includes = (v) => (name) => name.includes(v);
|
|
2315
|
+
const dashPrefix = (v) => (name) => name === v || name.startsWith(`${v}-`);
|
|
2316
|
+
const segments = value.split(/[\t\n\f\r ]+/);
|
|
2317
|
+
if (segments.length === 1) {
|
|
2318
|
+
switch (operator) {
|
|
2319
|
+
case "=":
|
|
2320
|
+
case "~=":
|
|
2321
|
+
return [eq(value)];
|
|
2322
|
+
case "|=":
|
|
2323
|
+
return [dashPrefix(value)];
|
|
2324
|
+
case "^=":
|
|
2325
|
+
return [startsWith(value)];
|
|
2326
|
+
case "$=":
|
|
2327
|
+
return [endsWith(value)];
|
|
2328
|
+
case "*=":
|
|
2329
|
+
return [includes(value)];
|
|
2330
|
+
default:
|
|
2331
|
+
return [];
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
if (operator === "~=") return [];
|
|
2335
|
+
const first = segments[0];
|
|
2336
|
+
const last = segments[segments.length - 1];
|
|
2337
|
+
const predicates = [];
|
|
2338
|
+
if (first.length > 0) {
|
|
2339
|
+
predicates.push(operator === "$=" || operator === "*=" ? endsWith(first) : eq(first));
|
|
2340
|
+
}
|
|
2341
|
+
for (const middle of segments.slice(1, -1)) predicates.push(eq(middle));
|
|
2342
|
+
if (last.length > 0) {
|
|
2343
|
+
if (operator === "^=" || operator === "*=") predicates.push(startsWith(last));
|
|
2344
|
+
else if (operator === "|=") predicates.push(dashPrefix(last));
|
|
2345
|
+
else predicates.push(eq(last));
|
|
2346
|
+
}
|
|
2347
|
+
return predicates;
|
|
2348
|
+
}
|
|
2349
|
+
function renderClassAttributeSelector(selector) {
|
|
2350
|
+
const flag = selector.insensitive ? " i" : "";
|
|
2351
|
+
return `[class${selector.operator}"${selector.value}"${flag}]`;
|
|
2352
|
+
}
|
|
2353
|
+
function selectorHazardFor(mangleMap, selector) {
|
|
2354
|
+
const value = selector.insensitive ? asciiLower(selector.value) : selector.value;
|
|
2355
|
+
const predicates = attributeSelectorPredicates(selector.operator, value);
|
|
2356
|
+
if (predicates.length === 0) return null;
|
|
2357
|
+
const fold = selector.insensitive ? asciiLower : (name) => name;
|
|
2358
|
+
const matches = (name) => {
|
|
2359
|
+
const folded = fold(name);
|
|
2360
|
+
return predicates.some((predicate) => predicate(folded));
|
|
2361
|
+
};
|
|
2362
|
+
const renamed = compiler.sortStrings(Object.keys(mangleMap).filter(matches));
|
|
2363
|
+
const matchedTokens = compiler.sortStrings(Object.values(mangleMap).filter(matches));
|
|
2364
|
+
if (renamed.length === 0 && matchedTokens.length === 0) return null;
|
|
2365
|
+
return {
|
|
2366
|
+
selector: renderClassAttributeSelector(selector),
|
|
2367
|
+
value: selector.value,
|
|
2368
|
+
renamed,
|
|
2369
|
+
matchedTokens
|
|
2370
|
+
};
|
|
2371
|
+
}
|
|
2372
|
+
function collectMangleHybridHazards(mangleMap, mangledSources, externalClasses, attributeSelectors = []) {
|
|
2233
2373
|
const tokenValues = new Set(Object.values(mangleMap));
|
|
2234
2374
|
const collisions = compiler.sortStrings([...tokenValues].filter((token) => externalClasses.has(token)));
|
|
2235
2375
|
const orphans = compiler.sortStrings(
|
|
2236
2376
|
Object.keys(mangleMap).filter((source) => !mangledSources.has(source))
|
|
2237
2377
|
);
|
|
2238
|
-
|
|
2378
|
+
const hazards = /* @__PURE__ */ new Map();
|
|
2379
|
+
for (const selector of attributeSelectors) {
|
|
2380
|
+
const hazard = selectorHazardFor(mangleMap, selector);
|
|
2381
|
+
if (hazard !== null) hazards.set(hazard.selector, hazard);
|
|
2382
|
+
}
|
|
2383
|
+
const selectorMatches = compiler.sortStrings([...hazards.keys()]).map(
|
|
2384
|
+
(key) => hazards.get(key)
|
|
2385
|
+
);
|
|
2386
|
+
return { collisions, orphans, selectorMatches };
|
|
2387
|
+
}
|
|
2388
|
+
const BACKSLASH = String.fromCodePoint(92);
|
|
2389
|
+
const SINGLE_QUOTE = String.fromCodePoint(39);
|
|
2390
|
+
function quoteForConfig(entry) {
|
|
2391
|
+
const escaped = entry.replaceAll(BACKSLASH, BACKSLASH + BACKSLASH).replaceAll(SINGLE_QUOTE, BACKSLASH + SINGLE_QUOTE);
|
|
2392
|
+
return SINGLE_QUOTE + escaped + SINGLE_QUOTE;
|
|
2393
|
+
}
|
|
2394
|
+
function preserveEntriesFor(hazard) {
|
|
2395
|
+
const quote = quoteForConfig;
|
|
2396
|
+
const { value } = hazard;
|
|
2397
|
+
if (hazard.renamed.every((name) => name === value)) return [quote(value)];
|
|
2398
|
+
if (hazard.renamed.every((name) => name.startsWith(value))) return [quote(`${value}*`)];
|
|
2399
|
+
return hazard.renamed.map(quote);
|
|
2239
2400
|
}
|
|
2240
2401
|
function mangleHybridHazardMessage(hazards) {
|
|
2241
|
-
const { collisions, orphans } = hazards;
|
|
2242
|
-
if (collisions.length === 0 && orphans.length === 0) {
|
|
2402
|
+
const { collisions, orphans, selectorMatches = [] } = hazards;
|
|
2403
|
+
if (collisions.length === 0 && orphans.length === 0 && selectorMatches.length === 0) {
|
|
2243
2404
|
return null;
|
|
2244
2405
|
}
|
|
2406
|
+
const broken = selectorMatches.filter((hazard) => hazard.renamed.length > 0);
|
|
2407
|
+
const newlyMatched = selectorMatches.filter((hazard) => hazard.matchedTokens.length > 0);
|
|
2245
2408
|
const parts = ["[csszyx] production mangle found hybrid hazards:"];
|
|
2246
2409
|
if (collisions.length > 0) {
|
|
2247
2410
|
const sample = collisions.slice(0, 8).join(", ");
|
|
2248
2411
|
parts.push(
|
|
2249
|
-
` ${collisions.length} mangled token(s) collide with class names in non-csszyx CSS (e.g. ${sample}) \u2014 those tokens will cross-contaminate external ".${collisions[0]}" elements
|
|
2412
|
+
` ${collisions.length} mangled token(s) collide with class names in non-csszyx CSS (e.g. ${sample}) \u2014 those tokens will cross-contaminate external ".${collisions[0]}" elements.`,
|
|
2413
|
+
" HOTFIX: pass `production: { mangle: false }` to the csszyx plugin to ship now. THEN fix it: if these short names are in your OWN CSS, rename them to something specific (e.g. `.x` \u2192 `.resize-handle-x`) \u2014 short/common names also clash on specificity with other libraries. Only for names in a third-party stylesheet you cannot edit, list them in `production.mangleExclude` instead. Run `npx @csszyx/cli scan-collisions` to find every offending name."
|
|
2250
2414
|
);
|
|
2251
2415
|
}
|
|
2252
2416
|
if (orphans.length > 0) {
|
|
2253
2417
|
const sample = orphans.slice(0, 8).join(", ");
|
|
2254
2418
|
parts.push(
|
|
2255
|
-
` ${orphans.length} mangled class(es) have no emitted CSS rule (e.g. ${sample}) \u2014 those elements lose styling
|
|
2419
|
+
` ${orphans.length} mangled class(es) have no emitted CSS rule (e.g. ${sample}) \u2014 those elements lose styling.`,
|
|
2420
|
+
" Those classes are csszyx-owned but no CSS was emitted for them (e.g. a separate Tailwind plugin owns the utility CSS, or the class is not a real utility). Ensure that CSS is generated, or pass `production: { mangle: false }` to the csszyx plugin until the pipelines are reconciled."
|
|
2256
2421
|
);
|
|
2257
2422
|
}
|
|
2258
|
-
if (
|
|
2423
|
+
if (broken.length > 0) {
|
|
2424
|
+
const sample = broken.slice(0, 3).map((hazard) => `${hazard.selector} \u2192 ${hazard.renamed.slice(0, 4).join(", ")}`).join("; ");
|
|
2425
|
+
const entries = [...new Set(broken.flatMap(preserveEntriesFor))].join(", ");
|
|
2259
2426
|
parts.push(
|
|
2260
|
-
|
|
2427
|
+
` ${broken.length} attribute selector(s) match class names by text (e.g. ${sample}) \u2014 those rules stop matching once the classes are renamed, so the elements lose those styles.`,
|
|
2428
|
+
` Keep those classes readable with production.manglePreserve: [${entries}] (paste-ready), or key the rule off a data attribute, which mangling never touches. production.mangleExclude cannot help here: it reserves token names and does not keep a class from being renamed.`
|
|
2261
2429
|
);
|
|
2262
|
-
}
|
|
2430
|
+
}
|
|
2431
|
+
if (newlyMatched.length > 0) {
|
|
2432
|
+
const sample = newlyMatched.slice(0, 3).map((hazard) => `${hazard.selector} \u2192 ${hazard.matchedTokens.slice(0, 4).join(", ")}`).join("; ");
|
|
2433
|
+
const tokens = [...new Set(newlyMatched.flatMap((hazard) => hazard.matchedTokens))].map(quoteForConfig).join(", ");
|
|
2263
2434
|
parts.push(
|
|
2264
|
-
|
|
2435
|
+
` ${newlyMatched.length} attribute selector(s) would start matching mangled tokens instead (e.g. ${sample}).`,
|
|
2436
|
+
` Reserve those token names with production.mangleExclude: [${tokens}] (paste-ready) so no class is renamed to one of them, or key the rule off a data attribute, which mangling never touches; a prefix or substring selector goes on matching other tokens, so the data attribute is the durable fix.`
|
|
2265
2437
|
);
|
|
2266
2438
|
}
|
|
2267
2439
|
return parts.join("");
|
|
@@ -2333,6 +2505,9 @@ function shouldEmitWarning(quiet, devOnly, isProduction) {
|
|
|
2333
2505
|
function shouldEmitMissingCssFallback(quiet, message) {
|
|
2334
2506
|
return resolveQuietMode(quiet) !== "all" && compiler.szFallbackConsequenceOf(message) === "missing-css";
|
|
2335
2507
|
}
|
|
2508
|
+
function shouldHoldAdvisories(quiet, serving, nodeEnv) {
|
|
2509
|
+
return quiet !== "off" || !serving && nodeEnv === "production";
|
|
2510
|
+
}
|
|
2336
2511
|
function emitMissingCssFallback(quiet, message, id, emit) {
|
|
2337
2512
|
if (shouldEmitMissingCssFallback(quiet, message)) emit(`[csszyx] ${id}
|
|
2338
2513
|
${message}`);
|
|
@@ -3162,12 +3337,15 @@ ${errors.join("\n")}`
|
|
|
3162
3337
|
function createCsszyxPlugins(options = {}) {
|
|
3163
3338
|
assertGlobalVarMangleConfig(options);
|
|
3164
3339
|
let manglingEnabled = options.production?.mangle === true;
|
|
3340
|
+
let serving = false;
|
|
3165
3341
|
const importedStaticSzEnabled = options.build?.importedStaticSz ?? types.DEFAULT_IMPORTED_STATIC_SZ;
|
|
3166
3342
|
const szvCrossModuleRegistry = /* @__PURE__ */ new Map();
|
|
3167
3343
|
const szvCrossModuleForwards = /* @__PURE__ */ new Map();
|
|
3168
3344
|
const szObjectProvidersExamined = /* @__PURE__ */ new Set();
|
|
3169
3345
|
let specifierAliases = [];
|
|
3170
3346
|
const mangleReserved = new Set(options.production?.mangleExclude ?? []);
|
|
3347
|
+
const manglePreserve = compileManglePreserve(options.production?.manglePreserve);
|
|
3348
|
+
let manglePreserveNoMatchWarned = false;
|
|
3171
3349
|
let mangleMapFrozen = false;
|
|
3172
3350
|
let prescanSawServerModule = false;
|
|
3173
3351
|
let skipRscRecords = false;
|
|
@@ -3178,6 +3356,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3178
3356
|
let projectCssFiles = [];
|
|
3179
3357
|
const transformMangledSources = /* @__PURE__ */ new Set();
|
|
3180
3358
|
const transformExternalClasses = /* @__PURE__ */ new Set();
|
|
3359
|
+
const transformAttributeSelectors = /* @__PURE__ */ new Map();
|
|
3181
3360
|
if (options.production?.mangleMapDelivery !== void 0) {
|
|
3182
3361
|
console.warn(removedMangleMapDeliveryMessage());
|
|
3183
3362
|
}
|
|
@@ -3207,6 +3386,10 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3207
3386
|
if (unknownConfigKeys.length > 0) {
|
|
3208
3387
|
emitWarning(unknownConfigKeysMessage(unknownConfigKeys));
|
|
3209
3388
|
}
|
|
3389
|
+
const excludeNeverTokens = mangleExcludeNeverTokenEntries(mangleReserved);
|
|
3390
|
+
if (excludeNeverTokens.length > 0) {
|
|
3391
|
+
emitWarning(mangleExcludeNeverTokenMessage(excludeNeverTokens));
|
|
3392
|
+
}
|
|
3210
3393
|
function emitWarning(message, opts = {}) {
|
|
3211
3394
|
if (shouldEmitWarning(quiet, opts.devOnly ?? false, process.env.NODE_ENV === "production")) {
|
|
3212
3395
|
console.warn(message);
|
|
@@ -4067,10 +4250,15 @@ function createCsszyxPlugins(options = {}) {
|
|
|
4067
4250
|
...state.authoredClasses,
|
|
4068
4251
|
...state.ownedClasses
|
|
4069
4252
|
]);
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
forbiddenTokens
|
|
4253
|
+
const eligible = mangleEligibleClasses(state.ownedClasses, state.authoredClasses).filter(
|
|
4254
|
+
(className) => !manglePreserve.test(className)
|
|
4073
4255
|
);
|
|
4256
|
+
if (!manglePreserveNoMatchWarned && manglingEnabled && state.ownedClasses.size > 0) {
|
|
4257
|
+
manglePreserveNoMatchWarned = true;
|
|
4258
|
+
const unmatched = manglePreserve.unmatched(state.ownedClasses);
|
|
4259
|
+
if (unmatched.length > 0) emitWarning(manglePreserveNoMatchMessage(unmatched));
|
|
4260
|
+
}
|
|
4261
|
+
return allocateMangleTokens(eligible, forbiddenTokens);
|
|
4074
4262
|
}
|
|
4075
4263
|
function freezeMangleMap() {
|
|
4076
4264
|
state.mangleMap = computeMangleMap();
|
|
@@ -4223,6 +4411,38 @@ function createCsszyxPlugins(options = {}) {
|
|
|
4223
4411
|
}
|
|
4224
4412
|
return modules;
|
|
4225
4413
|
}
|
|
4414
|
+
function handleHotFile(pass, ctx) {
|
|
4415
|
+
const { isClientPass } = pass;
|
|
4416
|
+
if (isClientPass) {
|
|
4417
|
+
prescanResultHandoff.clear();
|
|
4418
|
+
}
|
|
4419
|
+
const scanCss = options.build?.scanCss;
|
|
4420
|
+
const reloadThemeGroupsModule = () => {
|
|
4421
|
+
const themeGroupsModule = ctx.server.moduleGraph.getModuleById(
|
|
4422
|
+
themeGroupsFile.RESOLVED_THEME_GROUPS_VIRTUAL_ID
|
|
4423
|
+
);
|
|
4424
|
+
if (themeGroupsModule) {
|
|
4425
|
+
ctx.server.moduleGraph.invalidateModule(themeGroupsModule);
|
|
4426
|
+
}
|
|
4427
|
+
};
|
|
4428
|
+
if (isClientPass && ctx.file.endsWith(".css")) {
|
|
4429
|
+
const root = state.rootDir;
|
|
4430
|
+
const before = themeGroupsFile.createThemeGroupsModule(themeGroupTokens());
|
|
4431
|
+
if (scanCss && matchesAnyPattern(ctx.file, scanCss, root)) {
|
|
4432
|
+
state.scanCssTheme = runThemeScan(root, scanCss) ?? state.scanCssTheme;
|
|
4433
|
+
}
|
|
4434
|
+
runAutoThemeScan(root);
|
|
4435
|
+
reloadThemeGroupsModule();
|
|
4436
|
+
if (themeGroupsFile.createThemeGroupsModule(themeGroupTokens()) !== before) {
|
|
4437
|
+
ctx.server.ws.send({ type: "full-reload" });
|
|
4438
|
+
}
|
|
4439
|
+
}
|
|
4440
|
+
if (safelistSource.normalizePathSeparators(ctx.file) === safelistSource.normalizePathSeparators(path__namespace.join(state.rootDir, SAFELIST_FILENAME))) {
|
|
4441
|
+
return tailwindEntryModules(pass.moduleGraph());
|
|
4442
|
+
}
|
|
4443
|
+
if (isClientPass) discoverHotFileClasses(ctx.file, ctx.server.watcher);
|
|
4444
|
+
return void 0;
|
|
4445
|
+
}
|
|
4226
4446
|
function transformTailwindCssEntry(code, id) {
|
|
4227
4447
|
state.sawAnyCss = true;
|
|
4228
4448
|
const [cssFile] = id.split("?");
|
|
@@ -4258,7 +4478,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
4258
4478
|
}
|
|
4259
4479
|
const advisories = result.diagnostics.filter(isAdvisoryDiagnostic);
|
|
4260
4480
|
if (advisories.length === 0) return;
|
|
4261
|
-
if (quiet
|
|
4481
|
+
if (shouldHoldAdvisories(quiet, serving, process.env.NODE_ENV)) {
|
|
4262
4482
|
state.suppressedAdvisories += advisories.length;
|
|
4263
4483
|
return;
|
|
4264
4484
|
}
|
|
@@ -4677,6 +4897,7 @@ ${transformedCode}`;
|
|
|
4677
4897
|
specifierAliases = transformCache.collectSpecifierAliases(root, config.resolve?.alias);
|
|
4678
4898
|
if (config.command === "serve") {
|
|
4679
4899
|
manglingEnabled = false;
|
|
4900
|
+
serving = true;
|
|
4680
4901
|
}
|
|
4681
4902
|
if (manglingEnabled && config.build?.watch) {
|
|
4682
4903
|
manglingEnabled = false;
|
|
@@ -4724,38 +4945,39 @@ ${transformedCode}`;
|
|
|
4724
4945
|
* which leaves Vite's own handling in place.
|
|
4725
4946
|
*/
|
|
4726
4947
|
hotUpdate(ctx) {
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4948
|
+
return handleHotFile(
|
|
4949
|
+
{
|
|
4950
|
+
isClientPass: (this.environment?.name ?? "client") === "client",
|
|
4951
|
+
// `server.moduleGraph` holds the backward-compatible
|
|
4952
|
+
// nodes Vite mapped back for the legacy hook only,
|
|
4953
|
+
// so they are the wrong objects to hand this one —
|
|
4954
|
+
// TypeScript says so too.
|
|
4955
|
+
moduleGraph: () => this.environment?.moduleGraph ?? ctx.server.environments.client.moduleGraph
|
|
4956
|
+
},
|
|
4957
|
+
ctx
|
|
4958
|
+
);
|
|
4959
|
+
},
|
|
4960
|
+
/**
|
|
4961
|
+
* The hook Vite 5 calls. Vite 6 and later never run it while
|
|
4962
|
+
* `hotUpdate` is declared, so declaring both costs nothing
|
|
4963
|
+
* there and keeps a Vite 5 dev server compiling `sz` live.
|
|
4964
|
+
*
|
|
4965
|
+
* Vite 5 routes only a file CHANGE here, never a create, so a
|
|
4966
|
+
* project with no `sz` at prescan still sees its first `sz`
|
|
4967
|
+
* edit answered by `@tailwindcss/vite`'s full reload on that
|
|
4968
|
+
* generation — the behaviour it always had there. The hook
|
|
4969
|
+
* runs once, with no environment, so it is the client pass
|
|
4970
|
+
* and answers from the server-wide graph.
|
|
4971
|
+
*
|
|
4972
|
+
* @param ctx - HMR context: the changed file and the dev server.
|
|
4973
|
+
* @returns The modules a safelist write affects; undefined
|
|
4974
|
+
* otherwise.
|
|
4975
|
+
*/
|
|
4976
|
+
handleHotUpdate(ctx) {
|
|
4977
|
+
return handleHotFile(
|
|
4978
|
+
{ isClientPass: true, moduleGraph: () => ctx.server.moduleGraph },
|
|
4979
|
+
ctx
|
|
4980
|
+
);
|
|
4759
4981
|
},
|
|
4760
4982
|
transformIndexHtml: {
|
|
4761
4983
|
order: "pre",
|
|
@@ -4844,7 +5066,7 @@ ${transformedCode}`;
|
|
|
4844
5066
|
recordCodePair(sizeAccount, before, after);
|
|
4845
5067
|
return after;
|
|
4846
5068
|
}
|
|
4847
|
-
function rewriteOutputCss(source, file, shouldMangle, mangledSources, externalClasses) {
|
|
5069
|
+
function rewriteOutputCss(source, file, shouldMangle, mangledSources, externalClasses, attributeSelectors) {
|
|
4848
5070
|
const css = rewriteCssWithValidatedGlobalVarPlan(
|
|
4849
5071
|
source,
|
|
4850
5072
|
file,
|
|
@@ -4858,6 +5080,9 @@ ${transformedCode}`;
|
|
|
4858
5080
|
});
|
|
4859
5081
|
for (const className of result.mangledClasses) mangledSources.add(className);
|
|
4860
5082
|
for (const className of result.unmangledClasses) externalClasses.add(className);
|
|
5083
|
+
for (const selector of result.classAttributeSelectors) {
|
|
5084
|
+
attributeSelectors.set(cssMangler.classAttributeSelectorKey(selector), selector);
|
|
5085
|
+
}
|
|
4861
5086
|
const mangled = result.transformedCount > 0 ? result.css : css;
|
|
4862
5087
|
recordCssPair(sizeAccount, css, mangled);
|
|
4863
5088
|
return mangled;
|
|
@@ -4866,10 +5091,12 @@ ${transformedCode}`;
|
|
|
4866
5091
|
throw error;
|
|
4867
5092
|
}
|
|
4868
5093
|
}
|
|
4869
|
-
function reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses) {
|
|
5094
|
+
function reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses, attributeSelectors) {
|
|
4870
5095
|
if (!shouldMangle) return;
|
|
4871
5096
|
const message = mangleHybridHazardMessage(
|
|
4872
|
-
collectMangleHybridHazards(state.mangleMap, mangledSources, externalClasses
|
|
5097
|
+
collectMangleHybridHazards(state.mangleMap, mangledSources, externalClasses, [
|
|
5098
|
+
...attributeSelectors.values()
|
|
5099
|
+
])
|
|
4873
5100
|
);
|
|
4874
5101
|
if (message) console.warn(message);
|
|
4875
5102
|
}
|
|
@@ -4930,6 +5157,7 @@ ${transformedCode}`;
|
|
|
4930
5157
|
}
|
|
4931
5158
|
const mangledSources = /* @__PURE__ */ new Set();
|
|
4932
5159
|
const externalClasses = /* @__PURE__ */ new Set();
|
|
5160
|
+
const attributeSelectors = /* @__PURE__ */ new Map();
|
|
4933
5161
|
for (const file in assets) {
|
|
4934
5162
|
const source = assets[file].source().toString();
|
|
4935
5163
|
if (file.endsWith(".css")) {
|
|
@@ -4938,7 +5166,8 @@ ${transformedCode}`;
|
|
|
4938
5166
|
file,
|
|
4939
5167
|
shouldMangle,
|
|
4940
5168
|
mangledSources,
|
|
4941
|
-
externalClasses
|
|
5169
|
+
externalClasses,
|
|
5170
|
+
attributeSelectors
|
|
4942
5171
|
);
|
|
4943
5172
|
if (css !== source) {
|
|
4944
5173
|
compilation.updateAsset(file, new compiler.webpack.sources.RawSource(css));
|
|
@@ -4947,10 +5176,15 @@ ${transformedCode}`;
|
|
|
4947
5176
|
rewriteWebpackCodeAsset(file, source, shouldMangle, compilation, compiler);
|
|
4948
5177
|
}
|
|
4949
5178
|
}
|
|
4950
|
-
reportOutputMangleHazards(
|
|
5179
|
+
reportOutputMangleHazards(
|
|
5180
|
+
shouldMangle,
|
|
5181
|
+
mangledSources,
|
|
5182
|
+
externalClasses,
|
|
5183
|
+
attributeSelectors
|
|
5184
|
+
);
|
|
4951
5185
|
reportBuildSummary();
|
|
4952
5186
|
}
|
|
4953
|
-
function rewriteViteBundleEntry(chunk, file, shouldMangle, mangledSources, externalClasses) {
|
|
5187
|
+
function rewriteViteBundleEntry(chunk, file, shouldMangle, mangledSources, externalClasses, attributeSelectors) {
|
|
4954
5188
|
if (chunk.type !== "asset" || !chunk.fileName.endsWith(".css") || chunk.source === void 0) {
|
|
4955
5189
|
return;
|
|
4956
5190
|
}
|
|
@@ -4960,7 +5194,8 @@ ${transformedCode}`;
|
|
|
4960
5194
|
file,
|
|
4961
5195
|
shouldMangle,
|
|
4962
5196
|
mangledSources,
|
|
4963
|
-
externalClasses
|
|
5197
|
+
externalClasses,
|
|
5198
|
+
attributeSelectors
|
|
4964
5199
|
);
|
|
4965
5200
|
if (css !== originalCss) chunk.source = css;
|
|
4966
5201
|
}
|
|
@@ -4971,7 +5206,8 @@ ${transformedCode}`;
|
|
|
4971
5206
|
id,
|
|
4972
5207
|
shouldMangle,
|
|
4973
5208
|
transformMangledSources,
|
|
4974
|
-
transformExternalClasses
|
|
5209
|
+
transformExternalClasses,
|
|
5210
|
+
transformAttributeSelectors
|
|
4975
5211
|
);
|
|
4976
5212
|
return css === code ? null : { code: css, map: null };
|
|
4977
5213
|
}
|
|
@@ -4996,6 +5232,7 @@ ${transformedCode}`;
|
|
|
4996
5232
|
}
|
|
4997
5233
|
const mangledSources = new Set(transformMangledSources);
|
|
4998
5234
|
const externalClasses = new Set(transformExternalClasses);
|
|
5235
|
+
const attributeSelectors = new Map(transformAttributeSelectors);
|
|
4999
5236
|
if (!cssRewrittenInTransform) {
|
|
5000
5237
|
for (const file in bundle) {
|
|
5001
5238
|
rewriteViteBundleEntry(
|
|
@@ -5003,11 +5240,17 @@ ${transformedCode}`;
|
|
|
5003
5240
|
file,
|
|
5004
5241
|
shouldMangle,
|
|
5005
5242
|
mangledSources,
|
|
5006
|
-
externalClasses
|
|
5243
|
+
externalClasses,
|
|
5244
|
+
attributeSelectors
|
|
5007
5245
|
);
|
|
5008
5246
|
}
|
|
5009
5247
|
}
|
|
5010
|
-
reportOutputMangleHazards(
|
|
5248
|
+
reportOutputMangleHazards(
|
|
5249
|
+
shouldMangle,
|
|
5250
|
+
mangledSources,
|
|
5251
|
+
externalClasses,
|
|
5252
|
+
attributeSelectors
|
|
5253
|
+
);
|
|
5011
5254
|
}
|
|
5012
5255
|
const postPlugin = unplugin$1.createUnplugin(() => ({
|
|
5013
5256
|
name: "csszyx:post",
|
|
@@ -5204,6 +5447,7 @@ exports.rollupPlugin = rollupPlugin;
|
|
|
5204
5447
|
exports.scanGlobalVarCss = scanGlobalVarCss;
|
|
5205
5448
|
exports.shouldEmitMissingCssFallback = shouldEmitMissingCssFallback;
|
|
5206
5449
|
exports.shouldEmitWarning = shouldEmitWarning;
|
|
5450
|
+
exports.shouldHoldAdvisories = shouldHoldAdvisories;
|
|
5207
5451
|
exports.shouldTrackGlobalVarSources = shouldTrackGlobalVarSources;
|
|
5208
5452
|
exports.shouldWarnMissingTailwindEntry = shouldWarnMissingTailwindEntry;
|
|
5209
5453
|
exports.shouldWarnUnscopedMonorepo = shouldWarnUnscopedMonorepo;
|