Skip to content

Commit

Permalink
[RELEASE] JSX2MP @ 0919 (#1341)
Browse files Browse the repository at this point in the history
* chore: bump jsx-compiler version

* fix: render style tag in list

* chore: remove redundance code

* fix: path is not found (#1345)

* fix: path is not found

* fix: path is not found

* fix: cli copy files 

* fix: copy npm files with version conflict (probably work with npm)

* fix: copy npm files with version conflict (work with tnpm)

* fix: copy asset files (images) when imported

* fix: remove rax-recyclerview import in .js file

* fix: replace rax dependency with jsx2mp-runtime in single file

* fix: keep fn name to polyfill alipay miniapp environment

* fix: can't get rootNpmRelativePath in babel-plugin-rename-import file

* test: add test case for importing static assets

* ci: fix lint error (#1373)

* fix: path problem in single js file and npm file (only work with npm) (#1377)

* fix: path problem in single js file and npm file (only work with npm)

* refactor: remove redundant code in path calculation

* chore: add comment of transformCode params

* fix: remove useless code

* refactor: rework list (#1379)

* fix: path is not found

* chore: rework list

* chore: rework list

* fix: nested x-for

* fix: nested x-for

* fix: lint

* fix: lint

* fix: lint

* chore: bump version
  • Loading branch information
SoloJiang authored Sep 18, 2019
1 parent 9a4c3d3 commit cdf8b65
Show file tree
Hide file tree
Showing 26 changed files with 555 additions and 297 deletions.
2 changes: 1 addition & 1 deletion packages/jsx-compiler/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jsx-compiler",
"version": "0.2.6",
"version": "0.2.7",
"license": "BSD-3-Clause",
"description": "Parser for Rax JSX Statements.",
"main": "src/index.js",
Expand Down
52 changes: 46 additions & 6 deletions packages/jsx-compiler/src/modules/__tests__/jsx-plus.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,56 @@
const { _transformCondition, _transformList, _transformFragment } = require('../jsx-plus');
const {
_transformCondition,
_transformList,
_transformFragment,
} = require('../jsx-plus');
const { parseExpression } = require('../../parser');
const genExpression = require('../../codegen/genExpression');
const adapter = require('../../adapter');

describe('Directives', () => {
describe('list', () => {
it('simple', () => {
const ast = parseExpression(`
<View x-for={val in array}>{val}</View>
`);
_transformList(ast, adapter);
expect(genExpression(ast)).toEqual('<View a:for={array} a:for-item="val">{val}</View>');
const code = `
<View x-for={val in array}>{val}</View>
`;
const ast = parseExpression(code);
_transformList(ast, code, adapter);
expect(genExpression(ast))
.toEqual(`<View a:for={array.map((val, index) => {
return {
val: val,
index: index
};
})} a:for-item="val" a:for-index="index">{val}</View>`);
});

it('nested', () => {
const code = `
<View x-for={item in array}>
<View x-for={item2 in item}>
{item2}
</View>
</View>
`;
const ast = parseExpression(code);
_transformList(ast, code, adapter);
expect(genExpression(ast))
.toEqual(`<View a:for={array.map((item, index) => {
item = item.map((item2, index) => {
return {
item2: item2,
index: index
};
});
return {
item: item,
index: index
};
})} a:for-item="item" a:for-index="index">
<View a:for={item} a:for-item="item2" a:for-index="index">
{item2}
</View>
</View>`);
});
});

Expand Down
47 changes: 43 additions & 4 deletions packages/jsx-compiler/src/modules/code.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const SAFE_CREATE_APP = '__create_app__';
const SAFE_CREATE_COMPONENT = '__create_component__';
const SAFE_CREATE_PAGE = '__create_page__';
const SAFE_CREATE_STYLE = '__create_style__';
const SAFE_ROUTER_MAP = '__router_map__';

const USE_EFFECT = 'useEffect';
const USE_STATE = 'useState';
Expand All @@ -27,6 +28,8 @@ const RUNTIME = '/npm/jsx2mp-runtime';

const isCoreModule = (mod) => /^@core\//.test(mod);

const isFileModule = (mod) => /\.(png|jpe?g|gif|bmp|webp)$/.test(mod);

function getConstructor(type) {
switch (type) {
case 'app': return 'App';
Expand Down Expand Up @@ -100,6 +103,7 @@ module.exports = {

removeRaxImports(parsed.ast);
renameCoreModule(parsed.ast, options.outputPath, targetFileDir);
renameFileModule(parsed.ast);

const currentNodeModulePath = join(options.sourcePath, 'npm');
const npmRelativePath = relative(dirname(options.resourcePath), currentNodeModulePath);
Expand Down Expand Up @@ -144,7 +148,12 @@ module.exports = {
];
const callUpdateProps = t.expressionStatement(t.callExpression(updateProps, updatePropsArgs));
if (propMaps.length > 0) {
(parentNode || fnBody).push(callUpdateProps);
const targetNode = parentNode || fnBody;
if (t.isReturnStatement(targetNode[targetNode.length - 1])) {
targetNode.splice(targetNode.length - 1, 0, callUpdateProps);
} else {
targetNode.push(callUpdateProps);
}
} else if ((parentNode || fnBody).length === 0) {
// Remove empty loop exp.
parentNode && parentNode.remove && parentNode.remove();
Expand Down Expand Up @@ -182,6 +191,23 @@ function renameCoreModule(ast, outputPath, targetFileDir) {
});
}

// import img from '../assets/img.png' => const img = '../assets/img.png'
function renameFileModule(ast) {
traverse(ast, {
ImportDeclaration(path) {
const source = path.get('source');
if (source.isStringLiteral() && isFileModule(source.node.value)) {
source.parentPath.replaceWith(t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(path.get('specifiers')[0].node.local.name),
t.stringLiteral(source.node.value)
)
]));
}
}
});
}

const WEEX_MODULE_REG = /^@weex(-module)?\//;

function isNpmModule(value) {
Expand Down Expand Up @@ -213,9 +239,10 @@ function renameNpmModules(ast, npmRelativePath, filename, cwd) {
}

const moduleBasePath = join(packageJSONPath, '..');
const realNpmName = relative(nodeModulePath, moduleBasePath);
const modulePathSuffix = relative(moduleBasePath, target);

let ret = join(prefix, npmName, modulePathSuffix);
let ret = join(prefix, realNpmName, modulePathSuffix);
if (ret[0] !== '.') ret = './' + ret;
// ret => '../npm/_ali/universal-toast/lib/index.js

Expand Down Expand Up @@ -255,6 +282,20 @@ function addDefine(ast, type, outputPath, targetFileDir, userDefineType, eventHa
traverse(ast, {
Program(path) {
const localIdentifier = t.identifier(safeCreateInstanceId);
// Component(__create_component__(__class_def__));
const args = [t.identifier(EXPORTED_DEF)];

// Insert routerMap import declaration
if (type === 'app') {
path.node.body.unshift(
t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(SAFE_ROUTER_MAP))],
t.stringLiteral('./routerMap')
)
);
// App(__create_app__(__class_def__, __router_map__));
args.push(t.identifier(SAFE_ROUTER_MAP));
}

// import { createComponent as __create_component__ } from "/__helpers/component";
const specifiers = [t.importSpecifier(localIdentifier, t.identifier(importedIdentifier))];
Expand Down Expand Up @@ -287,8 +328,6 @@ function addDefine(ast, type, outputPath, targetFileDir, userDefineType, eventHa
)
);

// Component(__create_component__(__class_def__));
const args = [t.identifier(EXPORTED_DEF)];
// __create_component__(__class_def__, { events: ['_e*']})
if (eventHandlers.length > 0) {
args.push(
Expand Down
29 changes: 3 additions & 26 deletions packages/jsx-compiler/src/modules/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,31 +45,8 @@ module.exports = {
componentsDependentProps[tagId].tagIdExpression = parentPath.node.__tagIdExpression;

if (parsed.renderFunctionPath) {
const { args, iterValue, loopFnBody } = parentJSXListEl.node.__jsxlist;
const __args = [
args[0] || t.identifier('item'),
args[1] || t.identifier('index'),
];
const callee = t.memberExpression(iterValue, t.identifier('forEach'));
const block = t.blockStatement([]);

const loopArgs = [t.arrowFunctionExpression(__args, block)];
const loopExp = t.expressionStatement(t.callExpression(callee, loopArgs));

const fnBody = parsed.renderFunctionPath.node.body.body;
const grandJSXListEl = parentJSXListEl.findParent(p => p.node.__jsxlist);
const body = grandJSXListEl && grandJSXListEl.node.__jsxlist.loopBlockStatement
? grandJSXListEl.node.__jsxlist.loopBlockStatement.body
: fnBody;

body.push(loopExp);
// Can be removed if not used.
block.body.remove = () => {
const index = body.indexOf(loopExp);
body.splice(index, 1);
};
componentsDependentProps[tagId].parentNode = block.body;
parentJSXListEl.node.__jsxlist.loopBlockStatement = block;
const { loopFnBody } = parentJSXListEl.node.__jsxlist;
componentsDependentProps[tagId].parentNode = loopFnBody.body;
}
}

Expand Down Expand Up @@ -135,7 +112,7 @@ module.exports = {
const { object, property } = node.name;
if (t.isJSXIdentifier(object) && t.isJSXIdentifier(property)) {
const alias = getComponentAlias(object.name, parsed.imported);
removeImport(alias);
removeImport(parsed.ast, alias);
if (alias) {
const pkg = getComponentConfig(alias.from, options.resourcePath);
if (pkg && pkg.miniappConfig && pkg.miniappConfig.subComponents && pkg.miniappConfig.subComponents[property.name]) {
Expand Down
55 changes: 34 additions & 21 deletions packages/jsx-compiler/src/modules/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,8 @@ function transformTemplate(ast, scope = null, adapter, sourceCode, componentDepe
if (innerPath.node.__transformed
|| innerPath.parentPath.isMemberExpression()
|| innerPath.parentPath.isObjectProperty()
|| innerPath.node.__xforArgs
|| innerPath.node.__mapArgs
&& !innerPath.node.__mapArgs.item) return;
|| innerPath.node.__listItem
&& !innerPath.node.__listItem.item) return;
const replaceNode = transformIdentifier(innerPath.node, dynamicValues, isDirective);
replaceNode.__transformed = true;
innerPath.replaceWith(replaceNode);
Expand All @@ -304,18 +303,7 @@ function transformTemplate(ast, scope = null, adapter, sourceCode, componentDepe
},
ObjectExpression(innerPath) {
if (innerPath.node.__transformed) return;
const { properties } = innerPath.node;
const replaceProperties = properties.map(property => {
const { key, value } = property;
let replaceNode;
if (t.isIdentifier(value)) {
replaceNode = transformIdentifier(value, dynamicValues, isDirective);
}
if (t.isMemberExpression(value)) {
replaceNode = transformMemberExpression(value, dynamicValues, isDirective);
}
return t.objectProperty(key, replaceNode);
});
const replaceProperties = transformObjectExpression(innerPath.node, dynamicValues, isDirective);
const replaceNode = t.objectExpression(replaceProperties);
replaceNode.__transformed = true;
innerPath.replaceWith(replaceNode);
Expand Down Expand Up @@ -414,7 +402,7 @@ function hasComplexExpression(path) {
const { properties } = innerPath.node;
const checkNested = properties.some(property => {
const { value } = property;
return !t.isIdentifier(value) && !t.isMemberExpression(value);
return !t.isIdentifier(value) && !t.isMemberExpression(value) && !t.isBinaryExpression(value);
});
if (checkNested) {
isComplex(innerPath);
Expand Down Expand Up @@ -452,7 +440,7 @@ function transformMemberExpression(expression, dynamicBinding, isDirective) {
replaceNode.__transformed = true;
return replaceNode;
}
if (t.isIdentifier(object) && !object.__xforArgs) {
if (t.isIdentifier(object)) {
objectReplaceNode = transformIdentifier(object, dynamicBinding, isDirective);
objectReplaceNode.__transformed = true;
}
Expand All @@ -475,13 +463,17 @@ function transformMemberExpression(expression, dynamicBinding, isDirective) {
* */
function transformIdentifier(expression, dynamicBinding, isDirective) {
let replaceNode;
if (expression.__xforArgs
|| expression.__mapArgs && !expression.__mapArgs.item
if (expression.__listItem
&& !expression.__listItem.item
|| expression.__templateVar) {
// The identifier is x-for args or template variable or map's index
replaceNode = expression;
} else if (expression.__mapArgs && expression.__mapArgs.item) {
replaceNode = t.memberExpression(t.identifier(expression.__mapArgs.item), expression);
} else if (expression.__listItem && expression.__listItem.item) {
const itemNode = t.identifier(expression.__listItem.item);
itemNode.__listItem = {
jsxplus: expression.__listItem.jsxplus
};
replaceNode = t.memberExpression(itemNode, expression);
} else {
const name = dynamicBinding.add({
expression,
Expand All @@ -492,6 +484,27 @@ function transformIdentifier(expression, dynamicBinding, isDirective) {
return replaceNode;
}

/**
* Transform ObjectExpression
* */
function transformObjectExpression(expression, dynamicBinding, isDirective) {
const { properties } = expression;
return properties.map(property => {
const { key, value } = property;
let replaceNode = value;
if (t.isIdentifier(value)) {
replaceNode = transformIdentifier(value, dynamicBinding, isDirective);
}
if (t.isMemberExpression(value)) {
replaceNode = transformMemberExpression(value, dynamicBinding, isDirective);
}
if (t.isObjectExpression(value)) {
replaceNode = transformObjectExpression(value, dynamicBinding, isDirective);
}
return t.objectProperty(key, replaceNode);
});
}

function checkMemberHasThis(expression) {
const { object, property } = expression;
let hasThisExpression = false;
Expand Down
4 changes: 2 additions & 2 deletions packages/jsx-compiler/src/modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ module.exports = [
require('./style'),
// Handle Rax base components.
require('./components'),
// JSX+ Directives
require('./jsx-plus'),
// Directive a:for
require('./list'),
// Directive a:if
require('./condition'),
// JSX+ Directives
require('./jsx-plus'),
// Handle render function
require('./render-function'),
// Parse and generate template.
Expand Down
Loading

0 comments on commit cdf8b65

Please # to comment.