-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathloader.js
71 lines (65 loc) · 1.84 KB
/
loader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const BABEL_OPTIONS = {
configFile: false,
ast: true,
parserOpts: {
sourceType: "module",
plugins: [
"jsx",
"asyncFunctions",
"classConstructorCall",
"doExpressions",
"trailingFunctionCommas",
"objectRestSpread",
"decoratorsLegacy",
"classProperties",
"exportExtensions",
"exponentiationOperator",
"asyncGenerators",
"functionBind",
"functionSent",
"dynamicImport",
"optionalChaining",
"typescript",
],
},
};
const babel = require("@babel/core");
const generate = require("@babel/generator").default;
const t = require("@babel/types");
module.exports = function (source) {
const callback = this.async();
if (!source.includes("use client")) {
callback(null, source);
return;
}
const ast = babel.parse(source, BABEL_OPTIONS);
babel.traverse(ast, {
JSXOpeningElement(path) {
const existingClassNameAttr = path.node.attributes.find(
(attr) => attr.name && attr.name.name === "className"
);
const classToAdd = "csr-component";
if (existingClassNameAttr) {
if (t.isStringLiteral(existingClassNameAttr.value)) {
existingClassNameAttr.value.value += ` ${classToAdd}`;
} else if (t.isJSXExpressionContainer(existingClassNameAttr.value)) {
existingClassNameAttr.value = t.jsxExpressionContainer(
t.binaryExpression(
"+",
existingClassNameAttr.value.expression,
t.stringLiteral(` ${classToAdd}`)
)
);
}
} else {
const classNameAttr = t.jSXAttribute(
t.jSXIdentifier("className"),
t.stringLiteral(classToAdd)
);
path.node.attributes.push(classNameAttr);
}
},
});
const output = generate(ast, {}, source);
callback(null, output.code);
};