oak-cli/config/utils/injectGetRender.js

194 lines
6.8 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 { relative, dirname, join } = require('path');
const fs = require('fs');
const t = require('@babel/types');
const traverse = require('@babel/traverse').default;
const assert = require('assert');
/**
*
* @param {*} node
* @param {*} projectRoot
* @param {*} filename
* @param {*} env 'web' | 'native'
*/
function injectGetRender(node, projectRoot, filename, env) {
assert(t.isCallExpression(node) && t.isIdentifier(node.callee) && node.callee.name === 'OakComponent');
const dir = dirname(filename);
if (env === 'web') {
// web要根据this.props.width的宽度决定注入web.tsx还是web.pc.tsx
const tsxFile = join(dir, 'web.tsx');
const jsFile = join(dir, 'web.js');
const jsxFile = join(dir, 'web.jsx');
let webDestFile;
if (fs.existsSync(tsxFile)) {
webDestFile = './web.tsx';
}
else if (fs.existsSync(jsFile)) {
webDestFile = './web.js';
}
else if (fs.existsSync(jsxFile)) {
webDestFile = './web.jsx';
}
const acquireWebFileStmt = webDestFile && t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier('oakRenderFn'),
t.memberExpression(
t.callExpression(t.identifier('require'), [
t.stringLiteral(webDestFile),
]),
t.identifier('default')
)
),
]);
let pcDestFile;
const pcTsxFile = join(dir, 'web.pc.tsx');
const pcJsFile = join(dir, 'web.pc.js');
const pcJsxFile = join(dir, 'web.pc.jsx');
if (fs.existsSync(pcTsxFile)) {
pcDestFile = './web.pc.tsx';
}
else if (fs.existsSync(pcJsFile)) {
pcDestFile = './web.pc.js';
}
else if (fs.existsSync(pcJsxFile)) {
pcDestFile = './web.pc.jsx';
}
const acquirePcFileStmt = pcDestFile && t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier('oakRenderFn'),
t.memberExpression(
t.callExpression(t.identifier('require'), [
t.stringLiteral(pcDestFile),
]),
t.identifier('default')
)
),
]);
const getStatements = () => {
/** 根据tsx文件存在的情况注入如下的getRender函数
* if (this.props.width === 'xs') {
const oakRenderFn = require('./web.tsx').default;
return oakRenderFn;
}
else {
const oakRenderFn = require('./web.pc.tsx').default;
return oakRenderFn;
}
*/
const statements = [];
if (acquirePcFileStmt && acquireWebFileStmt) {
statements.push(
t.ifStatement(
t.binaryExpression(
'===',
t.memberExpression(
t.memberExpression(
t.thisExpression(),
t.identifier('props')
),
t.identifier('width')
),
t.stringLiteral('xs')
),
t.blockStatement([
acquireWebFileStmt,
t.returnStatement(
t.identifier('oakRenderFn')
)
]),
t.blockStatement([
acquirePcFileStmt,
t.returnStatement(
t.identifier('oakRenderFn')
)
])
)
);
}
else if (acquirePcFileStmt) {
statements.push(
acquirePcFileStmt,
t.returnStatement(
t.identifier('oakRenderFn')
)
);
}
else if (acquireWebFileStmt) {
statements.push(
acquireWebFileStmt,
t.returnStatement(
t.identifier('oakRenderFn')
)
);
} else {
assert(
false,
`${dir}文件夹中不存在web.tsx或者web.pc.tsx无法渲染`
);
}
return statements;
};
const statements = getStatements();
node.arguments.forEach((node4) => {
if (t.isObjectExpression(node4)) {
const propertyRender = t.objectProperty(
t.identifier('getRender'),
t.functionExpression(
null,
[],
t.blockStatement(statements)
)
);
node4.properties.unshift(propertyRender);
}
else {
assert(false, `[${filename}]OakComponent调用参数不是ObjectExpression`);
}
});
}
else {
assert(env === 'native');
/** native不用检测(react-native会自动检测render.native或render.ios/android直接注入
* OakComponent({
* getRender() {
* const oakRenderFn = require('./render').default;
* return oakRenderFn;
* },
* })
*/
const arg = node.arguments[0];
assert(t.isObjectExpression(arg));
const propertyRender = t.objectProperty(
t.identifier('getRender'),
t.functionExpression(null, [], t.blockStatement(
[
t.variableDeclaration('var', [
t.variableDeclarator(
t.identifier('oakRenderFn'),
t.memberExpression(
t.callExpression(
t.identifier('require'),
[
t.stringLiteral('./render')
]
),
t.identifier('default')
),
)
]),
t.returnStatement(
t.identifier('oakRenderFn')
)
]
))
);
arg.properties.unshift(propertyRender);
}
}
module.exports = {
injectGetRender
};