elcrm 1.1.10 → 1.1.12
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.
|
@@ -53,6 +53,12 @@ export declare function replaceCssVarToken(
|
|
|
53
53
|
/** Имена `--*` в CSS, без суффиксов BEM-классов. */
|
|
54
54
|
export declare function collectCssVarNames(texts: string[]): string[];
|
|
55
55
|
|
|
56
|
+
/** Один словарь: длинные `--*` первыми, граница токена (CSS и JS). */
|
|
57
|
+
export declare function applyVarDictionary(
|
|
58
|
+
text: string,
|
|
59
|
+
map: Iterable<[string, string]>,
|
|
60
|
+
): string;
|
|
61
|
+
|
|
56
62
|
export declare function isVendorJsChunk(code: string): boolean;
|
|
57
63
|
|
|
58
64
|
export declare function minifyCssVars(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/vite/minify-css-vars.ts
|
|
2
2
|
var VAR_RE = /(?<![\w-])--[a-zA-Z_][\w-]*/g;
|
|
3
|
-
var VAR_IN_JS_RE = /var\(\s*(--[a-zA-Z_][\w-]*)|["'](--[a-zA-Z_][\w-]*)["']
|
|
3
|
+
var VAR_IN_JS_RE = /var\(\s*(--[a-zA-Z_][\w-]*)|["'](--[a-zA-Z_][\w-]*)["']|(?<![\w-])(--[a-zA-Z_][\w-]*)\s*:/g;
|
|
4
4
|
var CLASS_SEL_RE = /\.(-?[_a-zA-Z]+[_a-zA-Z0-9-]*)/g;
|
|
5
5
|
var LETTERS = "abcdefghijklmnopqrstuvwxyz";
|
|
6
6
|
function collect(texts, re) {
|
|
@@ -23,7 +23,7 @@ function collectJsVars(texts) {
|
|
|
23
23
|
VAR_IN_JS_RE.lastIndex = 0;
|
|
24
24
|
let m;
|
|
25
25
|
while (m = VAR_IN_JS_RE.exec(text)) {
|
|
26
|
-
const name = m[1] ?? m[2];
|
|
26
|
+
const name = m[1] ?? m[2] ?? m[3];
|
|
27
27
|
if (name && !/^--[a-zA-Z_]{1,3}$/.test(name))
|
|
28
28
|
set.add(name);
|
|
29
29
|
}
|
|
@@ -70,6 +70,8 @@ function namespaceSize(length) {
|
|
|
70
70
|
}
|
|
71
71
|
function allocateUnique(originals, reserved, make, start, capacity, kind) {
|
|
72
72
|
const taken = new Set(reserved);
|
|
73
|
+
for (const from of originals)
|
|
74
|
+
taken.add(from);
|
|
73
75
|
const out = new Map;
|
|
74
76
|
let cursor = start;
|
|
75
77
|
for (const from of originals) {
|
|
@@ -91,12 +93,13 @@ function allocateUnique(originals, reserved, make, start, capacity, kind) {
|
|
|
91
93
|
taken.add(found);
|
|
92
94
|
}
|
|
93
95
|
const used = new Set;
|
|
96
|
+
const originalSet = new Set(originals);
|
|
94
97
|
for (const [from, to] of out) {
|
|
95
98
|
if (used.has(to)) {
|
|
96
99
|
throw new Error(`[minify-css-vars] коллизия ${kind}: «${from}» и ещё одно имя → «${to}»`);
|
|
97
100
|
}
|
|
98
101
|
used.add(to);
|
|
99
|
-
if (reserved.has(to)) {
|
|
102
|
+
if (reserved.has(to) || originalSet.has(to)) {
|
|
100
103
|
throw new Error(`[minify-css-vars] «${from}» → «${to}» затирает существующее имя ${kind}`);
|
|
101
104
|
}
|
|
102
105
|
}
|
|
@@ -111,18 +114,15 @@ function replaceCssVarToken(text, from, to) {
|
|
|
111
114
|
function collectCssVarNames(texts) {
|
|
112
115
|
return [...collect(texts, VAR_RE)].sort();
|
|
113
116
|
}
|
|
114
|
-
function
|
|
117
|
+
function applyVarDictionary(text, map) {
|
|
118
|
+
const entries = [...map].sort((a, b) => b[0].length - a[0].length || a[0].localeCompare(b[0]));
|
|
119
|
+
const mark = (i) => `${i.toString(36)}`;
|
|
115
120
|
let out = text;
|
|
116
|
-
for (
|
|
117
|
-
out = replaceCssVarToken(out,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
let out = text;
|
|
122
|
-
for (const [from, to] of map) {
|
|
123
|
-
const esc = escapeRe(from);
|
|
124
|
-
out = out.replace(new RegExp(`var\\(\\s*${esc}(?=[\\s,)])`, "g"), (m) => m.replace(from, to));
|
|
125
|
-
out = out.replace(new RegExp(`(["'])${esc}\\1`, "g"), `$1${to}$1`);
|
|
121
|
+
for (let i = 0;i < entries.length; i++) {
|
|
122
|
+
out = replaceCssVarToken(out, entries[i][0], mark(i));
|
|
123
|
+
}
|
|
124
|
+
for (let i = 0;i < entries.length; i++) {
|
|
125
|
+
out = out.split(mark(i)).join(entries[i][1]);
|
|
126
126
|
}
|
|
127
127
|
return out;
|
|
128
128
|
}
|
|
@@ -199,7 +199,7 @@ function minifyCssVars(options) {
|
|
|
199
199
|
files.push({ item, fileName, raw, isCss, isJs });
|
|
200
200
|
}
|
|
201
201
|
const cssTexts = files.filter((f) => f.isCss).map((f) => f.raw);
|
|
202
|
-
const jsTexts = files.filter((f) => f.isJs).map((f) => f.raw);
|
|
202
|
+
const jsTexts = files.filter((f) => f.isJs && !isVendorJsChunk(f.raw)).map((f) => f.raw);
|
|
203
203
|
const varMap = new Map;
|
|
204
204
|
if (opt.vars) {
|
|
205
205
|
const names = new Set([
|
|
@@ -260,7 +260,7 @@ function minifyCssVars(options) {
|
|
|
260
260
|
let next = file.raw;
|
|
261
261
|
const skipJsVendor = file.isJs && isVendorJsChunk(next);
|
|
262
262
|
if (varMap.size && !skipJsVendor) {
|
|
263
|
-
next =
|
|
263
|
+
next = applyVarDictionary(next, varEntries);
|
|
264
264
|
}
|
|
265
265
|
if (classMap.size && !skipJsVendor) {
|
|
266
266
|
next = replaceClasses(next, classMap, file.isCss);
|
|
@@ -296,5 +296,6 @@ export {
|
|
|
296
296
|
isVendorJsChunk,
|
|
297
297
|
encodeName,
|
|
298
298
|
collectCssVarNames,
|
|
299
|
+
applyVarDictionary,
|
|
299
300
|
allocateUnique
|
|
300
301
|
};
|
package/package.json
CHANGED
|
@@ -92,7 +92,7 @@ elcrm test --front|--server|--no-scripts
|
|
|
92
92
|
|
|
93
93
|
### Vite-плагины из пакета `elcrm`
|
|
94
94
|
|
|
95
|
-
Нужен **elcrm ≥ 1.1.
|
|
95
|
+
Нужен **elcrm ≥ 1.1.12** в `devDependencies` приложения (не только глобальный `bun i -g`). Иначе Vite: `Missing "./vite/minify-css-vars"` или CSS-in-JS / цепочка замен схлопывает токены.
|
|
96
96
|
|
|
97
97
|
```js
|
|
98
98
|
import { minifyCssVars } from "elcrm/vite/minify-css-vars";
|
|
@@ -102,7 +102,7 @@ minifyCssVars({ var: 2 })
|
|
|
102
102
|
// classes: true — только если нет className={\`foo--${x}\`}
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
-
`nameStart` / `varStart` — **числа** (индекс алфавита), не `"x"`. Префикс класса — `classPrefix`.
|
|
105
|
+
`nameStart` / `varStart` — **числа** (индекс алфавита), не `"x"`. Префикс класса — `classPrefix`. Словарь один на CSS+JS: `var(--token)`, `"--token"` и объявления `--token:` (в т.ч. CSS внутри JS от `@elcrm/form` size). Чанки JSZip не трогаем (`--n`). BEM `.account--wide` — класс, не переменная `--wide`. **`classes: true` нельзя** при динамических модификаторах (`account-passkey-status--${tone}`).
|
|
106
106
|
|
|
107
107
|
Короткие имена **уникальны и подряд**: `--aa`, `--ab`, `--ac`… Занятые слоты пропускаются; `--field` не затирает `--field-border`. Чанки JSZip не минифицируются (декремент `--n`). Если слотов нет — сборка падает.
|
|
108
108
|
|