Я пишу плагин, который будет своего рода легковесной babel-plugin-react-css-modules
реализацией, в любом случае…
плагину необходимо изменить значение атрибута className в элементах JSX со строки на массив , По сути, он должен отображать строку classNames в массив "class-one class-two" => [object["class-one"] || "class-one", object["class-two"] || "class-two"]
;
. Часть, с которой я борюсь, - это просто сделать вывод babel JS вместо строки, что я не уверен, как это сделать.
module.exports = () => {
const styles = "styles" + Math.random().toString(36).substr(2, 9);
let foundStyleImport;
return {
visitor: {
ImportDeclaration: (path) => {
if (
!/(sass|scss)\.js$/.test(path.node.source.value) &&
path.node.specifiers.length > 0
) return;
foundStyleImport = true;
path.node.specifiers[0] = {
type: "ImportDefaultSpecifier",
local: {
type: "Identifier",
name: styles,
loc: { identifierName: styles }
}
}
},
// The part I'm struggling with ⬇
JSXAttribute: ({node: {value, name}}) => {
if (!foundStyleImport || name.name !== "className") return;
// changing this from "stringLiteral" to "arrayExpression"
// results in an error…
value.type = "arrayExpression";
value.value = `[${value.value.split(" ").map(cls => {
return `${styles}["${cls}"] || "${cls}"`;
}).join(", ")}]`;
}
}
};
}
Вавилон должен взять это:
import "./header.sass.js";
import { h, Fragment } from "/web_modules/preact.js";
export default function () {
return h("header", {
className: "foobar"
}, h("p", null, "Hello"));
}
и вывести что-то вроде этого:
import styles0u33w7qps from "./header.sass.js";
import { h, Fragment } from "/web_modules/preact.js";
export default function () {
return h("header", {
className: [styles0u33w7qps["foobar"] || "foobar"]
}, h("p", null, "Hello"));
}