mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
feat: precompile JSX (#20962)
Co-authored-by: Marvin Hagemeister <marvin@deno.com>
This commit is contained in:
parent
658f958fb8
commit
587f2e0800
12 changed files with 71 additions and 13 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1115,9 +1115,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_config"
|
name = "deno_config"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fed704bc09eb4f88b26b16c75f87795d1ea1e658e26867fe684cef91c55543f1"
|
checksum = "0f4dd27020827a51857fbb47a21d2359f75db031e177821bff4e95368333a5a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"indexmap 2.0.2",
|
"indexmap 2.0.2",
|
||||||
|
|
|
@ -47,7 +47,7 @@ winres.workspace = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
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_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_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||||
deno_doc = { version = "=0.72.1", features = ["html"] }
|
deno_doc = { version = "=0.72.1", features = ["html"] }
|
||||||
deno_emit = "=0.31.1"
|
deno_emit = "=0.31.1"
|
||||||
|
|
|
@ -114,12 +114,13 @@ pub fn ts_config_to_emit_options(
|
||||||
"error" => deno_ast::ImportsNotUsedAsValues::Error,
|
"error" => deno_ast::ImportsNotUsedAsValues::Error,
|
||||||
_ => deno_ast::ImportsNotUsedAsValues::Remove,
|
_ => 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() {
|
match options.jsx.as_str() {
|
||||||
"react" => (true, false, false),
|
"react" => (true, false, false, false),
|
||||||
"react-jsx" => (true, true, false),
|
"react-jsx" => (true, true, false, false),
|
||||||
"react-jsxdev" => (true, true, true),
|
"react-jsxdev" => (true, true, true, false),
|
||||||
_ => (false, false, false),
|
"precompile" => (false, false, false, true),
|
||||||
|
_ => (false, false, false, false),
|
||||||
};
|
};
|
||||||
deno_ast::EmitOptions {
|
deno_ast::EmitOptions {
|
||||||
emit_metadata: options.emit_decorator_metadata,
|
emit_metadata: options.emit_decorator_metadata,
|
||||||
|
@ -132,7 +133,7 @@ pub fn ts_config_to_emit_options(
|
||||||
jsx_factory: options.jsx_factory,
|
jsx_factory: options.jsx_factory,
|
||||||
jsx_fragment_factory: options.jsx_fragment_factory,
|
jsx_fragment_factory: options.jsx_fragment_factory,
|
||||||
jsx_import_source: options.jsx_import_source,
|
jsx_import_source: options.jsx_import_source,
|
||||||
precompile_jsx: false,
|
precompile_jsx,
|
||||||
transform_jsx,
|
transform_jsx,
|
||||||
var_decl_imports: false,
|
var_decl_imports: false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,8 @@
|
||||||
"react",
|
"react",
|
||||||
"react-jsx",
|
"react-jsx",
|
||||||
"react-jsxdev",
|
"react-jsxdev",
|
||||||
"react-native"
|
"react-native",
|
||||||
|
"precompile"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"jsxFactory": {
|
"jsxFactory": {
|
||||||
|
|
|
@ -1779,6 +1779,12 @@ itest!(jsx_import_source_pragma_import_map_dev {
|
||||||
http_server: true,
|
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 {
|
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",
|
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",
|
output: "run/jsx_import_source_import_map.out",
|
||||||
|
|
6
cli/tests/testdata/jsx/deno-jsx-precompile.jsonc
vendored
Normal file
6
cli/tests/testdata/jsx/deno-jsx-precompile.jsonc
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "precompile",
|
||||||
|
"jsxImportSource": "jsx-precompile"
|
||||||
|
}
|
||||||
|
}
|
3
cli/tests/testdata/jsx/import-map.json
vendored
3
cli/tests/testdata/jsx/import-map.json
vendored
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"imports": {
|
"imports": {
|
||||||
"jsx/jsx-runtime": "http://localhost:4545/jsx/jsx-runtime/index.ts",
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
23
cli/tests/testdata/jsx/jsx-precompile/index.ts
vendored
Normal file
23
cli/tests/testdata/jsx/jsx-precompile/index.ts
vendored
Normal 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>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
cli/tests/testdata/run/jsx_precompile/no_pragma.out
vendored
Normal file
3
cli/tests/testdata/run/jsx_precompile/no_pragma.out
vendored
Normal 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
|
3
cli/tests/testdata/run/jsx_precompile/no_pragma.tsx
vendored
Normal file
3
cli/tests/testdata/run/jsx_precompile/no_pragma.tsx
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function A() {
|
||||||
|
return <h1>hello</h1>;
|
||||||
|
}
|
|
@ -589,12 +589,12 @@ impl ReplSession {
|
||||||
inline_sources: false,
|
inline_sources: false,
|
||||||
imports_not_used_as_values: ImportsNotUsedAsValues::Preserve,
|
imports_not_used_as_values: ImportsNotUsedAsValues::Preserve,
|
||||||
transform_jsx: true,
|
transform_jsx: true,
|
||||||
|
precompile_jsx: false,
|
||||||
jsx_automatic: false,
|
jsx_automatic: false,
|
||||||
jsx_development: false,
|
jsx_development: false,
|
||||||
jsx_factory: self.jsx.factory.clone(),
|
jsx_factory: self.jsx.factory.clone(),
|
||||||
jsx_fragment_factory: self.jsx.frag_factory.clone(),
|
jsx_fragment_factory: self.jsx.frag_factory.clone(),
|
||||||
jsx_import_source: None,
|
jsx_import_source: None,
|
||||||
precompile_jsx: false,
|
|
||||||
var_decl_imports: true,
|
var_decl_imports: true,
|
||||||
})?
|
})?
|
||||||
.text;
|
.text;
|
||||||
|
|
|
@ -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.
|
/** The API that is called by Rust when executing a request.
|
||||||
* @param {Request} request
|
* @param {Request} request
|
||||||
*/
|
*/
|
||||||
function exec({ config, debug: debugFlag, rootNames, localOnly }) {
|
function exec({ config, debug: debugFlag, rootNames, localOnly }) {
|
||||||
setLogDebug(debugFlag, "TS");
|
setLogDebug(debugFlag, "TS");
|
||||||
performanceStart();
|
performanceStart();
|
||||||
|
|
||||||
|
config = normalizeConfig(config);
|
||||||
|
|
||||||
if (logDebug) {
|
if (logDebug) {
|
||||||
debug(">>> exec start", { rootNames });
|
debug(">>> exec start", { rootNames });
|
||||||
debug(config);
|
debug(config);
|
||||||
|
@ -983,8 +996,9 @@ delete Object.prototype.__proto__;
|
||||||
return respond(id, true);
|
return respond(id, true);
|
||||||
}
|
}
|
||||||
case "$configure": {
|
case "$configure": {
|
||||||
|
const config = normalizeConfig(args[0]);
|
||||||
const { options, errors } = ts
|
const { options, errors } = ts
|
||||||
.convertCompilerOptionsFromJson(args[0], "");
|
.convertCompilerOptionsFromJson(config, "");
|
||||||
Object.assign(options, {
|
Object.assign(options, {
|
||||||
allowNonTsExtensions: true,
|
allowNonTsExtensions: true,
|
||||||
allowImportingTsExtensions: true,
|
allowImportingTsExtensions: true,
|
||||||
|
|
Loading…
Reference in a new issue