Skip to content

Commit ee13ebe

Browse files
committed
fix: lot of fixes related to function components
- rewrote tests - remove git hooks - fixes for self closing elements
1 parent aa4c7ae commit ee13ebe

File tree

7 files changed

+93
-103
lines changed

7 files changed

+93
-103
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ const App = props =>
100100

101101
## Roadmap/Caveats
102102

103+
- Always handle `children` property implicitly
104+
105+
- Self closing tags will be treated as such, (ie no children handling on the props)
106+
103107
- Using spread operators on html elements require _esnext_ environment because it compiles down to `Object.entries` expression:
104108

105109
```tsx

package.json

+2-12
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,18 @@
2929
"build": "tsc -p tsconfig-build.json",
3030
"prepare": "npm run build",
3131
"release": "standard-version",
32-
"test": "jest --coverage"
33-
},
34-
"husky": {
35-
"hooks": {
36-
"pre-commit": "npm test && pretty-quick --staged",
37-
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
38-
}
32+
"test": "jest"
3933
},
4034
"jest": {
4135
"preset": "ts-jest",
4236
"testEnvironment": "node"
4337
},
4438
"dependencies": {},
4539
"devDependencies": {
46-
"@commitlint/cli": "^7.2.1",
47-
"@commitlint/config-conventional": "^7.1.2",
4840
"@types/jest": "^24.0.5",
4941
"@types/node": "^10.12.18",
50-
"husky": "^1.1.2",
5142
"jest": "^23.6.0",
52-
"prettier": "^1.13.7",
53-
"pretty-quick": "^1.8.0",
43+
"safe-eval": "^0.4.1",
5444
"standard-version": "^5.0.0",
5545
"ts-jest": "^23.10.4",
5646
"typescript": "^3.1.6"

src/__fixtures/expected.js

-18
This file was deleted.

src/__fixtures/input.tsx

-41
This file was deleted.

src/index.test.ts

+73-26
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,82 @@
11
import * as ts from "typescript";
2-
import { readFileSync } from "fs";
3-
import { resolve } from "path";
42
import transformer from "./index";
5-
6-
describe("transformer", () => {
7-
it("should compile", () => {
8-
const inputFile = resolve(__dirname, "__fixtures/input.tsx");
9-
const expectedFile = resolve(__dirname, "__fixtures/expected.js");
10-
const result = compile(inputFile, compilerOptions);
11-
const expected = readFileSync(expectedFile).toString();
12-
expect(result).toBe(expected);
13-
});
14-
});
3+
import safeEval from "safe-eval";
154

165
const compilerOptions: ts.CompilerOptions = {
176
target: ts.ScriptTarget.ESNext,
187
module: ts.ModuleKind.CommonJS,
19-
jsx: ts.JsxEmit.Preserve
8+
jsx: ts.JsxEmit.Preserve,
209
};
2110

22-
function compile(file: string, options: ts.CompilerOptions): string {
23-
let content = "";
24-
const program = ts.createProgram([file], options);
25-
program.emit(
26-
undefined,
27-
(_, result) => (content = result),
28-
undefined,
29-
undefined,
30-
{
31-
after: [transformer(program)]
32-
}
33-
);
34-
return content;
11+
function compile(source: string) {
12+
const { outputText } = ts.transpileModule(source, {
13+
compilerOptions,
14+
transformers: { after: [transformer] },
15+
});
16+
return outputText;
17+
}
18+
19+
function runFunction(source: string) {
20+
const compiled = compile(source);
21+
const wrapped = `(function () {${compiled}})()`;
22+
return safeEval(wrapped);
3523
}
24+
25+
function run(source: string) {
26+
return safeEval(compile(source));
27+
}
28+
29+
function checkf(source: string, expected: string) {
30+
const actual = runFunction(source);
31+
expect(actual).toBe(expected);
32+
}
33+
34+
function check(source: string, expected: string) {
35+
const actual = run(source);
36+
expect(actual).toBe(expected);
37+
}
38+
39+
test("simple", () => {
40+
check(
41+
'<div className="container" moreProps="hello">Hello World</div>;',
42+
'<div className="container" moreProps="hello">Hello World</div>'
43+
);
44+
});
45+
46+
test("interpolation", () => {
47+
check('<div class={3}>{"hello"}</div>', '<div class="3">hello</div>');
48+
});
49+
50+
test("fragments", () => {
51+
check("<><h1>hello</h1><h2>world</h2></>", "<h1>hello</h1><h2>world</h2>");
52+
});
53+
54+
test("More Complex", () => {
55+
checkf(
56+
`
57+
const Control = ({label, children}: any) => <div><label>{label}</label>{children}</div>
58+
return <Control label='hello'>world</Control>;
59+
`,
60+
"<div><label>hello</label>world</div>"
61+
);
62+
});
63+
64+
test("spread", () => {
65+
checkf(
66+
`
67+
const Control = ({label, children}: any) => <div><label>{label}</label>{children}</div>
68+
return <Control {...{ label: "hello", children: "world" }} />;
69+
`,
70+
"<div><label>hello</label>world</div>"
71+
);
72+
});
73+
74+
test("spread2", () => {
75+
checkf(
76+
`
77+
const Control = ({children, label, ...props}: any) => <label>{label}<a {...props}/></label>
78+
return <Control label='hello' placeholder='world' type='string' />;
79+
`,
80+
'<label>hello<a placeholder="world" type="string"/></label>'
81+
);
82+
});

src/index.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Transformer {
3131
" ",
3232
new utils.Identifier("Object")
3333
.access("entries")
34-
.call(ts.createSpread(node.expression))
34+
.call(node.expression)
3535
.access("map")
3636
.call(
3737
new utils.ArrowFunction(
@@ -44,6 +44,8 @@ class Transformer {
4444
).getNode()
4545
).getNode()
4646
)
47+
.access("join")
48+
.call(ts.createLiteral(" "))
4749
.getNode()
4850
);
4951
}
@@ -156,12 +158,15 @@ class Transformer {
156158
node: ts.JsxSelfClosingElement,
157159
result: utils.StringTemplateHelper
158160
) {
159-
const parameters = node.attributes.properties.map(
160-
this.getObjectLiteralElementFromAttribute.bind(this)
161-
);
161+
let parameters: ts.ObjectLiteralElementLike[] = [];
162162
parameters.push(
163163
ts.createPropertyAssignment("children", ts.createLiteral(""))
164164
);
165+
parameters = parameters.concat(
166+
node.attributes.properties.map((property) =>
167+
this.getObjectLiteralElementFromAttribute(property)
168+
)
169+
);
165170
result.add(
166171
ts.createCall(node.tagName, [], [ts.createObjectLiteral(parameters)])
167172
);
@@ -177,8 +182,7 @@ class Transformer {
177182
}
178183
result.add("<", node.tagName.getText());
179184
this.getStringFromAttributes(node.attributes, result);
180-
result.add(">");
181-
result.add("</", node.tagName.getText(), ">");
185+
result.add("/>");
182186
}
183187

184188
getStringFromJsxExpression(

src/modules.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module "safe-eval" {
2+
function safeEval(content: string, fileName?: string): any;
3+
export default safeEval;
4+
}

0 commit comments

Comments
 (0)