"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); // src/index.ts var src_exports = {}; __export(src_exports, { default: () => vueCssModule }); module.exports = __toCommonJS(src_exports); var import_compiler_sfc2 = require("vue/compiler-sfc"); // src/utils/parseVue.ts var import_compiler_sfc = require("vue/compiler-sfc"); function parseVue(code) { const descriptor = (0, import_compiler_sfc.parse)(code).descriptor; const cssModule = descriptor.styles.find((style) => style.module !== void 0)?.module; return { cssModule, template: descriptor.template }; } // src/utils/tool.ts function isObjectExp(code) { return code.startsWith("{") && code.endsWith("}"); } function isArrayExp(code) { return code.startsWith("[") && code.endsWith("]"); } function getObjectOrArrayExpressionContent(code) { let str = trimString(code.substring(1, code.length - 1)); return str.endsWith(",") ? str.substring(0, str.length - 1) : str; } function trimString(code) { return code.trim(); } function transformString2Array(code) { return code.split(" ").filter((str) => str); } function transformString2ObjectString(code, quote) { if (!code) return ""; return splitStr2Arr(code, quote).map((val) => { const _val = trimString(val); if (isObjectExp(_val)) { return _val.substring(1, _val.length - 1); } else if (isArrayExp(_val)) { return transformString2ObjectString(_val.substring(1, _val.length - 1), quote); } else { return `[${_val}]:${_val}`; } }).join(","); } function transformExp(code, cssModuleName, quote, keepReturnType = false) { if (isObjectExp(code)) { return transformObject(code, cssModuleName, quote, keepReturnType); } else if (isArrayExp(code)) { return transformArray(code, cssModuleName, quote, keepReturnType); } else { return transformString(code, cssModuleName); } } function splitStr2Arr(code, quote) { const result = []; let buffer = ""; let stack = []; for (let i = 0; i < code.length; i++) { const char = code[i]; if (char === "{" || char === "[") { if (stack.length > 0 && stack[stack.length - 1] === quote) { buffer += char; } else { stack.push(char); buffer += char; } } else if (char === "}") { if (stack.length > 0 && stack[stack.length - 1] === "{") { stack.pop(); buffer += char; } else { buffer += char; } } else if (char === "]") { if (stack.length > 0 && stack[stack.length - 1] === "[") { stack.pop(); buffer += char; } else { buffer += char; } } else if (char === quote) { if (stack.length > 0 && stack[stack.length - 1] === quote) { stack.pop(); buffer += char; } else { stack.push(quote); buffer += char; } } else if (char === ",") { if (stack.length === 0) { result.push(trimString(buffer)); buffer = ""; } else { buffer += char; } } else { buffer += char; } } if (trimString(buffer) !== "") { result.push(trimString(buffer)); } return result; } function transformObject(code, cssModuleName, quote, keepReturnType) { const content = getObjectOrArrayExpressionContent(code); if (!content) return ""; const contentArr = splitStr2Arr(content, quote); const result = contentArr.map((item) => { let key = item, value = item; let firstColonIndex = item.indexOf(":"); if (firstColonIndex !== -1) { key = item.slice(0, firstColonIndex); value = item.slice(firstColonIndex + 1); } let _key = trimString(key); if (isLegalVariate(_key)) { _key = `${quote}${_key}${quote}`; } return `[${cssModuleName}[${_key}]]:${trimString(value)}`; }).join(","); return keepReturnType ? "{" + result + "}" : result; } function transformArray(code, cssModuleName, quote, keepReturnType) { const content = getObjectOrArrayExpressionContent(code); if (!content) return ""; const contentArr = splitStr2Arr(content, quote); const result = contentArr.map((item) => { return transformExp(item, cssModuleName, quote, true); }).join(","); return keepReturnType ? "[" + result + "]" : result; } function transformString(code, cssModuleName) { if (!code) return ""; return `${cssModuleName}[${code}]`; } function isLegalVariate(variableName) { return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(variableName); } function getQuote(code) { for (let i = 0; i < code.length; i++) { if (code[i] === '"') { return '"'; } if (code[i] === "'") { return "'"; } if (code[i] === "`") { return "`"; } } return ""; } function swapQuotes(code) { let result; const placeholder = "__QUOTE__"; result = code.replace(/'/g, placeholder); result = result.replace(/"/g, "'"); result = result.replace(new RegExp(placeholder, "g"), '"'); return result; } function transform2SingleQuotes(code) { return code.replace(/"/g, "'"); } function getPugVal(code) { if (typeof code === "boolean") return ""; return trimString(code.substring(1, code.length - 1)); } // src/utils/parseHtml.ts function parseHtml(childNode, s, attrName, cssModuleName) { childNode.forEach((node) => { if ("props" in node) { let bindClassNode, attrNameNode, bindAttrNameNode; node.props.forEach((prop) => { if (prop.name === "bind" && "arg" in prop && prop.arg && "content" in prop.arg) { if (prop.arg.content === "class") { bindClassNode = prop; } else if (prop.arg.content === attrName) { bindAttrNameNode = prop; } } else if (prop.name === attrName && "value" in prop) { attrNameNode = prop; } }); if (attrNameNode) { const attrNameQuote = getQuote(attrNameNode.loc.source); let attrNameArr = transformString2Array(attrNameNode.value?.content || ""); if (attrNameArr.length === 0) { s.update(attrNameNode.loc.start.offset, attrNameNode.loc.end.offset, ""); return; } if (bindClassNode && bindClassNode.exp && "content" in bindClassNode.exp) { const bindClassQuote = getQuote(bindClassNode.loc.source); const strQuote = bindClassQuote === "'" ? '"' : "'"; const bindClassContent = trimString(bindClassNode.exp.content); let result; if (isObjectExp(bindClassContent)) { let objectContent = getObjectOrArrayExpressionContent(bindClassContent); if (objectContent) { objectContent += ","; } result = `:class=${bindClassQuote}{${objectContent}${attrNameArr.map((val) => `[${cssModuleName}[${strQuote}${val}${strQuote}]]:true`).join(",")}}${bindClassQuote}`; } else if (isArrayExp(bindClassContent)) { let arrayContent = getObjectOrArrayExpressionContent(bindClassContent); if (arrayContent) { arrayContent += ","; } result = `:class=${bindClassQuote}[${arrayContent}${attrNameArr.map((val) => `${cssModuleName}[${strQuote}${val}${strQuote}]`).join(",")}]${bindClassQuote}`; } else { result = `:class=${bindClassQuote}[${bindClassContent},${attrNameArr.map((val) => `${cssModuleName}[${strQuote}${val}${strQuote}]`).join(",")}]${bindClassQuote}`; } s.update(bindClassNode.loc.start.offset, bindClassNode.loc.end.offset, result); s.update(attrNameNode.loc.start.offset, attrNameNode.loc.end.offset, ""); } else { const strQuote = attrNameQuote === "'" ? '"' : "'"; s.update( attrNameNode.loc.start.offset, attrNameNode.loc.end.offset, `:class=${attrNameQuote}[${attrNameArr.map((val) => `${cssModuleName}[${strQuote}${val}${strQuote}]`).join(",")}]${attrNameQuote}` ); } } if (bindAttrNameNode && bindAttrNameNode.exp && "content" in bindAttrNameNode.exp) { const bindAttrNameQuote = getQuote(bindAttrNameNode.loc.source); const bindAttrNameContent = trimString(bindAttrNameNode.exp.content); let bindAttrNameContent2CssModuleNameStr = transformExp( bindAttrNameContent, cssModuleName, bindAttrNameQuote === "'" ? '"' : "'" ); if (!bindAttrNameContent2CssModuleNameStr) { s.update(bindAttrNameNode.loc.start.offset, bindAttrNameNode.loc.end.offset, ""); return; } if (bindClassNode && bindClassNode.exp && "content" in bindClassNode.exp) { const bindClassQuote = getQuote(bindClassNode.loc.source); const bindClassContent = trimString(bindClassNode.exp.content); if (bindAttrNameQuote !== bindClassQuote) { bindAttrNameContent2CssModuleNameStr = swapQuotes(bindAttrNameContent2CssModuleNameStr); } let result; if (isObjectExp(bindClassContent)) { let objectContent = getObjectOrArrayExpressionContent(bindClassContent); if (objectContent) { objectContent += ","; } if (isObjectExp(bindAttrNameContent)) { result = `:class=${bindClassQuote}{${objectContent}${bindAttrNameContent2CssModuleNameStr}}${bindClassQuote}`; } else { result = `:class=${bindClassQuote}{${objectContent}${transformString2ObjectString( bindAttrNameContent2CssModuleNameStr, bindClassQuote === '"' ? "'" : '"' )}}${bindClassQuote}`; } } else if (isArrayExp(bindClassContent)) { let arrayContent = getObjectOrArrayExpressionContent(bindClassContent); if (isObjectExp(bindAttrNameContent)) { arrayContent = transformString2ObjectString( arrayContent, bindClassQuote === '"' ? "'" : '"' ); if (arrayContent) { arrayContent += ","; } result = `:class=${bindClassQuote}{${arrayContent}${bindAttrNameContent2CssModuleNameStr}}${bindClassQuote}`; } else { result = `:class=${bindClassQuote}[${arrayContent},${bindAttrNameContent2CssModuleNameStr}]${bindClassQuote}`; } } else { if (isObjectExp(bindAttrNameContent)) { result = `:class=${bindClassQuote}{${transformString2ObjectString( bindClassContent, bindClassQuote === '"' ? "'" : '"' )},${bindAttrNameContent2CssModuleNameStr}}${bindClassQuote}`; } else { result = `:class=${bindClassQuote}[${bindClassContent},${bindAttrNameContent2CssModuleNameStr}]${bindClassQuote}`; } } s.update(bindClassNode.loc.start.offset, bindClassNode.loc.end.offset, result); s.update(bindAttrNameNode.loc.start.offset, bindAttrNameNode.loc.end.offset, ""); } else { if (isObjectExp(bindAttrNameContent)) { s.update( bindAttrNameNode.loc.start.offset, bindAttrNameNode.loc.end.offset, `:class=${bindAttrNameQuote}{${bindAttrNameContent2CssModuleNameStr}}${bindAttrNameQuote}` ); } else { s.update( bindAttrNameNode.loc.start.offset, bindAttrNameNode.loc.end.offset, `:class=${bindAttrNameQuote}[${bindAttrNameContent2CssModuleNameStr}]${bindAttrNameQuote}` ); } } } node.children && parseHtml(node.children, s, attrName, cssModuleName); } }); } // src/utils/parsePug.ts var pugPackage; var setPugPackage = async () => { pugPackage = { parse: (await import("pug-parser")).default, lexer: (await import("pug-lexer")).default, walk: (await import("pug-walk")).default, generate: (await import("pug-source-gen")).default }; }; async function parsePug(source, options, cssModuleName) { const { attrName, pugClassLiterals } = options; if (!pugPackage) await setPugPackage(); const { parse: parse2, lexer, walk, generate } = pugPackage; const ast = parse2(lexer(source)); walk(ast, (node) => { if (node.attrs?.length) { let bindClassNode, bindAttrNameNode, attrNameNodes = []; node.attrs.forEach((attr) => { switch (attr.name) { case ":class": case "v-bind:class": bindClassNode = attr; break; case `:${attrName}`: case `v-bind:${attrName}`: bindAttrNameNode = attr; break; case attrName: attrNameNodes.push(attr); break; case "class": if (pugClassLiterals && attr.mustEscape === false) { attrNameNodes.push(attr); } } }); if (attrNameNodes.length) { const attrNameArr = transformString2Array( attrNameNodes.map((node2) => getPugVal(node2.val)).join(" ") ); if (attrNameArr.length) { if (bindClassNode) { let result; const bindClassContent = transform2SingleQuotes(getPugVal(bindClassNode.val)); if (isObjectExp(bindClassContent)) { let objectContent = getObjectOrArrayExpressionContent(bindClassContent); if (objectContent) { objectContent += ","; } result = `"{${objectContent}${attrNameArr.map((cls) => `[${cssModuleName}['${cls}']]:true`).join(",")}}"`; } else if (isArrayExp(bindClassContent)) { const arrayContent = getObjectOrArrayExpressionContent(bindClassContent); result = `"[${arrayContent}, ${attrNameArr.map((cls) => `${cssModuleName}['${cls}']`).join(",")}]"`; } else { result = `"[${bindClassContent},${attrNameArr.map((cls) => `${cssModuleName}['${cls}']`).join(",")}]"`; } bindClassNode.val = result; } else { const attrNameNode = attrNameNodes.shift(); attrNameNode.mustEscape = true; attrNameNode.name = `:class`; attrNameNode.val = `"[${attrNameArr.map((cls) => `${cssModuleName}['${cls}']`).join(",")}]"`; bindClassNode = attrNameNode; } } if (attrNameNodes.length) { node.attrs = node.attrs.filter((attr) => !attrNameNodes.includes(attr)); } } if (bindAttrNameNode) { const bindAttrNameContent = transform2SingleQuotes(getPugVal(bindAttrNameNode.val)); const bindAttrNameContent2CssModuleNameStr = transformExp( bindAttrNameContent, cssModuleName, "'" ); if (!bindAttrNameContent2CssModuleNameStr) { node.attrs = node.attrs.filter((attr) => attr !== bindAttrNameNode); return; } if (bindClassNode) { const bindClassContent = transform2SingleQuotes(getPugVal(bindClassNode.val)); let result; if (isObjectExp(bindClassContent)) { let objectContent = getObjectOrArrayExpressionContent(bindClassContent); if (objectContent) { objectContent += ","; } if (isObjectExp(bindAttrNameContent)) { result = `"{${objectContent}${bindAttrNameContent2CssModuleNameStr}}"`; } else { result = `"{${objectContent}${transformString2ObjectString( bindAttrNameContent2CssModuleNameStr, "'" )}}"`; } } else if (isArrayExp(bindClassContent)) { let arrayContent = getObjectOrArrayExpressionContent(bindClassContent); if (isObjectExp(bindAttrNameContent)) { arrayContent = transformString2ObjectString(arrayContent, "'"); if (arrayContent) { arrayContent += ","; } result = `"{${arrayContent}${bindAttrNameContent2CssModuleNameStr}}"`; } else { result = `"[${arrayContent},${bindAttrNameContent2CssModuleNameStr}]"`; } } else { if (isObjectExp(bindAttrNameContent)) { result = `"{${transformString2ObjectString( bindClassContent, "'" )},${bindAttrNameContent2CssModuleNameStr}}"`; } else { result = `"[${bindClassContent},${bindAttrNameContent2CssModuleNameStr}]"`; } } bindClassNode.val = result; node.attrs = node.attrs.filter((attr) => attr !== bindAttrNameNode); } else { bindAttrNameNode.name = ":class"; if (isObjectExp(bindAttrNameContent)) { bindAttrNameNode.val = `"{${bindAttrNameContent2CssModuleNameStr}}"`; } else { bindAttrNameNode.val = `"[${bindAttrNameContent2CssModuleNameStr}]"`; } } } } }); return generate(ast); } // src/index.ts function vueCssModule(userOptions = {}) { const options = { attrName: "cls", // 默认属性名 pugClassLiterals: false, ...userOptions }; const cache = /* @__PURE__ */ new Map(); async function transformTemplate({ code, template, cssModule }) { const cssModuleName = cssModule === true ? "$style" : cssModule; const s = new import_compiler_sfc2.MagicString(code); if (template.lang === "pug") { const result = await parsePug(template.content, options, cssModuleName); s.update(template.loc.start.offset, template.loc.end.offset, result); return s; } else if (template.ast?.children.length) { parseHtml(template.ast.children, s, options.attrName, cssModuleName); return s; } } return { name: "vite-plugin-vue-css-module", enforce: "pre", async transform(code, id) { const [file, queryString] = id.split("?"); if (file.endsWith(".vue")) { const params = new URLSearchParams(queryString); const type = params.get("type"); if (id === file) { const cached = cache.get(file); const { template, cssModule } = cached?.code === code ? cached : parseVue(code); cache.set(file, { code, template, cssModule }); if (template && cssModule) { const s = await transformTemplate({ code, template, cssModule }); if (s) { return { code: s.toString(), map: s.generateMap() }; } } } else if (type === "template") { const cached = cache.get(file); if (cached?.mustTransform) { cached.mustTransform = false; const { code: code2, template, cssModule } = cached; if (template && cssModule) { const s0 = await transformTemplate({ code: code2, template, cssModule }); if (s0) { const s = s0.snip(template.loc.start.offset, template.loc.end.offset); return { code: s.toString(), map: s.generateMap() }; } } } } } }, async handleHotUpdate({ file, read }) { if (file.endsWith(".vue")) { const cached = cache.get(file); if (cached) { const code = await read(); const { template, cssModule } = parseVue(code); if (template) { const mustTransform = !(cached.template && cached.template.content === template.content && cached.template.lang === template.lang && cached.cssModule === cssModule); cache.set(file, { code, template, cssModule, mustTransform }); } } } } }; } //# sourceMappingURL=index.cjs.map