Пользовательский плагин Babel - Измените значение stringLiteral на фактический Javascript код - PullRequest
0 голосов
/ 15 марта 2020

Я пишу плагин, который будет своего рода легковесной 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"));
}
...