修改了react-native的编译配置,将renderNative和i18n都以plugin的方式注入babel
This commit is contained in:
parent
0e0ea10b51
commit
381503e494
|
|
@ -9,16 +9,37 @@ const Regex =
|
|||
|
||||
|
||||
const ModuleDict = {};
|
||||
const ReactNativeProjectDict = {};
|
||||
|
||||
function parseFileModuleAndNs(cwd, filename) {
|
||||
const relativePath = relative(cwd, filename);
|
||||
let cwd2 = cwd;
|
||||
if (cwd.endsWith('native')) {
|
||||
// react-native环境,需要重新定位一下项目根目录
|
||||
if (ReactNativeProjectDict.hasOwnProperty(cwd)) {
|
||||
if (ReactNativeProjectDict[cwd]) {
|
||||
cwd2 = join(cwd, '..');
|
||||
}
|
||||
}
|
||||
else {
|
||||
const nodeModulePath = join(cwd, '..', 'node_modules');
|
||||
const packageJsonPath = join(cwd, '..', 'package.json');
|
||||
if (fs.existsSync(packageJsonPath) && fs.existsSync(nodeModulePath)) {
|
||||
ReactNativeProjectDict[cwd] = true;
|
||||
cwd2 = join(cwd, '..');
|
||||
}
|
||||
else {
|
||||
ReactNativeProjectDict[cwd] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
const relativePath = relative(cwd2, filename);
|
||||
|
||||
if (relativePath.startsWith('node_modules') || relativePath.startsWith('..')) { // 在测试环境下是相对路径
|
||||
const moduleRelativePath = relativePath
|
||||
.replace(/\\/g, '/')
|
||||
.split('/')
|
||||
.slice(0, 2);
|
||||
const modulePath = join(cwd, ...moduleRelativePath);
|
||||
const modulePath = join(cwd2, ...moduleRelativePath);
|
||||
const moduleDir = moduleRelativePath[1];
|
||||
|
||||
let moduleName = ModuleDict[moduleDir];
|
||||
|
|
@ -52,12 +73,12 @@ function parseFileModuleAndNs(cwd, filename) {
|
|||
else {
|
||||
let moduleName = ModuleDict['./'];
|
||||
if (!moduleName) {
|
||||
const { name } = require(join(cwd, 'package.json'));
|
||||
const { name } = require(join(cwd2, 'package.json'));
|
||||
ModuleDict['./'] = name;
|
||||
moduleName = name;
|
||||
}
|
||||
|
||||
const rel2paths = relative(cwd, filename)
|
||||
const rel2paths = relative(cwd2, filename)
|
||||
.replace(/\\/g, '/')
|
||||
.split('/');
|
||||
|
||||
|
|
@ -123,55 +144,58 @@ module.exports = (babel) => {
|
|||
) {
|
||||
const { moduleName, ns } = parseFileModuleAndNs(cwd, filename);
|
||||
const arguments = node.arguments;
|
||||
const [arg0, arg1] = arguments;
|
||||
assert(arg0);
|
||||
|
||||
if (arg1) {
|
||||
// 一般是对象,也可能是变量,表达式不予考虑
|
||||
if (t.isObjectExpression(arg1)) {
|
||||
const { properties } = arg1;
|
||||
const oakNsProp = properties.find(
|
||||
ele => t.isStringLiteral(ele.key) && ele.key.value === oakNsPropName
|
||||
);
|
||||
if (!oakNsProp) {
|
||||
properties.push(
|
||||
t.objectProperty(t.stringLiteral(oakNsPropName), t.stringLiteral(ns)),
|
||||
t.objectProperty(t.stringLiteral(oakModulePropName), t.stringLiteral(moduleName))
|
||||
if (arguments.length < 2) {
|
||||
// react-native会调用两次,这里要保护一下
|
||||
const [arg0, arg1] = arguments;
|
||||
assert(arg0);
|
||||
|
||||
if (arg1) {
|
||||
// 一般是对象,也可能是变量,表达式不予考虑
|
||||
if (t.isObjectExpression(arg1)) {
|
||||
const { properties } = arg1;
|
||||
const oakNsProp = properties.find(
|
||||
ele => t.isStringLiteral(ele.key) && ele.key.value === oakNsPropName
|
||||
);
|
||||
if (!oakNsProp) {
|
||||
properties.push(
|
||||
t.objectProperty(t.stringLiteral(oakNsPropName), t.stringLiteral(ns)),
|
||||
t.objectProperty(t.stringLiteral(oakModulePropName), t.stringLiteral(moduleName))
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (t.isIdentifier(arg1)) {
|
||||
arguments.splice(1, 1, t.callExpression(
|
||||
t.memberExpression(
|
||||
t.identifier('Object'),
|
||||
t.identifier('assign')
|
||||
),
|
||||
[
|
||||
arg1,
|
||||
t.objectExpression(
|
||||
[
|
||||
t.objectProperty(t.stringLiteral(oakNsPropName), t.stringLiteral(ns)),
|
||||
t.objectProperty(t.stringLiteral(oakModulePropName), t.stringLiteral(moduleName))
|
||||
]
|
||||
)
|
||||
]
|
||||
));
|
||||
}
|
||||
else {
|
||||
// 不处理,这里似乎会反复调用,不知道为什么
|
||||
}
|
||||
}
|
||||
else if (t.isIdentifier(arg1)) {
|
||||
arguments.splice(1, 1, t.callExpression(
|
||||
t.memberExpression(
|
||||
t.identifier('Object'),
|
||||
t.identifier('assign')
|
||||
),
|
||||
[
|
||||
arg1,
|
||||
t.objectExpression(
|
||||
[
|
||||
t.objectProperty(t.stringLiteral(oakNsPropName), t.stringLiteral(ns)),
|
||||
t.objectProperty(t.stringLiteral(oakModulePropName), t.stringLiteral(moduleName))
|
||||
]
|
||||
)
|
||||
]
|
||||
));
|
||||
}
|
||||
else {
|
||||
// 不处理,这里似乎会反复调用,不知道为什么
|
||||
// 如果无参数就构造一个对象传入
|
||||
arguments.push(
|
||||
t.objectExpression(
|
||||
[
|
||||
t.objectProperty(t.stringLiteral(oakNsPropName), t.stringLiteral(ns)),
|
||||
t.objectProperty(t.stringLiteral(oakModulePropName), t.stringLiteral(moduleName))
|
||||
]
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 如果无参数就构造一个对象传入
|
||||
arguments.push(
|
||||
t.objectExpression(
|
||||
[
|
||||
t.objectProperty(t.stringLiteral(oakNsPropName), t.stringLiteral(ns)),
|
||||
t.objectProperty(t.stringLiteral(oakModulePropName), t.stringLiteral(moduleName))
|
||||
]
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -31,12 +31,14 @@ module.exports = (babel) => {
|
|||
const pathProperty = properties.find(
|
||||
ele => t.isObjectProperty(ele) && t.isIdentifier(ele.key) && ele.key.name === 'path'
|
||||
);
|
||||
// console.log(filename, 'oakPath');
|
||||
if (pathProperty) {
|
||||
console.warn(`${resolvePath}页面的OakPage中还是定义了path,可以删除掉了`);
|
||||
// react-native的编译器会走两次,这里会被命中
|
||||
// console.warn(`${resolvePath}页面的OakPage中还是定义了path,可以删除掉了`);
|
||||
pathProperty.value = t.stringLiteral(relativePath);
|
||||
}
|
||||
else {
|
||||
properties.push(
|
||||
properties.unshift(
|
||||
t.objectProperty(t.identifier('path'), t.stringLiteral(relativePath))
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
const t = require('@babel/types');
|
||||
const { parse } = require('path');
|
||||
const { injectGetRender } = require('../utils/injectGetRender');
|
||||
|
||||
module.exports = (babel) => {
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression(path, state) {
|
||||
const { cwd, filename } = state;
|
||||
const { base } = parse(filename);
|
||||
const node = path.node;
|
||||
if (['index.ts', 'index.js'].includes(base) && t.isCallExpression(node) && t.isIdentifier(node.callee) && node.callee.name === 'OakComponent') {
|
||||
injectGetRender(node, cwd, filename, 'native');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
@ -22,6 +22,8 @@ const replaceEnvExpressionPlugin = require('./babelEnvPlugin');
|
|||
|
||||
const { injectGetRender } = require('../utils/injectGetRender');
|
||||
const oakPathTsxPlugin = require('../babel-plugin/oakPath');
|
||||
const oakRenderNativePlugin = require('../babel-plugin/oakRenderNative');
|
||||
const oakI18nPlugin = require('../babel-plugin/oakI18n');
|
||||
|
||||
async function renderToCSS({ src, filename, options = {} }) {
|
||||
const { lessOptions = {} } = options;
|
||||
|
|
@ -51,7 +53,7 @@ function transform({ filename, options, plugins, src }) {
|
|||
cwd: options.projectRoot,
|
||||
highlightCode: true,
|
||||
filename,
|
||||
plugins: plugins.concat([replaceEnvExpressionPlugin, oakPathTsxPlugin]),
|
||||
plugins: plugins.concat([replaceEnvExpressionPlugin, oakPathTsxPlugin, oakRenderNativePlugin, oakI18nPlugin]),
|
||||
sourceType: "module",
|
||||
// NOTE(EvanBacon): We split the parse/transform steps up to accommodate
|
||||
// Hermes parsing, but this defaults to cloning the AST which increases
|
||||
|
|
@ -71,18 +73,19 @@ function transform({ filename, options, plugins, src }) {
|
|||
const transformResult = transformFromAstSync(sourceAst, src, babelConfig);
|
||||
|
||||
// 为page和componet下的OakComponent注入getRender函数,去取得同目录下的render.native.tsx
|
||||
const resultAst = transformResult.ast;
|
||||
const { base } = path.parse(filename);
|
||||
if (['index.ts', 'index.js'].includes(base)) {
|
||||
traverse(resultAst, {
|
||||
CallExpression(path) {
|
||||
const node = path.node;
|
||||
if (t.isIdentifier(node.callee) && node.callee.name === 'OakComponent') {
|
||||
injectGetRender(node, options.projectRoot, filename, 'native');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 改成plugin注入
|
||||
// const resultAst = transformResult.ast;
|
||||
// const { base } = path.parse(filename);
|
||||
// if (['index.ts', 'index.js'].includes(base)) {
|
||||
// traverse(resultAst, {
|
||||
// CallExpression(path) {
|
||||
// const node = path.node;
|
||||
// if (t.isIdentifier(node.callee) && node.callee.name === 'OakComponent') {
|
||||
// injectGetRender(node, options.projectRoot, filename, 'native');
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
return {
|
||||
ast: nullthrows(transformResult.ast),
|
||||
|
|
|
|||
|
|
@ -161,31 +161,36 @@ function injectGetRender(node, projectRoot, filename, env) {
|
|||
*/
|
||||
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')
|
||||
]
|
||||
// react-native的编译器会命中两次
|
||||
if (!arg.properties.find(
|
||||
(ele) => t.isObjectProperty(ele) && t.isIdentifier(ele.key) && ele.key.name === 'getRender'
|
||||
)) {
|
||||
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.identifier('default')
|
||||
),
|
||||
)
|
||||
]),
|
||||
t.returnStatement(
|
||||
t.identifier('oakRenderFn')
|
||||
)
|
||||
]),
|
||||
t.returnStatement(
|
||||
t.identifier('oakRenderFn')
|
||||
)
|
||||
]
|
||||
))
|
||||
);
|
||||
arg.properties.unshift(propertyRender);
|
||||
]
|
||||
))
|
||||
);
|
||||
arg.properties.unshift(propertyRender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ buildscript {
|
|||
ndkVersion = "23.1.7779620"
|
||||
}
|
||||
repositories {
|
||||
maven { url 'https://maven.aliyun.com/repository/google' }
|
||||
maven { url 'https://maven.aliyun.com/repository/jcenter' }
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue