UNPKG

vite-plugin-vue-css-modules

Version:

✨ Ultimate solution for using CSS modules without any hassle. Automatic replacement for Vue templates and scripts

81 lines (80 loc) 3.66 kB
import * as babelParser from "@babel/parser"; import babelTraverse from "@babel/traverse"; import { parseQuotedValue } from "./shared.js"; const quoteRotation = (attributeQuote) => { return attributeQuote === '"' ? "'" : '"'; }; const generateModuleAccess = (path, module, contentOffset, sfcTransform) => { if (module) { const { node } = path; const { range } = node; const startOffset = contentOffset + range[0] - 1; const endOffset = contentOffset + range[1] - 1; sfcTransform.update(startOffset, endOffset, `${module}[${node.name}]`); } }; export const transformJsValue = (source, contentOffset, sfcTransform, attributeQuote, { preservePrefix, localNameGenerator, module }) => { let ast = babelParser.parse(`(${source})`, { ranges: true, plugins: ["typescript"], }); babelTraverse(ast, { noScope: true, Identifier(path) { let { parentPath, node } = path; if (parentPath.isExpressionStatement() || parentPath.isArrayExpression() || parentPath.isConditionalExpression({ consequent: node }) || parentPath.isConditionalExpression({ alternate: node })) { generateModuleAccess(path, module, contentOffset, sfcTransform); path.skip(); } else if (parentPath.isObjectProperty({ key: node })) { if (parentPath.node.computed) { generateModuleAccess(path, module, contentOffset, sfcTransform); } else { const { range } = node; const startOffset = contentOffset + range[0] - 1; const endOffset = contentOffset + range[1] - 1; if (node.name.startsWith(preservePrefix)) { sfcTransform.update(startOffset, endOffset, node.name.slice(preservePrefix.length)); } else { const transformedClass = localNameGenerator(node.name); const selectedQuote = quoteRotation(attributeQuote); const quotedTransformedClass = selectedQuote + transformedClass + selectedQuote; sfcTransform.update(startOffset, endOffset, parentPath.node.shorthand ? `${quotedTransformedClass}: ${node.name}` : quotedTransformedClass); } } path.skip(); } }, StringLiteral({ node, parentPath }) { if (parentPath.isBinaryExpression() || parentPath.isCallExpression() || parentPath.isOptionalCallExpression()) return; const { value } = parseQuotedValue(node.extra.raw); const startOffset = contentOffset + node.range[0] - 1 + 1; const endOffset = contentOffset + node.range[1] - 1 - 1; if (value.startsWith(preservePrefix)) { sfcTransform.update(startOffset, endOffset, value.slice(preservePrefix.length)); } else { sfcTransform.update(startOffset, endOffset, localNameGenerator(value)); } }, TemplateElement(path) { let { node } = path; const startOffset = contentOffset + node.range[0] - 1; const endOffset = contentOffset + node.range[1] - 1; sfcTransform.update(startOffset, endOffset, localNameGenerator(node.value.raw)); path.skip(); }, }); };