feat: precompile JSX (#20962)

Co-authored-by: Marvin Hagemeister <marvin@deno.com>
This commit is contained in:
Bartek Iwańczuk 2023-11-01 21:30:23 +01:00 committed by GitHub
parent 658f958fb8
commit 587f2e0800
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 71 additions and 13 deletions

4
Cargo.lock generated
View file

@ -1115,9 +1115,9 @@ dependencies = [
[[package]]
name = "deno_config"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed704bc09eb4f88b26b16c75f87795d1ea1e658e26867fe684cef91c55543f1"
checksum = "0f4dd27020827a51857fbb47a21d2359f75db031e177821bff4e95368333a5a0"
dependencies = [
"anyhow",
"indexmap 2.0.2",

View file

@ -47,7 +47,7 @@ winres.workspace = true
[dependencies]
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
deno_cache_dir = "=0.6.1"
deno_config = "=0.4.0"
deno_config = "=0.5.0"
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
deno_doc = { version = "=0.72.1", features = ["html"] }
deno_emit = "=0.31.1"

View file

@ -114,12 +114,13 @@ pub fn ts_config_to_emit_options(
"error" => deno_ast::ImportsNotUsedAsValues::Error,
_ => deno_ast::ImportsNotUsedAsValues::Remove,
};
let (transform_jsx, jsx_automatic, jsx_development) =
let (transform_jsx, jsx_automatic, jsx_development, precompile_jsx) =
match options.jsx.as_str() {
"react" => (true, false, false),
"react-jsx" => (true, true, false),
"react-jsxdev" => (true, true, true),
_ => (false, false, false),
"react" => (true, false, false, false),
"react-jsx" => (true, true, false, false),
"react-jsxdev" => (true, true, true, false),
"precompile" => (false, false, false, true),
_ => (false, false, false, false),
};
deno_ast::EmitOptions {
emit_metadata: options.emit_decorator_metadata,
@ -132,7 +133,7 @@ pub fn ts_config_to_emit_options(
jsx_factory: options.jsx_factory,
jsx_fragment_factory: options.jsx_fragment_factory,
jsx_import_source: options.jsx_import_source,
precompile_jsx: false,
precompile_jsx,
transform_jsx,
var_decl_imports: false,
}

View file

@ -54,7 +54,8 @@
"react",
"react-jsx",
"react-jsxdev",
"react-native"
"react-native",
"precompile"
]
},
"jsxFactory": {

View file

@ -1779,6 +1779,12 @@ itest!(jsx_import_source_pragma_import_map_dev {
http_server: true,
});
itest!(jsx_import_source_precompile_import_map {
args: "run --reload --check --import-map jsx/import-map.json --no-lock --config jsx/deno-jsx-precompile.jsonc run/jsx_precompile/no_pragma.tsx",
output: "run/jsx_precompile/no_pragma.out",
http_server: true,
});
itest!(jsx_import_source_import_map {
args: "run --reload --import-map jsx/import-map.json --no-lock --config jsx/deno-jsx-import-map.jsonc run/jsx_import_source_no_pragma.tsx",
output: "run/jsx_import_source_import_map.out",

View file

@ -0,0 +1,6 @@
{
"compilerOptions": {
"jsx": "precompile",
"jsxImportSource": "jsx-precompile"
}
}

View file

@ -1,6 +1,7 @@
{
"imports": {
"jsx/jsx-runtime": "http://localhost:4545/jsx/jsx-runtime/index.ts",
"jsx/jsx-dev-runtime": "http://localhost:4545/jsx/jsx-dev-runtime/index.ts"
"jsx/jsx-dev-runtime": "http://localhost:4545/jsx/jsx-dev-runtime/index.ts",
"jsx-precompile/jsx-runtime": "http://localhost:4545/jsx/jsx-precompile/index.ts"
}
}

View file

@ -0,0 +1,23 @@
// deno-lint-ignore-file no-explicit-any
export function jsx(
_type: any,
_props: any,
_key: any,
_source: any,
_self: any,
) {}
// deno-lint-ignore-file no-explicit-any
export const jsxAttr = (name: string, value: any) => `${name}="${value}"`;
// deno-lint-ignore-file no-explicit-any
export const jsxTemplate = (_template: string[], ..._exprs: any[]) => "";
// deno-lint-ignore-file no-explicit-any
export const jsxEscape = (_value: any) => "";
console.log("imported", import.meta.url);
declare global {
namespace JSX {
interface IntrinsicElements {
[tagName: string]: Record<string, any>;
}
}
}

View file

@ -0,0 +1,3 @@
Download http://localhost:4545/jsx/jsx-precompile/index.ts
Check file:///[WILDCARD]/run/jsx_precompile/no_pragma.tsx
imported http://localhost:4545/jsx/jsx-precompile/index.ts

View file

@ -0,0 +1,3 @@
export function A() {
return <h1>hello</h1>;
}

View file

@ -589,12 +589,12 @@ impl ReplSession {
inline_sources: false,
imports_not_used_as_values: ImportsNotUsedAsValues::Preserve,
transform_jsx: true,
precompile_jsx: false,
jsx_automatic: false,
jsx_development: false,
jsx_factory: self.jsx.factory.clone(),
jsx_fragment_factory: self.jsx.frag_factory.clone(),
jsx_import_source: None,
precompile_jsx: false,
var_decl_imports: true,
})?
.text;

View file

@ -862,12 +862,25 @@ delete Object.prototype.__proto__;
}
}
/** @param {Record<string, string>} config */
function normalizeConfig(config) {
// the typescript compiler doesn't know about the precompile
// transform at the moment, so just tell it we're using react-jsx
if (config.jsx === "precompile") {
config.jsx = "react-jsx";
}
return config;
}
/** The API that is called by Rust when executing a request.
* @param {Request} request
*/
function exec({ config, debug: debugFlag, rootNames, localOnly }) {
setLogDebug(debugFlag, "TS");
performanceStart();
config = normalizeConfig(config);
if (logDebug) {
debug(">>> exec start", { rootNames });
debug(config);
@ -983,8 +996,9 @@ delete Object.prototype.__proto__;
return respond(id, true);
}
case "$configure": {
const config = normalizeConfig(args[0]);
const { options, errors } = ts
.convertCompilerOptionsFromJson(args[0], "");
.convertCompilerOptionsFromJson(config, "");
Object.assign(options, {
allowNonTsExtensions: true,
allowImportingTsExtensions: true,