deno_runtime/
shared.rs

1// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2// Utilities shared between `build.rs` and the rest of the crate.
3
4use deno_ast::MediaType;
5use deno_ast::ParseParams;
6use deno_ast::SourceMapOption;
7use deno_core::error::AnyError;
8use deno_core::extension;
9use deno_core::Extension;
10use deno_core::ModuleCodeString;
11use deno_core::ModuleName;
12use deno_core::SourceMapData;
13use std::path::Path;
14
15extension!(runtime,
16  deps = [
17    deno_webidl,
18    deno_console,
19    deno_url,
20    deno_tls,
21    deno_web,
22    deno_fetch,
23    deno_cache,
24    deno_websocket,
25    deno_webstorage,
26    deno_crypto,
27    deno_broadcast_channel,
28    deno_node,
29    deno_ffi,
30    deno_net,
31    deno_napi,
32    deno_http,
33    deno_io,
34    deno_fs
35  ],
36  esm_entry_point = "ext:runtime/90_deno_ns.js",
37  esm = [
38    dir "js",
39    "01_errors.js",
40    "01_version.ts",
41    "06_util.js",
42    "10_permissions.js",
43    "11_workers.js",
44    "30_os.js",
45    "40_fs_events.js",
46    "40_process.js",
47    "40_signals.js",
48    "40_tty.js",
49    "41_prompt.js",
50    "90_deno_ns.js",
51    "98_global_scope_shared.js",
52    "98_global_scope_window.js",
53    "98_global_scope_worker.js"
54  ],
55  customizer = |ext: &mut Extension| {
56    #[cfg(not(feature = "exclude_runtime_main_js"))]
57    {
58      use deno_core::ascii_str_include;
59      use deno_core::ExtensionFileSource;
60      ext.esm_files.to_mut().push(ExtensionFileSource::new("ext:runtime_main/js/99_main.js", ascii_str_include!("./js/99_main.js")));
61      ext.esm_entry_point = Some("ext:runtime_main/js/99_main.js");
62    }
63  }
64);
65
66pub fn maybe_transpile_source(
67  name: ModuleName,
68  source: ModuleCodeString,
69) -> Result<(ModuleCodeString, Option<SourceMapData>), AnyError> {
70  // Always transpile `node:` built-in modules, since they might be TypeScript.
71  let media_type = if name.starts_with("node:") {
72    MediaType::TypeScript
73  } else {
74    MediaType::from_path(Path::new(&name))
75  };
76
77  match media_type {
78    MediaType::TypeScript => {}
79    MediaType::JavaScript => return Ok((source, None)),
80    MediaType::Mjs => return Ok((source, None)),
81    _ => panic!(
82      "Unsupported media type for snapshotting {media_type:?} for file {}",
83      name
84    ),
85  }
86
87  let parsed = deno_ast::parse_module(ParseParams {
88    specifier: deno_core::url::Url::parse(&name).unwrap(),
89    text: source.into(),
90    media_type,
91    capture_tokens: false,
92    scope_analysis: false,
93    maybe_syntax: None,
94  })?;
95  let transpiled_source = parsed
96    .transpile(
97      &deno_ast::TranspileOptions {
98        imports_not_used_as_values: deno_ast::ImportsNotUsedAsValues::Remove,
99        ..Default::default()
100      },
101      &deno_ast::TranspileModuleOptions::default(),
102      &deno_ast::EmitOptions {
103        source_map: if cfg!(debug_assertions) {
104          SourceMapOption::Separate
105        } else {
106          SourceMapOption::None
107        },
108        ..Default::default()
109      },
110    )?
111    .into_source();
112
113  let maybe_source_map: Option<SourceMapData> = transpiled_source
114    .source_map
115    .map(|sm| sm.into_bytes().into());
116  let source_text = transpiled_source.text;
117  Ok((source_text.into(), maybe_source_map))
118}