UNPKG

unplugin-vue-cssvars

Version:

πŸŒ€ A vue plugin that allows you to use vue's CSSVars feature in css files

1,510 lines (1,478 loc) β€’ 51.4 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // ../packages/core/index.ts var core_exports = {}; __export(core_exports, { esbuildVueCSSVars: () => esbuildVueCSSVars, rollupVueCSSVars: () => rollupVueCSSVars, viteVueCSSVars: () => viteVueCSSVars, webpackVueCSSVars: () => webpackVueCSSVars }); module.exports = __toCommonJS(core_exports); var import_unplugin = require("unplugin"); var import_utils9 = require("../utils/index.cjs"); var import_baiwusanyu_utils7 = require("baiwusanyu-utils"); var import_pluginutils = require("@rollup/pluginutils"); var import_magic_string3 = __toESM(require("magic-string"), 1); // ../packages/core/runtime/pre-process-css.ts var import_path2 = require("path"); var import_fast_glob = __toESM(require("fast-glob"), 1); var import_fs_extra = __toESM(require("fs-extra"), 1); var import_utils3 = require("../utils/index.cjs"); var import_baiwusanyu_utils3 = require("baiwusanyu-utils"); // ../packages/core/parser/parser-variable.ts var import_parser = require("@babel/parser"); // ../node_modules/.pnpm/estree-walker-ts@1.0.1/node_modules/estree-walker-ts/index.js var u = class { should_skip; should_remove; replacement; context; constructor() { this.should_skip = false, this.should_remove = false, this.replacement = null, this.context = { skip: () => this.should_skip = true, remove: () => this.should_remove = true, replace: (e) => this.replacement = e }; } replace(e, t, s, i) { e && t && (s != null ? e[t][s] = i : e[t] = i); } remove(e, t, s) { e && t && (s != null ? e[t].splice(s, 1) : delete e[t]); } }; function c(r) { return r !== null && typeof r == "object" && "type" in r && typeof r.type == "string"; } var d = class extends u { enter; leave; constructor(e, t) { super(), this.should_skip = false, this.should_remove = false, this.replacement = null, this.context = { skip: () => this.should_skip = true, remove: () => this.should_remove = true, replace: (s) => this.replacement = s }, this.enter = e, this.leave = t; } visit(e, t, s, i) { if (e) { if (this.enter) { let o = this.should_skip, l = this.should_remove, n = this.replacement; this.should_skip = false, this.should_remove = false, this.replacement = null, this.enter.call(this.context, e, t, s, i), this.replacement && (e = this.replacement, this.replace(t, s, i, e)), this.should_remove && this.remove(t, s, i); let h = this.should_skip, f = this.should_remove; if (this.should_skip = o, this.should_remove = l, this.replacement = n, h) return e; if (f) return null; } let a; for (a in e) { let o = e[a]; if (o && typeof o == "object") if (Array.isArray(o)) { let l = o; for (let n = 0; n < l.length; n += 1) { let h = l[n]; c(h) && (this.visit(h, e, a, n) || n--); } } else c(o) && this.visit(o, e, a, null); } if (this.leave) { let o = this.replacement, l = this.should_remove; this.replacement = null, this.should_remove = false, this.leave.call(this.context, e, t, s, i), this.replacement && (e = this.replacement, this.replace(t, s, i, e)), this.should_remove && this.remove(t, s, i); let n = this.should_remove; if (this.replacement = o, this.should_remove = l, n) return null; } } return e; } }; function A(r, { enter: e, leave: t }) { return new d(e, t).visit(r, null); } // ../packages/core/parser/parser-variable.ts var import_baiwusanyu_utils = require("baiwusanyu-utils"); var getVariable = (descriptor) => { let variableName = {}; variableName = getVariableNameBySetup(setScriptContent(descriptor, "setup")); variableName = getVariableNameByScript(setScriptContent(descriptor, "script"), variableName); return variableName; }; function setScriptContent(descriptor, type) { let content = ""; if (descriptor.scriptSetup && type === "setup") content = descriptor.scriptSetup.content; if (descriptor.script && type === "script") content = descriptor.script.content; return content; } function getVariableNameBySetup(content, contextAst) { const variableNameBySetup = {}; if (!content && !contextAst) return variableNameBySetup; const ast = contextAst || (0, import_parser.parse)(content, { sourceType: "module", plugins: ["typescript", "jsx"] }); A(ast, { enter(node, parent) { if (parent && parent.type === "Program" && node.type === "VariableDeclaration") { const declarations = node.declarations; declarations.forEach((declare) => { const identifier = declare.id; variableNameBySetup[identifier.name] = declare.init; }); } } }); return variableNameBySetup; } function getVariableNameByScript(content, variableName) { if (!content) return variableName; let variableNameInScript = {}; let isEmptyVariableNames = false; let setupIndex = 0; let dataIndex = 0; let hasSetup = false; let hasData = false; let setupReturnNode = {}; let dataReturnNode = {}; let index = 2; if ((0, import_baiwusanyu_utils.isEmptyObj)(variableName)) isEmptyVariableNames = true; const ast = (0, import_parser.parse)(content, { sourceType: "module", plugins: ["typescript", "jsx"] }); A(ast, { enter(node, parent) { if (parent && parent.type === "ObjectMethod" && node.type === "Identifier" && node.name === "setup") { hasSetup = true; setupIndex = index; index--; } if (parent && parent.type === "ObjectMethod" && node.type === "Identifier" && node.name === "data") { hasData = true; dataIndex = index; index--; } if (parent && parent.type === "ReturnStatement" && node.type === "ObjectExpression" && hasSetup) { hasSetup = false; setupReturnNode = node; } if (parent && parent.type === "ReturnStatement" && node.type === "ObjectExpression" && hasData) { hasData = false; dataReturnNode = node; } } }); if (setupIndex === 0 && dataIndex === 0) { if (isEmptyVariableNames) { return variableName; } else { variableNameInScript = getVariableNameBySetup("", ast); } variableNameInScript = (0, import_baiwusanyu_utils.extend)(variableNameInScript, variableName); setupReturnNode = {}; dataReturnNode = {}; return variableNameInScript; } const setupReturnRes = getObjectExpressionReturnNode(setupReturnNode); const dataReturnRes = getObjectExpressionReturnNode(dataReturnNode); variableNameInScript = setupIndex > dataIndex ? (0, import_baiwusanyu_utils.extend)(setupReturnRes, dataReturnRes) : (0, import_baiwusanyu_utils.extend)(dataReturnRes, setupReturnRes); if (!isEmptyVariableNames) variableNameInScript = (0, import_baiwusanyu_utils.extend)(variableNameInScript, variableName); return variableNameInScript; } function getObjectExpressionReturnNode(node) { const res = {}; if (!node.properties) return res; node.properties.forEach((value) => { const key = value.key; res[key.name] = value.value; }); return res; } function matchVariable(importCSSModule, variableName) { const res = []; importCSSModule.forEach((val) => { const varNode = variableName[val]; const resObj = { value: val, has: false, isRef: false }; if (varNode) { resObj.has = true; if (varNode.type === "CallExpression" && varNode.callee.type === "Identifier" && varNode.callee.name === "ref") resObj.isRef = true; } res.push(resObj); }); return res; } // ../packages/core/parser/parser-import.ts var innerAtRule = "media,extend,at-root,debug,warn,forward,mixin,include,function,error,keyframes,font-face,page,supports,namespace,return,if,else,for,while,each,content,tailwind,apply,layer,screen,responsive,variants,config,applyRule"; function parseImports(content, helper) { const imports = []; let currentImport; let state = 0 /* Initial */; let i = 0; let AtPath = ""; const source = content; while (i < source.length) { const char = source[i]; if (/[\r\t\f\v\\]/g.test(char)) { i++; continue; } switch (state) { case 0 /* Initial */: if (char === "@") state = 3 /* AtStart */; if (char === "/" && source[i + 1] === "/") state = 1 /* InlineComment */; if (char === "/" && source[i + 1] === "*") state = 2 /* Comment */; break; case 1 /* InlineComment */: if (char === "\n") state = 0 /* Initial */; break; case 2 /* Comment */: if (char === "*" && source[i + 1] === "/") state = 0 /* Initial */; break; case 3 /* AtStart */: if (/[A-Za-z]$/.test(char)) AtPath = AtPath + char; else state = 4 /* AtEnd */; if (i === source.length - 1) { if (char === '"' || char === "'") throw new Error("syntax error: unmatched quotes"); else walkContentEnd(i); } if (!/[A-Za-z]$/.test(char) && char !== "\n" && char !== " " && char !== "-") throw new Error("syntax error"); break; case 4 /* AtEnd */: if (char !== "\n" && char !== " " && char !== "-") { if (char === "/") throw new Error("syntax error"); if (AtPath === "import") { AtPath = ""; state = 5 /* AtImport */; currentImport = { type: "import", path: "" }; i--; } else if (AtPath === "use") { AtPath = ""; state = 6 /* AtUse */; currentImport = { type: "use", path: "" }; i--; } else if (AtPath === "require") { AtPath = ""; state = 7 /* AtRequire */; currentImport = { type: "require", path: "" }; i--; } else { if (!innerAtRule.includes(AtPath)) throw new Error("syntax error: unknown At Rule"); AtPath = ""; state = 0 /* Initial */; } } break; case 5 /* AtImport */: case 6 /* AtUse */: case 7 /* AtRequire */: if (char === "@" && !/[A-Za-z]$/.test(source[i - 1])) { i--; state = 0 /* Initial */; break; } if (char === "/" && (source[i + 1] === "/" || source[i + 1] === "*")) { i--; state = 0 /* Initial */; break; } if (char === "'" || char === '"') { currentImport.start = i; state = 8 /* QuotesStart */; break; } if (char !== "\n" && char !== " ") { currentImport.start = i; currentImport.path += char; state = 10 /* StringLiteral */; break; } break; case 8 /* QuotesStart */: if (char === "'" || char === '"') { currentImport.end = i; state = 9 /* QuotesEnd */; if (i === source.length - 1) walkContentEnd(i); break; } if (i === source.length - 1) throw new Error("syntax error: unmatched quotes"); currentImport.path += char; break; case 9 /* QuotesEnd */: if (i === source.length - 1 || char === ";" || char === "\n") { walkContentEnd(i); } else { i--; state = 10 /* StringLiteral */; } break; case 10 /* StringLiteral */: if (char === ";" || char === "\n") { walkContentEnd(i); break; } if (char !== "@" && (char === " " || char === "," || char === '"' || char === "'")) { const curType = currentImport?.type; walkContentEnd(i); if (curType === "import") { state = 5 /* AtImport */; currentImport = { type: "import", path: "" }; } else if (curType === "use") { state = 6 /* AtUse */; currentImport = { type: "use", path: "" }; } else if (curType === "require") { state = 7 /* AtRequire */; currentImport = { type: "require", path: "" }; } if (char === "'" || char === '"') { currentImport.start = i; state = 8 /* QuotesStart */; if (i === source.length - 1 && (char === '"' || char === "'")) throw new Error("syntax error: unmatched quotes"); break; } break; } currentImport.path += char; if (i === source.length - 1) walkContentEnd(i); break; } i++; } function walkContentEnd(index) { pushCurrentImport(index); state = 0 /* Initial */; } function pushCurrentImport(index) { if (currentImport && currentImport.start !== void 0) { currentImport.end = index; if (helper) { helper.forEach((fn) => { currentImport = fn(currentImport); }); } imports.push(currentImport); currentImport = void 0; } } function getCurState() { return state; } function getCurImport() { return currentImport; } return { imports, getCurState, getCurImport }; } // ../packages/core/parser/parser-vbind-m.ts function lexBinding(content, start) { let state = 0 /* inParens */; let parenDepth = 0; for (let i = start; i < content.length; i++) { const char = content.charAt(i); switch (state) { case 0 /* inParens */: if (char === "'") { state = 1 /* inSingleQuoteString */; } else if (char === '"') { state = 2 /* inDoubleQuoteString */; } else if (char === "(") { parenDepth++; } else if (char === ")") { if (parenDepth > 0) parenDepth--; else return i; } break; case 1 /* inSingleQuoteString */: if (char === "'") state = 0 /* inParens */; break; case 2 /* inDoubleQuoteString */: if (char === '"') state = 0 /* inParens */; break; } } return null; } function normalizeExpression(exp) { exp = exp.trim(); if (exp[0] === "'" && exp[exp.length - 1] === "'" || exp[0] === '"' && exp[exp.length - 1] === '"') return exp.slice(1, -1); return exp; } var vBindRE = /v-bind-m\s*\(/g; function parseCssVars(styles, hook) { const vars = []; styles.forEach((style) => { let match = null; const content = style.replace(/\/\*([\s\S]*?)\*\//g, ""); const offset = style.length - content.length; while (match = vBindRE.exec(content)) { const start = match.index + match[0].length; const end = lexBinding(content, start); if (end !== null) { const variable = normalizeExpression(content.slice(start, end)); hook && hook.getIndex(start, end, offset, variable); if (!vars.includes(variable)) vars.push(variable); } } }); return vars; } // ../packages/core/parser/parser-compiled-sfc.ts var import_parser2 = require("@babel/parser"); var isSetupEnter = false; var setupBodyNode = {}; function parseSetupBody(node) { if (node.type === "Identifier" && node.name === "setup") { isSetupEnter = true; return; } if (isSetupEnter && node.type === "BlockStatement") { isSetupEnter = false; setupBodyNode = node; } } var hasCSSVars = false; function parseHasCSSVars(node, parent) { if (node.type === "Identifier" && node.name === "useCssVars" && parent && parent.type === "ImportSpecifier") hasCSSVars = true; } var useCSSVarsNode = {}; var isUseCSSVarsEnter = false; function parseUseCSSVars(node, parent) { if (node.type === "Identifier" && node.name === "_useCssVars" && parent && parent.type === "CallExpression") isUseCSSVarsEnter = true; if (isUseCSSVarsEnter && node.type === "ObjectExpression") { isUseCSSVarsEnter = false; useCSSVarsNode = node; } } function parserCompiledSfc(code) { resetVar(); const ast = (0, import_parser2.parse)(code, { sourceType: "module", plugins: ["typescript", "jsx"] }); A(ast, { enter(node, parent) { parseSetupBody(node); parseHasCSSVars(node, parent); parseUseCSSVars(node, parent); } }); return { setupBodyNode, hasCSSVars, useCSSVarsNode }; } function resetVar() { isSetupEnter = false; setupBodyNode = {}; isUseCSSVarsEnter = false; useCSSVarsNode = {}; hasCSSVars = false; } // ../packages/core/parser/parser-script-bindings.ts var import_napi = require("@ast-grep/napi"); // ../packages/core/parser/utils.ts var CSSVarsBindingTypes = { /** * returned from data() */ DATA: "data", /** * declared as a prop βœ… */ PROPS: "props", /** * a local alias of a `<script setup>` destructured prop. * the original is stored in __propsAliases of the bindingMetadata object. */ PROPS_ALIASED: "props-aliased", /** * a let binding (may or may not be a ref) βœ… */ SETUP_LET: "setup-let", /** * a const binding that can never be a ref. * these bindings don't need `unref()` calls when processed in inlined * template expressions. βœ… */ SETUP_CONST: "setup-const", /** * a const binding that does not need `unref()`, but may be mutated. βœ… */ SETUP_REACTIVE_CONST: "setup-reactive-const", /** * a const binding that may be a ref. βœ… */ SETUP_MAYBE_REF: "setup-maybe-ref", /** * bindings that are guaranteed to be refs βœ… */ SETUP_REF: "setup-ref", /** * declared by other options, e.g. computed, inject */ OPTIONS: "options", /** * a literal constant, e.g. 'foo', 1, true βœ… */ LITERAL_CONST: "literal-const" }; // ../packages/core/parser/ast-grep-rules.ts var astGrepRules = { IDENT_NAME: { has: { kind: "identifier", field: "name" } }, FN_CALL: { has: { kind: "variable_declarator", has: { kind: "call_expression" } } }, ARROW_FN: { has: { kind: "variable_declarator", has: { kind: "arrow_function" } } }, NOR_FN_VAR: { has: { kind: "variable_declarator", has: { kind: "function" } } }, OBJ_VAR: { has: { kind: "variable_declarator", has: { kind: "object", field: "value" } } }, ARR_VAR: { has: { kind: "variable_declarator", has: { kind: "array", field: "value" } } }, NOR_FN: { has: { kind: "function_declaration", has: { kind: "identifier", field: "name" } } }, PROPS_DEFAULT_CALL: { has: { kind: "call_expression", has: { kind: "identifier", field: "function" } } }, PROPS_DEFAULT_ARG: { kind: "property_identifier", inside: { kind: "pair", inside: { kind: "object", inside: { kind: "arguments" } } } }, PROPS_DEFAULT_VAL: { kind: "object", inside: { kind: "arguments" } }, CONST_VAR: { any: [ { pattern: "const $VAR" } ] }, LET_VAR: { any: [ { pattern: "let $VAR" } ] }, CONST_REF_VAR: { any: [ { pattern: "const $VAR = ref($VAL)" } ] }, CONST_REACTIVE_VAR: { any: [ { pattern: "const $VAR = reactive($VAL)" } ] }, CONST_PROPS_VAR: { any: [ { pattern: "const $VAR = defineProps($VAL)" } ] }, CONST_NOR_FN: { has: { kind: "function_declaration" } }, OBJ_PATTERN: { has: { kind: "object_pattern" } }, NEW_EXP: { has: { kind: "new_expression", field: "value" } }, OBJ_PATTERN_VAL: { any: [ { kind: "identifier" }, { kind: "shorthand_property_identifier_pattern" } ] } }; var getRules = (name) => { return { rule: { matches: name }, utils: astGrepRules }; }; // ../packages/core/parser/parser-script-bindings.ts function analyzeScriptBindings(descriptor) { const scriptSetupContent = descriptor.scriptSetup?.content || ""; const scriptContent = descriptor.script?.content || ""; if (!scriptSetupContent && !scriptContent) return {}; const bindings = {}; const sgNodeScriptSetup = import_napi.ts.parse(scriptSetupContent).root(); walkSgNodeToGetBindings(sgNodeScriptSetup, bindings); const sgNodeScript = import_napi.ts.parse(scriptContent).root(); walkSgNodeToGetBindings(sgNodeScript, bindings); return bindings; } function walkSgNodeToGetBindings(node, bindings) { node.findAll(getRules("LET_VAR")).forEach((n) => { const key = n.getMatch("VAR")?.text() || ""; bindings[key] = CSSVarsBindingTypes.SETUP_LET; }); let constVARs = node.findAll(getRules("CONST_VAR")); constVARs = constVARs.concat(node.findAll(getRules("CONST_NOR_FN"))); constVARs.forEach((n) => { const key = n.getMatch("VAR")?.text() || n.find(getRules("IDENT_NAME"))?.text() || ""; if (!key) return; bindings[key] = CSSVarsBindingTypes.LITERAL_CONST; if (n.find(getRules("CONST_REF_VAR"))) { bindings[key] = CSSVarsBindingTypes.SETUP_REF; } else if (n.find(getRules("CONST_REACTIVE_VAR"))) { bindings[key] = CSSVarsBindingTypes.SETUP_REACTIVE_CONST; } else if (n.find(getRules("FN_CALL")) || n.find(getRules("NEW_EXP")) || n.find(getRules("OBJ_PATTERN"))?.text().startsWith("{") && n.find(getRules("OBJ_PATTERN"))?.text().endsWith("}")) { bindings[key] = CSSVarsBindingTypes.SETUP_MAYBE_REF; const deconstructVal = n.find(getRules("OBJ_PATTERN")); const deconstructKeyNode = deconstructVal?.findAll(getRules("OBJ_PATTERN_VAL")); deconstructKeyNode && deconstructKeyNode.forEach((nI) => { Reflect.deleteProperty(bindings, key); bindings[nI.text()] = CSSVarsBindingTypes.SETUP_MAYBE_REF; }); } else if (n.find(getRules("ARROW_FN")) || n.find(getRules("NOR_FN")) || n.find(getRules("OBJ_VAR")) || n.find(getRules("ARR_VAR")) || n.kind() === "function_declaration" || n.find(getRules("NOR_FN_VAR"))) { if (n.kind() === "function_declaration") bindings[n.find(getRules("IDENT_NAME"))?.text() || "unk"] = CSSVarsBindingTypes.SETUP_CONST; else bindings[key] = CSSVarsBindingTypes.SETUP_CONST; } if (n.find(getRules("PROPS_DEFAULT_CALL")) && n.find(getRules("PROPS_DEFAULT_CALL"))?.text().includes("withDefaults")) { const argObjNode = n.findAll(getRules("PROPS_DEFAULT_ARG")); argObjNode.forEach((nI) => { !bindings[nI.text()] && (bindings[nI.text()] = CSSVarsBindingTypes.PROPS); }); bindings[key] = CSSVarsBindingTypes.SETUP_CONST; } if (n.find(getRules("CONST_PROPS_VAR"))) { const argObjNode = n.findAll(getRules("PROPS_DEFAULT_ARG")); argObjNode.forEach((nI) => { !bindings[nI.text()] && (bindings[nI.text()] = CSSVarsBindingTypes.PROPS); }); bindings[key] = CSSVarsBindingTypes.SETUP_REACTIVE_CONST; } }); } // ../packages/core/transform/transform-quotes.ts function transformQuotes(importer2) { if (!importer2.path.startsWith('"') && !importer2.path.endsWith('"')) { if (importer2.path.startsWith("'") && importer2.path.endsWith("'")) importer2.path = `"${importer2.path.slice(1, -1)}"`; else importer2.path = `"${importer2.path}"`; } return importer2; } // ../packages/core/runtime/process-css.ts var import_path = require("path"); var import_utils2 = require("../utils/index.cjs"); var import_baiwusanyu_utils2 = require("baiwusanyu-utils"); var getCSSFileRecursion = (lang = import_utils2.SUPPORT_FILE.CSS, key, cssFiles, cb, sfcPath, matchedMark = /* @__PURE__ */ new Set()) => { key = (0, import_utils2.completeSuffix)(key, lang); if (!cssFiles.get(key)) key = (0, import_utils2.completeSuffix)(key, import_utils2.SUPPORT_FILE.CSS, true); if (matchedMark.has(key)) return; const cssFile = cssFiles.get(key); if (cssFile) { if (!cssFile.sfcPath) cssFile.sfcPath = /* @__PURE__ */ new Set(); cssFile.sfcPath?.add(sfcPath || ""); matchedMark.add(key); cb(cssFile); if (cssFile.importer.size > 0) { cssFile.importer.forEach((value) => { getCSSFileRecursion(lang, value, cssFiles, cb, sfcPath, matchedMark); }); } } else { throw new Error("path"); } }; var getVBindVariableListByPath = (descriptor, id, cssFiles, server, alias) => { const vbindVariable = /* @__PURE__ */ new Set(); const injectCSSContent = /* @__PURE__ */ new Set(); for (let i = 0; i < descriptor.styles.length; i++) { const content = descriptor.styles[i].content; const lang = descriptor.styles[i].lang === import_utils2.SUPPORT_FILE.STYLUS ? import_utils2.SUPPORT_FILE.STYL : descriptor.styles[i].lang; const idDirParse = (0, import_path.parse)(id); const parseImporterRes = parseImports(content); parseImporterRes.imports.forEach((res) => { const importerPath = handleAlias(res.path, alias, idDirParse.dir); try { getCSSFileRecursion(lang, importerPath, cssFiles, (res2) => { if (res2.vBindCode) { !server && injectCSSContent.add({ content: res2.content, lang: res2.lang, styleTagIndex: i }); res2.vBindCode.forEach((vb) => { vbindVariable.add(vb); }); } }, id); } catch (e) { if (e.message === "path") { const doc = "https://github.com/baiwusanyu-c/unplugin-vue-cssvars/pull/29"; throw new Error(`Unable to resolve file under path '${res.path}', see: ${doc}`); } else { throw new Error(e.message); } } }); } return { vbindVariableListByPath: (0, import_utils2.setTArray)(vbindVariable), injectCSSContent }; }; function handleAlias(path, alias, idDirPath) { let importerPath = ""; if (!alias && !idDirPath) return path; if (alias) { for (const aliasKey in alias) { if (alias[aliasKey] && path.startsWith(aliasKey)) { importerPath = path.replace(aliasKey, alias[aliasKey]); break; } } if (importerPath) return (0, import_baiwusanyu_utils2.normalizePath)(importerPath); importerPath = idDirPath ? (0, import_path.resolve)(idDirPath, path) : path; } else { idDirPath && (importerPath = (0, import_path.resolve)(idDirPath, path)); } return (0, import_baiwusanyu_utils2.normalizePath)(importerPath); } // ../packages/core/runtime/pre-process-css.ts function preProcessCSS(options, alias, filesPath) { const { rootDir, includeCompile } = options; const files = filesPath || getAllCSSFilePath(includeCompile, rootDir); return createCSSFileModuleMap(files, rootDir, alias); } function getAllCSSFilePath(includeCompile, rootDir) { return import_fast_glob.default.sync(includeCompile, { ignore: import_utils3.FG_IGNORE_LIST, cwd: rootDir }); } function createCSSFileModuleMap(files, rootDir, alias) { const cssFiles = /* @__PURE__ */ new Map(); for (const file of files) { let absoluteFilePath = (0, import_path2.resolve)((0, import_path2.parse)(file).dir, (0, import_path2.parse)(file).base); absoluteFilePath = (0, import_baiwusanyu_utils3.normalizePath)(absoluteFilePath); if (!cssFiles.get(absoluteFilePath)) { cssFiles.set(absoluteFilePath, { importer: /* @__PURE__ */ new Set(), vBindCode: [], content: "", lang: "css" }); } } for (const file of files) { const fileDirParse = (0, import_path2.parse)(file); const fileSuffix = fileDirParse.ext; const code = import_fs_extra.default.readFileSync((0, import_baiwusanyu_utils3.normalizePath)((0, import_path2.resolve)(rootDir, file)), { encoding: "utf-8" }); const { imports } = parseImports(code, [transformQuotes]); const absoluteFilePath = (0, import_baiwusanyu_utils3.normalizePath)((0, import_path2.resolve)(fileDirParse.dir, fileDirParse.base)); const cssF = cssFiles.get(absoluteFilePath); imports.forEach((value) => { const importerPath = handleAlias(value.path.replace(/^"|"$/g, ""), alias, fileDirParse.dir); let importerVal = (0, import_utils3.completeSuffix)(importerPath, import_utils3.SUPPORT_FILE.CSS); if (fileSuffix !== `.${import_utils3.SUPPORT_FILE.CSS}`) { const importerValBySuffix = (0, import_utils3.completeSuffix)( importerPath, fileSuffix.split(".")[1], true ); if (cssFiles.get(importerValBySuffix)) importerVal = importerValBySuffix; } cssF.importer.add(importerVal); }); cssF.vBindCode = parseCssVars([code]); cssF.content = code; cssF.lang = fileSuffix.replaceAll(".", ""); cssFiles.set(absoluteFilePath, cssF); } return cssFiles; } // ../packages/core/option/index.ts var import_path3 = require("path"); var import_utils4 = require("../utils/index.cjs"); var import_baiwusanyu_utils4 = require("baiwusanyu-utils"); var defaultOption = { rootDir: (0, import_path3.resolve)(), include: import_utils4.DEFAULT_INCLUDE_REG, exclude: import_utils4.DEFAULT_EXCLUDE_REG, includeCompile: import_utils4.SUPPORT_FILE_LIST }; function initOption(option) { option = (0, import_baiwusanyu_utils4.extend)(defaultOption, option); return option; } // ../packages/core/runtime/vite.ts var import_utils7 = require("../utils/index.cjs"); var import_baiwusanyu_utils5 = require("baiwusanyu-utils"); // ../packages/core/inject/inject-css.ts var import_hash_sum = __toESM(require("hash-sum"), 1); // ../packages/core/transform/transform-inject-css.ts var import_magic_string = __toESM(require("magic-string"), 1); function transformInjectCSS(code, importer2) { const mgc = new import_magic_string.default(code); importer2.forEach((imp) => { mgc.overwrite(imp.start, imp.end, ""); }); return mgc.toString().replaceAll("@import ;", "").replaceAll("v-bind-m", "v-bind"); } // ../packages/core/inject/inject-css.ts function injectCSSOnServer(mgcStr, vbindVariableList, isHMR) { const pCssVarsArr = []; parseCssVars([mgcStr.toString()], { getIndex(start, end, offset, variable) { pCssVarsArr.push({ start, end, offset, variable }); } }); pCssVarsArr.forEach((pca) => { if (vbindVariableList) { for (let i = 0; i < vbindVariableList.length; i++) { const vbVar = vbindVariableList[i]; if (!vbVar.hash && isHMR) vbVar.hash = (0, import_hash_sum.default)(vbVar.value + vbVar.has); if (vbVar.value === pca.variable) { const offset = pca.offset; const start = pca.start + offset; const end = pca.end + offset; vbVar.hash && (mgcStr = mgcStr.overwrite(start, end, `--${vbVar.hash}`)); break; } } } }); mgcStr = mgcStr.replace(/v-bind-m\s*\(/g, "var("); return mgcStr; } function injectCssOnBuild(mgcStr, injectCSSContent, descriptor) { if (!injectCSSContent && !descriptor) return mgcStr; const cssContent = [...injectCSSContent]; let resCode = ""; descriptor.styles && descriptor.styles.forEach((value, index) => { let injectCssCode = ""; cssContent.forEach((value2) => { if (value2.styleTagIndex === index) injectCssCode = `${injectCssCode} ${transformInjectCSS(value2.content, parseImports(value2.content).imports)}`; }); const lang = value.lang || "css"; const scoped = value.scoped ? "scoped" : ""; resCode = `${resCode} <style lang="${lang}" ${scoped}> ${injectCssCode} ${transformInjectCSS(value.content, parseImports(value.content).imports)} </style>`; }); resCode && (mgcStr = removeStyleTagsAndContent(mgcStr)); return mgcStr.prependRight(mgcStr.length(), resCode); } function removeStyleTagsAndContent(mgcStr) { return mgcStr.replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<style\b[^>]*>/gi, "").replace(/<\/style>/gi, ""); } // ../packages/core/inject/inject-cssvars.ts var import_hash_sum2 = __toESM(require("hash-sum"), 1); var import_napi2 = require("@ast-grep/napi"); var import_magic_string2 = __toESM(require("magic-string"), 1); var importer = 'import { useCssVars as _useCssVars } from "vue"\n'; var importerUnref = 'import { unref as _unref } from "vue"\n'; function findIdentifierFromExp(cssContent) { return import_napi2.ts.parse(cssContent).root().findAll({ rule: { matches: "cssComplexExpIdentifier" }, utils: { cssComplexExpIdentifier: { any: [ { kind: "identifier" } ] } } }); } var injectCSSVars = (vbindVariableList, isScriptSetup, parserRes, mgcStr, bindings) => { if (!vbindVariableList || vbindVariableList.length === 0) return { vbindVariableList, mgcStr }; return injectCSSVarsOnServer(vbindVariableList, isScriptSetup, parserRes, mgcStr, bindings); }; function injectCSSVarsOnServer(vbindVariableList, isScriptSetup, parserRes, mgcStr, bindings) { let resMgcStr = mgcStr; const hasUseCssVars = parserRes.hasCSSVars; const cssvarsObjectCode = createCSSVarsObjCode(vbindVariableList, isScriptSetup, resMgcStr, bindings); if (isScriptSetup) { if (hasUseCssVars) { resMgcStr = injectUseCssVarsSetup(resMgcStr, cssvarsObjectCode, true, parserRes); } else { const useCssVars = createUseCssVarsCode(cssvarsObjectCode, true); resMgcStr = injectUseCssVarsSetup(resMgcStr, useCssVars, false, parserRes); } } else { if (hasUseCssVars) { resMgcStr = injectUseCssVarsOption(resMgcStr, cssvarsObjectCode, true, parserRes); } else { const useCssVars = createUseCssVarsCode(cssvarsObjectCode, false); resMgcStr = injectUseCssVarsOption(resMgcStr, useCssVars, false, parserRes); } } return { vbindVariableList, mgcStr: resMgcStr }; } function injectUseCssVarsSetup(mgcStr, useCssVars, hasUseCssVars, parserRes) { let resMgcStr = mgcStr; if (!resMgcStr.toString().includes("_unref")) resMgcStr = resMgcStr.prependLeft(0, importerUnref); if (parserRes) { if (!hasUseCssVars && parserRes.setupBodyNode && parserRes.setupBodyNode.start) { const start = parserRes.setupBodyNode.start + 1; resMgcStr = resMgcStr.prependLeft(start, useCssVars); resMgcStr = resMgcStr.prependLeft(0, importer); } else if (hasUseCssVars && parserRes.useCSSVarsNode && parserRes.useCSSVarsNode.start) { const start = parserRes.useCSSVarsNode.start + 1; resMgcStr = resMgcStr.prependLeft(start, useCssVars); } } return resMgcStr; } function injectUseCssVarsOption(mgcStr, useCssVars, hasUseCssVars, parserRes) { let resMgcStr = mgcStr; if (!resMgcStr.toString().includes("_unref")) resMgcStr = resMgcStr.prependLeft(0, importerUnref); if (!hasUseCssVars) { if (resMgcStr.toString().includes("const _sfc_main")) resMgcStr = resMgcStr.replaceAll("const _sfc_main", "const __default__"); else if (resMgcStr.toString().includes("import _sfc_main")) resMgcStr = resMgcStr.replaceAll("import _sfc_main", "import __default__"); else resMgcStr = resMgcStr.replaceAll("export default {", "const __default__ = {"); if (resMgcStr.toString().includes("function _sfc_render")) { resMgcStr = resMgcStr.replaceAll( "function _sfc_render", `${useCssVars} const __setup__ = __default__.setup __default__.setup = __setup__ ? (props, ctx) => { __injectCSSVars__(); return __setup__(props, ctx) } : __injectCSSVars__ const _sfc_main = __default__ function _sfc_render` ); } else if (resMgcStr.toString().includes("const __default__")) { resMgcStr = resMgcStr.prependRight( resMgcStr.length(), `${useCssVars} const __setup__ = __default__.setup __default__.setup = __setup__ ? (props, ctx) => { __injectCSSVars__(); return __setup__(props, ctx) } : __injectCSSVars__ const _sfc_main = __default__ export default _sfc_main` ); } resMgcStr = resMgcStr.prependLeft(0, importer); } else if (hasUseCssVars && parserRes.useCSSVarsNode && parserRes.useCSSVarsNode.start) { const start = parserRes.useCSSVarsNode.start + 1; resMgcStr = resMgcStr.prependLeft(start, useCssVars); } return resMgcStr; } function createCSSVarsObjCode(vbindVariableList, isScriptSetup, mgcStr, bindings) { let resCode = ""; vbindVariableList.forEach((vbVar) => { const hashVal = vbVar.hash || (0, import_hash_sum2.default)(vbVar.value + vbVar.has); vbVar.hash = hashVal; let varStr = ""; const ms = new import_magic_string2.default(vbVar.value); const cssBindKeySgNodes = findIdentifierFromExp(vbVar.value); cssBindKeySgNodes.forEach((node) => { const range = node.range(); ms.overwrite( range.start.index, range.end.index, // non-inline composition api ε’Œ option api δΈ€η›΄εΈΆ _ctx !isScriptSetup ? `(_ctx.${node.text()})` : genCSSVarsValue(node, bindings) ); }); varStr = ms.toString(); resCode = ` "${hashVal}": ${varStr},${resCode}`; }); if (mgcStr && mgcStr.toString().includes(resCode)) return ""; return resCode; } function createUCVCSetupUnHas(cssvarsObjectCode) { return ` _useCssVars((_ctx) => ({ ${cssvarsObjectCode} }));`; } function createUCVCOptionUnHas(resCode) { return ` const __injectCSSVars__ = () => { _useCssVars((_ctx) => ({ ${resCode} })) };`; } function createUseCssVarsCode(cssvarsObjectCode, isScriptSetup) { let resCode = ""; if (isScriptSetup) { resCode = createUCVCSetupUnHas(cssvarsObjectCode); } else { resCode = createUCVCOptionUnHas(cssvarsObjectCode); } return resCode; } function genCSSVarsValue(node, bindings) { let res = `_ctx.${node.text()}`; if (bindings) { const binding = bindings[node.text()]; switch (binding) { case CSSVarsBindingTypes.PROPS: case CSSVarsBindingTypes.SETUP_CONST: case CSSVarsBindingTypes.SETUP_REACTIVE_CONST: case CSSVarsBindingTypes.LITERAL_CONST: res = node.text(); break; case CSSVarsBindingTypes.SETUP_MAYBE_REF: case CSSVarsBindingTypes.SETUP_LET: res = `_unref(${node.text()})`; break; case CSSVarsBindingTypes.SETUP_REF: res = `${node.text()}.value`; break; default: res = `_ctx.${node.text()}`; } } return res; } // ../packages/core/hmr/hmr.ts var import_utils6 = require("../utils/index.cjs"); function viteHMR(CSSFileModuleMap, userOptions, file, server) { const sfcModulesPathList = CSSFileModuleMap.get(file); if (!(sfcModulesPathList && sfcModulesPathList.sfcPath)) return; updatedCSSModules(CSSFileModuleMap, userOptions, file); reloadSFCModules(CSSFileModuleMap, userOptions, sfcModulesPathList, file, server); } function webpackHMR(CSSFileModuleMap, userOptions, file) { updatedCSSModules(CSSFileModuleMap, userOptions, file); } function updatedCSSModules(CSSFileModuleMap, userOptions, file) { const updatedCSSMS = preProcessCSS(userOptions, userOptions.alias, [file]).get(file); const sfcPath = CSSFileModuleMap.get(file).sfcPath || /* @__PURE__ */ new Set(); const res = { ...updatedCSSMS, sfcPath }; CSSFileModuleMap.set(file, res); } function reloadSFCModules(CSSFileModuleMap, userOptions, sfcModulesPathList, file, server) { if (sfcModulesPathList && sfcModulesPathList.sfcPath) { const ls = (0, import_utils6.setTArray)(sfcModulesPathList.sfcPath); ls.forEach((sfcp) => { const modules = server.moduleGraph.fileToModulesMap.get(sfcp) || /* @__PURE__ */ new Set(); const modulesList = (0, import_utils6.setTArray)(modules); for (let i = 0; i < modulesList.length; i++) { if (modulesList[i].id && modulesList[i].id.endsWith(".vue")) server.reloadModule(modulesList[i]); } }); } } // ../packages/core/runtime/handle-variable.ts var import_compiler_sfc = require("@vue/compiler-sfc"); function handleVBindVariable(code, id, ctx) { const { descriptor } = (0, import_compiler_sfc.parse)(code); ctx.isScriptSetup = !!descriptor.scriptSetup; const { vbindVariableListByPath, injectCSSContent } = getVBindVariableListByPath( descriptor, id, ctx.CSSFileModuleMap, ctx.isServer, ctx.userOptions.alias ); const variableName = getVariable(descriptor); ctx.vbindVariableList.set(id, matchVariable(vbindVariableListByPath, variableName)); ctx.isScriptSetup && (ctx.bindingsTypeMap[id] = analyzeScriptBindings(descriptor)); return { descriptor, injectCSSContent }; } // ../packages/core/runtime/handle-inject-css.ts function handleInjectCss(id, code, mgcStr, ctx) { const parseRes = parserCompiledSfc(code); const injectRes = injectCSSVars( ctx.vbindVariableList.get(id), ctx.isScriptSetup, parseRes, mgcStr, ctx.bindingsTypeMap[id] ); mgcStr = injectRes.mgcStr; injectRes.vbindVariableList && ctx.vbindVariableList.set(id, injectRes.vbindVariableList); return mgcStr; } // ../packages/core/runtime/vite.ts function transformPreVite(id, code, mgcStr, ctx) { let injectCSSContent = null; let descriptor = null; if (id.endsWith(".vue")) { const res = handleVBindVariable(code, id, ctx); if (res) { descriptor = res.descriptor; injectCSSContent = res.injectCSSContent; } } if (mgcStr && !ctx.isServer && ctx.framework !== "webpack" && ctx.framework !== "rspack") mgcStr = injectCssOnBuild(mgcStr, injectCSSContent, descriptor); return mgcStr; } function transformPostViteDev(id, code, mgcStr, ctx) { if (id.endsWith(".vue") || id.includes("&lang.tsx") || id.includes("&lang.jsx")) mgcStr = handleInjectCss(id.split("?vue")[0], code, mgcStr, ctx); if (id.includes("?vue&type=style")) { mgcStr = injectCSSOnServer( mgcStr, ctx.vbindVariableList.get(id.split("?vue")[0]), ctx.isHMR ); } return mgcStr; } var vitePlugin = (ctx) => { return { // Vite plugin configResolved(config) { if (ctx.userOptions.server !== void 0) ctx.isServer = ctx.userOptions.server; else ctx.isServer = config.command === "serve"; }, handleHotUpdate(hmr) { if (import_utils7.SUPPORT_FILE_REG.test(hmr.file)) { ctx.isHMR = true; viteHMR( ctx.CSSFileModuleMap, ctx.userOptions, (0, import_baiwusanyu_utils5.normalizePath)(hmr.file), hmr.server ); } } }; }; // ../packages/core/runtime/webpack.ts var import_utils8 = require("../utils/index.cjs"); var import_baiwusanyu_utils6 = require("baiwusanyu-utils"); function transformPreWebpack(id, code, ctx) { if (id.endsWith(".vue")) handleVBindVariable(code, id, ctx); if ((id.includes("?vue&type=style") || id.includes("?vue&type=script")) && ctx.isHMR && ctx.framework === "webpack") { id = id.split("?vue")[0]; handleVBindVariable(code, id, ctx); } } function transformPostWebpack(id, code, mgcStr, ctx) { if (id.includes("?vue&type=script")) { id = id.split("?vue")[0]; handleInjectCss(id, code, mgcStr, ctx); } const cssFMM = ctx.CSSFileModuleMap.get(id); if (cssFMM && cssFMM.sfcPath && cssFMM.sfcPath.size > 0) { const sfcPathIdList = (0, import_utils8.setTArray)(cssFMM.sfcPath); sfcPathIdList.forEach((v) => { mgcStr = injectCSSOnServer( mgcStr, ctx.vbindVariableList.get(v), ctx.isHMR ); }); } return mgcStr; } var webpackPlugin = (ctx, compiler) => { let modifiedFile = ""; compiler.hooks.watchRun.tapAsync(import_utils8.NAME, (compilation1, watchRunCallBack) => { if (compilation1.modifiedFiles) { modifiedFile = (0, import_baiwusanyu_utils6.normalizePath)((0, import_utils8.setTArray)(compilation1.modifiedFiles)[0]); if (import_utils8.SUPPORT_FILE_REG.test(modifiedFile)) { ctx.isHMR = true; webpackHMR( ctx.CSSFileModuleMap, ctx.userOptions, modifiedFile ); } } watchRunCallBack(); }); compiler.hooks.compilation.tap(import_utils8.NAME, (compilation) => { compilation.hooks.finishModules.tapAsync(import_utils8.NAME, async (modules, callback) => { if (ctx.isHMR) { const needRebuildModules = /* @__PURE__ */ new Map(); for (const value of modules) { const resource = (0, import_baiwusanyu_utils6.normalizePath)(value.resource); if (resource.includes("?vue&type=script")) { const sfcPathKey = resource.split("?vue")[0]; const cm = ctx.CSSFileModuleMap.get(modifiedFile); if (cm && cm.sfcPath && cm.sfcPath.has(sfcPathKey)) needRebuildModules.set(sfcPathKey, value); } } if (needRebuildModules.size > 0) { const promises = []; for (const [key] of needRebuildModules) { const promise = new Promise((resolve4, reject) => { compilation.rebuildModule(needRebuildModules.get(key), (e) => { if (e) reject(e); else resolve4(true); }); }); promises.push(promise); } Promise.all(promises).then(() => { callback(); ctx.isHMR = false; }).catch((e) => { (0, import_baiwusanyu_utils6.log)("error", e); }); } else { callback(); } } else { callback(); } }); }); }; // ../packages/core/index.ts var unplugin = (0, import_unplugin.createUnplugin)( (options = {}, meta) => { (0, import_baiwusanyu_utils7.setGlobalPrefix)(`[${import_utils9.NAME}]:`); const userOptions = initOption(options); const filter = (0, import_pluginutils.createFilter)( userOptions.include, userOptions.exclude ); if (userOptions.server === void 0) { (0, import_baiwusanyu_utils7.log)("warning", "The server of option is not set, you need to specify whether you are using the development server or building the project"); (0, import_baiwusanyu_utils7.log)("warning", "See: https://github.com/baiwusanyu-c/unplugin-vue-cssvars/blob/master/README.md#option"); } const context = { CSSFileModuleMap: preProcessCSS(userOptions, userOptions.alias), vbindVariableList: /* @__PURE__ */ new Map(), isServer: !!userOptions.server, isHMR: false, userOptions, framework: meta.framework, isScriptSetup: false, bindingsTypeMap: {} }; return [ { name: import_utils9.NAME, enforce: "pre", transformInclude(id) { return filter(id); }, async transform(code, id) { const transId = (0, import_baiwusanyu_utils7.normalizePath)(id); let mgcStr = new import_magic_string3.default(code); try { if (context.framework === "vite" || context.framework === "rollup" || context.framework === "esbuild") { mgcStr = transformPreVite( transId, code, mgcStr, context ); } if (context.framework === "webpack") { transformPreWebpack( transId, code, context ); } return { code: mgcStr.toString(), get map() { return mgcStr.generateMap({ source: id, includeContent: true, hires: true }); } }; } catch (err) { this.error(`[${import_utils9.NAME}] ${err}`); } }, // handle hmr with vite and command vite: vitePlugin(context), // handle hmr with webpack webpack(compiler) { webpackPlugin(context, compiler); } }, { name: `${import_utils9.NAME}:inject`, enforce: "post", transformInclude(id) { return filter(id); }, async transform(code, id) { const transId = (0, import_baiwusanyu_utils7.normalizePath)(id); let mgcStr = new import_magic_string3.default(code); try {