@bamboocss/vite 1.37.8 → 1.37.10
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/index.cjs +58 -22
- package/dist/index.mjs +58 -22
- package/package.json +9 -9
package/dist/index.cjs
CHANGED
|
@@ -80,20 +80,31 @@ const pruneStaticCss = (css, session, { prune = true } = {}) => {
|
|
|
80
80
|
};
|
|
81
81
|
if (prune) root.walkRules((rule) => {
|
|
82
82
|
if (!isUtilityRule(rule)) return;
|
|
83
|
-
|
|
83
|
+
let removedAny = false;
|
|
84
|
+
let selector;
|
|
84
85
|
try {
|
|
85
|
-
(0, postcss_selector_parser.default)((selectors) => {
|
|
86
|
-
selectors.
|
|
87
|
-
classes
|
|
86
|
+
selector = (0, postcss_selector_parser.default)((selectors) => {
|
|
87
|
+
selectors.each((candidate) => {
|
|
88
|
+
const classes = /* @__PURE__ */ new Set();
|
|
89
|
+
candidate.walkClasses((classNode) => {
|
|
90
|
+
classes.add(bare(classNode.toString().slice(1)));
|
|
91
|
+
});
|
|
92
|
+
if (classes.size !== 1) return;
|
|
93
|
+
const [className] = classes;
|
|
94
|
+
if (!className || !prunable.has(className) || used.has(className)) return;
|
|
95
|
+
candidate.remove();
|
|
96
|
+
removedAny = true;
|
|
88
97
|
});
|
|
89
98
|
}).processSync(rule.selector);
|
|
90
99
|
} catch {
|
|
91
100
|
return;
|
|
92
101
|
}
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
102
|
+
if (!removedAny) return;
|
|
103
|
+
if (!selector.trim()) {
|
|
104
|
+
rule.remove();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
rule.selector = selector;
|
|
97
108
|
});
|
|
98
109
|
let removed = true;
|
|
99
110
|
while (removed) {
|
|
@@ -740,10 +751,28 @@ const collectModuleScopeNames = (sourceFile) => {
|
|
|
740
751
|
* while under-reporting ships an element whose class has no rule behind it and says nothing.
|
|
741
752
|
* Shadowing a recipe binding is rare; silently shipping unstyled markup is not recoverable.
|
|
742
753
|
*/
|
|
754
|
+
const identifiersByName = /* @__PURE__ */ new WeakMap();
|
|
755
|
+
/**
|
|
756
|
+
* Every identifier in the module, grouped by the name it spells.
|
|
757
|
+
*
|
|
758
|
+
* Walking the whole tree per binding made this O(bindings x identifiers): a module declaring
|
|
759
|
+
* ten recipes walked its identifiers ten times. One walk answers for all of them, and the
|
|
760
|
+
* result is cached against the source text like the module-scope names beside it, so a
|
|
761
|
+
* re-transform of unchanged text reuses it.
|
|
762
|
+
*/
|
|
763
|
+
const identifierIndex = (sourceFile) => byText(identifiersByName, sourceFile, () => {
|
|
764
|
+
const index = /* @__PURE__ */ new Map();
|
|
765
|
+
for (const identifier of sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.Identifier)) {
|
|
766
|
+
const text = identifier.getText();
|
|
767
|
+
const known = index.get(text);
|
|
768
|
+
if (known) known.push(identifier);
|
|
769
|
+
else index.set(text, [identifier]);
|
|
770
|
+
}
|
|
771
|
+
return index;
|
|
772
|
+
});
|
|
743
773
|
const localReferencesTo = (sourceFile, name, declaration) => {
|
|
744
774
|
const references = [];
|
|
745
|
-
for (const identifier of sourceFile.
|
|
746
|
-
if (identifier.getText() !== name) continue;
|
|
775
|
+
for (const identifier of identifierIndex(sourceFile).get(name) ?? []) {
|
|
747
776
|
if (identifier === declaration) continue;
|
|
748
777
|
const parent = identifier.getParent();
|
|
749
778
|
if (!parent) continue;
|
|
@@ -2828,18 +2857,24 @@ const bamboocss = (options = {}) => {
|
|
|
2828
2857
|
skipped: /* @__PURE__ */ new Map()
|
|
2829
2858
|
};
|
|
2830
2859
|
const staticSession = createStaticCompilationSession();
|
|
2831
|
-
|
|
2832
|
-
|
|
2860
|
+
/**
|
|
2861
|
+
* Indexed by file, because the only bulk operation on it is "forget this one's".
|
|
2862
|
+
*
|
|
2863
|
+
* A flat array meant every transform scanned every survivor and then rebuilt the dedupe key
|
|
2864
|
+
* set from scratch — O(modules x survivors) across a build, and worst exactly when a build is
|
|
2865
|
+
* already failing and the user is iterating on it. One project had 736 of them across 9,461
|
|
2866
|
+
* modules, which is seven million string builds to discard.
|
|
2867
|
+
*/
|
|
2868
|
+
const survivorsByFile = /* @__PURE__ */ new Map();
|
|
2869
|
+
const allSurvivors = () => [...survivorsByFile.values()].flat();
|
|
2833
2870
|
const addSurvivor = (entry) => {
|
|
2834
|
-
const
|
|
2835
|
-
if (
|
|
2836
|
-
|
|
2837
|
-
|
|
2871
|
+
const forFile = survivorsByFile.get(entry.file) ?? [];
|
|
2872
|
+
if (forFile.some((seen) => seen.line === entry.line && seen.name === entry.name && seen.reason === entry.reason)) return;
|
|
2873
|
+
forFile.push(entry);
|
|
2874
|
+
survivorsByFile.set(entry.file, forFile);
|
|
2838
2875
|
};
|
|
2839
2876
|
const clearSurvivorsFor = (file) => {
|
|
2840
|
-
|
|
2841
|
-
survivorKeys.clear();
|
|
2842
|
-
for (const entry of survivors) survivorKeys.add(`${entry.file}:${entry.line}:${entry.name}:${entry.reason}`);
|
|
2877
|
+
survivorsByFile.delete(file);
|
|
2843
2878
|
};
|
|
2844
2879
|
const createSurvivorError = (entries) => {
|
|
2845
2880
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -2898,8 +2933,7 @@ const bamboocss = (options = {}) => {
|
|
|
2898
2933
|
totals.files = 0;
|
|
2899
2934
|
totals.filesWithFolds = 0;
|
|
2900
2935
|
totals.skipped.clear();
|
|
2901
|
-
|
|
2902
|
-
survivorKeys.clear();
|
|
2936
|
+
survivorsByFile.clear();
|
|
2903
2937
|
recipeConfigCache.clear();
|
|
2904
2938
|
resetStaticCompilationSession(staticSession);
|
|
2905
2939
|
}
|
|
@@ -3002,7 +3036,8 @@ const bamboocss = (options = {}) => {
|
|
|
3002
3036
|
}
|
|
3003
3037
|
if (reportSkipped && result.skipped.length) _bamboocss_logger.logger.info("vite:transform", formatSkipped(filePath, result.skipped));
|
|
3004
3038
|
for (const dependency of result.dependencies) this.addWatchFile?.(dependency);
|
|
3005
|
-
|
|
3039
|
+
const forFile = survivorsByFile.get(filePath);
|
|
3040
|
+
if (command === "serve" && forFile?.length) throw createSurvivorError(forFile);
|
|
3006
3041
|
if (!result.folded.length) return null;
|
|
3007
3042
|
_bamboocss_logger.logger.debug("vite:transform", `Compiled ${result.folded.length} call(s) in ${filePath}`);
|
|
3008
3043
|
return {
|
|
@@ -3011,6 +3046,7 @@ const bamboocss = (options = {}) => {
|
|
|
3011
3046
|
};
|
|
3012
3047
|
},
|
|
3013
3048
|
buildEnd() {
|
|
3049
|
+
const survivors = allSurvivors();
|
|
3014
3050
|
if (survivors.length) throw createSurvivorError(survivors);
|
|
3015
3051
|
if (typeof this.getModuleInfo === "function") {
|
|
3016
3052
|
if (!staticSession.cssLoaded) throw new Error(`bamboocss: compiled class values were produced, but ${JSON.stringify(VIRTUAL_CSS_ID)} was not imported. Add \`import ${JSON.stringify(VIRTUAL_CSS_ID)}\` once, from a JavaScript or TypeScript module in the application entry graph.\n\nIt has to be a JS import. \`@import\` from a stylesheet does not reach it: the id names a virtual module resolved by this plugin, and Vite resolves CSS \`@import\` before plugin resolution, so it fails as an unresolvable path. A project that ships one preloaded stylesheet imports this from its entry module instead, and lets Vite emit the CSS asset.`);
|
package/dist/index.mjs
CHANGED
|
@@ -50,20 +50,31 @@ const pruneStaticCss = (css, session, { prune = true } = {}) => {
|
|
|
50
50
|
};
|
|
51
51
|
if (prune) root.walkRules((rule) => {
|
|
52
52
|
if (!isUtilityRule(rule)) return;
|
|
53
|
-
|
|
53
|
+
let removedAny = false;
|
|
54
|
+
let selector;
|
|
54
55
|
try {
|
|
55
|
-
selectorParser((selectors) => {
|
|
56
|
-
selectors.
|
|
57
|
-
classes
|
|
56
|
+
selector = selectorParser((selectors) => {
|
|
57
|
+
selectors.each((candidate) => {
|
|
58
|
+
const classes = /* @__PURE__ */ new Set();
|
|
59
|
+
candidate.walkClasses((classNode) => {
|
|
60
|
+
classes.add(bare(classNode.toString().slice(1)));
|
|
61
|
+
});
|
|
62
|
+
if (classes.size !== 1) return;
|
|
63
|
+
const [className] = classes;
|
|
64
|
+
if (!className || !prunable.has(className) || used.has(className)) return;
|
|
65
|
+
candidate.remove();
|
|
66
|
+
removedAny = true;
|
|
58
67
|
});
|
|
59
68
|
}).processSync(rule.selector);
|
|
60
69
|
} catch {
|
|
61
70
|
return;
|
|
62
71
|
}
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
if (!removedAny) return;
|
|
73
|
+
if (!selector.trim()) {
|
|
74
|
+
rule.remove();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
rule.selector = selector;
|
|
67
78
|
});
|
|
68
79
|
let removed = true;
|
|
69
80
|
while (removed) {
|
|
@@ -710,10 +721,28 @@ const collectModuleScopeNames = (sourceFile) => {
|
|
|
710
721
|
* while under-reporting ships an element whose class has no rule behind it and says nothing.
|
|
711
722
|
* Shadowing a recipe binding is rare; silently shipping unstyled markup is not recoverable.
|
|
712
723
|
*/
|
|
724
|
+
const identifiersByName = /* @__PURE__ */ new WeakMap();
|
|
725
|
+
/**
|
|
726
|
+
* Every identifier in the module, grouped by the name it spells.
|
|
727
|
+
*
|
|
728
|
+
* Walking the whole tree per binding made this O(bindings x identifiers): a module declaring
|
|
729
|
+
* ten recipes walked its identifiers ten times. One walk answers for all of them, and the
|
|
730
|
+
* result is cached against the source text like the module-scope names beside it, so a
|
|
731
|
+
* re-transform of unchanged text reuses it.
|
|
732
|
+
*/
|
|
733
|
+
const identifierIndex = (sourceFile) => byText(identifiersByName, sourceFile, () => {
|
|
734
|
+
const index = /* @__PURE__ */ new Map();
|
|
735
|
+
for (const identifier of sourceFile.getDescendantsOfKind(SyntaxKind.Identifier)) {
|
|
736
|
+
const text = identifier.getText();
|
|
737
|
+
const known = index.get(text);
|
|
738
|
+
if (known) known.push(identifier);
|
|
739
|
+
else index.set(text, [identifier]);
|
|
740
|
+
}
|
|
741
|
+
return index;
|
|
742
|
+
});
|
|
713
743
|
const localReferencesTo = (sourceFile, name, declaration) => {
|
|
714
744
|
const references = [];
|
|
715
|
-
for (const identifier of sourceFile.
|
|
716
|
-
if (identifier.getText() !== name) continue;
|
|
745
|
+
for (const identifier of identifierIndex(sourceFile).get(name) ?? []) {
|
|
717
746
|
if (identifier === declaration) continue;
|
|
718
747
|
const parent = identifier.getParent();
|
|
719
748
|
if (!parent) continue;
|
|
@@ -2798,18 +2827,24 @@ const bamboocss = (options = {}) => {
|
|
|
2798
2827
|
skipped: /* @__PURE__ */ new Map()
|
|
2799
2828
|
};
|
|
2800
2829
|
const staticSession = createStaticCompilationSession();
|
|
2801
|
-
|
|
2802
|
-
|
|
2830
|
+
/**
|
|
2831
|
+
* Indexed by file, because the only bulk operation on it is "forget this one's".
|
|
2832
|
+
*
|
|
2833
|
+
* A flat array meant every transform scanned every survivor and then rebuilt the dedupe key
|
|
2834
|
+
* set from scratch — O(modules x survivors) across a build, and worst exactly when a build is
|
|
2835
|
+
* already failing and the user is iterating on it. One project had 736 of them across 9,461
|
|
2836
|
+
* modules, which is seven million string builds to discard.
|
|
2837
|
+
*/
|
|
2838
|
+
const survivorsByFile = /* @__PURE__ */ new Map();
|
|
2839
|
+
const allSurvivors = () => [...survivorsByFile.values()].flat();
|
|
2803
2840
|
const addSurvivor = (entry) => {
|
|
2804
|
-
const
|
|
2805
|
-
if (
|
|
2806
|
-
|
|
2807
|
-
|
|
2841
|
+
const forFile = survivorsByFile.get(entry.file) ?? [];
|
|
2842
|
+
if (forFile.some((seen) => seen.line === entry.line && seen.name === entry.name && seen.reason === entry.reason)) return;
|
|
2843
|
+
forFile.push(entry);
|
|
2844
|
+
survivorsByFile.set(entry.file, forFile);
|
|
2808
2845
|
};
|
|
2809
2846
|
const clearSurvivorsFor = (file) => {
|
|
2810
|
-
|
|
2811
|
-
survivorKeys.clear();
|
|
2812
|
-
for (const entry of survivors) survivorKeys.add(`${entry.file}:${entry.line}:${entry.name}:${entry.reason}`);
|
|
2847
|
+
survivorsByFile.delete(file);
|
|
2813
2848
|
};
|
|
2814
2849
|
const createSurvivorError = (entries) => {
|
|
2815
2850
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -2868,8 +2903,7 @@ const bamboocss = (options = {}) => {
|
|
|
2868
2903
|
totals.files = 0;
|
|
2869
2904
|
totals.filesWithFolds = 0;
|
|
2870
2905
|
totals.skipped.clear();
|
|
2871
|
-
|
|
2872
|
-
survivorKeys.clear();
|
|
2906
|
+
survivorsByFile.clear();
|
|
2873
2907
|
recipeConfigCache.clear();
|
|
2874
2908
|
resetStaticCompilationSession(staticSession);
|
|
2875
2909
|
}
|
|
@@ -2972,7 +3006,8 @@ const bamboocss = (options = {}) => {
|
|
|
2972
3006
|
}
|
|
2973
3007
|
if (reportSkipped && result.skipped.length) logger.info("vite:transform", formatSkipped(filePath, result.skipped));
|
|
2974
3008
|
for (const dependency of result.dependencies) this.addWatchFile?.(dependency);
|
|
2975
|
-
|
|
3009
|
+
const forFile = survivorsByFile.get(filePath);
|
|
3010
|
+
if (command === "serve" && forFile?.length) throw createSurvivorError(forFile);
|
|
2976
3011
|
if (!result.folded.length) return null;
|
|
2977
3012
|
logger.debug("vite:transform", `Compiled ${result.folded.length} call(s) in ${filePath}`);
|
|
2978
3013
|
return {
|
|
@@ -2981,6 +3016,7 @@ const bamboocss = (options = {}) => {
|
|
|
2981
3016
|
};
|
|
2982
3017
|
},
|
|
2983
3018
|
buildEnd() {
|
|
3019
|
+
const survivors = allSurvivors();
|
|
2984
3020
|
if (survivors.length) throw createSurvivorError(survivors);
|
|
2985
3021
|
if (typeof this.getModuleInfo === "function") {
|
|
2986
3022
|
if (!staticSession.cssLoaded) throw new Error(`bamboocss: compiled class values were produced, but ${JSON.stringify(VIRTUAL_CSS_ID)} was not imported. Add \`import ${JSON.stringify(VIRTUAL_CSS_ID)}\` once, from a JavaScript or TypeScript module in the application entry graph.\n\nIt has to be a JS import. \`@import\` from a stylesheet does not reach it: the id names a virtual module resolved by this plugin, and Vite resolves CSS \`@import\` before plugin resolution, so it fails as an unresolvable path. A project that ships one preloaded stylesheet imports this from its entry module instead, and lets Vite emit the CSS asset.`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bamboocss/vite",
|
|
3
|
-
"version": "1.37.
|
|
3
|
+
"version": "1.37.10",
|
|
4
4
|
"description": "Vite integration for Bamboo CSS",
|
|
5
5
|
"homepage": "https://bamboocss.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,18 +40,18 @@
|
|
|
40
40
|
"postcss": "8.5.26",
|
|
41
41
|
"postcss-selector-parser": "7.1.5",
|
|
42
42
|
"ts-morph": "28.0.0",
|
|
43
|
-
"@bamboocss/config": "1.37.
|
|
44
|
-
"@bamboocss/core": "1.37.
|
|
45
|
-
"@bamboocss/extractor": "1.37.
|
|
46
|
-
"@bamboocss/
|
|
47
|
-
"@bamboocss/
|
|
48
|
-
"@bamboocss/
|
|
49
|
-
"@bamboocss/
|
|
43
|
+
"@bamboocss/config": "1.37.10",
|
|
44
|
+
"@bamboocss/core": "1.37.10",
|
|
45
|
+
"@bamboocss/extractor": "1.37.10",
|
|
46
|
+
"@bamboocss/node": "1.37.10",
|
|
47
|
+
"@bamboocss/logger": "1.37.10",
|
|
48
|
+
"@bamboocss/types": "1.37.10",
|
|
49
|
+
"@bamboocss/shared": "1.37.10"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@jridgewell/trace-mapping": "^0.3.31",
|
|
53
53
|
"vite": "7.2.6",
|
|
54
|
-
"@bamboocss/fixture": "1.37.
|
|
54
|
+
"@bamboocss/fixture": "1.37.10"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"vite": ">=5"
|