Skip to content

Commit 658713f

Browse files
committed
refactor: use AST literals to generate AST
1 parent 5c8cdf0 commit 658713f

File tree

3 files changed

+31
-45
lines changed

3 files changed

+31
-45
lines changed

package.json

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"description": "Define styled React components using CSS based module format",
55
"main": "lib/index.js",
66
"babel": {
7+
"plugins": [
8+
"ast-literal"
9+
],
710
"presets": [
811
"prometheusresearch"
912
]
@@ -39,14 +42,16 @@
3942
"dependencies": {
4043
"babel-types": "^6.7.2",
4144
"loader-utils": "^0.2.14",
42-
"postcss": "^5.0.19"
45+
"postcss": "^5.0.19",
46+
"babel-plugin-ast-literal": "^0.4.0"
4347
},
4448
"devDependencies": {
4549
"babel-cli": "^6.7.5",
4650
"babel-core": "^6.7.6",
4751
"babel-preset-prometheusresearch": "^0.1.0",
4852
"eslint": "^2.7.0",
4953
"eslint-config-prometheusresearch": "^0.2.0",
50-
"mocha": "^2.4.5"
54+
"mocha": "^2.4.5",
55+
"babel-generator": "^6.7.5"
5156
}
5257
}

src/__tests__/fixtures/imported-base.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22
import styles from "css";
3-
import Label__Base from "somelib/Label";
3+
import { default as Label__Base } from "somelib/Label";
44
export function Label(props) {
55
return React.createElement(Label__Base, { ...props, className: styles.Label
66
});

src/index.js

+23-42
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
import * as types from 'babel-types';
7+
import {identifier, stringLiteral} from 'babel-types';
78
import * as postcss from 'postcss';
89
import * as LoaderUtils from 'loader-utils';
910
import generate from 'babel-generator';
@@ -55,59 +56,39 @@ function renderToCSS(source: string, _config: RenderConfig): string {
5556

5657
function renderToJS(source: string, config: RenderConfig): string {
5758
let root = postcss.parse(source);
59+
let imports = stmt`
60+
import React from "react";
61+
import styles from "${stringLiteral(config.requestCSS)}";
62+
`;
5863
let statements = [];
59-
let component = types.stringLiteral('div');
64+
let component = stringLiteral('div');
6065
root.walkRules(node => {
6166
if (!Syntax.isComponent(node)) {
6267
return;
6368
}
6469
node.walkDecls(decl => {
6570
if (decl.prop === 'base') {
6671
if (HTMLTagList[decl.value]) {
67-
component = types.stringLiteral(decl.value);
72+
component = stringLiteral(decl.value);
6873
} else {
69-
component = types.identifier(node.selector + '__Base');
70-
statements.unshift(
71-
ComponentRef.importDeclaration(component, decl.value)
72-
);
74+
component = identifier(node.selector + '__Base');
75+
let ref = ComponentRef.parse(decl.value);
76+
imports.push(stmt`
77+
import {
78+
${identifier(ref.name)} as ${component}
79+
} from "${stringLiteral(ref.source)}";
80+
`);
7381
}
7482
}
7583
});
76-
statements.push(exportComponent(node.selector, component, node.selector));
84+
statements.push(stmt`
85+
export function ${identifier(node.selector)}(props) {
86+
return React.createElement(
87+
${component},
88+
{...props, className: styles.${identifier(node.selector)}}
89+
);
90+
}
91+
`);
7792
});
78-
statements.unshift(
79-
types.importDeclaration(
80-
[types.importDefaultSpecifier(types.identifier('styles'))],
81-
types.stringLiteral(config.requestCSS)
82-
)
83-
);
84-
statements.unshift(
85-
types.importDeclaration(
86-
[types.importDefaultSpecifier(types.identifier('React'))],
87-
types.stringLiteral('react')
88-
)
89-
);
90-
return generate(types.program(statements)).code;
91-
}
92-
93-
function exportComponent(name: string, component: string, className: string) {
94-
let propsNode = types.objectExpression([
95-
types.spreadProperty(types.identifier('props')),
96-
types.objectProperty(
97-
types.identifier('className'),
98-
types.memberExpression(types.identifier('styles'), types.identifier(className))
99-
)
100-
]);
101-
let elementNode = types.callExpression(
102-
types.memberExpression(
103-
types.identifier('React'),
104-
types.identifier('createElement')),
105-
[component, propsNode]
106-
);
107-
let componentNode = types.functionDeclaration(
108-
types.identifier(name),
109-
[types.identifier('props')],
110-
types.blockStatement([types.returnStatement(elementNode)])
111-
);
112-
return types.exportNamedDeclaration(componentNode, [], null);
93+
return generate(types.program(imports.concat(statements))).code;
11394
}

0 commit comments

Comments
 (0)