@csszyx/unplugin 0.15.2 → 0.15.3
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 +2 -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.Bk9o8_RZ.mjs → unplugin.C-oQU1jl.mjs} +1 -1
- package/dist/shared/{unplugin.BT7PqYuK.d.cts → unplugin.CInSoHdQ.d.mts} +25 -4
- package/dist/shared/{unplugin.BxsTa17g.mjs → unplugin.CPo2xrEy.mjs} +288 -62
- package/dist/shared/{unplugin.DK0b4fr7.mjs → unplugin.Ceq-N4jI.mjs} +1 -1
- package/dist/shared/{unplugin.DAzgbtuZ.mjs → unplugin.Vn9x8SBP.mjs} +1 -1
- package/dist/shared/{unplugin.dz3AdzsO.cjs → unplugin.ZqxgHk5F.cjs} +286 -60
- package/dist/shared/{unplugin.BT7PqYuK.d.mts → unplugin.nvme_dSL.d.cts} +25 -4
- 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,60 @@ 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 compileManglePreserve(entries) {
|
|
1940
|
+
const exact = /* @__PURE__ */ new Set();
|
|
1941
|
+
const prefixes = [];
|
|
1942
|
+
const list = entries ?? [];
|
|
1943
|
+
list.forEach((entry, index) => {
|
|
1944
|
+
if (typeof entry !== "string" || entry.length === 0) {
|
|
1945
|
+
throw new TypeError(
|
|
1946
|
+
`[csszyx] production.manglePreserve[${index}] must be a non-empty string (an exact class name, or a prefix ending in \`*\`); got ${describe(entry)}.`
|
|
1947
|
+
);
|
|
1948
|
+
}
|
|
1949
|
+
if (entry === "*") {
|
|
1950
|
+
throw new TypeError(
|
|
1951
|
+
"[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`."
|
|
1952
|
+
);
|
|
1953
|
+
}
|
|
1954
|
+
if (entry.endsWith("*")) prefixes.push(entry.slice(0, -1));
|
|
1955
|
+
else exact.add(entry);
|
|
1956
|
+
});
|
|
1957
|
+
const test = (className) => exact.has(className) || prefixes.some((prefix) => className.startsWith(prefix));
|
|
1958
|
+
return {
|
|
1959
|
+
entries: list,
|
|
1960
|
+
test,
|
|
1961
|
+
unmatched(census) {
|
|
1962
|
+
const names = [...census];
|
|
1963
|
+
return list.filter((entry) => {
|
|
1964
|
+
if (entry.endsWith("*")) {
|
|
1965
|
+
const prefix = entry.slice(0, -1);
|
|
1966
|
+
return !names.some((name) => name.startsWith(prefix));
|
|
1967
|
+
}
|
|
1968
|
+
return !names.includes(entry);
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
};
|
|
1972
|
+
}
|
|
1973
|
+
function describe(value) {
|
|
1974
|
+
if (typeof value === "string") return "an empty string";
|
|
1975
|
+
if (value instanceof RegExp) return `a RegExp (${String(value)})`;
|
|
1976
|
+
return `${typeof value} ${JSON.stringify(value) ?? String(value)}`;
|
|
1977
|
+
}
|
|
1978
|
+
function manglePreserveNoMatchMessage(entries) {
|
|
1979
|
+
const sample = entries.slice(0, 8).join(", ");
|
|
1980
|
+
const noun = entries.length === 1 ? "entry" : "entries";
|
|
1981
|
+
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.`;
|
|
1982
|
+
}
|
|
1983
|
+
const TOKEN_CHARACTERS = /^[0-9a-z]+$/i;
|
|
1984
|
+
function mangleExcludeNeverTokenEntries(entries) {
|
|
1985
|
+
return [...entries].filter((entry) => !TOKEN_CHARACTERS.test(entry));
|
|
1986
|
+
}
|
|
1987
|
+
function mangleExcludeNeverTokenMessage(entries) {
|
|
1988
|
+
const sample = entries.slice(0, 8).join(", ");
|
|
1989
|
+
const noun = entries.length === 1 ? "name" : "names";
|
|
1990
|
+
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.`;
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1939
1993
|
const MANGLE_RUNTIME_FILE = "mangle-runtime.mjs";
|
|
1940
1994
|
function ensureMangleRuntimeFile(outputDir, globalVarAliasPrefix, exposeDebugGlobal) {
|
|
1941
1995
|
const target = path__default.join(outputDir, MANGLE_RUNTIME_FILE);
|
|
@@ -2185,9 +2239,9 @@ let _hasWarnedTsConfig = false;
|
|
|
2185
2239
|
let _hasWarnedTransformCacheVersion = false;
|
|
2186
2240
|
let _hasWarnedNativeFallback = false;
|
|
2187
2241
|
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.
|
|
2242
|
+
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.ZqxgHk5F.cjs', document.baseURI).href)));
|
|
2189
2243
|
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.
|
|
2244
|
+
node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/unplugin.ZqxgHk5F.cjs', document.baseURI).href))),
|
|
2191
2245
|
UNKNOWN_PACKAGE_VERSION
|
|
2192
2246
|
);
|
|
2193
2247
|
const COMPILER_VERSION = findPackageVersionFromModule("@csszyx/compiler", UNKNOWN_PACKAGE_VERSION);
|
|
@@ -2229,17 +2283,103 @@ function shouldWarnMissingTailwindEntry(ownedClassCount, sawTailwindEntry, sawAn
|
|
|
2229
2283
|
function missingTailwindEntryMessage(ownedClassCount) {
|
|
2230
2284
|
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
2285
|
}
|
|
2232
|
-
function
|
|
2286
|
+
function asciiLower(text) {
|
|
2287
|
+
return text.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
|
|
2288
|
+
}
|
|
2289
|
+
function attributeSelectorPredicates(operator, value) {
|
|
2290
|
+
const eq = (v) => (name) => name === v;
|
|
2291
|
+
const startsWith = (v) => (name) => name.startsWith(v);
|
|
2292
|
+
const endsWith = (v) => (name) => name.endsWith(v);
|
|
2293
|
+
const includes = (v) => (name) => name.includes(v);
|
|
2294
|
+
const dashPrefix = (v) => (name) => name === v || name.startsWith(`${v}-`);
|
|
2295
|
+
const segments = value.split(/[\t\n\f\r ]+/);
|
|
2296
|
+
if (segments.length === 1) {
|
|
2297
|
+
switch (operator) {
|
|
2298
|
+
case "=":
|
|
2299
|
+
case "~=":
|
|
2300
|
+
return [eq(value)];
|
|
2301
|
+
case "|=":
|
|
2302
|
+
return [dashPrefix(value)];
|
|
2303
|
+
case "^=":
|
|
2304
|
+
return [startsWith(value)];
|
|
2305
|
+
case "$=":
|
|
2306
|
+
return [endsWith(value)];
|
|
2307
|
+
case "*=":
|
|
2308
|
+
return [includes(value)];
|
|
2309
|
+
default:
|
|
2310
|
+
return [];
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
if (operator === "~=") return [];
|
|
2314
|
+
const first = segments[0];
|
|
2315
|
+
const last = segments[segments.length - 1];
|
|
2316
|
+
const predicates = [];
|
|
2317
|
+
if (first.length > 0) {
|
|
2318
|
+
predicates.push(operator === "$=" || operator === "*=" ? endsWith(first) : eq(first));
|
|
2319
|
+
}
|
|
2320
|
+
for (const middle of segments.slice(1, -1)) predicates.push(eq(middle));
|
|
2321
|
+
if (last.length > 0) {
|
|
2322
|
+
if (operator === "^=" || operator === "*=") predicates.push(startsWith(last));
|
|
2323
|
+
else if (operator === "|=") predicates.push(dashPrefix(last));
|
|
2324
|
+
else predicates.push(eq(last));
|
|
2325
|
+
}
|
|
2326
|
+
return predicates;
|
|
2327
|
+
}
|
|
2328
|
+
function renderClassAttributeSelector(selector) {
|
|
2329
|
+
const flag = selector.insensitive ? " i" : "";
|
|
2330
|
+
return `[class${selector.operator}"${selector.value}"${flag}]`;
|
|
2331
|
+
}
|
|
2332
|
+
function selectorHazardFor(mangleMap, selector) {
|
|
2333
|
+
const value = selector.insensitive ? asciiLower(selector.value) : selector.value;
|
|
2334
|
+
const predicates = attributeSelectorPredicates(selector.operator, value);
|
|
2335
|
+
if (predicates.length === 0) return null;
|
|
2336
|
+
const fold = selector.insensitive ? asciiLower : (name) => name;
|
|
2337
|
+
const matches = (name) => {
|
|
2338
|
+
const folded = fold(name);
|
|
2339
|
+
return predicates.some((predicate) => predicate(folded));
|
|
2340
|
+
};
|
|
2341
|
+
const renamed = compiler.sortStrings(Object.keys(mangleMap).filter(matches));
|
|
2342
|
+
const matchedTokens = compiler.sortStrings(Object.values(mangleMap).filter(matches));
|
|
2343
|
+
if (renamed.length === 0 && matchedTokens.length === 0) return null;
|
|
2344
|
+
return {
|
|
2345
|
+
selector: renderClassAttributeSelector(selector),
|
|
2346
|
+
value: selector.value,
|
|
2347
|
+
renamed,
|
|
2348
|
+
matchedTokens
|
|
2349
|
+
};
|
|
2350
|
+
}
|
|
2351
|
+
function collectMangleHybridHazards(mangleMap, mangledSources, externalClasses, attributeSelectors = []) {
|
|
2233
2352
|
const tokenValues = new Set(Object.values(mangleMap));
|
|
2234
2353
|
const collisions = compiler.sortStrings([...tokenValues].filter((token) => externalClasses.has(token)));
|
|
2235
2354
|
const orphans = compiler.sortStrings(
|
|
2236
2355
|
Object.keys(mangleMap).filter((source) => !mangledSources.has(source))
|
|
2237
2356
|
);
|
|
2238
|
-
|
|
2357
|
+
const hazards = /* @__PURE__ */ new Map();
|
|
2358
|
+
for (const selector of attributeSelectors) {
|
|
2359
|
+
const hazard = selectorHazardFor(mangleMap, selector);
|
|
2360
|
+
if (hazard !== null) hazards.set(hazard.selector, hazard);
|
|
2361
|
+
}
|
|
2362
|
+
const selectorMatches = compiler.sortStrings([...hazards.keys()]).map(
|
|
2363
|
+
(key) => hazards.get(key)
|
|
2364
|
+
);
|
|
2365
|
+
return { collisions, orphans, selectorMatches };
|
|
2366
|
+
}
|
|
2367
|
+
const BACKSLASH = String.fromCodePoint(92);
|
|
2368
|
+
const SINGLE_QUOTE = String.fromCodePoint(39);
|
|
2369
|
+
function quoteForConfig(entry) {
|
|
2370
|
+
const escaped = entry.replaceAll(BACKSLASH, BACKSLASH + BACKSLASH).replaceAll(SINGLE_QUOTE, BACKSLASH + SINGLE_QUOTE);
|
|
2371
|
+
return SINGLE_QUOTE + escaped + SINGLE_QUOTE;
|
|
2372
|
+
}
|
|
2373
|
+
function preserveEntriesFor(hazard) {
|
|
2374
|
+
const quote = quoteForConfig;
|
|
2375
|
+
const { value } = hazard;
|
|
2376
|
+
if (hazard.renamed.every((name) => name === value)) return [quote(value)];
|
|
2377
|
+
if (hazard.renamed.every((name) => name.startsWith(value))) return [quote(`${value}*`)];
|
|
2378
|
+
return hazard.renamed.map(quote);
|
|
2239
2379
|
}
|
|
2240
2380
|
function mangleHybridHazardMessage(hazards) {
|
|
2241
|
-
const { collisions, orphans } = hazards;
|
|
2242
|
-
if (collisions.length === 0 && orphans.length === 0) {
|
|
2381
|
+
const { collisions, orphans, selectorMatches = [] } = hazards;
|
|
2382
|
+
if (collisions.length === 0 && orphans.length === 0 && selectorMatches.length === 0) {
|
|
2243
2383
|
return null;
|
|
2244
2384
|
}
|
|
2245
2385
|
const parts = ["[csszyx] production mangle found hybrid hazards:"];
|
|
@@ -2255,15 +2395,35 @@ function mangleHybridHazardMessage(hazards) {
|
|
|
2255
2395
|
` ${orphans.length} mangled class(es) have no emitted CSS rule (e.g. ${sample}) \u2014 those elements lose styling.`
|
|
2256
2396
|
);
|
|
2257
2397
|
}
|
|
2398
|
+
const broken = selectorMatches.filter((hazard) => hazard.renamed.length > 0);
|
|
2399
|
+
const newlyMatched = selectorMatches.filter((hazard) => hazard.matchedTokens.length > 0);
|
|
2400
|
+
if (broken.length > 0) {
|
|
2401
|
+
const sample = broken.slice(0, 3).map((hazard) => `${hazard.selector} \u2192 ${hazard.renamed.slice(0, 4).join(", ")}`).join("; ");
|
|
2402
|
+
parts.push(
|
|
2403
|
+
` ${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.`
|
|
2404
|
+
);
|
|
2405
|
+
}
|
|
2406
|
+
if (newlyMatched.length > 0) {
|
|
2407
|
+
const sample = newlyMatched.slice(0, 3).map((hazard) => `${hazard.selector} \u2192 ${hazard.matchedTokens.slice(0, 4).join(", ")}`).join("; ");
|
|
2408
|
+
parts.push(
|
|
2409
|
+
` ${newlyMatched.length} attribute selector(s) would start matching mangled tokens instead (e.g. ${sample}).`
|
|
2410
|
+
);
|
|
2411
|
+
}
|
|
2258
2412
|
if (collisions.length > 0) {
|
|
2259
2413
|
parts.push(
|
|
2260
2414
|
" 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."
|
|
2261
2415
|
);
|
|
2262
|
-
} else {
|
|
2416
|
+
} else if (orphans.length > 0) {
|
|
2263
2417
|
parts.push(
|
|
2264
2418
|
" 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."
|
|
2265
2419
|
);
|
|
2266
2420
|
}
|
|
2421
|
+
if (broken.length > 0) {
|
|
2422
|
+
const entries = [...new Set(broken.flatMap(preserveEntriesFor))].join(", ");
|
|
2423
|
+
parts.push(
|
|
2424
|
+
` 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.`
|
|
2425
|
+
);
|
|
2426
|
+
}
|
|
2267
2427
|
return parts.join("");
|
|
2268
2428
|
}
|
|
2269
2429
|
const TAILWIND_IMPORT_SPECIFIER = /@import\s+["']tailwindcss(?:\/[^"']*)?["']/g;
|
|
@@ -3168,6 +3328,8 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3168
3328
|
const szObjectProvidersExamined = /* @__PURE__ */ new Set();
|
|
3169
3329
|
let specifierAliases = [];
|
|
3170
3330
|
const mangleReserved = new Set(options.production?.mangleExclude ?? []);
|
|
3331
|
+
const manglePreserve = compileManglePreserve(options.production?.manglePreserve);
|
|
3332
|
+
let manglePreserveNoMatchWarned = false;
|
|
3171
3333
|
let mangleMapFrozen = false;
|
|
3172
3334
|
let prescanSawServerModule = false;
|
|
3173
3335
|
let skipRscRecords = false;
|
|
@@ -3178,6 +3340,7 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3178
3340
|
let projectCssFiles = [];
|
|
3179
3341
|
const transformMangledSources = /* @__PURE__ */ new Set();
|
|
3180
3342
|
const transformExternalClasses = /* @__PURE__ */ new Set();
|
|
3343
|
+
const transformAttributeSelectors = /* @__PURE__ */ new Map();
|
|
3181
3344
|
if (options.production?.mangleMapDelivery !== void 0) {
|
|
3182
3345
|
console.warn(removedMangleMapDeliveryMessage());
|
|
3183
3346
|
}
|
|
@@ -3207,6 +3370,10 @@ function createCsszyxPlugins(options = {}) {
|
|
|
3207
3370
|
if (unknownConfigKeys.length > 0) {
|
|
3208
3371
|
emitWarning(unknownConfigKeysMessage(unknownConfigKeys));
|
|
3209
3372
|
}
|
|
3373
|
+
const excludeNeverTokens = mangleExcludeNeverTokenEntries(mangleReserved);
|
|
3374
|
+
if (excludeNeverTokens.length > 0) {
|
|
3375
|
+
emitWarning(mangleExcludeNeverTokenMessage(excludeNeverTokens));
|
|
3376
|
+
}
|
|
3210
3377
|
function emitWarning(message, opts = {}) {
|
|
3211
3378
|
if (shouldEmitWarning(quiet, opts.devOnly ?? false, process.env.NODE_ENV === "production")) {
|
|
3212
3379
|
console.warn(message);
|
|
@@ -4067,10 +4234,15 @@ function createCsszyxPlugins(options = {}) {
|
|
|
4067
4234
|
...state.authoredClasses,
|
|
4068
4235
|
...state.ownedClasses
|
|
4069
4236
|
]);
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
forbiddenTokens
|
|
4237
|
+
const eligible = mangleEligibleClasses(state.ownedClasses, state.authoredClasses).filter(
|
|
4238
|
+
(className) => !manglePreserve.test(className)
|
|
4073
4239
|
);
|
|
4240
|
+
if (!manglePreserveNoMatchWarned && manglingEnabled && state.ownedClasses.size > 0) {
|
|
4241
|
+
manglePreserveNoMatchWarned = true;
|
|
4242
|
+
const unmatched = manglePreserve.unmatched(state.ownedClasses);
|
|
4243
|
+
if (unmatched.length > 0) emitWarning(manglePreserveNoMatchMessage(unmatched));
|
|
4244
|
+
}
|
|
4245
|
+
return allocateMangleTokens(eligible, forbiddenTokens);
|
|
4074
4246
|
}
|
|
4075
4247
|
function freezeMangleMap() {
|
|
4076
4248
|
state.mangleMap = computeMangleMap();
|
|
@@ -4223,6 +4395,38 @@ function createCsszyxPlugins(options = {}) {
|
|
|
4223
4395
|
}
|
|
4224
4396
|
return modules;
|
|
4225
4397
|
}
|
|
4398
|
+
function handleHotFile(pass, ctx) {
|
|
4399
|
+
const { isClientPass } = pass;
|
|
4400
|
+
if (isClientPass) {
|
|
4401
|
+
prescanResultHandoff.clear();
|
|
4402
|
+
}
|
|
4403
|
+
const scanCss = options.build?.scanCss;
|
|
4404
|
+
const reloadThemeGroupsModule = () => {
|
|
4405
|
+
const themeGroupsModule = ctx.server.moduleGraph.getModuleById(
|
|
4406
|
+
themeGroupsFile.RESOLVED_THEME_GROUPS_VIRTUAL_ID
|
|
4407
|
+
);
|
|
4408
|
+
if (themeGroupsModule) {
|
|
4409
|
+
ctx.server.moduleGraph.invalidateModule(themeGroupsModule);
|
|
4410
|
+
}
|
|
4411
|
+
};
|
|
4412
|
+
if (isClientPass && ctx.file.endsWith(".css")) {
|
|
4413
|
+
const root = state.rootDir;
|
|
4414
|
+
const before = themeGroupsFile.createThemeGroupsModule(themeGroupTokens());
|
|
4415
|
+
if (scanCss && matchesAnyPattern(ctx.file, scanCss, root)) {
|
|
4416
|
+
state.scanCssTheme = runThemeScan(root, scanCss) ?? state.scanCssTheme;
|
|
4417
|
+
}
|
|
4418
|
+
runAutoThemeScan(root);
|
|
4419
|
+
reloadThemeGroupsModule();
|
|
4420
|
+
if (themeGroupsFile.createThemeGroupsModule(themeGroupTokens()) !== before) {
|
|
4421
|
+
ctx.server.ws.send({ type: "full-reload" });
|
|
4422
|
+
}
|
|
4423
|
+
}
|
|
4424
|
+
if (safelistSource.normalizePathSeparators(ctx.file) === safelistSource.normalizePathSeparators(path__namespace.join(state.rootDir, SAFELIST_FILENAME))) {
|
|
4425
|
+
return tailwindEntryModules(pass.moduleGraph());
|
|
4426
|
+
}
|
|
4427
|
+
if (isClientPass) discoverHotFileClasses(ctx.file, ctx.server.watcher);
|
|
4428
|
+
return void 0;
|
|
4429
|
+
}
|
|
4226
4430
|
function transformTailwindCssEntry(code, id) {
|
|
4227
4431
|
state.sawAnyCss = true;
|
|
4228
4432
|
const [cssFile] = id.split("?");
|
|
@@ -4724,38 +4928,39 @@ ${transformedCode}`;
|
|
|
4724
4928
|
* which leaves Vite's own handling in place.
|
|
4725
4929
|
*/
|
|
4726
4930
|
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
|
-
|
|
4931
|
+
return handleHotFile(
|
|
4932
|
+
{
|
|
4933
|
+
isClientPass: (this.environment?.name ?? "client") === "client",
|
|
4934
|
+
// `server.moduleGraph` holds the backward-compatible
|
|
4935
|
+
// nodes Vite mapped back for the legacy hook only,
|
|
4936
|
+
// so they are the wrong objects to hand this one —
|
|
4937
|
+
// TypeScript says so too.
|
|
4938
|
+
moduleGraph: () => this.environment?.moduleGraph ?? ctx.server.environments.client.moduleGraph
|
|
4939
|
+
},
|
|
4940
|
+
ctx
|
|
4941
|
+
);
|
|
4942
|
+
},
|
|
4943
|
+
/**
|
|
4944
|
+
* The hook Vite 5 calls. Vite 6 and later never run it while
|
|
4945
|
+
* `hotUpdate` is declared, so declaring both costs nothing
|
|
4946
|
+
* there and keeps a Vite 5 dev server compiling `sz` live.
|
|
4947
|
+
*
|
|
4948
|
+
* Vite 5 routes only a file CHANGE here, never a create, so a
|
|
4949
|
+
* project with no `sz` at prescan still sees its first `sz`
|
|
4950
|
+
* edit answered by `@tailwindcss/vite`'s full reload on that
|
|
4951
|
+
* generation — the behaviour it always had there. The hook
|
|
4952
|
+
* runs once, with no environment, so it is the client pass
|
|
4953
|
+
* and answers from the server-wide graph.
|
|
4954
|
+
*
|
|
4955
|
+
* @param ctx - HMR context: the changed file and the dev server.
|
|
4956
|
+
* @returns The modules a safelist write affects; undefined
|
|
4957
|
+
* otherwise.
|
|
4958
|
+
*/
|
|
4959
|
+
handleHotUpdate(ctx) {
|
|
4960
|
+
return handleHotFile(
|
|
4961
|
+
{ isClientPass: true, moduleGraph: () => ctx.server.moduleGraph },
|
|
4962
|
+
ctx
|
|
4963
|
+
);
|
|
4759
4964
|
},
|
|
4760
4965
|
transformIndexHtml: {
|
|
4761
4966
|
order: "pre",
|
|
@@ -4844,7 +5049,7 @@ ${transformedCode}`;
|
|
|
4844
5049
|
recordCodePair(sizeAccount, before, after);
|
|
4845
5050
|
return after;
|
|
4846
5051
|
}
|
|
4847
|
-
function rewriteOutputCss(source, file, shouldMangle, mangledSources, externalClasses) {
|
|
5052
|
+
function rewriteOutputCss(source, file, shouldMangle, mangledSources, externalClasses, attributeSelectors) {
|
|
4848
5053
|
const css = rewriteCssWithValidatedGlobalVarPlan(
|
|
4849
5054
|
source,
|
|
4850
5055
|
file,
|
|
@@ -4858,6 +5063,9 @@ ${transformedCode}`;
|
|
|
4858
5063
|
});
|
|
4859
5064
|
for (const className of result.mangledClasses) mangledSources.add(className);
|
|
4860
5065
|
for (const className of result.unmangledClasses) externalClasses.add(className);
|
|
5066
|
+
for (const selector of result.classAttributeSelectors) {
|
|
5067
|
+
attributeSelectors.set(cssMangler.classAttributeSelectorKey(selector), selector);
|
|
5068
|
+
}
|
|
4861
5069
|
const mangled = result.transformedCount > 0 ? result.css : css;
|
|
4862
5070
|
recordCssPair(sizeAccount, css, mangled);
|
|
4863
5071
|
return mangled;
|
|
@@ -4866,10 +5074,12 @@ ${transformedCode}`;
|
|
|
4866
5074
|
throw error;
|
|
4867
5075
|
}
|
|
4868
5076
|
}
|
|
4869
|
-
function reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses) {
|
|
5077
|
+
function reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses, attributeSelectors) {
|
|
4870
5078
|
if (!shouldMangle) return;
|
|
4871
5079
|
const message = mangleHybridHazardMessage(
|
|
4872
|
-
collectMangleHybridHazards(state.mangleMap, mangledSources, externalClasses
|
|
5080
|
+
collectMangleHybridHazards(state.mangleMap, mangledSources, externalClasses, [
|
|
5081
|
+
...attributeSelectors.values()
|
|
5082
|
+
])
|
|
4873
5083
|
);
|
|
4874
5084
|
if (message) console.warn(message);
|
|
4875
5085
|
}
|
|
@@ -4930,6 +5140,7 @@ ${transformedCode}`;
|
|
|
4930
5140
|
}
|
|
4931
5141
|
const mangledSources = /* @__PURE__ */ new Set();
|
|
4932
5142
|
const externalClasses = /* @__PURE__ */ new Set();
|
|
5143
|
+
const attributeSelectors = /* @__PURE__ */ new Map();
|
|
4933
5144
|
for (const file in assets) {
|
|
4934
5145
|
const source = assets[file].source().toString();
|
|
4935
5146
|
if (file.endsWith(".css")) {
|
|
@@ -4938,7 +5149,8 @@ ${transformedCode}`;
|
|
|
4938
5149
|
file,
|
|
4939
5150
|
shouldMangle,
|
|
4940
5151
|
mangledSources,
|
|
4941
|
-
externalClasses
|
|
5152
|
+
externalClasses,
|
|
5153
|
+
attributeSelectors
|
|
4942
5154
|
);
|
|
4943
5155
|
if (css !== source) {
|
|
4944
5156
|
compilation.updateAsset(file, new compiler.webpack.sources.RawSource(css));
|
|
@@ -4947,10 +5159,15 @@ ${transformedCode}`;
|
|
|
4947
5159
|
rewriteWebpackCodeAsset(file, source, shouldMangle, compilation, compiler);
|
|
4948
5160
|
}
|
|
4949
5161
|
}
|
|
4950
|
-
reportOutputMangleHazards(
|
|
5162
|
+
reportOutputMangleHazards(
|
|
5163
|
+
shouldMangle,
|
|
5164
|
+
mangledSources,
|
|
5165
|
+
externalClasses,
|
|
5166
|
+
attributeSelectors
|
|
5167
|
+
);
|
|
4951
5168
|
reportBuildSummary();
|
|
4952
5169
|
}
|
|
4953
|
-
function rewriteViteBundleEntry(chunk, file, shouldMangle, mangledSources, externalClasses) {
|
|
5170
|
+
function rewriteViteBundleEntry(chunk, file, shouldMangle, mangledSources, externalClasses, attributeSelectors) {
|
|
4954
5171
|
if (chunk.type !== "asset" || !chunk.fileName.endsWith(".css") || chunk.source === void 0) {
|
|
4955
5172
|
return;
|
|
4956
5173
|
}
|
|
@@ -4960,7 +5177,8 @@ ${transformedCode}`;
|
|
|
4960
5177
|
file,
|
|
4961
5178
|
shouldMangle,
|
|
4962
5179
|
mangledSources,
|
|
4963
|
-
externalClasses
|
|
5180
|
+
externalClasses,
|
|
5181
|
+
attributeSelectors
|
|
4964
5182
|
);
|
|
4965
5183
|
if (css !== originalCss) chunk.source = css;
|
|
4966
5184
|
}
|
|
@@ -4971,7 +5189,8 @@ ${transformedCode}`;
|
|
|
4971
5189
|
id,
|
|
4972
5190
|
shouldMangle,
|
|
4973
5191
|
transformMangledSources,
|
|
4974
|
-
transformExternalClasses
|
|
5192
|
+
transformExternalClasses,
|
|
5193
|
+
transformAttributeSelectors
|
|
4975
5194
|
);
|
|
4976
5195
|
return css === code ? null : { code: css, map: null };
|
|
4977
5196
|
}
|
|
@@ -4996,6 +5215,7 @@ ${transformedCode}`;
|
|
|
4996
5215
|
}
|
|
4997
5216
|
const mangledSources = new Set(transformMangledSources);
|
|
4998
5217
|
const externalClasses = new Set(transformExternalClasses);
|
|
5218
|
+
const attributeSelectors = new Map(transformAttributeSelectors);
|
|
4999
5219
|
if (!cssRewrittenInTransform) {
|
|
5000
5220
|
for (const file in bundle) {
|
|
5001
5221
|
rewriteViteBundleEntry(
|
|
@@ -5003,11 +5223,17 @@ ${transformedCode}`;
|
|
|
5003
5223
|
file,
|
|
5004
5224
|
shouldMangle,
|
|
5005
5225
|
mangledSources,
|
|
5006
|
-
externalClasses
|
|
5226
|
+
externalClasses,
|
|
5227
|
+
attributeSelectors
|
|
5007
5228
|
);
|
|
5008
5229
|
}
|
|
5009
5230
|
}
|
|
5010
|
-
reportOutputMangleHazards(
|
|
5231
|
+
reportOutputMangleHazards(
|
|
5232
|
+
shouldMangle,
|
|
5233
|
+
mangledSources,
|
|
5234
|
+
externalClasses,
|
|
5235
|
+
attributeSelectors
|
|
5236
|
+
);
|
|
5011
5237
|
}
|
|
5012
5238
|
const postPlugin = unplugin$1.createUnplugin(() => ({
|
|
5013
5239
|
name: "csszyx:post",
|
|
@@ -4,6 +4,7 @@ import { Plugin } from 'esbuild';
|
|
|
4
4
|
import { InputPluginOption } from 'rollup';
|
|
5
5
|
import { UnpluginInstance, WebpackPluginInstance } from 'unplugin';
|
|
6
6
|
import { PluginOption } from 'vite';
|
|
7
|
+
import { ClassAttributeSelector } from '../css-mangler.cjs';
|
|
7
8
|
|
|
8
9
|
/** Source location for one CSS custom-property occurrence. */
|
|
9
10
|
interface CssVarLocation {
|
|
@@ -655,6 +656,25 @@ interface MangleHybridHazards {
|
|
|
655
656
|
* DOM class is rewritten to a token with no rule → the element loses styling.
|
|
656
657
|
*/
|
|
657
658
|
orphans: string[];
|
|
659
|
+
/**
|
|
660
|
+
* Attribute selectors on `class` whose match depends on a name the map
|
|
661
|
+
* renamed. `[class*="bg-tag"]` matched `bg-tag-blue-bg` by text; after
|
|
662
|
+
* the rename the element carries `y4`, the rule stops applying, and
|
|
663
|
+
* nothing in the build says so — the CSS is intact and the page renders.
|
|
664
|
+
* Absent when the caller has no selector census.
|
|
665
|
+
*/
|
|
666
|
+
selectorMatches?: MangleSelectorHazard[];
|
|
667
|
+
}
|
|
668
|
+
/** One attribute selector the mangle map breaks or newly satisfies. */
|
|
669
|
+
interface MangleSelectorHazard {
|
|
670
|
+
/** The selector as written: `[class*="bg-tag"]`, with ` i` when case-insensitive. */
|
|
671
|
+
selector: string;
|
|
672
|
+
/** The attribute value the selector compares against, unescaped. */
|
|
673
|
+
value: string;
|
|
674
|
+
/** Map keys the selector was matching by name, sorted; renamed, so it no longer does. */
|
|
675
|
+
renamed: string[];
|
|
676
|
+
/** Tokens the selector would start matching that no class name did before, sorted. */
|
|
677
|
+
matchedTokens: string[];
|
|
658
678
|
}
|
|
659
679
|
/**
|
|
660
680
|
* Detect hybrid-mangle hazards from the accumulated per-asset mangle results.
|
|
@@ -662,9 +682,10 @@ interface MangleHybridHazards {
|
|
|
662
682
|
* @param mangleMap - the full original→token map injected into the runtime.
|
|
663
683
|
* @param mangledSources - map keys that were actually found and renamed in some CSS asset.
|
|
664
684
|
* @param externalClasses - class names found in CSS that are NOT in the mangle map (non-csszyx).
|
|
665
|
-
* @
|
|
685
|
+
* @param attributeSelectors - every `[class …]` selector the emitted CSS contains.
|
|
686
|
+
* @returns the colliding tokens, orphan sources and selector hazards (each sorted, deduped).
|
|
666
687
|
*/
|
|
667
|
-
declare function collectMangleHybridHazards(mangleMap: Record<string, string>, mangledSources: ReadonlySet<string>, externalClasses: ReadonlySet<string
|
|
688
|
+
declare function collectMangleHybridHazards(mangleMap: Record<string, string>, mangledSources: ReadonlySet<string>, externalClasses: ReadonlySet<string>, attributeSelectors?: readonly ClassAttributeSelector[]): MangleHybridHazards;
|
|
668
689
|
/**
|
|
669
690
|
* Build the hybrid-mangle hazard warning, or null when there is nothing to warn.
|
|
670
691
|
*
|
|
@@ -1042,5 +1063,5 @@ declare const rollupPlugin: (options?: PartialCsszyxConfig) => InputPluginOption
|
|
|
1042
1063
|
*/
|
|
1043
1064
|
declare const esbuildPlugin: (options?: PartialCsszyxConfig) => Plugin;
|
|
1044
1065
|
|
|
1045
|
-
export {
|
|
1046
|
-
export type { CssVarScanResult as C, GlobalVarScanCacheKeyInput as G, MangleHybridHazards as M, PlanGlobalVarAliasesInput as P, QuietMode as Q, RewriteGlobalVarCssAliasesOptions as R, ScanGlobalVarCssOptions as S, ValidateGlobalVarAliasInputsOptions as V, GlobalVarAliasPlan as a, GlobalVarCssAliasRewriteResult as b, CreateGlobalVarAliasValidationOptionsInput as c, GlobalVarAliasValidationResult as d, CssVarDefinition as e, CssVarLocation as f, CssVarReference as g, GlobalVarAliasDiagnostic as h, GlobalVarAliasDiagnosticSeverity as i, GlobalVarAliasEntry as j, GlobalVarCodeSource as k, GlobalVarCssAssetSource as l, GlobalVarCssSource as m, GlobalVarScanCacheEntry as n,
|
|
1066
|
+
export { isRSCServerModule as $, unplugin as A, deleteRSCModuleRecord as B, emitMissingCssFallback as D, esbuildPlugin as E, extractGlobalVarAliasesForManifest as F, fileMayContainSafelistableSz as H, findLocalImportSources as I, findRSCBoundaryViolation as J, findRSCGraphViolation as K, hasInjectableTailwindCandidate as L, hasTokens as N, hasUseClientDirective as O, hasUseServerDirective as T, isAdvisoryDiagnostic as U, isCompileSourceOptedIn as W, isHardIgnoredPath as X, isMangleableCssId as Y, isMonorepoPackage as Z, isPackagesSkippedSource as _, lateMangleCensusMessage as a0, mangleCodeClassesSync as a1, mangleEligibleClasses as a2, mangleHybridHazardMessage as a3, mergeThemes as a4, missingTailwindEntryMessage as a5, normalizeGlobalVarAliasesForCache as a6, parseThemeBlocks as a7, parseUtilityBlocks as a8, realContentHashDisabledMessage as a9, recordGlobalVarSourceFile as aa, resolveCompileSourceDirs as ab, resolveNativeCacheIdentity as ac, resolveQuietMode as ad, rollupPlugin as ae, scanCustomPropertyNames as af, shouldEmitMissingCssFallback as ag, shouldEmitWarning as ah, shouldTrackGlobalVarSources as ai, shouldWarnMissingTailwindEntry as aj, shouldWarnUnscopedMonorepo as ak, skippedSzFilesMessage as al, suppressedAdvisoryMessage as am, unscopedMonorepoMessage as an, vitePlugin as ao, watchModeMangleMessage as ap, webpackPlugin as aq, allocateMangleTokens as t, assertNoRSCBoundaryViolation as u, assertNoRSCGraphViolation as v, collectMangleHybridHazards as w, createGlobalVarMapAssetSource as x, createRSCModuleRecord as y, cssHasContentScope as z };
|
|
1067
|
+
export type { CssVarScanResult as C, GlobalVarScanCacheKeyInput as G, MangleHybridHazards as M, PlanGlobalVarAliasesInput as P, QuietMode as Q, RewriteGlobalVarCssAliasesOptions as R, ScanGlobalVarCssOptions as S, ValidateGlobalVarAliasInputsOptions as V, GlobalVarAliasPlan as a, GlobalVarCssAliasRewriteResult as b, CreateGlobalVarAliasValidationOptionsInput as c, GlobalVarAliasValidationResult as d, CssVarDefinition as e, CssVarLocation as f, CssVarReference as g, GlobalVarAliasDiagnostic as h, GlobalVarAliasDiagnosticSeverity as i, GlobalVarAliasEntry as j, GlobalVarCodeSource as k, GlobalVarCssAssetSource as l, GlobalVarCssSource as m, GlobalVarScanCacheEntry as n, MangleSelectorHazard as o, ParsedTheme as p, ParsedUtilities as q, RSCBoundaryViolation as r, RSCModuleRecord as s };
|
package/dist/vite.cjs
CHANGED
package/dist/vite.d.cts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export =
|
|
1
|
+
import { ao } from './shared/unplugin.nvme_dSL.cjs';
|
|
2
|
+
export = ao;
|
|
3
3
|
import '@csszyx/compiler';
|
|
4
4
|
import '@csszyx/types';
|
|
5
5
|
import 'esbuild';
|
|
6
6
|
import 'rollup';
|
|
7
7
|
import 'unplugin';
|
|
8
8
|
import 'vite';
|
|
9
|
+
import './css-mangler.cjs';
|
|
10
|
+
import 'postcss';
|
package/dist/vite.d.mts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { ao as default } from './shared/unplugin.CInSoHdQ.mjs';
|
|
2
2
|
import '@csszyx/compiler';
|
|
3
3
|
import '@csszyx/types';
|
|
4
4
|
import 'esbuild';
|
|
5
5
|
import 'rollup';
|
|
6
6
|
import 'unplugin';
|
|
7
7
|
import 'vite';
|
|
8
|
+
import './css-mangler.mjs';
|
|
9
|
+
import 'postcss';
|
package/dist/vite.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { a1 as default } from './shared/unplugin.
|
|
1
|
+
export { a1 as default } from './shared/unplugin.CPo2xrEy.mjs';
|
|
2
2
|
import 'node:crypto';
|
|
3
3
|
import 'node:fs';
|
|
4
4
|
import 'node:module';
|
|
@@ -13,10 +13,10 @@ import '@csszyx/types';
|
|
|
13
13
|
import '@csszyx/vue-adapter';
|
|
14
14
|
import 'unplugin';
|
|
15
15
|
import './shared/unplugin.DH_ij6cf.mjs';
|
|
16
|
-
import './shared/unplugin.
|
|
16
|
+
import './shared/unplugin.C-oQU1jl.mjs';
|
|
17
17
|
import './css-mangler.mjs';
|
|
18
18
|
import 'postcss';
|
|
19
19
|
import 'postcss-selector-parser';
|
|
20
|
-
import './shared/unplugin.
|
|
20
|
+
import './shared/unplugin.Ceq-N4jI.mjs';
|
|
21
21
|
import 'node:zlib';
|
|
22
22
|
import 'postcss-value-parser';
|
package/dist/webpack.cjs
CHANGED