add scripts

This commit is contained in:
dntzhang 2019-03-30 23:00:55 +08:00
parent 1b53576b93
commit f928e6eed3
35 changed files with 5352 additions and 1 deletions

View File

@ -0,0 +1,69 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Adapters;
(function (Adapters) {
Adapters["weapp"] = "weapp";
Adapters["swan"] = "swan";
Adapters["alipay"] = "alipay";
Adapters["quickapp"] = "quickapp";
Adapters["tt"] = "tt";
})(Adapters = exports.Adapters || (exports.Adapters = {}));
const weixinAdapter = {
if: 'wx:if',
else: 'wx:else',
elseif: 'wx:elif',
for: 'wx:for',
forItem: 'wx:for-item',
forIndex: 'wx:for-index',
key: 'wx:key',
type: "weapp" /* weapp */
};
const swanAdapter = {
if: 's-if',
else: 's-else',
elseif: 's-elif',
for: 's-for',
forItem: 's-for-item',
forIndex: 's-for-index',
key: 's-key',
type: "swan" /* swan */
};
const alipayAdapter = {
if: 'a:if',
else: 'a:else',
elseif: 'a:elif',
for: 'a:for',
forItem: 'a:for-item',
forIndex: 'a:for-index',
key: 'a:key',
type: "alipay" /* alipay */
};
const ttAdapter = {
if: 'tt:if',
else: 'tt:else',
elseif: 'tt:elif',
for: 'tt:for',
forItem: 'tt:for-item',
forIndex: 'tt:for-index',
key: 'tt:key',
type: "tt" /* tt */
};
exports.Adapter = weixinAdapter;
function setAdapter(adapter) {
switch (adapter.toLowerCase()) {
case "swan" /* swan */:
exports.Adapter = swanAdapter;
break;
case "alipay" /* alipay */:
exports.Adapter = alipayAdapter;
break;
case "tt" /* tt */:
exports.Adapter = ttAdapter;
break;
default:
exports.Adapter = weixinAdapter;
break;
}
}
exports.setAdapter = setAdapter;
//# sourceMappingURL=adapter.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":";;AAAA,IAAkB,QAMjB;AAND,WAAkB,QAAQ;IACxB,2BAAe,CAAA;IACf,yBAAa,CAAA;IACb,6BAAiB,CAAA;IACjB,iCAAqB,CAAA;IACrB,qBAAS,CAAA;AACX,CAAC,EANiB,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAMzB;AAaD,MAAM,aAAa,GAAY;IAC7B,EAAE,EAAE,OAAO;IACX,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;IACjB,GAAG,EAAE,QAAQ;IACb,OAAO,EAAE,aAAa;IACtB,QAAQ,EAAE,cAAc;IACxB,GAAG,EAAE,QAAQ;IACb,IAAI,qBAAgB;CACrB,CAAA;AAED,MAAM,WAAW,GAAY;IAC3B,EAAE,EAAE,MAAM;IACV,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,OAAO;IACZ,OAAO,EAAE,YAAY;IACrB,QAAQ,EAAE,aAAa;IACvB,GAAG,EAAE,OAAO;IACZ,IAAI,mBAAe;CACpB,CAAA;AAED,MAAM,aAAa,GAAY;IAC7B,EAAE,EAAE,MAAM;IACV,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,QAAQ;IAChB,GAAG,EAAE,OAAO;IACZ,OAAO,EAAE,YAAY;IACrB,QAAQ,EAAE,aAAa;IACvB,GAAG,EAAE,OAAO;IACZ,IAAI,uBAAiB;CACtB,CAAA;AAED,MAAM,SAAS,GAAY;IACzB,EAAE,EAAE,OAAO;IACX,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;IACjB,GAAG,EAAE,QAAQ;IACb,OAAO,EAAE,aAAa;IACtB,QAAQ,EAAE,cAAc;IACxB,GAAG,EAAE,QAAQ;IACb,IAAI,eAAa;CAClB,CAAA;AAEU,QAAA,OAAO,GAAY,aAAa,CAAA;AAE3C,SAAgB,UAAU,CAAE,OAAiB;IAC3C,QAAQ,OAAO,CAAC,WAAW,EAAE,EAAE;QAC7B;YACE,eAAO,GAAG,WAAW,CAAA;YACrB,MAAK;QACP;YACE,eAAO,GAAG,aAAa,CAAA;YACvB,MAAK;QACP;YACE,eAAO,GAAG,SAAS,CAAA;YACnB,MAAK;QACP;YACE,eAAO,GAAG,aAAa,CAAA;YACvB,MAAK;KACR;AACH,CAAC;AAfD,gCAeC"}

View File

@ -0,0 +1,616 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const t = require("babel-types");
const utils_1 = require("./utils");
const constant_1 = require("./constant");
const lodash_1 = require("lodash");
const render_1 = require("./render");
const jsx_1 = require("./jsx");
const adapter_1 = require("./adapter");
const babel_generator_1 = require("babel-generator");
function buildConstructor() {
const ctor = t.classMethod('constructor', t.identifier('constructor'), [t.identifier('props')], t.blockStatement([
t.expressionStatement(t.callExpression(t.identifier('super'), [
t.identifier('props')
]))
]));
return ctor;
}
function processThisPropsFnMemberProperties(member, path, args, binded) {
const propertyArray = [];
function traverseMember(member) {
const object = member.object;
const property = member.property;
if (t.isIdentifier(property)) {
propertyArray.push(property.name);
}
if (t.isMemberExpression(object)) {
if (t.isThisExpression(object.object) &&
t.isIdentifier(object.property) &&
object.property.name === 'props') {
if ("alipay" /* alipay */ === adapter_1.Adapter.type) {
if (binded)
args.shift();
path.replaceWith(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('__triggerPropsFn')), [
t.stringLiteral(propertyArray.reverse().join('.')),
t.arrayExpression(args)
]));
}
else {
path.replaceWith(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('__triggerPropsFn')), [t.stringLiteral(propertyArray.reverse().join('.')), t.callExpression(t.memberExpression(t.arrayExpression([t.nullLiteral()]), t.identifier('concat')), [t.arrayExpression(args)])]));
}
}
traverseMember(object);
}
}
traverseMember(member);
}
class Transformer {
constructor(path, sourcePath, componentProperies) {
this.result = {
template: '',
components: [],
componentProperies: []
};
this.methods = new Map();
this.initState = new Set();
this.jsxReferencedIdentifiers = new Set();
this.customComponents = new Map();
this.anonymousMethod = new Map();
this.renderMethod = null;
this.customComponentNames = new Set();
this.usedState = new Set();
this.loopStateName = new Map();
this.customComponentData = [];
this.refs = [];
this.loopRefs = new Map();
this.anonymousFuncCounter = utils_1.incrementId();
this.buildPropsAnonymousFunc = (attr, expr, isBind = false) => {
const { code } = babel_generator_1.default(expr);
if (code.startsWith('this.props')) {
const methodName = utils_1.findMethodName(expr);
const hasMethodName = this.anonymousMethod.has(methodName) || !methodName;
const funcName = hasMethodName
? this.anonymousMethod.get(methodName)
// 测试时使用1个稳定的 uniqueID 便于测试实际使用5个英文字母否则小程序不支持
: process.env.NODE_ENV === 'test' ? lodash_1.uniqueId('funPrivate') : `funPrivate${utils_1.createRandomLetters(5)}`;
this.anonymousMethod.set(methodName, funcName);
const newVal = isBind
? t.callExpression(t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier(funcName)), t.identifier('bind')), expr.arguments || [])
: t.memberExpression(t.thisExpression(), t.identifier(funcName));
attr.get('value.expression').replaceWith(newVal);
this.methods.set(funcName, null);
this.componentProperies.add(methodName);
if (hasMethodName) {
return;
}
const attrName = attr.node.name;
if (t.isJSXIdentifier(attrName) && attrName.name.startsWith('on')) {
this.componentProperies.add(`__fn_${attrName.name}`);
}
if (methodName.startsWith('on')) {
this.componentProperies.add(`__fn_${methodName}`);
}
const method = t.classMethod('method', t.identifier(funcName), [], t.blockStatement([
t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('__triggerPropsFn')), [t.stringLiteral(methodName), t.arrayExpression([t.spreadElement(t.identifier('arguments'))])]))
]));
this.classPath.node.body.body = this.classPath.node.body.body.concat(method);
}
};
this.classPath = path;
this.sourcePath = sourcePath;
this.moduleNames = Object.keys(path.scope.getAllBindings('module'));
this.componentProperies = new Set(componentProperies);
this.compile();
}
setMultipleSlots() {
const body = this.classPath.node.body.body;
if (body.some(c => t.isClassProperty(c) && c.key.name === 'multipleSlots')) {
return;
}
const multipleSlots = t.classProperty(t.identifier('multipleSlots'), t.booleanLiteral(true));
multipleSlots.static = true;
body.push(multipleSlots);
}
createStringRef(componentName, id, refName) {
this.refs.push({
type: constant_1.DEFAULT_Component_SET.has(componentName) ? 'dom' : 'component',
id,
refName
});
}
createFunctionRef(componentName, id, fn) {
this.refs.push({
type: constant_1.DEFAULT_Component_SET.has(componentName) ? 'dom' : 'component',
id,
fn
});
}
handleRefs() {
const objExpr = this.refs.map(ref => {
return t.objectExpression([
t.objectProperty(t.identifier('type'), t.stringLiteral(ref.type)),
t.objectProperty(t.identifier('id'), t.stringLiteral(ref.id)),
t.objectProperty(t.identifier('refName'), t.stringLiteral(ref.refName || '')),
t.objectProperty(t.identifier('fn'), ref.fn ? ref.fn : t.nullLiteral())
]);
});
this.classPath.node.body.body.push(t.classProperty(t.identifier('$$refs'), t.arrayExpression(objExpr)));
}
traverse() {
const self = this;
self.classPath.traverse({
JSXOpeningElement: (path) => {
const jsx = path.node;
const attrs = jsx.attributes;
if (!t.isJSXIdentifier(jsx.name)) {
return;
}
const loopCallExpr = path.findParent(p => utils_1.isArrayMapCallExpression(p));
const componentName = jsx.name.name;
const refAttr = jsx_1.findJSXAttrByName(attrs, 'ref');
if (!refAttr) {
return;
}
const idAttr = jsx_1.findJSXAttrByName(attrs, 'id');
let id = utils_1.createRandomLetters(5);
let idExpr;
if (!idAttr) {
if (loopCallExpr && loopCallExpr.isCallExpression()) {
const [func] = loopCallExpr.node.arguments;
let indexId = null;
if (t.isFunctionExpression(func) || t.isArrowFunctionExpression(func)) {
const params = func.params;
indexId = params[1];
}
if (indexId === null || !t.isIdentifier(indexId)) {
throw utils_1.codeFrameError(path.node, '在循环中使用 ref 必须暴露循环的第二个参数 `index`');
}
attrs.push(t.jSXAttribute(t.jSXIdentifier('id'), t.jSXExpressionContainer(t.binaryExpression('+', t.stringLiteral(id), indexId))));
}
else {
attrs.push(t.jSXAttribute(t.jSXIdentifier('id'), t.stringLiteral(id)));
}
}
else {
const idValue = idAttr.value;
if (t.isStringLiteral(idValue)) {
id = idValue.value;
}
else if (t.isJSXExpressionContainer(idValue)) {
if (t.isStringLiteral(idValue.expression)) {
id = idValue.expression.value;
}
else {
idExpr = idValue.expression;
}
}
}
if (t.isStringLiteral(refAttr.value)) {
if (loopCallExpr) {
throw utils_1.codeFrameError(refAttr, '循环中的 ref 只能使用函数。');
}
this.createStringRef(componentName, id, refAttr.value.value);
}
if (t.isJSXExpressionContainer(refAttr.value)) {
const expr = refAttr.value.expression;
if (t.isStringLiteral(expr)) {
if (loopCallExpr) {
throw utils_1.codeFrameError(refAttr, '循环中的 ref 只能使用函数。');
}
this.createStringRef(componentName, id, expr.value);
}
else if (t.isArrowFunctionExpression(expr) || t.isMemberExpression(expr)) {
const type = constant_1.DEFAULT_Component_SET.has(componentName) ? 'dom' : 'component';
if (loopCallExpr) {
this.loopRefs.set(path.parentPath.node, {
id: idExpr || id,
fn: expr,
type,
component: path.parentPath
});
}
else {
this.refs.push({
type,
id,
fn: expr
});
}
}
else {
throw utils_1.codeFrameError(refAttr, 'ref 仅支持传入字符串、匿名箭头函数和 class 中已声明的函数');
}
}
for (const [index, attr] of attrs.entries()) {
if (attr === refAttr) {
attrs.splice(index, 1);
}
}
},
ClassMethod(path) {
const node = path.node;
if (t.isIdentifier(node.key)) {
const name = node.key.name;
self.methods.set(name, path);
if (name === 'render') {
self.renderMethod = path;
path.traverse({
ReturnStatement(returnPath) {
const arg = returnPath.node.argument;
const ifStem = returnPath.findParent(p => p.isIfStatement());
if (ifStem && ifStem.isIfStatement() && arg === null) {
const consequent = ifStem.get('consequent');
if (consequent.isBlockStatement() && consequent.node.body.includes(returnPath.node)) {
returnPath.get('argument').replaceWith(t.nullLiteral());
}
}
}
});
}
if (name === 'constructor') {
path.traverse({
AssignmentExpression(p) {
if (t.isMemberExpression(p.node.left) &&
t.isThisExpression(p.node.left.object) &&
t.isIdentifier(p.node.left.property) &&
p.node.left.property.name === 'state' &&
t.isObjectExpression(p.node.right)) {
const properties = p.node.right.properties;
properties.forEach(p => {
if (t.isObjectProperty(p) && t.isIdentifier(p.key)) {
self.initState.add(p.key.name);
}
});
}
}
});
}
}
},
IfStatement(path) {
const test = path.get('test');
const consequent = path.get('consequent');
if (utils_1.isContainJSXElement(consequent) && utils_1.hasComplexExpression(test)) {
const scope = self.renderMethod && self.renderMethod.scope || path.scope;
utils_1.generateAnonymousState(scope, test, self.jsxReferencedIdentifiers, true);
}
},
ClassProperty(path) {
const { key: { name }, value } = path.node;
if (t.isArrowFunctionExpression(value) || t.isFunctionExpression(value)) {
self.methods.set(name, path);
}
if (name === 'state' && t.isObjectExpression(value)) {
value.properties.forEach(p => {
if (t.isObjectProperty(p)) {
if (t.isIdentifier(p.key)) {
self.initState.add(p.key.name);
}
}
});
}
},
JSXExpressionContainer(path) {
const attr = path.findParent(p => p.isJSXAttribute());
const isFunctionProp = attr && typeof attr.node.name.name === 'string' && attr.node.name.name.startsWith('on');
path.traverse({
MemberExpression(path) {
const sibling = path.getSibling('property');
if (path.get('object').isThisExpression() &&
(path.get('property').isIdentifier({ name: 'props' }) || path.get('property').isIdentifier({ name: 'state' })) &&
sibling.isIdentifier()) {
if (!isFunctionProp) {
self.usedState.add(sibling.node.name);
}
}
}
});
const expression = path.get('expression');
const scope = self.renderMethod && self.renderMethod.scope || path.scope;
const calleeExpr = expression.get('callee');
const parentPath = path.parentPath;
if (utils_1.hasComplexExpression(expression) &&
!isFunctionProp &&
!(calleeExpr &&
calleeExpr.isMemberExpression() &&
calleeExpr.get('object').isMemberExpression() &&
calleeExpr.get('property').isIdentifier({ name: 'bind' })) // is not bind
) {
utils_1.generateAnonymousState(scope, expression, self.jsxReferencedIdentifiers);
}
else {
if (parentPath.isJSXAttribute()) {
if (!(expression.isMemberExpression() || expression.isIdentifier()) && parentPath.node.name.name === 'key') {
utils_1.generateAnonymousState(scope, expression, self.jsxReferencedIdentifiers);
}
}
}
if (!attr)
return;
const key = attr.node.name;
const value = attr.node.value;
if (!t.isJSXIdentifier(key)) {
return;
}
if (t.isJSXIdentifier(key) && key.name.startsWith('on') && t.isJSXExpressionContainer(value)) {
const expr = value.expression;
if (t.isCallExpression(expr) && t.isMemberExpression(expr.callee) && t.isIdentifier(expr.callee.property, { name: 'bind' })) {
self.buildPropsAnonymousFunc(attr, expr, true);
}
else if (t.isMemberExpression(expr)) {
self.buildPropsAnonymousFunc(attr, expr, false);
}
else if (t.isArrowFunctionExpression(expr)) {
const exprPath = attr.get('value.expression');
const stemParent = path.getStatementParent();
const counter = self.anonymousFuncCounter();
const anonymousFuncName = `anonymousFunc${counter}`;
const isCatch = utils_1.isContainStopPropagation(exprPath);
const classBody = self.classPath.node.body.body;
const loopCallExpr = path.findParent(p => utils_1.isArrayMapCallExpression(p));
let index;
if (loopCallExpr) {
index = lodash_1.get(loopCallExpr, 'node.arguments[0].params[1]');
if (!t.isIdentifier(index)) {
index = t.identifier('__index' + counter);
lodash_1.set(loopCallExpr, 'node.arguments[0].params[1]', index);
}
classBody.push(t.classProperty(t.identifier(anonymousFuncName + 'Array'), t.arrayExpression([])));
const arrayFunc = t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier(anonymousFuncName + 'Array')), t.identifier(index.name), true);
classBody.push(t.classMethod('method', t.identifier(anonymousFuncName), [t.identifier(index.name), t.identifier('e')], t.blockStatement([
isCatch ? t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('e'), t.identifier('stopPropagation')), [])) : t.emptyStatement(),
t.expressionStatement(t.logicalExpression('&&', arrayFunc, t.callExpression(arrayFunc, [t.identifier('e')])))
])));
exprPath.replaceWith(t.callExpression(t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier(anonymousFuncName)), t.identifier('bind')), [t.thisExpression(), t.identifier(index.name)]));
stemParent.insertBefore(t.expressionStatement(t.assignmentExpression('=', arrayFunc, expr)));
}
else {
classBody.push(t.classMethod('method', t.identifier(anonymousFuncName), [t.identifier('e')], t.blockStatement([
isCatch ? t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('e'), t.identifier('stopPropagation')), [])) : t.emptyStatement()
])));
exprPath.replaceWith(t.memberExpression(t.thisExpression(), t.identifier(anonymousFuncName)));
stemParent.insertBefore(t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.thisExpression(), t.identifier(anonymousFuncName)), expr)));
}
}
else {
throw utils_1.codeFrameError(path.node, '组件事件传参只能在使用匿名箭头函数,或使用类作用域下的确切引用(this.handleXX || this.props.handleXX),或使用 bind。');
}
}
const jsx = path.findParent(p => p.isJSXOpeningElement());
if (!jsx)
return;
const jsxName = jsx.node.name;
if (!t.isJSXIdentifier(jsxName))
return;
if (expression.isJSXElement())
return;
if (constant_1.DEFAULT_Component_SET.has(jsxName.name) || expression.isIdentifier() || expression.isMemberExpression() || expression.isLiteral() || expression.isLogicalExpression() || expression.isConditionalExpression() || key.name.startsWith('on') || expression.isCallExpression())
return;
utils_1.generateAnonymousState(scope, expression, self.jsxReferencedIdentifiers);
},
JSXElement(path) {
const id = path.node.openingElement.name;
if (t.isJSXIdentifier(id) &&
!constant_1.DEFAULT_Component_SET.has(id.name) &&
self.moduleNames.indexOf(id.name) !== -1) {
const name = id.name;
const binding = self.classPath.scope.getBinding(name);
if (binding && t.isImportDeclaration(binding.path.parent)) {
const sourcePath = binding.path.parent.source.value;
if (binding.path.isImportDefaultSpecifier()) {
self.customComponents.set(name, {
sourcePath,
type: 'default'
});
}
else {
self.customComponents.set(name, {
sourcePath,
type: 'pattern'
});
}
}
}
},
MemberExpression: (path) => {
const object = path.get('object');
const property = path.get('property');
if (!(object.isThisExpression() && property.isIdentifier({ name: 'props' }))) {
return;
}
const parentPath = path.parentPath;
if (parentPath.isMemberExpression()) {
const siblingProp = parentPath.get('property');
if (siblingProp.isIdentifier()) {
const name = siblingProp.node.name;
if (name === 'children') {
parentPath.replaceWith(t.jSXElement(t.jSXOpeningElement(t.jSXIdentifier('slot'), [], true), t.jSXClosingElement(t.jSXIdentifier('slot')), [], true));
}
else if (/^render[A-Z]/.test(name)) {
const slotName = utils_1.getSlotName(name);
parentPath.replaceWith(t.jSXElement(t.jSXOpeningElement(t.jSXIdentifier('slot'), [
t.jSXAttribute(t.jSXIdentifier('name'), t.stringLiteral(slotName))
], true), t.jSXClosingElement(t.jSXIdentifier('slot')), []));
this.setMultipleSlots();
}
else {
self.componentProperies.add(siblingProp.node.name);
}
}
}
else if (parentPath.isVariableDeclarator()) {
const siblingId = parentPath.get('id');
if (siblingId.isObjectPattern()) {
const properties = siblingId.node.properties;
for (const prop of properties) {
if (t.isRestProperty(prop)) {
throw utils_1.codeFrameError(prop.loc, 'this.props 不支持使用 rest property 语法,请把每一个 prop 都单独列出来');
}
else if (t.isIdentifier(prop.key)) {
self.componentProperies.add(prop.key.name);
}
}
}
}
},
CallExpression(path) {
const node = path.node;
const callee = node.callee;
if (t.isMemberExpression(callee) && t.isMemberExpression(callee.object)) {
const property = callee.property;
if (t.isIdentifier(property)) {
if (property.name.startsWith('on')) {
self.componentProperies.add(`__fn_${property.name}`);
processThisPropsFnMemberProperties(callee, path, node.arguments, false);
}
else if (property.name === 'call' || property.name === 'apply') {
self.componentProperies.add(`__fn_${property.name}`);
processThisPropsFnMemberProperties(callee.object, path, node.arguments, true);
}
}
}
}
});
}
setComponents() {
this.customComponents.forEach((component, name) => {
this.result.components.push({
path: utils_1.pathResolver(component.sourcePath, this.sourcePath),
name: lodash_1.kebabCase(name),
type: component.type
});
});
}
setMethods() {
const methods = this.classPath.get('body').get('body');
for (const method of methods) {
if (method.isClassMethod()) {
const key = method.get('key');
if (key.isIdentifier()) {
this.methods.set(key.node.name, method);
}
}
}
}
resetConstructor() {
const body = this.classPath.node.body.body;
if (!this.methods.has('constructor')) {
const ctor = buildConstructor();
body.unshift(ctor);
}
if (process.env.NODE_ENV === 'test') {
return;
}
for (const method of body) {
if (t.isClassMethod(method) && method.kind === 'constructor') {
method.kind = 'method';
method.key = t.identifier('_constructor');
if (t.isBlockStatement(method.body)) {
for (const statement of method.body.body) {
if (t.isExpressionStatement(statement)) {
const expr = statement.expression;
if (t.isCallExpression(expr) && (t.isIdentifier(expr.callee, { name: 'super' }) || t.isSuper(expr.callee))) {
expr.callee = t.memberExpression(t.identifier('super'), t.identifier('_constructor'));
}
}
}
}
}
}
}
handleLifecyclePropParam(propParam, properties) {
let propsName = null;
if (!propParam) {
return null;
}
if (t.isIdentifier(propParam)) {
propsName = propParam.name;
}
else if (t.isObjectPattern(propParam)) {
for (const prop of propParam.properties) {
if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) {
properties.add(prop.key.name);
}
else if (t.isRestProperty(prop) && t.isIdentifier(prop.argument)) {
propsName = prop.argument.name;
}
}
}
else {
throw utils_1.codeFrameError(propParam.loc, '此生命周期的第一个参数只支持写标识符或对象解构');
}
return propsName;
}
findMoreProps() {
// 第一个参数是 props 的生命周期
const lifeCycles = new Set([
// 'constructor',
'componentDidUpdate',
'shouldComponentUpdate',
'getDerivedStateFromProps',
'getSnapshotBeforeUpdate',
'componentWillReceiveProps',
'componentWillUpdate'
]);
const properties = new Set();
this.methods.forEach((method, name) => {
if (!lifeCycles.has(name)) {
return;
}
const node = method.node;
let propsName = null;
if (t.isClassMethod(node)) {
propsName = this.handleLifecyclePropParam(node.params[0], properties);
}
else if (t.isArrowFunctionExpression(node.value) || t.isFunctionExpression(node.value)) {
propsName = this.handleLifecyclePropParam(node.value.params[0], properties);
}
if (propsName === null) {
return;
}
method.traverse({
MemberExpression(path) {
if (!path.isReferencedMemberExpression()) {
return;
}
const { object, property } = path.node;
if (t.isIdentifier(object, { name: propsName }) && t.isIdentifier(property)) {
properties.add(property.name);
}
},
VariableDeclarator(path) {
const { id, init } = path.node;
if (t.isObjectPattern(id) && t.isIdentifier(init, { name: propsName })) {
for (const prop of id.properties) {
if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) {
properties.add(prop.key.name);
}
}
}
}
});
properties.forEach((value) => {
this.componentProperies.add(value);
});
});
}
parseRender() {
if (this.renderMethod) {
this.result.template = this.result.template
+ new render_1.RenderParser(this.renderMethod, this.methods, this.initState, this.jsxReferencedIdentifiers, this.usedState, this.loopStateName, this.customComponentNames, this.customComponentData, this.componentProperies, this.loopRefs).outputTemplate;
}
}
compile() {
this.traverse();
this.setMethods();
this.setComponents();
this.resetConstructor();
this.findMoreProps();
this.handleRefs();
this.parseRender();
this.result.componentProperies = [...this.componentProperies];
}
}
exports.Transformer = Transformer;
//# sourceMappingURL=class.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,94 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.THIRD_PARTY_COMPONENTS = new Set();
// tslint:disable-next-line:variable-name
exports.DEFAULT_Component_SET = new Set([
'view',
'scroll-view',
'swiper',
'movable-view',
'cover-view',
'cover-image',
'icon',
'text',
'rich-text',
'progress',
'button',
'checkbox',
'form',
'input',
'label',
'picker',
'picker-view',
'picker-view-column',
'radio',
'radio-group',
'checkbox-group',
'slider',
'switch',
'textarea',
'navigator',
'audio',
'image',
'video',
'camera',
'live-player',
'live-pusher',
'map',
'canvas',
'open-data',
'web-view',
'swiper-item',
'movable-area',
'movable-view',
'functional-page-navigator',
'ad',
'block',
'import',
'official-account'
]);
exports.INTERNAL_SAFE_GET = 'internal_safe_get';
exports.TARO_PACKAGE_NAME = '@tarojs/taro';
exports.COMPONENTS_PACKAGE_NAME = '@tarojs/components';
exports.REDUX_PACKAGE_NAME = '@tarojs/redux';
exports.MOBX_PACKAGE_NAME = '@tarojs/mobx';
exports.MAP_CALL_ITERATOR = '__item';
exports.INTERNAL_INLINE_STYLE = 'internal_inline_style';
exports.INTERNAL_GET_ORIGNAL = 'internal_get_original';
exports.GEL_ELEMENT_BY_ID = 'getElementById';
exports.LOOP_STATE = '$loopState';
exports.LOOP_ORIGINAL = '$original';
exports.setLoopOriginal = (s) => exports.LOOP_ORIGINAL = s;
exports.LOOP_CALLEE = '$anonymousCallee_';
exports.SPECIAL_COMPONENT_PROPS = new Map();
exports.SPECIAL_COMPONENT_PROPS.set('Progress', new Set([
'activeColor',
'backgroundColor'
]));
exports.IMAGE_COMPONENTS = new Set([
'Image',
'CoverImage'
]);
exports.swanSpecialAttrs = {
'ScrollView': ['scrollTop', 'scrollLeft', 'scrollIntoView'],
'Input': ['value'],
'Textarea': ['value'],
'MovableView': ['x', 'y'],
'Slider': ['value']
};
exports.ALIPAY_BUBBLE_EVENTS = new Set([
'onTouchStart',
'onTouchMove',
'onTouchEnd',
'onTouchCancel',
'onClick',
'onLongTap'
]);
exports.TRANSFORM_COMPONENT_PROPS = new Map();
exports.TRANSFORM_COMPONENT_PROPS.set("alipay" /* alipay */, {
'Canvas': {
'canvasId': 'id'
}
});
exports.lessThanSignPlacehold = '__LESS_THAN_SIGN_PLACEHOLDER__';
//# sourceMappingURL=constant.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"constant.js","sourceRoot":"","sources":["../../src/constant.ts"],"names":[],"mappings":";;AAEa,QAAA,sBAAsB,GAAG,IAAI,GAAG,EAAU,CAAA;AAEvD,yCAAyC;AAC5B,QAAA,qBAAqB,GAAG,IAAI,GAAG,CAAS;IACnD,MAAM;IACN,YAAY;IACZ,QAAQ;IACR,aAAa;IACb,WAAW;IACX,YAAY;IACZ,MAAM;IACN,MAAM;IACN,UAAU;IACV,UAAU;IACV,QAAQ;IACR,UAAU;IACV,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,YAAY;IACZ,kBAAkB;IAClB,OAAO;IACP,YAAY;IACZ,eAAe;IACf,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,WAAW;IACX,OAAO;IACP,OAAO;IACP,OAAO;IACP,QAAQ;IACR,YAAY;IACZ,YAAY;IACZ,KAAK;IACL,QAAQ;IACR,UAAU;IACV,SAAS;IACT,YAAY;IACZ,aAAa;IACb,aAAa;IACb,yBAAyB;IACzB,IAAI;IACJ,OAAO;IACP,QAAQ;IACR,iBAAiB;CAClB,CAAC,CAAA;AAEW,QAAA,iBAAiB,GAAG,mBAAmB,CAAA;AAEvC,QAAA,iBAAiB,GAAG,cAAc,CAAA;AAElC,QAAA,uBAAuB,GAAG,oBAAoB,CAAA;AAE9C,QAAA,kBAAkB,GAAG,eAAe,CAAA;AAEpC,QAAA,iBAAiB,GAAG,cAAc,CAAA;AAElC,QAAA,iBAAiB,GAAG,QAAQ,CAAA;AAE5B,QAAA,qBAAqB,GAAG,uBAAuB,CAAA;AAE/C,QAAA,oBAAoB,GAAG,uBAAuB,CAAA;AAE9C,QAAA,iBAAiB,GAAG,gBAAgB,CAAA;AAEpC,QAAA,UAAU,GAAG,YAAY,CAAA;AAE3B,QAAA,aAAa,GAAG,WAAW,CAAA;AAEzB,QAAA,eAAe,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,qBAAa,GAAG,CAAC,CAAA;AAElD,QAAA,WAAW,GAAG,mBAAmB,CAAA;AAEjC,QAAA,uBAAuB,GAAG,IAAI,GAAG,EAAuB,CAAA;AAErE,+BAAuB,CAAC,GAAG,CACzB,UAAU,EACV,IAAI,GAAG,CAAC;IACN,aAAa;IACb,iBAAiB;CAClB,CAAC,CACH,CAAA;AAEY,QAAA,gBAAgB,GAAG,IAAI,GAAG,CAAS;IAC9C,OAAO;IACP,YAAY;CACb,CAAC,CAAA;AAEW,QAAA,gBAAgB,GAAG;IAC9B,YAAY,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,gBAAgB,CAAC;IAC3D,OAAO,EAAE,CAAC,OAAO,CAAC;IAClB,UAAU,EAAE,CAAC,OAAO,CAAC;IACrB,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;IACzB,QAAQ,EAAE,CAAC,OAAO,CAAC;CACpB,CAAA;AAEY,QAAA,oBAAoB,GAAG,IAAI,GAAG,CAAS;IAClD,cAAc;IACd,aAAa;IACb,YAAY;IACZ,eAAe;IACf,SAAS;IACT,WAAW;CACZ,CAAC,CAAA;AAEW,QAAA,yBAAyB,GAAG,IAAI,GAAG,EAA0D,CAAA;AAE1G,iCAAyB,CAAC,GAAG,wBAAkB;IAC7C,QAAQ,EAAE;QACR,UAAU,EAAE,IAAI;KACjB;CACF,CAAC,CAAA;AAEW,QAAA,qBAAqB,GAAG,gCAAgC,CAAA"}

View File

@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const voidHtmlTags = new Set([
// 'image',
'img',
'input',
'import'
]);
if (process.env.NODE_ENV === 'test') {
voidHtmlTags.add('image');
}
function stringifyAttributes(input) {
const attributes = [];
for (const key of Object.keys(input)) {
let value = input[key];
if (value === false) {
continue;
}
if (Array.isArray(value)) {
value = value.join(' ');
}
let attribute = key;
if (value !== true) {
attribute += `="${String(value)}"`;
}
attributes.push(attribute);
}
return attributes.length > 0 ? ' ' + attributes.join(' ') : '';
}
exports.createHTMLElement = (options) => {
options = Object.assign({
name: 'div',
attributes: {},
value: ''
}, options);
const isVoidTag = voidHtmlTags.has(options.name);
let ret = `<${options.name}${stringifyAttributes(options.attributes)}${isVoidTag ? `/` : ''}>`;
if (!isVoidTag) {
ret += `${options.value}</${options.name}>`;
}
return ret;
};
//# sourceMappingURL=create-html-element.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"create-html-element.js","sourceRoot":"","sources":["../../src/create-html-element.ts"],"names":[],"mappings":";;AAAA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS;IACnC,WAAW;IACX,KAAK;IACL,OAAO;IACP,QAAQ;CACT,CAAC,CAAA;AAEF,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE;IACnC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;CAC1B;AAQD,SAAS,mBAAmB,CAAE,KAAa;IACzC,MAAM,UAAU,GAAa,EAAE,CAAA;IAE/B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QACpC,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;QAEtB,IAAI,KAAK,KAAK,KAAK,EAAE;YACnB,SAAQ;SACT;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACxB,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;SACxB;QAED,IAAI,SAAS,GAAG,GAAG,CAAA;QAEnB,IAAI,KAAK,KAAK,IAAI,EAAE;YAClB,SAAS,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,CAAA;SACnC;QAED,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;KAC3B;IAED,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAEhE,CAAC;AAEY,QAAA,iBAAiB,GAAG,CAAC,OAAgB,EAAE,EAAE;IACpD,OAAO,GAAG,MAAM,CAAC,MAAM,CACrB;QACE,IAAI,EAAE,KAAK;QACX,UAAU,EAAE,EAAE;QACd,KAAK,EAAE,EAAE;KACV,EACD,OAAO,CACR,CAAA;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAEhD,IAAI,GAAG,GAAG,IAAI,OAAO,CAAC,IAAI,GAAG,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAG,GAAG,CAAA;IAE/F,IAAI,CAAC,SAAS,EAAE;QACd,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,IAAI,GAAG,CAAA;KAC5C;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}

View File

@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const eslint_1 = require("eslint");
const utils_1 = require("./utils");
const cli = new eslint_1.CLIEngine({
baseConfig: {
extends: ['plugin:taro/transformer']
},
useEslintrc: false,
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 2018,
ecmaFeatures: {
jsx: true,
legacyDecorators: true
}
}
});
exports.eslintValidation = () => {
return {
visitor: {
Program(_, state) {
const { file: { code } } = state;
const report = cli.executeOnText(code);
if (report.errorCount > 0) {
for (const result of report.results) {
for (const msg of result.messages) {
const err = utils_1.codeFrameError({
start: {
line: msg.line,
column: msg.column
},
end: {
line: msg.endLine,
column: msg.endColumn
}
}, msg.message);
// tslint:disable-next-line
console.warn('\n' + `ESLint(${msg.ruleId}) 错误:` + err.message + '\n');
}
}
}
}
}
};
};
//# sourceMappingURL=eslint.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../src/eslint.ts"],"names":[],"mappings":";;AAAA,mCAAkC;AAElC,mCAAwC;AAExC,MAAM,GAAG,GAAG,IAAI,kBAAS,CAAC;IACxB,UAAU,EAAE;QACV,OAAO,EAAE,CAAC,yBAAyB,CAAC;KACrC;IACD,WAAW,EAAE,KAAK;IAClB,MAAM,EAAE,cAAc;IACtB,aAAa,EAAE;QACb,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE;YACZ,GAAG,EAAE,IAAI;YACT,gBAAgB,EAAE,IAAI;SACvB;KACF;CACF,CAAC,CAAA;AAEW,QAAA,gBAAgB,GAEzB,GAAG,EAAE;IACP,OAAO;QACL,OAAO,EAAE;YACP,OAAO,CAAE,CAAC,EAAE,KAAK;gBACf,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,KAAK,CAAA;gBAChC,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;gBACtC,IAAI,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE;oBACzB,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE;wBACnC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE;4BACjC,MAAM,GAAG,GAAG,sBAAc,CAAC;gCACzB,KAAK,EAAE;oCACL,IAAI,EAAE,GAAG,CAAC,IAAI;oCACd,MAAM,EAAE,GAAG,CAAC,MAAM;iCACnB;gCACD,GAAG,EAAE;oCACH,IAAI,EAAE,GAAG,CAAC,OAAO;oCACjB,MAAM,EAAE,GAAG,CAAC,SAAS;iCACtB;6BACF,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;4BACf,2BAA2B;4BAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,UAAU,GAAG,CAAC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;yBACtE;qBACF;iBACF;YACH,CAAC;SACF;KACF,CAAA;AACH,CAAC,CAAA"}

View File

@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./utils");
const t = require("babel-types");
const lodash_1 = require("lodash");
function initialIsCapital(word) {
return word[0] !== word[0].toLowerCase();
}
exports.functionalComponent = () => {
return {
visitor: {
JSXElement(path) {
const arrowFuncExpr = path.findParent(p => p.isArrowFunctionExpression());
if (arrowFuncExpr && arrowFuncExpr.isArrowFunctionExpression() && arrowFuncExpr.parentPath.isVariableDeclarator()) {
const valDecl = arrowFuncExpr.parentPath.parentPath;
if (!valDecl.isVariableDeclaration()) {
throw utils_1.codeFrameError(valDecl.node, '函数式组件不能同时定义多个值');
}
const id = arrowFuncExpr.parentPath.node.id;
if (!t.isIdentifier(id)) {
throw utils_1.codeFrameError(id, '函数式组件只能使用普通标识符定义');
}
if (!initialIsCapital(id.name)) {
throw utils_1.codeFrameError(id, '组件命名规则请遵守帕斯卡命名法Pascal Case');
}
const hasClassDecl = arrowFuncExpr.findParent(p => p.isClassDeclaration());
if (hasClassDecl) {
// @TODO: 加上链接
throw utils_1.codeFrameError(arrowFuncExpr.node, '在类中的函数式组件请写成类函数式组件:参考:');
}
const { body } = arrowFuncExpr.node;
if (t.isBlockStatement(body)) {
valDecl.replaceWith(t.functionDeclaration(id, arrowFuncExpr.node.params, body));
}
else {
valDecl.replaceWith(t.functionDeclaration(id, arrowFuncExpr.node.params, t.blockStatement([
t.returnStatement(body)
])));
}
return;
}
const functionDecl = path.findParent(p => p.isFunctionDeclaration());
if (functionDecl && functionDecl.isFunctionDeclaration()) {
const hasClassDecl = functionDecl.findParent(p => p.isClassDeclaration());
if (hasClassDecl) {
// @TODO: 加上链接
throw utils_1.codeFrameError(functionDecl.node, '在类中的函数式组件请写成类函数式组件:参考:');
}
const { id, body, params } = functionDecl.node;
let arg = null;
if (params.length > 1) {
throw utils_1.codeFrameError(id, '函数式组件的参数最多只能传入一个');
}
else if (params.length === 1) {
arg = params[0];
}
const cloneBody = lodash_1.cloneDeep(body);
if (!initialIsCapital(id.name)) {
throw utils_1.codeFrameError(id, '组件命名规则请遵守帕斯卡命名法Pascal Case');
}
if (arg) {
if (t.isIdentifier(arg)) {
cloneBody.body.push(utils_1.buildConstVariableDeclaration(arg.name, t.memberExpression(t.thisExpression(), t.identifier('props'))));
}
else if (t.isObjectPattern(arg)) {
cloneBody.body.push(t.variableDeclaration('const', [
t.variableDeclarator(arg, t.memberExpression(t.thisExpression(), t.identifier('props')))
]));
}
else {
throw utils_1.codeFrameError(arg, '函数式组件只支持传入一个简单标识符或使用对象结构');
}
}
const classDecl = t.classDeclaration(id, t.memberExpression(t.identifier('Taro'), t.identifier('Component')), t.classBody([
t.classMethod('method', t.identifier('render'), [], cloneBody)
]), []);
functionDecl.replaceWith(classDecl);
}
}
}
};
};
//# sourceMappingURL=functional.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"functional.js","sourceRoot":"","sources":["../../src/functional.ts"],"names":[],"mappings":";;AACA,mCAAuE;AACvE,iCAAgC;AAChC,mCAAkC;AAElC,SAAS,gBAAgB,CAAE,IAAY;IACrC,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;AAC1C,CAAC;AAEY,QAAA,mBAAmB,GAE5B,GAAG,EAAE;IACP,OAAO;QACL,OAAO,EAAE;YACP,UAAU,CAAE,IAAI;gBACd,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,yBAAyB,EAAE,CAAC,CAAA;gBACzE,IAAI,aAAa,IAAI,aAAa,CAAC,yBAAyB,EAAE,IAAI,aAAa,CAAC,UAAU,CAAC,oBAAoB,EAAE,EAAE;oBACjH,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,UAAU,CAAA;oBACnD,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE;wBACpC,MAAM,sBAAc,CAAC,OAAO,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAA;qBACrD;oBACD,MAAM,EAAE,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAA;oBAC3C,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE;wBACvB,MAAM,sBAAc,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAA;qBAC7C;oBACD,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;wBAC9B,MAAM,sBAAc,CAAC,EAAE,EAAE,8BAA8B,CAAC,CAAA;qBACzD;oBACD,MAAM,YAAY,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAA;oBAC1E,IAAI,YAAY,EAAE;wBAChB,cAAc;wBACd,MAAM,sBAAc,CAAC,aAAa,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAA;qBACnE;oBACD,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,IAAI,CAAA;oBACnC,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE;wBAC5B,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;qBAChF;yBAAM;wBACL,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,cAAc,CAAC;4BACxF,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC;yBACxB,CAAC,CAAC,CAAC,CAAA;qBACL;oBACD,OAAM;iBACP;gBAED,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,qBAAqB,EAAE,CAAC,CAAA;gBACpE,IAAI,YAAY,IAAI,YAAY,CAAC,qBAAqB,EAAE,EAAE;oBACxD,MAAM,YAAY,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAA;oBACzE,IAAI,YAAY,EAAE;wBAChB,cAAc;wBACd,MAAM,sBAAc,CAAC,YAAY,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAA;qBAClE;oBACD,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,CAAA;oBAC9C,IAAI,GAAG,GAAkB,IAAI,CAAA;oBAC7B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;wBACrB,MAAM,sBAAc,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAA;qBAC7C;yBAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;wBAC9B,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;qBAChB;oBACD,MAAM,SAAS,GAAG,kBAAS,CAAC,IAAI,CAAC,CAAA;oBACjC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;wBAC9B,MAAM,sBAAc,CAAC,EAAE,EAAE,8BAA8B,CAAC,CAAA;qBACzD;oBACD,IAAI,GAAG,EAAE;wBACP,IAAI,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE;4BACvB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,qCAA6B,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;yBAC5H;6BAAM,IAAI,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE;4BACjC,SAAS,CAAC,IAAI,CAAC,IAAI,CACjB,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE;gCAC7B,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;6BACzF,CAAC,CACH,CAAA;yBACF;6BAAM;4BACL,MAAM,sBAAc,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAA;yBACtD;qBACF;oBACD,MAAM,SAAS,GAAG,CAAC,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;wBACxH,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC;qBAC/D,CAAC,EAAE,EAAE,CAAC,CAAA;oBACP,YAAY,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;iBACpC;YACH,CAAC;SACF;KACF,CAAA;AACH,CAAC,CAAA"}

View File

@ -0,0 +1,507 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const babel_traverse_1 = require("babel-traverse");
const babel_generator_1 = require("babel-generator");
const html_1 = require("html");
const babel_core_1 = require("babel-core");
const ts = require("typescript");
const class_1 = require("./class");
const utils_1 = require("./utils");
const t = require("babel-types");
const constant_1 = require("./constant");
const adapter_1 = require("./adapter");
const options_1 = require("./options");
const lodash_1 = require("lodash");
const template = require('babel-template');
function getIdsFromMemberProps(member) {
let ids = [];
const { object, property } = member;
if (t.isMemberExpression(object)) {
ids = ids.concat(getIdsFromMemberProps(object));
}
if (t.isThisExpression(object)) {
ids.push('this');
}
if (t.isIdentifier(object)) {
ids.push(object.name);
}
if (t.isIdentifier(property)) {
ids.push(property.name);
}
return ids;
}
/**
* TS 编译器会把 class property 移到构造器
* 而小程序要求 `config` 和所有函数在初始化(after new Class)之后就收集到所有的函数和 config 信息
* 所以当如构造器里有 this.func = () => {...} 的形式就给他转换成普通的 classProperty function
* 如果有 config 就给他还原
*/
function resetTSClassProperty(body) {
for (const method of body) {
if (t.isClassMethod(method) && method.kind === 'constructor') {
if (t.isBlockStatement(method.body)) {
method.body.body = method.body.body.filter(statement => {
if (t.isExpressionStatement(statement) && t.isAssignmentExpression(statement.expression)) {
const expr = statement.expression;
const { left, right } = expr;
if (t.isMemberExpression(left) &&
t.isThisExpression(left.object) &&
t.isIdentifier(left.property)) {
if ((t.isArrowFunctionExpression(right) || t.isFunctionExpression(right))
||
(left.property.name === 'config' && t.isObjectExpression(right))) {
const classProp = t.classProperty(left.property, right);
body.push(classProp);
handleThirdPartyComponent(classProp);
return false;
}
}
}
return true;
});
}
}
}
}
function findDeclarationScope(path, id) {
const scopePath = path.findParent(p => !!p.scope.getOwnBindingIdentifier(id.name));
if (scopePath) {
return scopePath;
}
throw utils_1.codeFrameError(path.node, '该引用从未被定义');
}
function buildFullPathThisPropsRef(id, memberIds, path) {
const scopePath = findDeclarationScope(path, id);
const binding = scopePath.scope.getOwnBinding(id.name);
if (binding) {
const bindingPath = binding.path;
if (bindingPath.isVariableDeclarator()) {
const dclId = bindingPath.get('id');
const dclInit = bindingPath.get('init');
let dclInitIds = [];
if (dclInit.isMemberExpression()) {
dclInitIds = getIdsFromMemberProps(dclInit.node);
if (dclId.isIdentifier()) {
memberIds.shift();
}
if (dclInitIds[0] === 'this' && dclInitIds[1] === 'props') {
return template(dclInitIds.concat(memberIds).join('.'))().expression;
}
}
}
}
}
function handleThirdPartyComponent(expr) {
if (t.isClassProperty(expr) && expr.key.name === 'config' && t.isObjectExpression(expr.value)) {
const properties = expr.value.properties;
for (const prop of properties) {
if (t.isObjectProperty(prop) &&
(t.isIdentifier(prop.key, { name: 'usingComponents' }) || t.isStringLiteral(prop.key, { value: 'usingComponents' })) &&
t.isObjectExpression(prop.value)) {
for (const value of prop.value.properties) {
if (t.isObjectProperty(value)) {
if (t.isStringLiteral(value.key)) {
constant_1.THIRD_PARTY_COMPONENTS.add(value.key.value);
}
if (t.isIdentifier(value.key)) {
constant_1.THIRD_PARTY_COMPONENTS.add(value.key.name);
}
}
}
}
}
}
}
function transform(options) {
if (options.adapter) {
adapter_1.setAdapter(options.adapter);
}
if (adapter_1.Adapter.type === "swan" /* swan */) {
constant_1.setLoopOriginal('privateOriginal');
}
constant_1.THIRD_PARTY_COMPONENTS.clear();
const code = options.isTyped
? ts.transpile(options.code, {
jsx: ts.JsxEmit.Preserve,
target: ts.ScriptTarget.ESNext,
importHelpers: true,
noEmitHelpers: true
})
: options.code;
options.env = Object.assign({ 'process.env.TARO_ENV': options.adapter || 'weapp' }, options.env || {});
options_1.setTransformOptions(options);
utils_1.setting.sourceCode = code;
// babel-traverse 无法生成 Hub
// 导致 Path#getSource|buildCodeFrameError 都无法直接使用
// 原因大概是 babylon.parse 没有生成 File 实例导致 scope 和 path 原型上都没有 `file`
// 将来升级到 babel@7 可以直接用 parse 而不是 transform
const ast = babel_core_1.transform(code, options_1.buildBabelTransformOptions()).ast;
if (options.isNormal) {
return { ast };
}
// transformFromAst(ast, code)
let result;
const componentSourceMap = new Map();
const imageSource = new Set();
const importSources = new Set();
let componentProperies = [];
let mainClass;
let storeName;
let renderMethod;
let isImportTaro = false;
babel_traverse_1.default(ast, {
TemplateLiteral(path) {
const nodes = [];
const { quasis, expressions } = path.node;
let index = 0;
if (path.parentPath.isTaggedTemplateExpression()) {
return;
}
for (const elem of quasis) {
if (elem.value.cooked) {
nodes.push(t.stringLiteral(elem.value.cooked));
}
if (index < expressions.length) {
const expr = expressions[index++];
if (!t.isStringLiteral(expr, { value: '' })) {
nodes.push(expr);
}
}
}
// + 号连接符必须保证第一和第二个 node 都是字符串
if (!t.isStringLiteral(nodes[0]) && !t.isStringLiteral(nodes[1])) {
nodes.unshift(t.stringLiteral(''));
}
let root = nodes[0];
for (let i = 1; i < nodes.length; i++) {
root = t.binaryExpression('+', root, nodes[i]);
}
path.replaceWith(root);
},
ClassDeclaration(path) {
mainClass = path;
const superClass = utils_1.getSuperClassCode(path);
if (superClass) {
try {
componentProperies = transform({
isRoot: false,
isApp: false,
code: superClass.code,
isTyped: true,
sourcePath: superClass.sourcePath,
outputPath: superClass.sourcePath
}).componentProperies;
}
catch (error) {
//
}
}
},
ClassExpression(path) {
mainClass = path;
},
ClassMethod(path) {
if (t.isIdentifier(path.node.key) && path.node.key.name === 'render') {
renderMethod = path;
}
},
IfStatement(path) {
const consequent = path.get('consequent');
if (!consequent.isBlockStatement()) {
consequent.replaceWith(t.blockStatement([
consequent.node
]));
}
},
CallExpression(path) {
const callee = path.get('callee');
if (utils_1.isContainJSXElement(path)) {
return;
}
if (callee.isReferencedMemberExpression()) {
const id = utils_1.findFirstIdentifierFromMemberExpression(callee.node);
const property = callee.node.property;
if (t.isIdentifier(property) && property.name.startsWith('on')) {
const funcExpr = path.findParent(p => p.isFunctionExpression());
if (funcExpr && funcExpr.isFunctionExpression()) {
const taroAPI = funcExpr.findParent(p => p.isCallExpression() && t.isMemberExpression(p.node.callee) && t.isIdentifier(p.node.callee.object, { name: 'Taro' }));
if (taroAPI && taroAPI.isCallExpression()) {
throw utils_1.codeFrameError(funcExpr.node, '在回调函数使用从 props 传递的函数时,请把回调函数改造为箭头函数并一直使用 `this` 取值');
}
}
}
const calleeIds = getIdsFromMemberProps(callee.node);
if (t.isIdentifier(id) && id.name.startsWith('on') && "alipay" /* alipay */ !== adapter_1.Adapter.type) {
const fullPath = buildFullPathThisPropsRef(id, calleeIds, path);
if (fullPath) {
path.replaceWith(t.callExpression(fullPath, path.node.arguments));
}
}
}
if (callee.isReferencedIdentifier()) {
const id = callee.node;
const ids = [id.name];
if (t.isIdentifier(id) && id.name.startsWith('on')) {
const funcExpr = path.findParent(p => p.isFunctionExpression());
if (funcExpr && funcExpr.isFunctionExpression()) {
const taroAPI = funcExpr.findParent(p => p.isCallExpression() && t.isMemberExpression(p.node.callee) && t.isIdentifier(p.node.callee.object, { name: 'Taro' }));
if (taroAPI && taroAPI.isCallExpression()) {
throw utils_1.codeFrameError(funcExpr.node, '在回调函数使用从 props 传递的函数时,请把回调函数改造为箭头函数并一直使用 `this` 取值');
}
}
const fullPath = buildFullPathThisPropsRef(id, ids, path);
if (fullPath) {
path.replaceWith(t.callExpression(fullPath, path.node.arguments));
}
}
}
},
// JSXIdentifier (path) {
// const parentPath = path.parentPath
// if (!parentPath.isJSXAttribute()) {
// return
// }
// const element = parentPath.parentPath
// if (!element.isJSXOpeningElement()) {
// return
// }
// const elementName = element.get('name')
// if (!elementName.isJSXIdentifier()) {
// return
// }
// if (DEFAULT_Component_SET.has(elementName.node.name)) {
// return
// }
// const expr = parentPath.get('value.expression')
// },
JSXElement(path) {
const assignment = path.findParent(p => p.isAssignmentExpression());
if (assignment && assignment.isAssignmentExpression() && !options.isTyped) {
const left = assignment.node.left;
if (t.isIdentifier(left)) {
const binding = assignment.scope.getBinding(left.name);
if (binding && binding.scope === assignment.scope) {
if (binding.path.isVariableDeclarator()) {
binding.path.node.init = path.node;
assignment.remove();
}
else {
throw utils_1.codeFrameError(path.node, '同一个作用域的JSX 变量延时赋值没有意义。详见https://github.com/NervJS/taro/issues/550');
}
}
}
}
const switchStatement = path.findParent(p => p.isSwitchStatement());
if (switchStatement && switchStatement.isSwitchStatement()) {
const { discriminant, cases } = switchStatement.node;
const ifStatement = cases.map((Case, index) => {
const [consequent] = Case.consequent;
if (!t.isBlockStatement(consequent)) {
throw utils_1.codeFrameError(switchStatement.node, '含有 JSX 的 switch case 语句必须每种情况都用花括号 `{}` 包裹结果');
}
const block = t.blockStatement(consequent.body.filter(b => !t.isBreakStatement(b)));
if (index !== cases.length - 1 && t.isNullLiteral(Case.test)) {
throw utils_1.codeFrameError(Case, '含有 JSX 的 switch case 语句只有最后一个 case 才能是 default');
}
const test = Case.test === null ? t.nullLiteral() : t.binaryExpression('===', discriminant, Case.test);
return { block, test };
}).reduceRight((ifStatement, item) => {
if (t.isNullLiteral(item.test)) {
ifStatement.alternate = item.block;
return ifStatement;
}
const newStatement = t.ifStatement(item.test, item.block, t.isBooleanLiteral(ifStatement.test, { value: false })
? ifStatement.alternate
: ifStatement);
return newStatement;
}, t.ifStatement(t.booleanLiteral(false), t.blockStatement([])));
switchStatement.insertAfter(ifStatement);
switchStatement.remove();
}
const isForStatement = (p) => p && (p.isForStatement() || p.isForInStatement() || p.isForOfStatement());
const forStatement = path.findParent(isForStatement);
if (isForStatement(forStatement)) {
throw utils_1.codeFrameError(forStatement.node, '不行使用 for 循环操作 JSX 元素详情https://github.com/NervJS/taro/blob/master/packages/eslint-plugin-taro/docs/manipulate-jsx-as-array.md');
}
const loopCallExpr = path.findParent(p => utils_1.isArrayMapCallExpression(p));
if (loopCallExpr && loopCallExpr.isCallExpression()) {
const [func] = loopCallExpr.node.arguments;
if (t.isArrowFunctionExpression(func) && !t.isBlockStatement(func.body)) {
func.body = t.blockStatement([
t.returnStatement(func.body)
]);
}
}
},
JSXOpeningElement(path) {
const { name } = path.node.name;
const binding = path.scope.getBinding(name);
if (process.env.NODE_ENV !== 'test' && constant_1.DEFAULT_Component_SET.has(name) && binding && binding.kind === 'module') {
const bindingPath = binding.path;
if (bindingPath.parentPath.isImportDeclaration()) {
const source = bindingPath.parentPath.node.source;
if (source.value !== constant_1.COMPONENTS_PACKAGE_NAME) {
throw utils_1.codeFrameError(bindingPath.parentPath.node, `内置组件名: '${name}' 只能从 ${constant_1.COMPONENTS_PACKAGE_NAME} 引入。`);
}
}
}
if (name === 'Provider') {
const modules = path.scope.getAllBindings('module');
const providerBinding = Object.values(modules).some((m) => m.identifier.name === 'Provider');
if (providerBinding) {
path.node.name = t.jSXIdentifier('view');
const store = path.node.attributes.find(attr => attr.name.name === 'store');
if (store && t.isJSXExpressionContainer(store.value) && t.isIdentifier(store.value.expression)) {
storeName = store.value.expression.name;
}
path.node.attributes = [];
}
}
if (constant_1.IMAGE_COMPONENTS.has(name)) {
for (const attr of path.node.attributes) {
if (attr.name.name === 'src') {
if (t.isStringLiteral(attr.value)) {
imageSource.add(attr.value.value);
}
else if (t.isJSXExpressionContainer(attr.value)) {
if (t.isStringLiteral(attr.value.expression)) {
imageSource.add(attr.value.expression.value);
}
}
}
}
}
},
JSXAttribute(path) {
const { name, value } = path.node;
if (options.jsxAttributeNameReplace) {
for (const r in options.jsxAttributeNameReplace) {
if (options.jsxAttributeNameReplace.hasOwnProperty(r)) {
const element = options.jsxAttributeNameReplace[r];
if (t.isJSXIdentifier(name, { name: r })) {
path.node.name = t.jSXIdentifier(element);
}
}
}
}
if (!t.isJSXIdentifier(name) || value === null || t.isStringLiteral(value) || t.isJSXElement(value)) {
return;
}
const expr = value.expression;
const exprPath = path.get('value.expression');
const classDecl = path.findParent(p => p.isClassDeclaration());
const classDeclName = classDecl && classDecl.isClassDeclaration() && lodash_1.get(classDecl, 'node.id.name', '');
let isConverted = false;
if (classDeclName) {
isConverted = classDeclName === '_C' || classDeclName.endsWith('Tmpl');
}
if (!t.isBinaryExpression(expr, { operator: '+' }) && !t.isLiteral(expr) && name.name === 'style' && !isConverted) {
const jsxID = path.findParent(p => p.isJSXOpeningElement()).get('name');
if (jsxID && jsxID.isJSXIdentifier() && constant_1.DEFAULT_Component_SET.has(jsxID.node.name)) {
exprPath.replaceWith(t.callExpression(t.identifier(constant_1.INTERNAL_INLINE_STYLE), [expr]));
}
}
if (name.name.startsWith('on')) {
if (exprPath.isReferencedIdentifier()) {
const ids = [expr.name];
const fullPath = buildFullPathThisPropsRef(expr, ids, path);
if (fullPath) {
exprPath.replaceWith(fullPath);
}
}
if (exprPath.isReferencedMemberExpression()) {
const id = utils_1.findFirstIdentifierFromMemberExpression(expr);
const ids = getIdsFromMemberProps(expr);
if (t.isIdentifier(id)) {
const fullPath = buildFullPathThisPropsRef(id, ids, path);
if (fullPath) {
exprPath.replaceWith(fullPath);
}
}
}
// @TODO: bind 的处理待定
}
},
ImportDeclaration(path) {
const source = path.node.source.value;
if (importSources.has(source)) {
throw utils_1.codeFrameError(path.node, '无法在同一文件重复 import 相同的包。');
}
else {
importSources.add(source);
}
const names = [];
if (source === constant_1.TARO_PACKAGE_NAME) {
isImportTaro = true;
path.node.specifiers.push(t.importSpecifier(t.identifier(constant_1.INTERNAL_SAFE_GET), t.identifier(constant_1.INTERNAL_SAFE_GET)), t.importSpecifier(t.identifier(constant_1.INTERNAL_GET_ORIGNAL), t.identifier(constant_1.INTERNAL_GET_ORIGNAL)), t.importSpecifier(t.identifier(constant_1.INTERNAL_INLINE_STYLE), t.identifier(constant_1.INTERNAL_INLINE_STYLE)), t.importSpecifier(t.identifier(constant_1.GEL_ELEMENT_BY_ID), t.identifier(constant_1.GEL_ELEMENT_BY_ID)));
}
if (source === constant_1.REDUX_PACKAGE_NAME || source === constant_1.MOBX_PACKAGE_NAME) {
path.node.specifiers.forEach((s, index, specs) => {
if (s.local.name === 'Provider') {
specs.splice(index, 1);
specs.push(t.importSpecifier(t.identifier('setStore'), t.identifier('setStore')));
}
});
}
path.traverse({
ImportDefaultSpecifier(path) {
const name = path.node.local.name;
names.push(name);
},
ImportSpecifier(path) {
const name = path.node.imported.name;
names.push(name);
if (source === constant_1.TARO_PACKAGE_NAME && name === 'Component') {
path.node.local = t.identifier('__BaseComponent');
}
}
});
componentSourceMap.set(source, names);
}
});
if (!isImportTaro) {
ast.program.body.unshift(t.importDeclaration([
t.importDefaultSpecifier(t.identifier('Taro')),
t.importSpecifier(t.identifier(constant_1.INTERNAL_SAFE_GET), t.identifier(constant_1.INTERNAL_SAFE_GET)),
t.importSpecifier(t.identifier(constant_1.INTERNAL_GET_ORIGNAL), t.identifier(constant_1.INTERNAL_GET_ORIGNAL)),
t.importSpecifier(t.identifier(constant_1.INTERNAL_INLINE_STYLE), t.identifier(constant_1.INTERNAL_INLINE_STYLE))
], t.stringLiteral('@tarojs/taro')));
}
if (!mainClass) {
throw new Error('未找到 Taro.Component 的类定义');
}
mainClass.node.body.body.forEach(handleThirdPartyComponent);
const storeBinding = mainClass.scope.getBinding(storeName);
mainClass.scope.rename('Component', '__BaseComponent');
if (storeBinding) {
const statementPath = storeBinding.path.getStatementParent();
if (statementPath) {
ast.program.body.forEach((node, index, body) => {
if (node === statementPath.node) {
body.splice(index + 1, 0, t.expressionStatement(t.callExpression(t.identifier('setStore'), [
t.identifier(storeName)
])));
}
});
}
}
resetTSClassProperty(mainClass.node.body.body);
if (options.isApp) {
renderMethod.replaceWith(t.classMethod('method', t.identifier('_createData'), [], t.blockStatement([])));
return { ast };
}
result = new class_1.Transformer(mainClass, options.sourcePath, componentProperies).result;
result.code = babel_generator_1.default(ast).code;
result.ast = ast;
const lessThanSignReg = new RegExp(constant_1.lessThanSignPlacehold, 'g');
result.compressedTemplate = result.template;
result.template = html_1.prettyPrint(result.template, {
max_char: 0,
unformatted: process.env.NODE_ENV === 'test' ? [] : ['text']
});
result.template = result.template.replace(lessThanSignReg, '<');
result.imageSrcs = Array.from(imageSource);
return result;
}
exports.default = transform;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,258 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const babel_generator_1 = require("babel-generator");
const t = require("babel-types");
const lodash_1 = require("lodash");
const constant_1 = require("./constant");
const create_html_element_1 = require("./create-html-element");
const utils_1 = require("./utils");
const adapter_1 = require("./adapter");
function isStartWithWX(str) {
return str[0] === 'w' && str[1] === 'x';
}
exports.isStartWithWX = isStartWithWX;
const specialComponentName = ['block', 'Block', 'slot', 'Slot'];
function removeJSXThisProperty(path) {
if (!path.parentPath.isCallExpression()) {
const p = path.getSibling('property');
if (p.isIdentifier({ name: 'props' }) ||
p.isIdentifier({ name: 'state' })) {
path.parentPath.replaceWithSourceString('this');
}
else {
path.parentPath.replaceWith(p);
}
}
}
exports.removeJSXThisProperty = removeJSXThisProperty;
function findJSXAttrByName(attrs, name) {
for (const attr of attrs) {
if (!t.isJSXIdentifier(attr.name)) {
break;
}
if (attr.name.name === name) {
return attr;
}
}
return null;
}
exports.findJSXAttrByName = findJSXAttrByName;
function buildRefTemplate(name, refName, loop, key) {
const attrs = [
t.jSXAttribute(t.jSXIdentifier('is'), t.stringLiteral(name)),
t.jSXAttribute(t.jSXIdentifier('data'), t.stringLiteral(`{{...${refName ? `${loop ? '' : '$$'}${refName}` : '__data'}}}`))
];
if (key) {
attrs.push(key);
}
return t.jSXElement(t.jSXOpeningElement(t.jSXIdentifier('template'), attrs), t.jSXClosingElement(t.jSXIdentifier('template')), []);
}
exports.buildRefTemplate = buildRefTemplate;
function buildJSXAttr(name, value) {
return t.jSXAttribute(t.jSXIdentifier(name), t.jSXExpressionContainer(value));
}
exports.buildJSXAttr = buildJSXAttr;
function newJSXIfAttr(jsx, value) {
jsx.openingElement.attributes.push(buildJSXAttr(adapter_1.Adapter.if, value));
}
exports.newJSXIfAttr = newJSXIfAttr;
function setJSXAttr(jsx, name, value, path) {
const element = jsx.openingElement;
if (!t.isJSXIdentifier(element.name)) {
return;
}
if (element.name.name === 'Block' || element.name.name === 'block' || !path) {
jsx.openingElement.attributes.push(t.jSXAttribute(t.jSXIdentifier(name), value));
}
else {
const block = buildBlockElement();
setJSXAttr(block, name, value);
block.children = [jsx];
path.node = block;
}
}
exports.setJSXAttr = setJSXAttr;
function isAllLiteral(...args) {
return args.every(p => t.isLiteral(p));
}
exports.isAllLiteral = isAllLiteral;
function buildBlockElement() {
return t.jSXElement(t.jSXOpeningElement(t.jSXIdentifier('block'), []), t.jSXClosingElement(t.jSXIdentifier('block')), []);
}
exports.buildBlockElement = buildBlockElement;
function parseJSXChildren(children) {
return children
.filter(child => {
return !(t.isJSXText(child) && child.value.trim() === '');
})
.reduce((str, child) => {
if (t.isJSXText(child)) {
const strings = [];
child.value.split(/(\r?\n\s*)/).forEach((val) => {
const value = val.replace(/\u00a0/g, '&nbsp;').trimLeft();
if (!value) {
return;
}
if (value.startsWith('\n')) {
return;
}
strings.push(value);
});
return str + strings.join('');
}
if (t.isJSXElement(child)) {
return str + parseJSXElement(child);
}
if (t.isJSXExpressionContainer(child)) {
if (t.isJSXElement(child.expression)) {
return str + parseJSXElement(child.expression);
}
return str + `{${utils_1.decodeUnicode(babel_generator_1.default(child, {
quotes: 'single',
jsonCompatibleStrings: true
})
.code)
.replace(/(this\.props\.)|(this\.state\.)/g, '')
.replace(/(props\.)|(state\.)/g, '')
.replace(/this\./g, '')
.replace(/</g, constant_1.lessThanSignPlacehold)}}`;
}
return str;
}, '');
}
function parseJSXElement(element) {
const children = element.children;
const { attributes, name } = element.openingElement;
const TRIGGER_OBSERER = adapter_1.Adapter.type === "swan" /* swan */ ? 'privateTriggerObserer' : '__triggerObserer';
if (t.isJSXMemberExpression(name)) {
throw utils_1.codeFrameError(name.loc, '暂不支持 JSX 成员表达式');
}
const componentName = name.name;
const isDefaultComponent = constant_1.DEFAULT_Component_SET.has(componentName);
const componentSpecialProps = constant_1.SPECIAL_COMPONENT_PROPS.get(componentName);
const componentTransfromProps = constant_1.TRANSFORM_COMPONENT_PROPS.get(adapter_1.Adapter.type);
let hasElseAttr = false;
attributes.forEach((a, index) => {
if (a.name.name === adapter_1.Adapter.else && !['block', 'Block'].includes(componentName) && !isDefaultComponent) {
hasElseAttr = true;
attributes.splice(index, 1);
}
});
if (hasElseAttr) {
return create_html_element_1.createHTMLElement({
name: 'block',
attributes: {
[adapter_1.Adapter.else]: true
},
value: parseJSXChildren([element])
});
}
let attributesTrans = {};
if (attributes.length) {
attributesTrans = attributes.reduce((obj, attr) => {
if (t.isJSXSpreadAttribute(attr)) {
throw utils_1.codeFrameError(attr.loc, 'JSX 参数暂不支持 ...spread 表达式');
}
let name = attr.name.name;
if (constant_1.DEFAULT_Component_SET.has(componentName)) {
if (name === 'className') {
name = 'class';
}
}
let value = true;
let attrValue = attr.value;
if (typeof name === 'string') {
const isAlipayEvent = adapter_1.Adapter.type === "alipay" /* alipay */ && /(^on[A-Z_])|(^catch[A-Z_])/.test(name);
if (t.isStringLiteral(attrValue)) {
value = attrValue.value;
}
else if (t.isJSXExpressionContainer(attrValue)) {
let isBindEvent = (name.startsWith('bind') && name !== 'bind') || (name.startsWith('catch') && name !== 'catch');
let code = utils_1.decodeUnicode(babel_generator_1.default(attrValue.expression, {
quotes: 'single',
concise: true
}).code)
.replace(/"/g, "'")
.replace(/(this\.props\.)|(this\.state\.)/g, '')
.replace(/this\./g, '');
if ("swan" /* swan */ === adapter_1.Adapter.type &&
code !== 'true' &&
code !== 'false' &&
constant_1.swanSpecialAttrs[componentName] &&
constant_1.swanSpecialAttrs[componentName].includes(name)) {
value = `{= ${code} =}`;
}
else {
if (adapter_1.Adapter.key === name) {
const splitCode = code.split('.');
if (splitCode.length > 1) {
value = splitCode.slice(1).join('.');
}
else {
value = code;
}
}
else {
value = isBindEvent || isAlipayEvent ? code : `{{${code}}}`;
}
}
if (adapter_1.Adapter.type === "swan" /* swan */ && name === adapter_1.Adapter.for) {
value = code;
}
if (t.isStringLiteral(attrValue.expression)) {
value = attrValue.expression.value;
}
}
else if (attrValue === null && name !== adapter_1.Adapter.else) {
value = `{{true}}`;
}
if (constant_1.THIRD_PARTY_COMPONENTS.has(componentName) && /^bind/.test(name) && name.includes('-')) {
name = name.replace(/^bind/, 'bind:');
}
if (componentTransfromProps && componentTransfromProps[componentName]) {
const transfromProps = componentTransfromProps[componentName];
Object.keys(transfromProps).forEach(oriName => {
if (transfromProps.hasOwnProperty(name)) {
name = transfromProps[oriName];
}
});
}
if ((componentName === 'Input' || componentName === 'input') && name === 'maxLength') {
obj['maxlength'] = value;
}
else if (componentSpecialProps && componentSpecialProps.has(name) ||
name.startsWith('__fn_') ||
isAlipayEvent) {
obj[name] = value;
}
else {
obj[isDefaultComponent && !name.includes('-') && !name.includes(':') ? lodash_1.kebabCase(name) : name] = value;
}
}
// if (!isDefaultComponent && !specialComponentName.includes(componentName)) {
// obj[TRIGGER_OBSERER] = '{{ _triggerObserer }}';
// }
return obj;
}, {});
}
// else if (!isDefaultComponent && !specialComponentName.includes(componentName)) {
// attributesTrans[TRIGGER_OBSERER] = '{{ _triggerObserer }}';
// }
return create_html_element_1.createHTMLElement({
name: lodash_1.kebabCase(componentName),
attributes: attributesTrans,
value: parseJSXChildren(children)
});
}
exports.parseJSXElement = parseJSXElement;
function generateHTMLTemplate(template, name) {
return create_html_element_1.createHTMLElement({
name: 'template',
attributes: {
name
},
value: parseJSXElement(template)
});
}
exports.generateHTMLTemplate = generateHTMLTemplate;
//# sourceMappingURL=jsx.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Lifecycle;
(function (Lifecycle) {
Lifecycle["constructor"] = "constructor";
Lifecycle["componentWillMount"] = "componentWillMount";
Lifecycle["componentDidMount"] = "componentDidMount";
Lifecycle["componentWillUpdate"] = "componentWillUpdate";
Lifecycle["componentDidUpdate"] = "componentDidUpdate";
Lifecycle["componentWillUnmount"] = "componentWillUnmount";
Lifecycle["componentDidCatch"] = "componentDidCatch";
Lifecycle["componentDidShow"] = "componentDidShow";
Lifecycle["componentDidHide"] = "componentDidHide";
Lifecycle["componentDidAttached"] = "componentDidAttached";
Lifecycle["componentDidMoved"] = "componentDidMoved";
Lifecycle["shouldComponentUpdate"] = "shouldComponentUpdate";
Lifecycle["componentWillReceiveProps"] = "componentWillReceiveProps";
})(Lifecycle = exports.Lifecycle || (exports.Lifecycle = {}));
exports.PageLifecycle = {
[Lifecycle.componentDidMount]: 'onLaunch',
[Lifecycle.componentWillMount]: 'onLoad',
[Lifecycle.componentWillUnmount]: 'onUnload',
[Lifecycle.componentDidShow]: 'onShow',
[Lifecycle.componentDidHide]: 'onHide'
};
exports.ComponentLifeCycle = {
[Lifecycle.componentWillMount]: 'created',
[Lifecycle.componentDidAttached]: 'attached',
[Lifecycle.componentDidMount]: 'ready',
[Lifecycle.componentDidMoved]: 'moved',
[Lifecycle.componentWillUnmount]: 'detached'
};
//# sourceMappingURL=lifecycle.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":";;AAAA,IAAY,SAcX;AAdD,WAAY,SAAS;IACnB,wCAA2B,CAAA;IAC3B,sDAAyC,CAAA;IACzC,oDAAuC,CAAA;IACvC,wDAA2C,CAAA;IAC3C,sDAAyC,CAAA;IACzC,0DAA6C,CAAA;IAC7C,oDAAuC,CAAA;IACvC,kDAAqC,CAAA;IACrC,kDAAqC,CAAA;IACrC,0DAA6C,CAAA;IAC7C,oDAAuC,CAAA;IACvC,4DAA+C,CAAA;IAC/C,oEAAuD,CAAA;AACzD,CAAC,EAdW,SAAS,GAAT,iBAAS,KAAT,iBAAS,QAcpB;AAEY,QAAA,aAAa,GAAG;IAC3B,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,UAAU;IACzC,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE,QAAQ;IACxC,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,UAAU;IAC5C,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,QAAQ;IACtC,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,QAAQ;CACvC,CAAA;AAEY,QAAA,kBAAkB,GAAG;IAChC,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE,SAAS;IACzC,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,UAAU;IAC5C,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,OAAO;IACtC,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,OAAO;IACtC,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,UAAU;CAC7C,CAAA"}

View File

@ -0,0 +1,227 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const t = require("babel-types");
const utils_1 = require("./utils");
const jsx_1 = require("./jsx");
const constant_1 = require("./constant");
const adapter_1 = require("./adapter");
// @TODO
// 重构 parseRender 和 parseLoop 失败
// 尚不清楚 babel 的 state 和 context 传参机制
// 目前先写两份代码,有时间看看 babel 具体对 state 和 context 做了什么导致传参失败
function parseLoopBody(body, jsxDeclarations,
// @TODO
// 把 templates 换成 Map 可以支持 shalow variables declared
// 现在先用 ESLint 的 no-shalow 顶着
templates, loopScopes, finalReturnElement, returnedPaths) {
const bodyScope = body.scope;
body.traverse({
JSXElement(jsxElementPath) {
const parentNode = jsxElementPath.parent;
const parentPath = jsxElementPath.parentPath;
const isFinalReturn = jsxElementPath.getFunctionParent().isClassMethod();
const isJSXChildren = t.isJSXElement(parentNode);
if (!isJSXChildren) {
let statementParent = jsxElementPath.getStatementParent();
if (!(statementParent.isVariableDeclaration() ||
statementParent.isExpressionStatement())) {
statementParent = statementParent.findParent(s => s.isVariableDeclaration() || s.isExpressionStatement());
}
jsxDeclarations.add(statementParent);
if (t.isVariableDeclarator(parentNode)) {
if (statementParent) {
const name = utils_1.findIdentifierFromStatement(statementParent.node);
// setTemplate(name, path, templates)
name && templates.set(name, jsxElementPath.node);
}
}
else if (t.isLogicalExpression(parentNode)) {
const { left, operator } = parentNode;
if (operator === '&&') {
if (t.isExpression(left)) {
utils_1.newJSXIfAttr(jsxElementPath.node, left);
parentPath.replaceWith(jsxElementPath.node);
if (statementParent) {
const name = utils_1.findIdentifierFromStatement(statementParent.node);
utils_1.setTemplate(name, jsxElementPath, templates);
// name && templates.set(name, path.node)
}
}
}
}
else if (t.isConditionalExpression(parentNode)) {
const { test, consequent, alternate } = parentNode;
const block = jsx_1.buildBlockElement();
if (t.isJSXElement(consequent) && t.isLiteral(alternate)) {
const { value, confident } = parentPath.get('alternate').evaluate();
if (confident && !value) {
utils_1.newJSXIfAttr(block, test);
block.children = [jsxElementPath.node];
// newJSXIfAttr(jsxElementPath.node, test)
parentPath.replaceWith(block);
if (statementParent) {
const name = utils_1.findIdentifierFromStatement(statementParent.node);
utils_1.setTemplate(name, jsxElementPath, templates);
// name && templates.set(name, path.node)
}
}
}
else if (t.isLiteral(consequent) && t.isJSXElement(consequent)) {
if (t.isNullLiteral(consequent)) {
utils_1.newJSXIfAttr(block, utils_1.reverseBoolean(test));
// newJSXIfAttr(jsxElementPath.node, reverseBoolean(test))
parentPath.replaceWith(block);
if (statementParent) {
const name = utils_1.findIdentifierFromStatement(statementParent.node);
utils_1.setTemplate(name, jsxElementPath, templates);
// name && templates.set(name, path.node)
}
}
}
else if (t.isJSXElement(consequent) && t.isJSXElement(alternate)) {
const block2 = jsx_1.buildBlockElement();
block.children = [consequent];
utils_1.newJSXIfAttr(block, test);
jsx_1.setJSXAttr(block2, adapter_1.Adapter.else);
block2.children = [alternate];
const parentBlock = jsx_1.buildBlockElement();
parentBlock.children = [block, block2];
parentPath.replaceWith(parentBlock);
if (statementParent) {
const name = utils_1.findIdentifierFromStatement(statementParent.node);
utils_1.setTemplate(name, jsxElementPath, templates);
}
}
else {
// console.log('todo')
}
}
else if (t.isReturnStatement(parentNode)) {
if (!isFinalReturn) {
const caller = parentPath.findParent(p => p.isCallExpression());
if (caller.isCallExpression()) {
const callee = caller.node.callee;
if (t.isMemberExpression(callee) &&
t.isIdentifier(callee.property) &&
callee.property.name === 'map') {
let ary = callee.object;
const blockStatementPath = parentPath.findParent(p => p.isBlockStatement());
const body = blockStatementPath.node.body;
let stateToBeAssign = new Set();
for (const statement of body) {
if (t.isVariableDeclaration(statement)) {
for (const dcl of statement.declarations) {
if (t.isIdentifier(dcl.id)) {
const scope = blockStatementPath.scope;
const stateName = scope.generateUid(constant_1.LOOP_STATE);
stateToBeAssign.add(stateName);
blockStatementPath.scope.rename(dcl.id.name, stateName);
}
}
}
}
if (t.isCallExpression(ary) || utils_1.isContainFunction(caller.get('callee').get('object'))) {
const variableName = `anonymousState_${bodyScope.generateUid()}`;
caller.getStatementParent().insertBefore(utils_1.buildConstVariableDeclaration(variableName, ary));
ary = t.identifier(variableName);
}
jsx_1.setJSXAttr(jsxElementPath.node, adapter_1.Adapter.for, t.jSXExpressionContainer(ary));
const [func] = caller.node.arguments;
if (t.isFunctionExpression(func) ||
t.isArrowFunctionExpression(func)) {
const [item, index] = func.params;
if (t.isIdentifier(item)) {
jsx_1.setJSXAttr(jsxElementPath.node, adapter_1.Adapter.forItem, t.stringLiteral(item.name));
loopScopes.add(item.name);
}
else {
jsx_1.setJSXAttr(jsxElementPath.node, adapter_1.Adapter.forItem, t.stringLiteral('__item'));
}
if (t.isIdentifier(index)) {
jsx_1.setJSXAttr(jsxElementPath.node, adapter_1.Adapter.forIndex, t.stringLiteral(index.name));
loopScopes.add(index.name);
}
caller.replaceWith(jsxElementPath.node);
if (statementParent) {
const name = utils_1.findIdentifierFromStatement(statementParent.node);
// setTemplate(name, path, templates)
name && templates.set(name, jsxElementPath.node);
}
}
}
}
}
else {
const ifStatement = parentPath.findParent(p => p.isIfStatement());
const blockStatement = parentPath.findParent(p => p.isBlockStatement());
const block = finalReturnElement || jsx_1.buildBlockElement();
if (utils_1.isBlockIfStatement(ifStatement, blockStatement)) {
const { test, alternate, consequent } = ifStatement.node;
if (alternate === blockStatement.node) {
throw utils_1.codeFrameError(parentNode.loc, '不必要的 else 分支,请遵从 ESLint consistent-return: https://eslint.org/docs/rules/consistent-return');
}
else if (consequent === blockStatement.node) {
const parentIfStatement = ifStatement.findParent(p => p.isIfStatement());
if (parentIfStatement) {
jsx_1.setJSXAttr(jsxElementPath.node, adapter_1.Adapter.elseif, t.jSXExpressionContainer(test));
}
else {
utils_1.newJSXIfAttr(jsxElementPath.node, test);
}
}
}
else if (block.children.length !== 0) {
jsx_1.setJSXAttr(jsxElementPath.node, adapter_1.Adapter.else);
}
block.children.push(jsxElementPath.node);
finalReturnElement = block;
returnedPaths.push(parentPath);
}
}
else if (t.isArrowFunctionExpression(parentNode)) {
//
}
else if (t.isAssignmentExpression(parentNode)) {
if (t.isIdentifier(parentNode.left)) {
const name = parentNode.left.name;
const bindingNode = bodyScope.getOwnBinding(name).path.node;
const block = templates.get(name) || jsx_1.buildBlockElement();
if (utils_1.isEmptyDeclarator(bindingNode)) {
const ifStatement = parentPath.findParent(p => p.isIfStatement());
const blockStatement = parentPath.findParent(p => p.isBlockStatement());
if (utils_1.isBlockIfStatement(ifStatement, blockStatement)) {
const { test, alternate, consequent } = ifStatement.node;
if (alternate === blockStatement.node) {
jsx_1.setJSXAttr(jsxElementPath.node, adapter_1.Adapter.else);
}
else if (consequent === blockStatement.node) {
const parentIfStatement = ifStatement.findParent(p => p.isIfStatement());
if (parentIfStatement && parentIfStatement.get('alternate') === ifStatement) {
jsx_1.setJSXAttr(jsxElementPath.node, adapter_1.Adapter.elseif, t.jSXExpressionContainer(test));
}
else {
if (parentIfStatement) {
utils_1.newJSXIfAttr(block, parentIfStatement.node.test);
}
utils_1.newJSXIfAttr(jsxElementPath.node, test);
}
}
block.children.push(jsxElementPath.node);
// setTemplate(name, path, templates)
name && templates.set(name, block);
}
}
else {
throw utils_1.codeFrameError(jsxElementPath.node.loc, '请将 JSX 赋值表达式初始化为 null然后再进行 if 条件表达式赋值。');
}
}
}
else if (!t.isJSXElement(parentNode)) {
// throwError(path, '考虑只对 JSX 元素赋值一次。')
}
}
}
});
}
exports.parseLoopBody = parseLoopBody;
//# sourceMappingURL=loop-component.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const eslint_1 = require("./eslint");
exports.transformOptions = {};
exports.setTransformOptions = (options) => {
for (const key in options) {
if (options.hasOwnProperty(key)) {
exports.transformOptions[key] = options[key];
}
}
};
exports.buildBabelTransformOptions = () => {
return {
parserOpts: {
sourceType: 'module',
plugins: [
'classProperties',
'jsx',
'flow',
'flowComment',
'trailingFunctionCommas',
'asyncFunctions',
'exponentiationOperator',
'asyncGenerators',
'objectRestSpread',
'decorators',
'dynamicImport'
]
},
plugins: [
require('babel-plugin-transform-flow-strip-types'),
[require('babel-plugin-transform-define').default, exports.transformOptions.env]
].concat(process.env.ESLINT === 'false' || exports.transformOptions.isNormal || exports.transformOptions.isTyped ? [] : eslint_1.eslintValidation)
.concat((process.env.NODE_ENV === 'test') ? [] : require('babel-plugin-remove-dead-code').default)
};
};
//# sourceMappingURL=options.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/options.ts"],"names":[],"mappings":";;AACA,qCAA2C;AAgB9B,QAAA,gBAAgB,GAAY,EAAS,CAAA;AAErC,QAAA,mBAAmB,GAAG,CAAC,OAAgB,EAAE,EAAE;IACtD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE;QACzB,IAAI,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;YAC/B,wBAAgB,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;SACrC;KACF;AACH,CAAC,CAAA;AAEY,QAAA,0BAA0B,GAA2B,GAAG,EAAE;IACrE,OAAO;QACL,UAAU,EAAE;YACV,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE;gBACP,iBAAiB;gBACjB,KAAK;gBACL,MAAM;gBACN,aAAa;gBACb,wBAAwB;gBACxB,gBAAgB;gBAChB,wBAAwB;gBACxB,iBAAiB;gBACjB,kBAAkB;gBAClB,YAAY;gBACZ,eAAe;aACP;SACX;QACD,OAAO,EAAE;YACP,OAAO,CAAC,yCAAyC,CAAC;YAClD,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,OAAO,EAAE,wBAAgB,CAAC,GAAG,CAAC;SACzE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,OAAO,IAAI,wBAAgB,CAAC,QAAQ,IAAI,wBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,yBAAgB,CAAC;aACxH,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,OAAO,CAAC;KACnG,CAAA;AACH,CAAC,CAAA"}

View File

@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const t = require("babel-types");
function isString(node) {
return t.isLiteral(node) && typeof node.value === 'string';
}
function buildBinaryExpression(left, right) {
return t.binaryExpression('+', left, right);
}
function templateLiterals(path, state) {
let nodes = [];
const expressions = path.get('expressions');
for (const elem of (path.node.quasis)) {
nodes.push(t.stringLiteral(elem.value.cooked));
const expr = expressions.shift();
if (expr) {
// tslint:disable-next-line:no-multi-spaces
if (state.opts.spec && !expr.isBaseType('string') && !expr.isBaseType('number')) {
nodes.push(t.callExpression(t.identifier('String'), [expr.node]));
}
else {
nodes.push(expr.node);
}
}
}
// filter out empty string literals
nodes = nodes.filter((n) => !t.isLiteral(n, { value: '' }));
// since `+` is left-to-right associative
// ensure the first node is a string if first/second isn't
if (!isString(nodes[0]) && !isString(nodes[1])) {
nodes.unshift(t.stringLiteral(''));
}
if (nodes.length > 1) {
let root = buildBinaryExpression(nodes.shift(), nodes.shift());
for (const node of nodes) {
root = buildBinaryExpression(root, node);
}
path.replaceWith(root);
}
else {
path.replaceWith(nodes[0]);
}
}
exports.templateLiterals = templateLiterals;
//# sourceMappingURL=plugins.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/plugins.ts"],"names":[],"mappings":";;AAAA,iCAAgC;AAEhC,SAAS,QAAQ,CAAE,IAAI;IACrB,OAAO,CAAC,CAAC,SAAS,CAAC,IAAW,CAAC,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAA;AACnE,CAAC;AAED,SAAS,qBAAqB,CAAE,IAAI,EAAE,KAAK;IACzC,OAAO,CAAC,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;AAC7C,CAAC;AACD,SAAgB,gBAAgB,CAAE,IAAI,EAAE,KAAK;IAE3C,IAAI,KAAK,GAAkB,EAAE,CAAA;IAE7B,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IAE3C,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACrC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;QAE9C,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,CAAA;QAChC,IAAI,IAAI,EAAE;YACR,2CAA2C;YAC3C,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAG;gBAChF,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;aAClE;iBAAM;gBACL,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;aACtB;SACF;KACF;IAED,mCAAmC;IACnC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IAE3D,yCAAyC;IACzC,0DAA0D;IAC1D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAA;KACnC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;QACpB,IAAI,IAAI,GAAG,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;QAE9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,IAAI,GAAG,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;SACzC;QAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;KACvB;SAAM;QACL,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;KAC3B;AACH,CAAC;AAxCD,4CAwCC"}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,512 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const t = require("babel-types");
const babel_generator_1 = require("babel-generator");
const code_frame_1 = require("@babel/code-frame");
const constant_1 = require("./constant");
const lodash_1 = require("lodash");
const fs = require("fs");
const path = require("path");
const jsx_1 = require("./jsx");
const adapter_1 = require("./adapter");
const options_1 = require("./options");
const template = require('babel-template');
exports.incrementId = () => {
let id = 0;
return () => id++;
};
// tslint:disable-next-line:no-empty
exports.noop = function () { };
function getSuperClassCode(path) {
const superClass = path.node.superClass;
if (t.isIdentifier(superClass)) {
const binding = path.scope.getBinding(superClass.name);
if (binding && binding.kind === 'module') {
const bindingPath = binding.path.parentPath;
if (bindingPath.isImportDeclaration()) {
const source = bindingPath.node.source;
if (source.value === constant_1.TARO_PACKAGE_NAME) {
return;
}
try {
const p = pathResolver(source.value, options_1.transformOptions.sourcePath) + (options_1.transformOptions.isTyped ? '.tsx' : '.js');
const code = fs.readFileSync(p, 'utf8');
return {
code,
sourcePath: source.value
};
}
catch (error) {
return;
}
}
}
}
}
exports.getSuperClassCode = getSuperClassCode;
function isContainStopPropagation(path) {
let matched = false;
if (path) {
path.traverse({
Identifier(p) {
if (p.node.name === 'stopPropagation' &&
p.parentPath.parentPath.isCallExpression()) {
matched = true;
}
}
});
}
return matched;
}
exports.isContainStopPropagation = isContainStopPropagation;
function decodeUnicode(s) {
return unescape(s.replace(/\\(u[0-9a-fA-F]{4})/gm, '%$1'));
}
exports.decodeUnicode = decodeUnicode;
function isVarName(str) {
if (typeof str !== 'string') {
return false;
}
if (str.trim() !== str) {
return false;
}
try {
// tslint:disable-next-line:no-unused-expression
new Function(str, 'var ' + str);
}
catch (e) {
return false;
}
return true;
}
exports.isVarName = isVarName;
function findMethodName(expression) {
let methodName;
if (t.isIdentifier(expression) ||
t.isJSXIdentifier(expression)) {
methodName = expression.name;
}
else if (t.isStringLiteral(expression)) {
methodName = expression.value;
}
else if (t.isMemberExpression(expression) &&
t.isIdentifier(expression.property)) {
const { code } = babel_generator_1.default(expression);
const ids = code.split('.');
if (ids[0] === 'this' && ids[1] === 'props' && ids[2]) {
methodName = code.replace('this.props.', '');
}
else {
methodName = expression.property.name;
}
}
else if (t.isCallExpression(expression) &&
t.isMemberExpression(expression.callee) &&
t.isIdentifier(expression.callee.object)) {
methodName = expression.callee.object.name;
}
else if (t.isCallExpression(expression) &&
t.isMemberExpression(expression.callee) &&
t.isMemberExpression(expression.callee.object) &&
t.isIdentifier(expression.callee.property) &&
expression.callee.property.name === 'bind' &&
t.isIdentifier(expression.callee.object.property)) {
methodName = expression.callee.object.property.name;
}
else {
throw codeFrameError(expression.loc, '当 props 为事件时(props name 以 `on` 开头),只能传入一个 this 作用域下的函数。');
}
return methodName;
}
exports.findMethodName = findMethodName;
function setParentCondition(jsx, expr, array = false) {
const conditionExpr = jsx.findParent(p => p.isConditionalExpression());
const logicExpr = jsx.findParent(p => p.isLogicalExpression({ operator: '&&' }));
if (array) {
const ifAttrSet = new Set([
adapter_1.Adapter.if,
adapter_1.Adapter.else
]);
const logicalJSX = jsx.findParent(p => p.isJSXElement() && p.node.openingElement.attributes.some(a => ifAttrSet.has(a.name.name)));
if (logicalJSX) {
const attr = logicalJSX.node.openingElement.attributes.find(a => ifAttrSet.has(a.name.name));
if (attr) {
if (attr.name.name === adapter_1.Adapter.else) {
const prevElement = logicalJSX.getPrevSibling();
if (prevElement && prevElement.isJSXElement()) {
const attr = prevElement.node.openingElement.attributes.find(a => a.name.name === adapter_1.Adapter.if);
if (attr && t.isJSXExpressionContainer(attr.value)) {
expr = t.conditionalExpression(reverseBoolean(lodash_1.cloneDeep(attr.value.expression)), expr, t.arrayExpression());
return expr;
}
}
}
else if (t.isJSXExpressionContainer(attr.value)) {
expr = t.conditionalExpression(lodash_1.cloneDeep(attr.value.expression), expr, t.arrayExpression());
return expr;
}
}
}
}
if (conditionExpr && conditionExpr.isConditionalExpression()) {
const consequent = conditionExpr.get('consequent');
if (consequent === jsx || jsx.findParent(p => p === consequent)) {
expr = t.conditionalExpression(lodash_1.cloneDeep(conditionExpr.get('test').node), expr, array ? t.arrayExpression([]) : t.nullLiteral());
}
}
if (logicExpr && logicExpr.isLogicalExpression({ operator: '&&' })) {
const consequent = logicExpr.get('right');
if (consequent === jsx || jsx.findParent(p => p === consequent)) {
expr = t.conditionalExpression(lodash_1.cloneDeep(logicExpr.get('left').node), expr, array ? t.arrayExpression([]) : t.nullLiteral());
}
}
return expr;
}
exports.setParentCondition = setParentCondition;
function generateAnonymousState(scope, expression, refIds, isLogical) {
let variableName = `anonymousState_${scope.generateUid()}`;
let statementParent = expression.getStatementParent();
if (!statementParent) {
throw codeFrameError(expression.node.loc, '无法生成匿名 State尝试先把值赋到一个变量上再把变量调换。');
}
const jsx = isLogical ? expression : expression.findParent(p => p.isJSXElement());
const callExpr = jsx.findParent(p => p.isCallExpression() && isArrayMapCallExpression(p));
const ifExpr = jsx.findParent(p => p.isIfStatement());
const blockStatement = jsx.findParent(p => p.isBlockStatement() && p.parentPath === ifExpr);
const expr = setParentCondition(jsx, lodash_1.cloneDeep(expression.node));
if (!callExpr) {
refIds.add(t.identifier(variableName));
statementParent.insertBefore(buildConstVariableDeclaration(variableName, expr));
if (blockStatement && blockStatement.isBlockStatement()) {
blockStatement.traverse({
VariableDeclarator: (p) => {
const { id, init } = p.node;
if (t.isIdentifier(id) && !id.name.startsWith(constant_1.LOOP_STATE)) {
const newId = scope.generateDeclaredUidIdentifier('$' + id.name);
refIds.forEach((refId) => {
if (refId.name === variableName && !variableName.startsWith('_$')) {
refIds.delete(refId);
}
});
variableName = newId.name;
refIds.add(t.identifier(variableName));
blockStatement.scope.rename(id.name, newId.name);
p.parentPath.replaceWith(template('ID = INIT;')({ ID: newId, INIT: init }));
}
}
});
}
}
else {
variableName = `${constant_1.LOOP_STATE}_${callExpr.scope.generateUid()}`;
const func = callExpr.node.arguments[0];
if (t.isArrowFunctionExpression(func)) {
if (!t.isBlockStatement(func.body)) {
func.body = t.blockStatement([
buildConstVariableDeclaration(variableName, expr),
t.returnStatement(func.body)
]);
}
else {
if (ifExpr && ifExpr.isIfStatement() && ifExpr.findParent(p => p === callExpr)) {
const consequent = ifExpr.get('consequent');
const test = ifExpr.get('test');
if (consequent.isBlockStatement()) {
if (jsx === test || jsx.findParent(p => p === test)) {
func.body.body.unshift(buildConstVariableDeclaration(variableName, expr));
}
else {
func.body.body.unshift(t.variableDeclaration('let', [t.variableDeclarator(t.identifier(variableName), t.nullLiteral())]));
consequent.node.body.push(t.expressionStatement(t.assignmentExpression('=', t.identifier(variableName), expr)));
}
}
else {
throw codeFrameError(consequent.node, 'if 表达式的结果必须由一个花括号包裹');
}
}
else {
func.body.body.splice(func.body.body.length - 1, 0, buildConstVariableDeclaration(variableName, expr));
}
}
}
}
const id = t.identifier(variableName);
expression.replaceWith(id);
return id;
}
exports.generateAnonymousState = generateAnonymousState;
function isArrayMapCallExpression(callExpression) {
return callExpression &&
t.isCallExpression(callExpression.node) &&
t.isMemberExpression(callExpression.node.callee) &&
t.isIdentifier(callExpression.node.callee.property, { name: 'map' });
}
exports.isArrayMapCallExpression = isArrayMapCallExpression;
function buildConstVariableDeclaration(variableName, expresion) {
return t.variableDeclaration('const', [
t.variableDeclarator(t.identifier(variableName), expresion)
]);
}
exports.buildConstVariableDeclaration = buildConstVariableDeclaration;
function setTemplate(name, path, templates) {
const parentPath = path.parentPath;
const jsxChildren = parentPath.findParent(p => p.isJSXElement());
if (name && !jsxChildren) {
templates.set(name, path.node);
}
}
exports.setTemplate = setTemplate;
function isContainFunction(p) {
let bool = false;
p.traverse({
CallExpression() {
bool = true;
}
});
return bool;
}
exports.isContainFunction = isContainFunction;
function slash(input) {
const isExtendedLengthPath = /^\\\\\?\\/.test(input);
const hasNonAscii = /[^\u0000-\u0080]+/.test(input);
const hasChinese = /[^\u4e00-\u9fa5]+/.test(input); // has Chinese characters
if (isExtendedLengthPath || (hasNonAscii && !hasChinese)) {
return input;
}
return input.replace(/\\/g, '/');
}
function pathResolver(source, location) {
const extName = path.extname(source);
const promotedPath = source;
if (!['js', 'tsx'].includes(extName)) {
try {
const pathExist = fs.existsSync(path.resolve(path.dirname(location), source, 'index.js'));
const tsxPathExist = fs.existsSync(path.resolve(path.dirname(location), source, 'index.tsx'));
if (pathExist || tsxPathExist) {
let p = path.join(promotedPath, 'index');
if (!p.startsWith('.')) {
p = './' + p;
}
return slash(p);
}
return slash(promotedPath);
}
catch (error) {
return slash(promotedPath);
}
}
return slash(promotedPath.split('.').slice(0, -1).join('.'));
}
exports.pathResolver = pathResolver;
function codeFrameError(node, msg) {
let errMsg = '';
try {
errMsg = code_frame_1.codeFrameColumns(exports.setting.sourceCode, node && node.type && node.loc ? node.loc : node, {
highlightCode: true
});
}
catch (error) {
errMsg = 'failed to locate source';
}
return new Error(`${msg}
-----
${errMsg}`);
}
exports.codeFrameError = codeFrameError;
exports.setting = {
sourceCode: ''
};
function createUUID() {
return '$' + 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = Math.random() * 16 | 0;
let v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
}).replace(/-/g, '').slice(0, 8);
}
exports.createUUID = createUUID;
function createRandomLetters(n) {
const str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
return Array(n).join().split(',').map(function () { return str.charAt(Math.floor(Math.random() * str.length)); }).join('');
}
exports.createRandomLetters = createRandomLetters;
function isBlockIfStatement(ifStatement, blockStatement) {
return ifStatement && blockStatement &&
ifStatement.isIfStatement() &&
blockStatement.isBlockStatement();
}
exports.isBlockIfStatement = isBlockIfStatement;
function buildCodeFrame(code) {
return (loc) => code_frame_1.codeFrameColumns(code, loc);
}
exports.buildCodeFrame = buildCodeFrame;
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
exports.isNumeric = isNumeric;
function buildJSXAttr(name, value) {
return t.jSXAttribute(t.jSXIdentifier(name), t.jSXExpressionContainer(value));
}
exports.buildJSXAttr = buildJSXAttr;
function newJSXIfAttr(jsx, value, path) {
const element = jsx.openingElement;
if (!t.isJSXIdentifier(element.name)) {
return;
}
if (element.name.name === 'Block' || element.name.name === 'block' || !path) {
element.attributes.push(buildJSXAttr(adapter_1.Adapter.if, value));
}
else {
const block = jsx_1.buildBlockElement();
newJSXIfAttr(block, value);
block.children.push(jsx);
path.node = block;
}
}
exports.newJSXIfAttr = newJSXIfAttr;
function getSlotName(name) {
return name.slice(6).toLowerCase();
}
exports.getSlotName = getSlotName;
function isContainJSXElement(path) {
let matched = false;
path.traverse({
JSXElement(p) {
matched = true;
p.stop();
}
});
return matched;
}
exports.isContainJSXElement = isContainJSXElement;
function hasComplexExpression(path) {
let matched = false;
if (isContainJSXElement(path)) {
return false;
}
if (path.isObjectExpression()) {
return true;
}
if (path.isTemplateLiteral() || path.isCallExpression()) {
return true;
}
if (path.isArrayExpression()) {
const { elements } = path.node;
if (elements.some(el => t.isObjectExpression(el) || t.isArrayExpression(el))) {
return true;
}
}
path.traverse({
CallExpression: (p) => {
matched = true;
p.stop();
},
TemplateLiteral(p) {
matched = true;
p.stop();
},
ObjectExpression(p) {
matched = true;
p.stop();
},
ArrayExpression(p) {
const { elements } = p.node;
if (elements.some(el => t.isObjectExpression(el))) {
return true;
}
},
TaggedTemplateExpression(p) {
matched = true;
p.stop();
},
MemberExpression(path) {
const jsxElement = path.findParent(p => p.isJSXExpressionContainer());
const object = path.get('object');
const property = path.get('property');
const parentPath = path.parentPath;
if (jsxElement &&
object.isThisExpression() &&
property.isIdentifier({ name: 'state' }) &&
parentPath.isMemberExpression() &&
parentPath.parentPath.isMemberExpression()) {
const sourceCode = parentPath.parentPath.getSource();
if (sourceCode.includes('[') && sourceCode.includes(']')) {
matched = true;
path.stop();
}
}
}
});
return matched;
}
exports.hasComplexExpression = hasComplexExpression;
function findFirstIdentifierFromMemberExpression(node, member) {
let id;
let object = node.object;
while (true) {
if (t.identifier(object) && !t.isMemberExpression(object)) {
id = object;
if (member) {
object = member;
}
break;
}
object = object.object;
}
return id;
}
exports.findFirstIdentifierFromMemberExpression = findFirstIdentifierFromMemberExpression;
function getArgumentName(arg) {
if (t.isThisExpression(arg)) {
return 'this';
}
else if (t.isNullLiteral(arg)) {
return 'null';
}
else if (t.isStringLiteral(arg) || t.isNumericLiteral(arg)) {
return arg.value;
}
else if (t.isIdentifier(arg)) {
return arg.name;
}
else {
return babel_generator_1.default(arg).code;
}
throw new Error(`bind 不支持传入该参数: ${arg}`);
}
exports.getArgumentName = getArgumentName;
function isAllLiteral(...args) {
return args.every(p => t.isLiteral(p));
}
exports.isAllLiteral = isAllLiteral;
function reverseBoolean(expression) {
return t.unaryExpression('!', expression);
}
exports.reverseBoolean = reverseBoolean;
function isEmptyDeclarator(node) {
if (t.isVariableDeclarator(node) &&
(node.init === null ||
t.isNullLiteral(node.init))) {
return true;
}
return false;
}
exports.isEmptyDeclarator = isEmptyDeclarator;
function toLetters(num) {
let mod = num % 26;
let pow = num / 26 | 0;
let out = mod ? String.fromCharCode(64 + mod) : (--pow, 'Z');
const letter = pow ? toLetters(pow) + out : out;
return letter.toLowerCase();
}
exports.toLetters = toLetters;
function findIdentifierFromStatement(statement) {
if (t.isVariableDeclaration(statement)) {
const declarator = statement.declarations.find(s => t.isIdentifier(s.id));
if (declarator && t.isIdentifier(declarator.id)) {
return declarator.id.name;
}
}
return '__return';
}
exports.findIdentifierFromStatement = findIdentifierFromStatement;
//# sourceMappingURL=utils.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,74 @@
/* mp-jsx v0.1.0
base on taro-transformer-wx v1.2.22
https://github.com/NervJS/taro/tree/master/packages/taro-transformer-wx
*/
const jsx2wxml = require('../jsx2wxml')
const fs = require('fs')
const path = require('path')
function buildComponent(code) {
return `
class WeElement {
render () {
return ${code}
}
}
`
}
const baseOptions = {
isRoot: false,
isApp: false,
sourcePath: __dirname,
outputPath: __dirname,
code: '',
isTyped: false
}
let { template } = jsx2wxml.default({
...baseOptions,
code: buildComponent(fs.readFileSync(path.join(__dirname, "./test.jsx"), 'utf8'))
})
console.log(template ===
`<block>
<view>show</view>
</block>`)
template = jsx2wxml.default({
...baseOptions,
code: buildComponent(fs.readFileSync(path.join(__dirname, "./test.1.jsx"), 'utf8'))
}).template
console.log(template ===
`<block>
<block>
<block wx:if="{{bb}}">
<view>show</view>
</block>
<block wx:else>
<view>hide</view>
</block>
</block>
</block>`)
template = jsx2wxml.default({
...baseOptions,
code: buildComponent(fs.readFileSync(path.join(__dirname, "./test.2.jsx"), 'utf8'))
}).template
console.log(template ===
`<block>
<view>
<view bindtap="onTap" wx:for="{{array}}" wx:for-item="item" wx:for-index="_anonIdx"><text>{{item.name}}</text>
</view>
</view>
</block>`)

View File

@ -0,0 +1 @@
bb?<view>show</view>:<view>hide</view>

View File

@ -0,0 +1,7 @@
<view>
{array.map(item => (
<view onTap={this.onTap}>
<text>{item.name}</text>
</view>
))}
</view>

View File

@ -0,0 +1 @@
<view>show</view>

View File

@ -3,9 +3,24 @@
"version": "1.0.0",
"scripts": {
"tsc": "./node_modules/typescript/bin/tsc",
"compile": "tsc"
"compile": "tsc",
"start": "gulp",
"_test": "node _scripts/test/index.js"
},
"devDependencies": {
"typescript": "^3.1.6"
},
"dependencies": {
"@babel/code-frame": "^7.0.0",
"@tarojs/transformer-wx": "^1.2.22",
"babel-core": "^6.26.3",
"babel-generator": "^6.26.1",
"babel-template": "^6.26.0",
"babel-traverse": "^6.26.0",
"babel-types": "^6.26.0",
"gulp": "^3.9.1",
"gulp-tap": "^1.0.1",
"gulp-watch": "^5.0.1",
"lodash": "^4.17.11"
}
}