支持 web编译 加入 import render from ‘./index.tsx’ 及函数参数 render:render

This commit is contained in:
Wang Kejun 2022-06-29 19:12:46 +08:00
parent 62b79b8444
commit f8f8eaffc4
3 changed files with 88 additions and 31 deletions

View File

@ -22,93 +22,105 @@ module.exports = (babel) => {
const { attributes } = path.parent;
const parentAttr = attributes.find(
(ele) => t.isJSXIdentifier(ele.name) && ele.name.name === 'oakParent'
(ele) =>
t.isJSXIdentifier(ele.name) &&
ele.name.name === 'oakParent'
);
if (parentAttr) {
console.warn(`${state.filename}」有JSX元素同时定义了oak:path和oakParent请确保oakParent等于{this.state.oakFullpath}`);
}
else {
console.warn(
`${state.filename}」有JSX元素同时定义了oak:path和oakParent请确保oakParent等于{this.state.oakFullpath}`
);
} else {
attributes.push(
t.jsxAttribute(
t.jsxIdentifier("oakParent"),
t.jsxIdentifier('oakParent'),
t.jsxExpressionContainer(
t.memberExpression(
t.memberExpression(
t.thisExpression(),
t.identifier("state")
t.identifier('state')
),
t.identifier("oakFullpath")
t.identifier('oakFullpath')
)
)
)
)
);
}
const pathAttr = attributes.find(
(ele) => t.isJSXIdentifier(ele.name) && ele.name.name === 'oakPath'
(ele) =>
t.isJSXIdentifier(ele.name) &&
ele.name.name === 'oakPath'
);
if (pathAttr) {
console.warn(`${state.filename}」有JSX元素同时定义了oak:path和oakPath请确保两者相等`);
}
else {
console.warn(
`${state.filename}」有JSX元素同时定义了oak:path和oakPath请确保两者相等`
);
} else {
attributes.push(
t.jsxAttribute(
t.jsxIdentifier("oakPath"),
t.jsxIdentifier('oakPath'),
node.value
)
);
}
path.remove();
}
else if (isOakNamespaceIdentifier(node.name, 'value')) {
} 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'
(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 {
console.warn(
`${state.filename}」有JSX元素同时定义了oak:value和value请确保value等于{this.state["oak:value"]}`
);
} else {
attributes.push(
t.jsxAttribute(
t.jsxIdentifier("value"),
t.jsxIdentifier('value'),
t.jsxExpressionContainer(
t.memberExpression(
t.memberExpression(
t.thisExpression(),
t.identifier("state")
t.identifier('state')
),
t.identifier(node.value.value)
)
)
)
)
);
}
const dataAttrAttr = attributes.find(
(ele) => t.isJSXIdentifier(ele.name) && ele.name.name === 'data-attr'
(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 {
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"),
t.jsxIdentifier('data-attr'),
node.value
)
);
}
path.remove();
}
}
}
}
},
},
};
};

View File

@ -0,0 +1,43 @@
const t = require('@babel/types');
const pull = require('lodash/pull');
const { assert } = require('console');
module.exports = (babel) => {
return {
visitor: {
Program(path, state) {
const node = path.node;
const body = node.body;
let isOak = false;
body.forEach((node2) => {
if (
node2 &&
node2.declaration &&
node2.declaration.callee &&
(node2.declaration.callee.name === 'OakPage' ||
node2.declaration.callee.name === 'OakComponent')
) {
isOak = true;
node2.declaration.arguments.forEach((node3) => {
if (t.isObjectExpression(node3)) {
const propertyRender = t.objectProperty(
t.identifier('render'),
t.identifier('render')
);
node3.properties.unshift(propertyRender);
}
});
}
});
if (isOak) {
const importRender = t.importDeclaration(
[t.importDefaultSpecifier(t.identifier('render'))],
t.stringLiteral('./index.tsx')
);
body.unshift(importRender);
}
},
},
};
};

View File

@ -29,6 +29,7 @@ const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'
const createEnvironmentHash = require('./webpack/persistentCache/createEnvironmentHash');
const oakPathTsxPlugin = require('../babel-plugin/oakPath');
const oakRenderTsxPlugin = require('../babel-plugin/oakRender');
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
@ -472,6 +473,7 @@ module.exports = function (webpackEnv) {
'react-refresh/babel'
),
oakPathTsxPlugin,
oakRenderTsxPlugin,
],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/