From 55a84a24f3023308e14591c6cf21eb8833b776d8 Mon Sep 17 00:00:00 2001 From: keroxp Date: Tue, 1 Oct 2019 01:19:40 +0900 Subject: [PATCH 1/4] feat: JSX Support --- cli/file_fetcher.rs | 18 +++++++++ cli/msg.rs | 10 +++-- cli/state.rs | 4 +- js/compiler.ts | 18 ++++++--- js/deno.ts | 1 + js/jsx.ts | 81 ++++++++++++++++++++++++++++++++++++++++ js/jsx_test.tsx | 52 ++++++++++++++++++++++++++ js/jsx_view.tsx | 12 ++++++ js/lib.deno_runtime.d.ts | 41 ++++++++++++++++++++ tsconfig.json | 2 + 10 files changed, 229 insertions(+), 10 deletions(-) create mode 100644 js/jsx.ts create mode 100644 js/jsx_test.tsx create mode 100644 js/jsx_view.tsx diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs index 9c0ef920c523cc..128bba2ef06c36 100644 --- a/cli/file_fetcher.rs +++ b/cli/file_fetcher.rs @@ -481,7 +481,9 @@ fn map_file_extension(path: &Path) -> msg::MediaType { None => msg::MediaType::Unknown, Some(os_str) => match os_str.to_str() { Some("ts") => msg::MediaType::TypeScript, + Some("tsx") => msg::MediaType::TSX, Some("js") => msg::MediaType::JavaScript, + Some("jsx") => msg::MediaType::JSX, Some("mjs") => msg::MediaType::JavaScript, Some("json") => msg::MediaType::Json, _ => msg::MediaType::Unknown, @@ -1342,6 +1344,10 @@ mod tests { map_file_extension(Path::new("foo/bar.ts")), msg::MediaType::TypeScript ); + assert_eq!( + map_file_extension(Path::new("foo/bar.tsx")), + msg::MediaType::TSX + ); assert_eq!( map_file_extension(Path::new("foo/bar.d.ts")), msg::MediaType::TypeScript @@ -1350,6 +1356,10 @@ mod tests { map_file_extension(Path::new("foo/bar.js")), msg::MediaType::JavaScript ); + assert_eq!( + map_file_extension(Path::new("foo/bar.jsx")), + msg::MediaType::JSX + ); assert_eq!( map_file_extension(Path::new("foo/bar.json")), msg::MediaType::Json @@ -1371,6 +1381,10 @@ mod tests { map_content_type(Path::new("foo/bar.ts"), None), msg::MediaType::TypeScript ); + assert_eq!( + map_content_type(Path::new("foo/bar.tsx"), None), + msg::MediaType::TSX + ); assert_eq!( map_content_type(Path::new("foo/bar.d.ts"), None), msg::MediaType::TypeScript @@ -1379,6 +1393,10 @@ mod tests { map_content_type(Path::new("foo/bar.js"), None), msg::MediaType::JavaScript ); + assert_eq!( + map_content_type(Path::new("foo/bar.jsx"), None), + msg::MediaType::JSX + ); assert_eq!( map_content_type(Path::new("foo/bar.json"), None), msg::MediaType::Json diff --git a/cli/msg.rs b/cli/msg.rs index 4416c7d71b67f2..20ab9db130408c 100644 --- a/cli/msg.rs +++ b/cli/msg.rs @@ -66,15 +66,19 @@ pub enum ErrorKind { #[derive(Clone, Copy, PartialEq, Debug)] pub enum MediaType { JavaScript = 0, - TypeScript = 1, - Json = 2, - Unknown = 3, + JSX = 1, + TypeScript = 2, + TSX = 3, + Json = 4, + Unknown = 5, } pub fn enum_name_media_type(mt: MediaType) -> &'static str { match mt { MediaType::JavaScript => "JavaScript", + MediaType::JSX => "JSX", MediaType::TypeScript => "TypeScript", + MediaType::TSX => "TSX", MediaType::Json => "Json", MediaType::Unknown => "Unknown", } diff --git a/cli/state.rs b/cli/state.rs index d7c6102048f4b0..c11d3b7e7cb70c 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -250,10 +250,10 @@ impl ThreadSafeState { msg::MediaType::Json => { state_.json_compiler.compile_async(state_.clone(), &out) } - msg::MediaType::TypeScript => { + msg::MediaType::TypeScript | msg::MediaType::TSX => { state_.ts_compiler.compile_async(state_.clone(), &out) } - msg::MediaType::JavaScript => { + msg::MediaType::JavaScript | msg::MediaType::JSX => { if state_.ts_compiler.compile_js { state_.ts_compiler.compile_async(state_.clone(), &out) } else { diff --git a/js/compiler.ts b/js/compiler.ts index 1e1fe3dd397f06..7e8b3f1c7c75e6 100644 --- a/js/compiler.ts +++ b/js/compiler.ts @@ -24,9 +24,11 @@ import { writeFileSync } from "./write_file.ts"; // Update carefully! enum MediaType { JavaScript = 0, - TypeScript = 1, - Json = 2, - Unknown = 3 + JSX = 1, + TypeScript = 2, + TSX = 3, + Json = 4, + Unknown = 5 } // Startup boilerplate. This is necessary because the compiler has its own @@ -195,11 +197,16 @@ function emitBundle(fileName: string, data: string): void { /** Returns the TypeScript Extension enum for a given media type. */ function getExtension(fileName: string, mediaType: MediaType): ts.Extension { + console.log(fileName, mediaType); switch (mediaType) { case MediaType.JavaScript: return ts.Extension.Js; + case MediaType.JSX: + return ts.Extension.Jsx; case MediaType.TypeScript: return fileName.endsWith(".d.ts") ? ts.Extension.Dts : ts.Extension.Ts; + case MediaType.TSX: + return ts.Extension.Tsx; case MediaType.Json: return ts.Extension.Json; case MediaType.Unknown: @@ -221,7 +228,9 @@ class Host implements ts.CompilerHost { resolveJsonModule: true, sourceMap: true, stripComments: true, - target: ts.ScriptTarget.ESNext + target: ts.ScriptTarget.ESNext, + jsx: ts.JsxEmit.React, + jsxFactory: "Deno.h" }; private _sourceFileCache: Record = {}; @@ -511,7 +520,6 @@ window.compilerMain = function compilerMain(): void { window.onmessage = ({ data }: { data: CompilerReq }): void => { const { rootNames, configPath, config, bundle } = data; const host = new Host(bundle); - let emitSkipped = true; let diagnostics: ts.Diagnostic[] | undefined; diff --git a/js/deno.ts b/js/deno.ts index 511e4f0ecc26e1..588a3b324e5045 100644 --- a/js/deno.ts +++ b/js/deno.ts @@ -89,6 +89,7 @@ export { export { inspect, customInspect } from "./console.ts"; export { build, OperatingSystem, Arch } from "./build.ts"; export { version } from "./version.ts"; +export { h, renderToString } from "./jsx.ts"; export const args: string[] = []; // These are internal Deno APIs. We are marking them as internal so they do not diff --git a/js/jsx.ts b/js/jsx.ts new file mode 100644 index 00000000000000..f7887f33a0aa6b --- /dev/null +++ b/js/jsx.ts @@ -0,0 +1,81 @@ +export type Element = null | string | number | View | View[]; +export type ElementFactory = string | Component; +export type PropsWithChildren

= { children?: Element[] } & P; +export type Component

= ( + params: PropsWithChildren

+) => View; + +export type ElementAttribute = number | string | boolean | undefined | null; +export type View = { + type: T; + props?: P; + children?: Element[]; +}; + +/** Create JSX View from function component. This is default JSX Factory for typescript compiler. + * + * // JSX expressions are only available in TSX/JSX files. + * const Link: Deno.Component<{href: string, class: string}> = ({children, ...props}) => ( + * {children} + * ) + */ +export function h

(type: Component

): View; +export function h

( + type: string, + props?: P, + ...children: Element[] +): View; +export function h( + type: T, + props?: P, + ...children: Element[] +): View { + return { type, props, children }; +} + +function isValid(x: unknown): x is ElementAttribute { + return ( + typeof x === "string" || + typeof x === "number" || + typeof x === "boolean" || + x === null + ); +} + +/** Render JSX Element to string. + * + * // JSX expressions are only available in TSX/JSX files. + * Deno.renderToString(Deno) + * // In plain js/ts files, use with Deno.h. + * Deno.renderToString(Deno.h("a", {href: "https://deno.land"}, "Deno")) + */ +export function renderToString(node: Element): string { + if (node === null) { + return ""; + } else if (typeof node === "string") { + return node; + } else if (typeof node === "number") { + return `${node.toString()}`; + } else if (Array.isArray(node)) { + return node.map(renderToString).join(""); + } + let name: string; + const props = node.props || {}; + const children = node.children || []; + if (typeof node.type === "function") { + const rendererd = node.type({ ...props, children: node.children }); + return renderToString(rendererd); + } else if (typeof node.type === "string") { + name = node.type; + } else { + throw new Error("invalid node type: " + node.type); + } + const propsStr = Object.entries(props) + .filter(([_, v]) => isValid(v)) + .map(([k, v]) => { + return `${k}="${v}"`; + }) + .join(" "); + const childrenStr = children.map(v => renderToString(v)).join(""); + return `<${name}${propsStr ? ` ${propsStr} ` : ""}>${childrenStr}`; +} diff --git a/js/jsx_test.tsx b/js/jsx_test.tsx new file mode 100644 index 00000000000000..e479229ca1cdb3 --- /dev/null +++ b/js/jsx_test.tsx @@ -0,0 +1,52 @@ +import { test, assertEquals } from "./test_util.ts"; +import { runIfMain } from "./deps/https/deno.land/std/testing/mod.ts"; +import { h, renderToString } from "./jsx.ts"; +import { Layout } from "./jsx_view.tsx"; + +test(function jsxH(): void { + const v = h(() => bbb); + assertEquals(typeof v.type, "function"); + assertEquals(v.props, undefined); + assertEquals(v.children, []); +}); + +test(function jsxH2(): void { + const v = h("div", {class: "deno"}, "land"); + assertEquals(v.type, "div"); + assertEquals(v.props, {class: "deno"}); + assertEquals(v.children, ["land"]); +}); + +test(function jsxBasic(): void { + const str = renderToString(link); + const exp = `link`; + assertEquals(str, exp); +}); + +test(function jsxImported(): void { + const str = renderToString(land); + const exp = `denoland`; + assertEquals(str, exp); +}); + +test(function jsxRendrerToStringIgnoredProps(): void { + const v = h("div", { + str: "str", + num: 1, + bool: true, + nul: null, + undef: undefined, + symbol: Symbol("a"), + inst: new TextEncoder(), + bigint: BigInt(11), + obj: {}, + arr: [], + func: () => { }, + }, "land"); + // @ts-ignore + const str = renderToString(v); + assertEquals(str, `

land
`); +}); + + +runIfMain(import.meta); diff --git a/js/jsx_view.tsx b/js/jsx_view.tsx new file mode 100644 index 00000000000000..d16b64ba338c6b --- /dev/null +++ b/js/jsx_view.tsx @@ -0,0 +1,12 @@ +import { h, Component } from "./jsx.ts"; + +export const Layout: Component<{ title: string }> = ({ title, children }) => ( + + + {title} + + + {children} + + +) diff --git a/js/lib.deno_runtime.d.ts b/js/lib.deno_runtime.d.ts index 8eb46b410ee47f..f7cf2a09441d11 100644 --- a/js/lib.deno_runtime.d.ts +++ b/js/lib.deno_runtime.d.ts @@ -1206,6 +1206,47 @@ declare namespace Deno { */ export function inspect(value: unknown, options?: ConsoleOptions): string; + // @url js/jsx.d.ts + export type Element = null | string | number | View | View[]; + export type ElementFactory = string | Component; + export type PropsWithChildren

= { children?: Element[] } & P; + export type Component

= ( + params: PropsWithChildren

+ ) => View; + + export type ElementAttribute = number | string | boolean | undefined | null; + export type View = { + type: T; + props: P; + children?: Element[]; + }; + export function h

(type: Component

): View; + export function h

( + type: string, + props?: P, + ...children: Element[] + ): View; + /** Create JSX View from function component. This is default JSX Factory for typescript compiler. + * + * // JSX expressions are only available in TSX/JSX files. + * const Link: Deno.Component<{href: string, class: string}> = ({children, ...props}) => ( + * {children} + * ) + */ + export function h( + type: T, + props?: P, + ...children: Element[] + ): View; + /** Render JSX Element to string. + * + * // JSX expressions are only available in TSX/JSX files. + * Deno.renderToString(Deno) + * // In plain js/ts files, use with `Deno.h()`. + * Deno.renderToString(Deno.h("a", {href: "https://deno.land"}, "Deno")) + */ + export function renderToString(node: Element): string; + // @url js/build.d.ts export type OperatingSystem = "mac" | "win" | "linux"; diff --git a/tsconfig.json b/tsconfig.json index f62cf4c6d024c9..e8ca36b1fd0650 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,6 +17,8 @@ "sourceMap": true, "strict": true, "target": "esnext", + "jsx": "react", + "jsxFactory": "h", "types": [] }, "files": [ From 280b098917498fe9e2d7540f5bce185f456787a0 Mon Sep 17 00:00:00 2001 From: keroxp Date: Tue, 1 Oct 2019 02:05:40 +0900 Subject: [PATCH 2/4] del: default jsx factory --- cli/tests/046_jsx_test.tsx | 7 +++ cli/tests/046_jsx_test.tsx.out | 1 + cli/tests/integration_tests.rs | 5 +++ js/compiler.ts | 2 +- js/deno.ts | 1 - js/jsx.ts | 81 ---------------------------------- js/jsx_test.tsx | 52 ---------------------- js/jsx_view.tsx | 12 ----- js/lib.deno_runtime.d.ts | 41 ----------------- 9 files changed, 14 insertions(+), 188 deletions(-) create mode 100644 cli/tests/046_jsx_test.tsx create mode 100644 cli/tests/046_jsx_test.tsx.out delete mode 100644 js/jsx.ts delete mode 100644 js/jsx_test.tsx delete mode 100644 js/jsx_view.tsx diff --git a/cli/tests/046_jsx_test.tsx b/cli/tests/046_jsx_test.tsx new file mode 100644 index 00000000000000..e6ea7cc2f96088 --- /dev/null +++ b/cli/tests/046_jsx_test.tsx @@ -0,0 +1,7 @@ +function h(factory, props, ...children) { + return {factory, props, children} +} +const View = () => ( +

land
+) +console.log() diff --git a/cli/tests/046_jsx_test.tsx.out b/cli/tests/046_jsx_test.tsx.out new file mode 100644 index 00000000000000..85cfe824b15b21 --- /dev/null +++ b/cli/tests/046_jsx_test.tsx.out @@ -0,0 +1 @@ +{ factory: [Function: View], props: null, children: [] } diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 99ab54a021a07e..7fe7411cb010fd 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -322,6 +322,11 @@ itest!(_045_proxy { output: "045_proxy_test.ts.out", }); +itest!(_046_jsx { + args: "run --allow-net --allow-env --allow-run --reload 046_jsx_test.tsx", + output: "046_jsx_test.tsx.out", +}); + itest!(async_error { exit_code: 1, args: "run --reload async_error.ts", diff --git a/js/compiler.ts b/js/compiler.ts index 7e8b3f1c7c75e6..f06005f3250511 100644 --- a/js/compiler.ts +++ b/js/compiler.ts @@ -230,7 +230,7 @@ class Host implements ts.CompilerHost { stripComments: true, target: ts.ScriptTarget.ESNext, jsx: ts.JsxEmit.React, - jsxFactory: "Deno.h" + jsxFactory: "h" }; private _sourceFileCache: Record = {}; diff --git a/js/deno.ts b/js/deno.ts index 588a3b324e5045..511e4f0ecc26e1 100644 --- a/js/deno.ts +++ b/js/deno.ts @@ -89,7 +89,6 @@ export { export { inspect, customInspect } from "./console.ts"; export { build, OperatingSystem, Arch } from "./build.ts"; export { version } from "./version.ts"; -export { h, renderToString } from "./jsx.ts"; export const args: string[] = []; // These are internal Deno APIs. We are marking them as internal so they do not diff --git a/js/jsx.ts b/js/jsx.ts deleted file mode 100644 index f7887f33a0aa6b..00000000000000 --- a/js/jsx.ts +++ /dev/null @@ -1,81 +0,0 @@ -export type Element = null | string | number | View | View[]; -export type ElementFactory = string | Component; -export type PropsWithChildren

= { children?: Element[] } & P; -export type Component

= ( - params: PropsWithChildren

-) => View; - -export type ElementAttribute = number | string | boolean | undefined | null; -export type View = { - type: T; - props?: P; - children?: Element[]; -}; - -/** Create JSX View from function component. This is default JSX Factory for typescript compiler. - * - * // JSX expressions are only available in TSX/JSX files. - * const Link: Deno.Component<{href: string, class: string}> = ({children, ...props}) => ( - * {children} - * ) - */ -export function h

(type: Component

): View; -export function h

( - type: string, - props?: P, - ...children: Element[] -): View; -export function h( - type: T, - props?: P, - ...children: Element[] -): View { - return { type, props, children }; -} - -function isValid(x: unknown): x is ElementAttribute { - return ( - typeof x === "string" || - typeof x === "number" || - typeof x === "boolean" || - x === null - ); -} - -/** Render JSX Element to string. - * - * // JSX expressions are only available in TSX/JSX files. - * Deno.renderToString(Deno) - * // In plain js/ts files, use with Deno.h. - * Deno.renderToString(Deno.h("a", {href: "https://deno.land"}, "Deno")) - */ -export function renderToString(node: Element): string { - if (node === null) { - return ""; - } else if (typeof node === "string") { - return node; - } else if (typeof node === "number") { - return `${node.toString()}`; - } else if (Array.isArray(node)) { - return node.map(renderToString).join(""); - } - let name: string; - const props = node.props || {}; - const children = node.children || []; - if (typeof node.type === "function") { - const rendererd = node.type({ ...props, children: node.children }); - return renderToString(rendererd); - } else if (typeof node.type === "string") { - name = node.type; - } else { - throw new Error("invalid node type: " + node.type); - } - const propsStr = Object.entries(props) - .filter(([_, v]) => isValid(v)) - .map(([k, v]) => { - return `${k}="${v}"`; - }) - .join(" "); - const childrenStr = children.map(v => renderToString(v)).join(""); - return `<${name}${propsStr ? ` ${propsStr} ` : ""}>${childrenStr}`; -} diff --git a/js/jsx_test.tsx b/js/jsx_test.tsx deleted file mode 100644 index e479229ca1cdb3..00000000000000 --- a/js/jsx_test.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { test, assertEquals } from "./test_util.ts"; -import { runIfMain } from "./deps/https/deno.land/std/testing/mod.ts"; -import { h, renderToString } from "./jsx.ts"; -import { Layout } from "./jsx_view.tsx"; - -test(function jsxH(): void { - const v = h(() => bbb); - assertEquals(typeof v.type, "function"); - assertEquals(v.props, undefined); - assertEquals(v.children, []); -}); - -test(function jsxH2(): void { - const v = h("div", {class: "deno"}, "land"); - assertEquals(v.type, "div"); - assertEquals(v.props, {class: "deno"}); - assertEquals(v.children, ["land"]); -}); - -test(function jsxBasic(): void { - const str = renderToString(link); - const exp = `link`; - assertEquals(str, exp); -}); - -test(function jsxImported(): void { - const str = renderToString(land); - const exp = `denoland`; - assertEquals(str, exp); -}); - -test(function jsxRendrerToStringIgnoredProps(): void { - const v = h("div", { - str: "str", - num: 1, - bool: true, - nul: null, - undef: undefined, - symbol: Symbol("a"), - inst: new TextEncoder(), - bigint: BigInt(11), - obj: {}, - arr: [], - func: () => { }, - }, "land"); - // @ts-ignore - const str = renderToString(v); - assertEquals(str, `

land
`); -}); - - -runIfMain(import.meta); diff --git a/js/jsx_view.tsx b/js/jsx_view.tsx deleted file mode 100644 index d16b64ba338c6b..00000000000000 --- a/js/jsx_view.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { h, Component } from "./jsx.ts"; - -export const Layout: Component<{ title: string }> = ({ title, children }) => ( - - - {title} - - - {children} - - -) diff --git a/js/lib.deno_runtime.d.ts b/js/lib.deno_runtime.d.ts index f7cf2a09441d11..8eb46b410ee47f 100644 --- a/js/lib.deno_runtime.d.ts +++ b/js/lib.deno_runtime.d.ts @@ -1206,47 +1206,6 @@ declare namespace Deno { */ export function inspect(value: unknown, options?: ConsoleOptions): string; - // @url js/jsx.d.ts - export type Element = null | string | number | View | View[]; - export type ElementFactory = string | Component; - export type PropsWithChildren

= { children?: Element[] } & P; - export type Component

= ( - params: PropsWithChildren

- ) => View; - - export type ElementAttribute = number | string | boolean | undefined | null; - export type View = { - type: T; - props: P; - children?: Element[]; - }; - export function h

(type: Component

): View; - export function h

( - type: string, - props?: P, - ...children: Element[] - ): View; - /** Create JSX View from function component. This is default JSX Factory for typescript compiler. - * - * // JSX expressions are only available in TSX/JSX files. - * const Link: Deno.Component<{href: string, class: string}> = ({children, ...props}) => ( - * {children} - * ) - */ - export function h( - type: T, - props?: P, - ...children: Element[] - ): View; - /** Render JSX Element to string. - * - * // JSX expressions are only available in TSX/JSX files. - * Deno.renderToString(Deno) - * // In plain js/ts files, use with `Deno.h()`. - * Deno.renderToString(Deno.h("a", {href: "https://deno.land"}, "Deno")) - */ - export function renderToString(node: Element): string; - // @url js/build.d.ts export type OperatingSystem = "mac" | "win" | "linux"; From 375e44a45573ec875135f88cb22265cb49fa48f4 Mon Sep 17 00:00:00 2001 From: keroxp Date: Tue, 1 Oct 2019 02:31:42 +0900 Subject: [PATCH 3/4] Update compiler.ts --- js/compiler.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/js/compiler.ts b/js/compiler.ts index cbe28d6217d97a..366bcfb385d136 100644 --- a/js/compiler.ts +++ b/js/compiler.ts @@ -197,7 +197,6 @@ function emitBundle(fileName: string, data: string): void { /** Returns the TypeScript Extension enum for a given media type. */ function getExtension(fileName: string, mediaType: MediaType): ts.Extension { - console.log(fileName, mediaType); switch (mediaType) { case MediaType.JavaScript: return ts.Extension.Js; From acf798514fd07cc630906a394248d4cdcc8096ac Mon Sep 17 00:00:00 2001 From: keroxp Date: Tue, 1 Oct 2019 22:33:12 +0900 Subject: [PATCH 4/4] fix: compile jsx also as tsx --- cli/state.rs | 6 ++++-- cli/tests/046_jsx_test.tsx | 6 ++++-- cli/tests/047_jsx_test.jsx | 9 +++++++++ cli/tests/047_jsx_test.jsx.out | 1 + cli/tests/integration_tests.rs | 9 +++++++-- js/compiler.ts | 3 +-- tsconfig.json | 1 - 7 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 cli/tests/047_jsx_test.jsx create mode 100644 cli/tests/047_jsx_test.jsx.out diff --git a/cli/state.rs b/cli/state.rs index c11d3b7e7cb70c..ef870bef046c85 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -250,10 +250,12 @@ impl ThreadSafeState { msg::MediaType::Json => { state_.json_compiler.compile_async(state_.clone(), &out) } - msg::MediaType::TypeScript | msg::MediaType::TSX => { + msg::MediaType::TypeScript + | msg::MediaType::TSX + | msg::MediaType::JSX => { state_.ts_compiler.compile_async(state_.clone(), &out) } - msg::MediaType::JavaScript | msg::MediaType::JSX => { + msg::MediaType::JavaScript => { if state_.ts_compiler.compile_js { state_.ts_compiler.compile_async(state_.clone(), &out) } else { diff --git a/cli/tests/046_jsx_test.tsx b/cli/tests/046_jsx_test.tsx index e6ea7cc2f96088..4e9380eb8f6df5 100644 --- a/cli/tests/046_jsx_test.tsx +++ b/cli/tests/046_jsx_test.tsx @@ -1,5 +1,7 @@ -function h(factory, props, ...children) { - return {factory, props, children} +const React = { + createElement(factory: any, props: any, ...children: any[]) { + return {factory, props, children} + } } const View = () => (

land
diff --git a/cli/tests/047_jsx_test.jsx b/cli/tests/047_jsx_test.jsx new file mode 100644 index 00000000000000..553c4c5a5de824 --- /dev/null +++ b/cli/tests/047_jsx_test.jsx @@ -0,0 +1,9 @@ +const React = { + createElement(factory, props, ...children) { + return {factory, props, children} + } +} +const View = () => ( +
land
+) +console.log() diff --git a/cli/tests/047_jsx_test.jsx.out b/cli/tests/047_jsx_test.jsx.out new file mode 100644 index 00000000000000..85cfe824b15b21 --- /dev/null +++ b/cli/tests/047_jsx_test.jsx.out @@ -0,0 +1 @@ +{ factory: [Function: View], props: null, children: [] } diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 21d783e5dd8555..930ad9477c0ac1 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -322,11 +322,16 @@ itest!(_045_proxy { output: "045_proxy_test.ts.out", }); -itest!(_046_jsx { - args: "run --allow-net --allow-env --allow-run --reload 046_jsx_test.tsx", +itest!(_046_tsx { + args: "run --reload 046_jsx_test.tsx", output: "046_jsx_test.tsx.out", }); +itest!(_047_jsx { + args: "run --reload 047_jsx_test.jsx", + output: "047_jsx_test.jsx.out", +}); + itest!(async_error { exit_code: 1, args: "run --reload async_error.ts", diff --git a/js/compiler.ts b/js/compiler.ts index 366bcfb385d136..77d88dd8b362c1 100644 --- a/js/compiler.ts +++ b/js/compiler.ts @@ -228,8 +228,7 @@ class Host implements ts.CompilerHost { sourceMap: true, stripComments: true, target: ts.ScriptTarget.ESNext, - jsx: ts.JsxEmit.React, - jsxFactory: "h" + jsx: ts.JsxEmit.React }; private _sourceFileCache: Record = {}; diff --git a/tsconfig.json b/tsconfig.json index e8ca36b1fd0650..cf252cfd797664 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,7 +18,6 @@ "strict": true, "target": "esnext", "jsx": "react", - "jsxFactory": "h", "types": [] }, "files": [