oak-cli/config/babel-plugin/oakPath.js

114 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const t = require('@babel/types');
const pull = require('lodash/pull');
const { assert } = require('console');
function isOakNamespaceIdentifier(node, name) {
if (t.isJSXNamespacedName(node) && t.isJSXIdentifier(node.namespace) && node.namespace.name === 'oak'
&& t.isJSXIdentifier(node.name) && node.name.name === name) {
return true;
}
return false;
}
module.exports = (babel) => {
return {
visitor: {
JSXAttribute(path, state) {
const node = path.node;
if (isOakNamespaceIdentifier(node.name, 'path')) {
// 若存在oak:path则注入oakParent={this.state.oakFullpath}和oakPath={oak:path}
assert(t.isJSXOpeningElement(path.parent));
const { attributes } = path.parent;
const parentAttr = attributes.find(
(ele) => t.isJSXIdentifier(ele.name) && ele.name.name === 'oakParent'
);
if (parentAttr) {
console.warn(`${state.filename}」有JSX元素同时定义了oak:path和oakParent请确保oakParent等于{this.state.oakFullpath}`);
}
else {
attributes.push(
t.jsxAttribute(
t.jsxIdentifier("oakParent"),
t.jsxExpressionContainer(
t.memberExpression(
t.memberExpression(
t.thisExpression(),
t.identifier("state")
),
t.identifier("oakFullpath")
)
)
)
)
}
const pathAttr = attributes.find(
(ele) => t.isJSXIdentifier(ele.name) && ele.name.name === 'oakPath'
);
if (pathAttr) {
console.warn(`${state.filename}」有JSX元素同时定义了oak:path和oakPath请确保两者相等`);
}
else {
attributes.push(
t.jsxAttribute(
t.jsxIdentifier("oakPath"),
node.value
)
);
}
path.remove();
}
else if (isOakNamespaceIdentifier(node.name, 'value')) {
// 如果是oak:value增加value和data-attr属性
assert(t.isJSXOpeningElement(path.parent));
assert(t.isStringLiteral(node.value));
const { attributes } = path.parent;
const valueAttr = attributes.find(
(ele) => t.isJSXIdentifier(ele.name) && ele.name.name === 'value'
);
if (valueAttr) {
console.warn(`${state.filename}」有JSX元素同时定义了oak:value和value请确保value等于{this.state["oak:value"]}`);
}
else {
attributes.push(
t.jsxAttribute(
t.jsxIdentifier("value"),
t.jsxExpressionContainer(
t.memberExpression(
t.memberExpression(
t.thisExpression(),
t.identifier("state")
),
t.identifier(node.value.value)
)
)
)
)
}
const dataAttrAttr = attributes.find(
(ele) => t.isJSXIdentifier(ele.name) && ele.name.name === 'data-attr'
);
if (dataAttrAttr) {
assert(t.isStringLiteral(dataAttrAttr.value) && dataAttrAttr.value.value === node.value.value, `${state.filename}」中有JSX元素同时定义了oak:value和data-attr且两者的值不相等`);
}
else {
attributes.push(
t.jsxAttribute(
t.jsxIdentifier("data-attr"),
node.value
)
);
}
path.remove();
}
}
}
}
};