@vetta-org/plugin-vite 0.0.5 → 0.2.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/build-warning-filter.d.ts +8 -0
- package/dist/build-warning-filter.d.ts.map +1 -0
- package/dist/build-warning-filter.js +26 -0
- package/dist/build-warning-filter.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +83 -0
- package/dist/cli.js.map +1 -0
- package/dist/dev-events.d.ts +23 -0
- package/dist/dev-events.d.ts.map +1 -0
- package/dist/dev-events.js +9 -0
- package/dist/dev-events.js.map +1 -0
- package/dist/dev-server.d.ts +9 -0
- package/dist/dev-server.d.ts.map +1 -0
- package/dist/dev-server.js +244 -0
- package/dist/dev-server.js.map +1 -0
- package/dist/dev-vite-plugins.d.ts +5 -0
- package/dist/dev-vite-plugins.d.ts.map +1 -0
- package/dist/dev-vite-plugins.js +144 -0
- package/dist/dev-vite-plugins.js.map +1 -0
- package/dist/host-theme.d.ts +5 -0
- package/dist/host-theme.d.ts.map +1 -0
- package/dist/host-theme.js +42 -0
- package/dist/host-theme.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +89 -4
- package/dist/index.js.map +1 -1
- package/dist/pack.d.ts +4 -0
- package/dist/pack.d.ts.map +1 -1
- package/dist/pack.js +45 -89
- package/dist/pack.js.map +1 -1
- package/dist/permission-contract.d.ts +13 -0
- package/dist/permission-contract.d.ts.map +1 -0
- package/dist/permission-contract.js +94 -0
- package/dist/permission-contract.js.map +1 -0
- package/dist/request-query.d.ts +8 -0
- package/dist/request-query.d.ts.map +1 -0
- package/dist/request-query.js +19 -0
- package/dist/request-query.js.map +1 -0
- package/dist/style-scope.d.ts +8 -0
- package/dist/style-scope.d.ts.map +1 -1
- package/dist/style-scope.js +102 -3
- package/dist/style-scope.js.map +1 -1
- package/package.json +13 -3
package/dist/style-scope.js
CHANGED
|
@@ -2,9 +2,32 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import postcss from "postcss";
|
|
4
4
|
import selectorParser from "postcss-selector-parser";
|
|
5
|
+
import { hasOpaqueResourceQuery } from "./request-query.js";
|
|
5
6
|
const PLUGIN_ROOT_ATTRIBUTE = "data-vetta-plugin-root";
|
|
6
7
|
const PLUGIN_ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;
|
|
7
8
|
const KEYFRAMES_PATTERN = /(?:^|-)keyframes$/i;
|
|
9
|
+
const ICONIFY_CLASS_PATTERN = /^icon-\[[a-z0-9]+(?:-[a-z0-9]+)*--[a-z0-9]+(?:-[a-z0-9]+)*\]$/u;
|
|
10
|
+
const ICONIFY_DECLARATION_VALUES = {
|
|
11
|
+
width: "1em",
|
|
12
|
+
height: "1em",
|
|
13
|
+
"-webkit-mask-image": "var(--svg)",
|
|
14
|
+
"mask-image": "var(--svg)",
|
|
15
|
+
"background-color": "currentColor",
|
|
16
|
+
display: "inline-block",
|
|
17
|
+
"-webkit-mask-size": "100% 100%",
|
|
18
|
+
"mask-size": "100% 100%",
|
|
19
|
+
"-webkit-mask-repeat": "no-repeat",
|
|
20
|
+
"mask-repeat": "no-repeat",
|
|
21
|
+
};
|
|
22
|
+
const ICONIFY_SVG_VALUE_PATTERN = /^url\((?:"|')?data:image\/svg\+xml,/u;
|
|
23
|
+
/**
|
|
24
|
+
* 全局化的 Iconify 规则要放进一个嵌套 layer:插件样式表在宿主之后加载,
|
|
25
|
+
* 而 `icon-[…]{width:1em;height:1em}` 与宿主的 `.w-4/.h-4` 同特异性,
|
|
26
|
+
* 直接全局化会让宿主里任何同名图标退化成 1em(字号),把相邻文字挤偏。
|
|
27
|
+
* 同一 layer 内「未嵌套的规则」优先于其子 layer,因此包一层即可让显式尺寸工具类稳定胜出,
|
|
28
|
+
* 同时保留插件自身不写尺寸时的 1em 默认值。
|
|
29
|
+
*/
|
|
30
|
+
const ICONIFY_LAYER_NAME = "vetta-plugin-icons";
|
|
8
31
|
function createPluginRootAttribute(pluginId) {
|
|
9
32
|
return selectorParser.attribute({
|
|
10
33
|
attribute: PLUGIN_ROOT_ATTRIBUTE,
|
|
@@ -44,18 +67,71 @@ function replacePluginRootSelectors(selector) {
|
|
|
44
67
|
function isKeyframesAtRule(node) {
|
|
45
68
|
return node.type === "atrule" && KEYFRAMES_PATTERN.test(node.name);
|
|
46
69
|
}
|
|
70
|
+
function hasOnlyIconifySelectors(rule) {
|
|
71
|
+
let selectorCount = 0;
|
|
72
|
+
let valid = true;
|
|
73
|
+
selectorParser((selectors) => {
|
|
74
|
+
selectors.each((selector) => {
|
|
75
|
+
selectorCount += 1;
|
|
76
|
+
const nodes = selector.nodes.filter((node) => node.type !== "comment");
|
|
77
|
+
const candidate = nodes[0];
|
|
78
|
+
if (nodes.length !== 1 ||
|
|
79
|
+
candidate?.type !== "class" ||
|
|
80
|
+
!ICONIFY_CLASS_PATTERN.test(candidate.value)) {
|
|
81
|
+
valid = false;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}).processSync(rule.selector);
|
|
85
|
+
return valid && selectorCount > 0;
|
|
86
|
+
}
|
|
87
|
+
function hasOnlyIconifyDeclarations(rule) {
|
|
88
|
+
let hasSvg = false;
|
|
89
|
+
let hasMask = false;
|
|
90
|
+
for (const node of rule.nodes) {
|
|
91
|
+
if (node.type !== "decl")
|
|
92
|
+
return false;
|
|
93
|
+
if (node.prop === "--svg") {
|
|
94
|
+
if (!ICONIFY_SVG_VALUE_PATTERN.test(node.value))
|
|
95
|
+
return false;
|
|
96
|
+
hasSvg = true;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (ICONIFY_DECLARATION_VALUES[node.prop] !== node.value)
|
|
100
|
+
return false;
|
|
101
|
+
if (node.prop === "mask-image" || node.prop === "-webkit-mask-image")
|
|
102
|
+
hasMask = true;
|
|
103
|
+
}
|
|
104
|
+
return hasSvg && hasMask;
|
|
105
|
+
}
|
|
106
|
+
function isSafeGlobalIconifyRule(rule) {
|
|
107
|
+
return hasOnlyIconifySelectors(rule) && hasOnlyIconifyDeclarations(rule);
|
|
108
|
+
}
|
|
47
109
|
function createScopeRule(pluginId) {
|
|
48
110
|
return postcss.atRule({
|
|
49
111
|
name: "scope",
|
|
50
112
|
params: `(${createPluginRootAttribute(pluginId).toString()})`,
|
|
51
113
|
});
|
|
52
114
|
}
|
|
115
|
+
function createIconifyLayerRule() {
|
|
116
|
+
return postcss.atRule({ name: "layer", params: ICONIFY_LAYER_NAME });
|
|
117
|
+
}
|
|
53
118
|
function scopeRulesInContainer(container, pluginId) {
|
|
54
119
|
if (!container.nodes)
|
|
55
120
|
return;
|
|
56
121
|
let currentScope;
|
|
122
|
+
let currentIconifyLayer;
|
|
57
123
|
for (const node of [...container.nodes]) {
|
|
58
124
|
if (node.type === "rule") {
|
|
125
|
+
if (isSafeGlobalIconifyRule(node)) {
|
|
126
|
+
currentScope = undefined;
|
|
127
|
+
if (!currentIconifyLayer) {
|
|
128
|
+
currentIconifyLayer = createIconifyLayerRule();
|
|
129
|
+
node.before(currentIconifyLayer);
|
|
130
|
+
}
|
|
131
|
+
currentIconifyLayer.append(node);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
currentIconifyLayer = undefined;
|
|
59
135
|
if (!currentScope) {
|
|
60
136
|
currentScope = createScopeRule(pluginId);
|
|
61
137
|
node.before(currentScope);
|
|
@@ -64,6 +140,7 @@ function scopeRulesInContainer(container, pluginId) {
|
|
|
64
140
|
continue;
|
|
65
141
|
}
|
|
66
142
|
currentScope = undefined;
|
|
143
|
+
currentIconifyLayer = undefined;
|
|
67
144
|
if (node.type === "atrule" && !isKeyframesAtRule(node)) {
|
|
68
145
|
const atRule = node;
|
|
69
146
|
if (atRule.nodes)
|
|
@@ -71,7 +148,7 @@ function scopeRulesInContainer(container, pluginId) {
|
|
|
71
148
|
}
|
|
72
149
|
}
|
|
73
150
|
}
|
|
74
|
-
function scopePluginCss(css, pluginId) {
|
|
151
|
+
export function scopePluginCss(css, pluginId) {
|
|
75
152
|
const root = postcss.parse(css);
|
|
76
153
|
root.walkRules((rule) => {
|
|
77
154
|
if (isInsideKeyframes(rule))
|
|
@@ -81,6 +158,19 @@ function scopePluginCss(css, pluginId) {
|
|
|
81
158
|
scopeRulesInContainer(root, pluginId);
|
|
82
159
|
return root.toString();
|
|
83
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Vite can import a CSS file as a JavaScript resource module via queries such
|
|
163
|
+
* as `?raw`. Those requests keep the `.css` pathname, but their transform
|
|
164
|
+
* input is JavaScript and must not be parsed by PostCSS. Other queries such as
|
|
165
|
+
* `?direct` and HMR timestamps still represent stylesheet requests.
|
|
166
|
+
*/
|
|
167
|
+
export function isPluginStylesheetRequest(id) {
|
|
168
|
+
const queryIndex = id.indexOf("?");
|
|
169
|
+
const pathname = queryIndex === -1 ? id : id.slice(0, queryIndex);
|
|
170
|
+
if (!pathname.endsWith(".css"))
|
|
171
|
+
return false;
|
|
172
|
+
return !hasOpaqueResourceQuery(id);
|
|
173
|
+
}
|
|
84
174
|
function readPluginId(rootDir) {
|
|
85
175
|
const manifestPath = join(rootDir, "plugin.json");
|
|
86
176
|
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
@@ -91,12 +181,21 @@ function readPluginId(rootDir) {
|
|
|
91
181
|
}
|
|
92
182
|
export function createPluginStyleScopePlugin() {
|
|
93
183
|
let pluginId = "";
|
|
184
|
+
let command = "build";
|
|
94
185
|
return {
|
|
95
186
|
name: "vetta-plugin-style-scope",
|
|
96
|
-
|
|
97
|
-
enforce: "post",
|
|
187
|
+
enforce: "pre",
|
|
98
188
|
configResolved(config) {
|
|
99
189
|
pluginId = readPluginId(config.root);
|
|
190
|
+
command = config.command;
|
|
191
|
+
},
|
|
192
|
+
transform(code, id) {
|
|
193
|
+
if (command !== "serve" || !isPluginStylesheetRequest(id))
|
|
194
|
+
return;
|
|
195
|
+
return {
|
|
196
|
+
code: scopePluginCss(code, pluginId),
|
|
197
|
+
map: null,
|
|
198
|
+
};
|
|
100
199
|
},
|
|
101
200
|
generateBundle(_options, bundle) {
|
|
102
201
|
for (const output of Object.values(bundle)) {
|
package/dist/style-scope.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style-scope.js","sourceRoot":"","sources":["../src/style-scope.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport postcss, { type AtRule, type Container, type Node, type Rule } from \"postcss\";\nimport selectorParser from \"postcss-selector-parser\";\nimport type { Plugin } from \"vite\";\n\nconst PLUGIN_ROOT_ATTRIBUTE = \"data-vetta-plugin-root\";\nconst PLUGIN_ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;\nconst KEYFRAMES_PATTERN = /(?:^|-)keyframes$/i;\n\nfunction createPluginRootAttribute(pluginId: string) {\n\treturn selectorParser.attribute({\n\t\tattribute: PLUGIN_ROOT_ATTRIBUTE,\n\t\toperator: \"=\",\n\t\tquoteMark: '\"',\n\t\traws: {},\n\t\tvalue: pluginId,\n\t});\n}\n\nfunction isInsideKeyframes(rule: Rule): boolean {\n\tlet parent: Node | undefined = rule.parent;\n\twhile (parent) {\n\t\tif (\n\t\t\tparent.type === \"atrule\" &&\n\t\t\t\"name\" in parent &&\n\t\t\ttypeof parent.name === \"string\" &&\n\t\t\tKEYFRAMES_PATTERN.test(parent.name)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tparent = parent.parent;\n\t}\n\treturn false;\n}\n\nfunction replacePluginRootSelectors(selector: string): string {\n\treturn selectorParser((selectors) => {\n\t\tselectors.walkPseudos((pseudo) => {\n\t\t\tif (pseudo.value === \":root\") {\n\t\t\t\tpseudo.replaceWith(selectorParser.pseudo({ value: \":scope\" }));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (pseudo.value === \":host\") {\n\t\t\t\tconst hostArgumentNodes =\n\t\t\t\t\tpseudo.nodes.length === 1 ? pseudo.nodes[0].nodes.map((node) => node.clone()) : [];\n\t\t\t\tpseudo.replaceWith(selectorParser.pseudo({ value: \":scope\" }), ...hostArgumentNodes);\n\t\t\t}\n\t\t});\n\t}).processSync(selector);\n}\n\nfunction isKeyframesAtRule(node: Node): boolean {\n\treturn node.type === \"atrule\" && KEYFRAMES_PATTERN.test((node as AtRule).name);\n}\n\nfunction createScopeRule(pluginId: string): AtRule {\n\treturn postcss.atRule({\n\t\tname: \"scope\",\n\t\tparams: `(${createPluginRootAttribute(pluginId).toString()})`,\n\t});\n}\n\nfunction scopeRulesInContainer(container: Container, pluginId: string): void {\n\tif (!container.nodes) return;\n\tlet currentScope: AtRule | undefined;\n\tfor (const node of [...container.nodes]) {\n\t\tif (node.type === \"rule\") {\n\t\t\tif (!currentScope) {\n\t\t\t\tcurrentScope = createScopeRule(pluginId);\n\t\t\t\tnode.before(currentScope);\n\t\t\t}\n\t\t\tcurrentScope.append(node);\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrentScope = undefined;\n\t\tif (node.type === \"atrule\" && !isKeyframesAtRule(node)) {\n\t\t\tconst atRule = node as AtRule;\n\t\t\tif (atRule.nodes) scopeRulesInContainer(atRule, pluginId);\n\t\t}\n\t}\n}\n\nfunction scopePluginCss(css: string, pluginId: string): string {\n\tconst root = postcss.parse(css);\n\troot.walkRules((rule) => {\n\t\tif (isInsideKeyframes(rule)) return;\n\t\trule.selector = replacePluginRootSelectors(rule.selector);\n\t});\n\tscopeRulesInContainer(root, pluginId);\n\treturn root.toString();\n}\n\nfunction readPluginId(rootDir: string): string {\n\tconst manifestPath = join(rootDir, \"plugin.json\");\n\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as { id?: unknown };\n\tif (typeof manifest.id !== \"string\" || !PLUGIN_ID_PATTERN.test(manifest.id)) {\n\t\tthrow new Error(`Invalid plugin id in ${manifestPath}`);\n\t}\n\treturn manifest.id;\n}\n\nexport function createPluginStyleScopePlugin(): Plugin {\n\tlet pluginId = \"\";\n\treturn {\n\t\tname: \"vetta-plugin-style-scope\",\n\t\tapply: \"build\",\n\t\tenforce: \"post\",\n\t\tconfigResolved(config) {\n\t\t\tpluginId = readPluginId(config.root);\n\t\t},\n\t\tgenerateBundle(_options, bundle) {\n\t\t\tfor (const output of Object.values(bundle)) {\n\t\t\t\tif (output.type !== \"asset\" || !output.fileName.endsWith(\".css\")) continue;\n\t\t\t\tconst css = typeof output.source === \"string\" ? output.source : Buffer.from(output.source).toString(\"utf8\");\n\t\t\t\toutput.source = scopePluginCss(css, pluginId);\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"style-scope.js","sourceRoot":"","sources":["../src/style-scope.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport postcss, { type AtRule, type Container, type Node, type Rule } from \"postcss\";\nimport selectorParser from \"postcss-selector-parser\";\nimport type { Plugin } from \"vite\";\nimport { hasOpaqueResourceQuery } from \"./request-query.js\";\n\nconst PLUGIN_ROOT_ATTRIBUTE = \"data-vetta-plugin-root\";\nconst PLUGIN_ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;\nconst KEYFRAMES_PATTERN = /(?:^|-)keyframes$/i;\nconst ICONIFY_CLASS_PATTERN = /^icon-\\[[a-z0-9]+(?:-[a-z0-9]+)*--[a-z0-9]+(?:-[a-z0-9]+)*\\]$/u;\nconst ICONIFY_DECLARATION_VALUES: Readonly<Record<string, string>> = {\n\twidth: \"1em\",\n\theight: \"1em\",\n\t\"-webkit-mask-image\": \"var(--svg)\",\n\t\"mask-image\": \"var(--svg)\",\n\t\"background-color\": \"currentColor\",\n\tdisplay: \"inline-block\",\n\t\"-webkit-mask-size\": \"100% 100%\",\n\t\"mask-size\": \"100% 100%\",\n\t\"-webkit-mask-repeat\": \"no-repeat\",\n\t\"mask-repeat\": \"no-repeat\",\n};\nconst ICONIFY_SVG_VALUE_PATTERN = /^url\\((?:\"|')?data:image\\/svg\\+xml,/u;\n/**\n * 全局化的 Iconify 规则要放进一个嵌套 layer:插件样式表在宿主之后加载,\n * 而 `icon-[…]{width:1em;height:1em}` 与宿主的 `.w-4/.h-4` 同特异性,\n * 直接全局化会让宿主里任何同名图标退化成 1em(字号),把相邻文字挤偏。\n * 同一 layer 内「未嵌套的规则」优先于其子 layer,因此包一层即可让显式尺寸工具类稳定胜出,\n * 同时保留插件自身不写尺寸时的 1em 默认值。\n */\nconst ICONIFY_LAYER_NAME = \"vetta-plugin-icons\";\n\nfunction createPluginRootAttribute(pluginId: string) {\n\treturn selectorParser.attribute({\n\t\tattribute: PLUGIN_ROOT_ATTRIBUTE,\n\t\toperator: \"=\",\n\t\tquoteMark: '\"',\n\t\traws: {},\n\t\tvalue: pluginId,\n\t});\n}\n\nfunction isInsideKeyframes(rule: Rule): boolean {\n\tlet parent: Node | undefined = rule.parent;\n\twhile (parent) {\n\t\tif (\n\t\t\tparent.type === \"atrule\" &&\n\t\t\t\"name\" in parent &&\n\t\t\ttypeof parent.name === \"string\" &&\n\t\t\tKEYFRAMES_PATTERN.test(parent.name)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tparent = parent.parent;\n\t}\n\treturn false;\n}\n\nfunction replacePluginRootSelectors(selector: string): string {\n\treturn selectorParser((selectors) => {\n\t\tselectors.walkPseudos((pseudo) => {\n\t\t\tif (pseudo.value === \":root\") {\n\t\t\t\tpseudo.replaceWith(selectorParser.pseudo({ value: \":scope\" }));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (pseudo.value === \":host\") {\n\t\t\t\tconst hostArgumentNodes =\n\t\t\t\t\tpseudo.nodes.length === 1 ? pseudo.nodes[0].nodes.map((node) => node.clone()) : [];\n\t\t\t\tpseudo.replaceWith(selectorParser.pseudo({ value: \":scope\" }), ...hostArgumentNodes);\n\t\t\t}\n\t\t});\n\t}).processSync(selector);\n}\n\nfunction isKeyframesAtRule(node: Node): boolean {\n\treturn node.type === \"atrule\" && KEYFRAMES_PATTERN.test((node as AtRule).name);\n}\n\nfunction hasOnlyIconifySelectors(rule: Rule): boolean {\n\tlet selectorCount = 0;\n\tlet valid = true;\n\tselectorParser((selectors) => {\n\t\tselectors.each((selector) => {\n\t\t\tselectorCount += 1;\n\t\t\tconst nodes = selector.nodes.filter((node) => node.type !== \"comment\");\n\t\t\tconst candidate = nodes[0];\n\t\t\tif (\n\t\t\t\tnodes.length !== 1 ||\n\t\t\t\tcandidate?.type !== \"class\" ||\n\t\t\t\t!ICONIFY_CLASS_PATTERN.test(candidate.value)\n\t\t\t) {\n\t\t\t\tvalid = false;\n\t\t\t}\n\t\t});\n\t}).processSync(rule.selector);\n\treturn valid && selectorCount > 0;\n}\n\nfunction hasOnlyIconifyDeclarations(rule: Rule): boolean {\n\tlet hasSvg = false;\n\tlet hasMask = false;\n\tfor (const node of rule.nodes) {\n\t\tif (node.type !== \"decl\") return false;\n\t\tif (node.prop === \"--svg\") {\n\t\t\tif (!ICONIFY_SVG_VALUE_PATTERN.test(node.value)) return false;\n\t\t\thasSvg = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ICONIFY_DECLARATION_VALUES[node.prop] !== node.value) return false;\n\t\tif (node.prop === \"mask-image\" || node.prop === \"-webkit-mask-image\") hasMask = true;\n\t}\n\treturn hasSvg && hasMask;\n}\n\nfunction isSafeGlobalIconifyRule(rule: Rule): boolean {\n\treturn hasOnlyIconifySelectors(rule) && hasOnlyIconifyDeclarations(rule);\n}\n\nfunction createScopeRule(pluginId: string): AtRule {\n\treturn postcss.atRule({\n\t\tname: \"scope\",\n\t\tparams: `(${createPluginRootAttribute(pluginId).toString()})`,\n\t});\n}\n\nfunction createIconifyLayerRule(): AtRule {\n\treturn postcss.atRule({ name: \"layer\", params: ICONIFY_LAYER_NAME });\n}\n\nfunction scopeRulesInContainer(container: Container, pluginId: string): void {\n\tif (!container.nodes) return;\n\tlet currentScope: AtRule | undefined;\n\tlet currentIconifyLayer: AtRule | undefined;\n\tfor (const node of [...container.nodes]) {\n\t\tif (node.type === \"rule\") {\n\t\t\tif (isSafeGlobalIconifyRule(node)) {\n\t\t\t\tcurrentScope = undefined;\n\t\t\t\tif (!currentIconifyLayer) {\n\t\t\t\t\tcurrentIconifyLayer = createIconifyLayerRule();\n\t\t\t\t\tnode.before(currentIconifyLayer);\n\t\t\t\t}\n\t\t\t\tcurrentIconifyLayer.append(node);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tcurrentIconifyLayer = undefined;\n\t\t\tif (!currentScope) {\n\t\t\t\tcurrentScope = createScopeRule(pluginId);\n\t\t\t\tnode.before(currentScope);\n\t\t\t}\n\t\t\tcurrentScope.append(node);\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrentScope = undefined;\n\t\tcurrentIconifyLayer = undefined;\n\t\tif (node.type === \"atrule\" && !isKeyframesAtRule(node)) {\n\t\t\tconst atRule = node as AtRule;\n\t\t\tif (atRule.nodes) scopeRulesInContainer(atRule, pluginId);\n\t\t}\n\t}\n}\n\nexport function scopePluginCss(css: string, pluginId: string): string {\n\tconst root = postcss.parse(css);\n\troot.walkRules((rule) => {\n\t\tif (isInsideKeyframes(rule)) return;\n\t\trule.selector = replacePluginRootSelectors(rule.selector);\n\t});\n\tscopeRulesInContainer(root, pluginId);\n\treturn root.toString();\n}\n\n/**\n * Vite can import a CSS file as a JavaScript resource module via queries such\n * as `?raw`. Those requests keep the `.css` pathname, but their transform\n * input is JavaScript and must not be parsed by PostCSS. Other queries such as\n * `?direct` and HMR timestamps still represent stylesheet requests.\n */\nexport function isPluginStylesheetRequest(id: string): boolean {\n\tconst queryIndex = id.indexOf(\"?\");\n\tconst pathname = queryIndex === -1 ? id : id.slice(0, queryIndex);\n\tif (!pathname.endsWith(\".css\")) return false;\n\treturn !hasOpaqueResourceQuery(id);\n}\n\nfunction readPluginId(rootDir: string): string {\n\tconst manifestPath = join(rootDir, \"plugin.json\");\n\tconst manifest = JSON.parse(readFileSync(manifestPath, \"utf8\")) as { id?: unknown };\n\tif (typeof manifest.id !== \"string\" || !PLUGIN_ID_PATTERN.test(manifest.id)) {\n\t\tthrow new Error(`Invalid plugin id in ${manifestPath}`);\n\t}\n\treturn manifest.id;\n}\n\nexport function createPluginStyleScopePlugin(): Plugin {\n\tlet pluginId = \"\";\n\tlet command: \"build\" | \"serve\" = \"build\";\n\treturn {\n\t\tname: \"vetta-plugin-style-scope\",\n\t\tenforce: \"pre\",\n\t\tconfigResolved(config) {\n\t\t\tpluginId = readPluginId(config.root);\n\t\t\tcommand = config.command;\n\t\t},\n\t\ttransform(code, id) {\n\t\t\tif (command !== \"serve\" || !isPluginStylesheetRequest(id)) return;\n\t\t\treturn {\n\t\t\t\tcode: scopePluginCss(code, pluginId),\n\t\t\t\tmap: null,\n\t\t\t};\n\t\t},\n\t\tgenerateBundle(_options, bundle) {\n\t\t\tfor (const output of Object.values(bundle)) {\n\t\t\t\tif (output.type !== \"asset\" || !output.fileName.endsWith(\".css\")) continue;\n\t\t\t\tconst css = typeof output.source === \"string\" ? output.source : Buffer.from(output.source).toString(\"utf8\");\n\t\t\t\toutput.source = scopePluginCss(css, pluginId);\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vetta-org/plugin-vite",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"vetta-plugin": "./dist/cli.js"
|
|
9
|
+
},
|
|
7
10
|
"exports": {
|
|
8
11
|
".": {
|
|
9
12
|
"types": "./dist/index.d.ts",
|
|
10
13
|
"import": "./dist/index.js"
|
|
11
14
|
},
|
|
15
|
+
"./cli": "./dist/cli.js",
|
|
12
16
|
"./pack": {
|
|
13
17
|
"types": "./dist/pack.d.ts",
|
|
14
18
|
"import": "./dist/pack.js"
|
|
@@ -19,19 +23,25 @@
|
|
|
19
23
|
],
|
|
20
24
|
"scripts": {
|
|
21
25
|
"clean": "rm -rf dist",
|
|
22
|
-
"build": "tsgo -p tsconfig.build.json"
|
|
26
|
+
"build": "tsgo -p tsconfig.build.json",
|
|
27
|
+
"test": "bun ../../../scripts/quality/run-vitest.mjs --run"
|
|
23
28
|
},
|
|
24
29
|
"dependencies": {
|
|
25
30
|
"@module-federation/vite": "^1.16.6",
|
|
31
|
+
"@vitejs/plugin-react": "^5.0.4",
|
|
32
|
+
"chokidar": "^4.0.3",
|
|
26
33
|
"postcss": "^8.5.15",
|
|
27
34
|
"postcss-selector-parser": "^7.1.4"
|
|
28
35
|
},
|
|
29
36
|
"peerDependencies": {
|
|
37
|
+
"@vetta-org/plugin-sdk": ">=0.3.0 <0.4.0",
|
|
30
38
|
"vite": "^7.0.0"
|
|
31
39
|
},
|
|
32
40
|
"devDependencies": {
|
|
41
|
+
"@vetta-org/plugin-sdk": "workspace:*",
|
|
33
42
|
"typescript": "^5.9.2",
|
|
34
|
-
"vite": "^7.1.7"
|
|
43
|
+
"vite": "^7.1.7",
|
|
44
|
+
"vitest": "^3.2.4"
|
|
35
45
|
},
|
|
36
46
|
"publishConfig": {
|
|
37
47
|
"access": "public",
|