diff --git a/packages/transpiler/babel-preset-inula-jsx/src/const.ts b/packages/transpiler/babel-preset-inula-jsx/src/const.ts index 34744cc8..81c613e0 100644 --- a/packages/transpiler/babel-preset-inula-jsx/src/const.ts +++ b/packages/transpiler/babel-preset-inula-jsx/src/const.ts @@ -1,4 +1,4 @@ - +const importAliasPrefix = '$$'; export const importMap = [ 'createElement', 'setStyle', @@ -13,7 +13,7 @@ export const importMap = [ 'runComponent', 'createText' ].reduce>((acc, cur) => { - acc[cur] = cur; + acc[cur] = `${importAliasPrefix}${cur}`; return acc; }, {}); diff --git a/packages/transpiler/babel-preset-inula-jsx/src/pluginProvider.ts b/packages/transpiler/babel-preset-inula-jsx/src/pluginProvider.ts index 4acc0ab5..f54ee885 100644 --- a/packages/transpiler/babel-preset-inula-jsx/src/pluginProvider.ts +++ b/packages/transpiler/babel-preset-inula-jsx/src/pluginProvider.ts @@ -82,7 +82,10 @@ export class PluginProvider { const t = this.babelApi.types; // add automatic import return t.importDeclaration( - [...this.allUsedApis].map(api => t.importSpecifier(t.identifier(api), t.identifier(api))), + [...this.allUsedApis].map(api => { + if (importMap[api] === undefined) throw new Error(`Unknown api: ${api}`); + return t.importSpecifier(t.identifier(importMap[api]), t.identifier(api)); + }), t.stringLiteral(this.inulaPackageName), ); } @@ -103,7 +106,7 @@ export class PluginProvider { // ---- Add templates to the program this.programNode!.body.unshift(...templates); // ---- collect the used apis - usedApis.forEach(api => this.allUsedApis.add(api)) + usedApis.forEach(api => this.allUsedApis.add(api)); // ---- Replace the JSXElement with the viewAst path.replaceWith(viewAst); path.skip(); diff --git a/packages/transpiler/babel-preset-inula-jsx/src/test/simple.test.ts b/packages/transpiler/babel-preset-inula-jsx/src/test/simple.test.ts index 9d1864d5..9101ffb2 100644 --- a/packages/transpiler/babel-preset-inula-jsx/src/test/simple.test.ts +++ b/packages/transpiler/babel-preset-inula-jsx/src/test/simple.test.ts @@ -3,51 +3,60 @@ import { expect } from './mock'; describe('Entering', () => { it('should use inula jsx preset in babel', () => { - const code = 'console.log(\'hello world\');'; + const code = "console.log('hello world');"; expect(code, code); }); it('should transform jsx to inula view', () => { - expect(/*jsx*/` + expect( + /*jsx*/ ` import A from "inula" function App() { return (
) } - `, /*js*/` + `, + /*js*/ ` + import { createElement as $$createElement } from "inula"; import A from "inula"; function App() { return (() => { - const $node0 = createElement("div"); + const $node0 = $$createElement("div"); return [$node0]; })(); } - `); + ` + ); }); it('should transform jsx to inula view with props', () => { - expect(/*jsx*/` + expect( + /*jsx*/ ` import A from "inula" function App() { return (
) } - `, /*js*/` + `, + /*js*/ ` + import { createElement as $$createElement } from "inula"; import A from "inula"; function App() { return (() => { - const $node0 = createElement("div"); + const $node0 = $$createElement("div"); $node0.id = "myDiv"; return [$node0]; })(); } - `); + ` + ); }); it('should transform jsx to inula view with template', () => { - expect(/*jsx*/` + expect( + /*jsx*/ ` import A from "inula" function App() { return ( @@ -57,15 +66,17 @@ describe('Entering', () => { ) } - `, /*js*/` + `, + /*js*/ ` + import { createElement as $$createElement, insert as $$insert } from "inula"; const $template0 = (() => { - const $node0 = createElement("div"); - const $node1 = createElement("p"); + const $node0 = $$createElement("div"); + const $node1 = $$createElement("p"); $node1.textContent = "ok"; - insert($node0, $node1); - const $node2 = createElement("h1"); + $$insert($node0, $node1); + const $node2 = $$createElement("h1"); $node2.textContent = "fine"; - insert($node0, $node2); + $$insert($node0, $node2); return $node0; })(); import A from "inula"; @@ -75,6 +86,62 @@ describe('Entering', () => { return [$node0]; })(); } - `); + ` + ); }); -}); \ No newline at end of file + + it('should transform fragment', () => { + expect( + /*jsx*/ ` + import A from "inula" + + const CountingComponent = () => { + const count = reactive(0); + const add = () => { + count.set(c => c + 1); + }; + return ( + <> +
Count value is {count.get()}.
+
+ +
+ + ); + }; + `, + /*js*/ ` + import { createElement as $$createElement, createText as $$createText, insert as $$insert, delegateEvent as $$delegateEvent } from "inula"; + const $template0 = (() => { + const $node0 = $$createElement("div"); + const $node1 = $$createElement("button"); + $node1.id = "btn"; + $node1.textContent = "add"; + $$insert($node0, $node1); + return $node0; + })(); + import A from "inula"; + const CountingComponent = () => { + const count = reactive(0); + const add = () => { + count.set(c => c + 1); + }; + return (() => { + const $node0 = $$createElement("div"); + $node0.id = "count"; + const $node1 = $$createText("Count value is"); + $$insert($node0, $node1); + const $node2 = count.get(); + $$insert($node0, $node2); + const $node3 = $$createText("."); + $$insert($node0, $node3); + const $node4 = $template0.cloneNode(true); + const $node5 = $node4.firstChild; + $$delegateEvent($node5, "click", add); + return [$node0, $node4]; + })(); + }; + ` + ); + }); +}); diff --git a/packages/transpiler/jsx-view-generator/src/HelperGenerators/HTMLPropGenerator.ts b/packages/transpiler/jsx-view-generator/src/HelperGenerators/HTMLPropGenerator.ts index 2ed4dde6..2f06e997 100644 --- a/packages/transpiler/jsx-view-generator/src/HelperGenerators/HTMLPropGenerator.ts +++ b/packages/transpiler/jsx-view-generator/src/HelperGenerators/HTMLPropGenerator.ts @@ -48,7 +48,7 @@ export class HTMLPropGenerator extends BaseGenerator { nodeName: string, value: t.Expression, ) { - this.addUsedApi(this.importMap.setStyle); + this.addUsedApi('setStyle'); return this.t.callExpression( this.t.identifier(this.importMap.setStyle), [this.t.identifier(nodeName), value] @@ -63,7 +63,7 @@ export class HTMLPropGenerator extends BaseGenerator { nodeName: string, value: t.Expression, ) { - this.addUsedApi(this.importMap.setDataset); + this.addUsedApi('setDataset'); return this.t.callExpression( this.t.identifier(this.importMap.setDataset), [this.t.identifier(nodeName), value] @@ -98,7 +98,7 @@ export class HTMLPropGenerator extends BaseGenerator { key: string, value: t.Expression, ) { - this.addUsedApi(this.importMap.setProperty); + this.addUsedApi('setProperty'); return this.t.callExpression( this.t.identifier(this.importMap.setProperty), [this.t.identifier(nodeName), this.t.stringLiteral(key), value] @@ -133,7 +133,7 @@ export class HTMLPropGenerator extends BaseGenerator { key: string, value: t.Expression, ) { - this.addUsedApi(this.importMap.setAttribute); + this.addUsedApi('setAttribute'); return this.t.callExpression( this.t.identifier(this.importMap.setAttribute), [this.t.identifier(nodeName), this.t.stringLiteral(key), value] @@ -149,7 +149,7 @@ export class HTMLPropGenerator extends BaseGenerator { eventName: string, value: t.Expression, ) { - this.addUsedApi(this.importMap.delegateEvent); + this.addUsedApi('delegateEvent'); return this.t.callExpression( this.t.identifier(this.importMap.delegateEvent), [this.t.identifier(nodeName), this.t.stringLiteral(eventName), value] @@ -183,7 +183,7 @@ export class HTMLPropGenerator extends BaseGenerator { eventName: string, value: t.Expression, ) { - this.addUsedApi(this.importMap.addEventListener); + this.addUsedApi('addEventListener'); return this.t.callExpression( this.t.identifier(this.importMap.addEventListener), [this.t.identifier(nodeName), this.t.stringLiteral(eventName), value] diff --git a/packages/transpiler/jsx-view-generator/src/NodeGenerators/CompGenerator.ts b/packages/transpiler/jsx-view-generator/src/NodeGenerators/CompGenerator.ts index c6bd7a5b..ec4b622a 100644 --- a/packages/transpiler/jsx-view-generator/src/NodeGenerators/CompGenerator.ts +++ b/packages/transpiler/jsx-view-generator/src/NodeGenerators/CompGenerator.ts @@ -55,7 +55,7 @@ export class CompGenerator extends BaseGenerator { nodes.push(propNode); } - this.addUsedApi(this.importMap.runComponent); + this.addUsedApi('runComponent'); return [name, this.t.variableDeclaration('const', [ this.t.variableDeclarator( this.t.identifier(name), diff --git a/packages/transpiler/jsx-view-generator/src/NodeGenerators/HTMLGenerator.ts b/packages/transpiler/jsx-view-generator/src/NodeGenerators/HTMLGenerator.ts index df83c2f7..8effa5f8 100644 --- a/packages/transpiler/jsx-view-generator/src/NodeGenerators/HTMLGenerator.ts +++ b/packages/transpiler/jsx-view-generator/src/NodeGenerators/HTMLGenerator.ts @@ -34,7 +34,7 @@ export class HTMLGenerator extends HTMLPropGenerator { */ declareHTMLNode(tag: t.Expression): [string, t.Statement] { const name = this.geneNodeName(); - this.addUsedApi(this.importMap.createElement); + this.addUsedApi('createElement'); return [name, this.t.variableDeclaration('const', [ this.t.variableDeclarator( this.t.identifier(name), @@ -54,7 +54,7 @@ export class HTMLGenerator extends HTMLPropGenerator { parent: string, child: string ) { - this.addUsedApi(this.importMap.insert); + this.addUsedApi('insert'); return this.t.expressionStatement( this.t.callExpression( this.t.identifier(this.importMap.insert), diff --git a/packages/transpiler/jsx-view-generator/src/NodeGenerators/TemplateGenerator.ts b/packages/transpiler/jsx-view-generator/src/NodeGenerators/TemplateGenerator.ts index 597cb3bf..8ced033a 100644 --- a/packages/transpiler/jsx-view-generator/src/NodeGenerators/TemplateGenerator.ts +++ b/packages/transpiler/jsx-view-generator/src/NodeGenerators/TemplateGenerator.ts @@ -115,7 +115,7 @@ export class TemplateGenerator extends HTMLPropGenerator{ nextName: string ) { const nextNode = nextName ? [this.t.identifier(nextName)] : []; - this.addUsedApi(this.importMap.insert); + this.addUsedApi('insert'); return this.t.expressionStatement( this.t.callExpression( this.t.identifier(this.importMap.insert), diff --git a/packages/transpiler/jsx-view-generator/src/NodeGenerators/TextGenerator.ts b/packages/transpiler/jsx-view-generator/src/NodeGenerators/TextGenerator.ts index c155becb..786ff425 100644 --- a/packages/transpiler/jsx-view-generator/src/NodeGenerators/TextGenerator.ts +++ b/packages/transpiler/jsx-view-generator/src/NodeGenerators/TextGenerator.ts @@ -12,7 +12,7 @@ export class TextGenerator extends BaseGenerator { declareTextNode(content: t.Literal): [string, t.Statement] { const name = this.geneNodeName(); - this.addUsedApi(this.importMap.createText); + this.addUsedApi('createText'); return [name, this.t.variableDeclaration('const', [ this.t.variableDeclarator( this.t.identifier(name),