deno.land / x / deno@v1.28.2 / core / examples / ts_module_loader.rs

ts_module_loader.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.//! This example shows how to use swc to transpile TypeScript and JSX/TSX//! modules.//!//! It will only transpile, not typecheck (like Deno's `--no-check` flag).
use std::pin::Pin;use std::rc::Rc;
use anyhow::anyhow;use anyhow::bail;use anyhow::Error;use deno_ast::MediaType;use deno_ast::ParseParams;use deno_ast::SourceTextInfo;use deno_core::resolve_import;use deno_core::resolve_path;use deno_core::JsRuntime;use deno_core::ModuleLoader;use deno_core::ModuleSource;use deno_core::ModuleSourceFuture;use deno_core::ModuleSpecifier;use deno_core::ModuleType;use deno_core::RuntimeOptions;use futures::FutureExt;
struct TypescriptModuleLoader;
impl ModuleLoader for TypescriptModuleLoader { fn resolve( &self, specifier: &str, referrer: &str, _is_main: bool, ) -> Result<ModuleSpecifier, Error> { Ok(resolve_import(specifier, referrer)?) }
fn load( &self, module_specifier: &ModuleSpecifier, _maybe_referrer: Option<ModuleSpecifier>, _is_dyn_import: bool, ) -> Pin<Box<ModuleSourceFuture>> { let module_specifier = module_specifier.clone(); async move { let path = module_specifier .to_file_path() .map_err(|_| anyhow!("Only file: URLs are supported."))?;
let media_type = MediaType::from(&path); let (module_type, should_transpile) = match MediaType::from(&path) { MediaType::JavaScript | MediaType::Mjs | MediaType::Cjs => { (ModuleType::JavaScript, false) } MediaType::Jsx => (ModuleType::JavaScript, true), MediaType::TypeScript | MediaType::Mts | MediaType::Cts | MediaType::Dts | MediaType::Dmts | MediaType::Dcts | MediaType::Tsx => (ModuleType::JavaScript, true), MediaType::Json => (ModuleType::Json, false), _ => bail!("Unknown extension {:?}", path.extension()), };
let code = std::fs::read_to_string(&path)?; let code = if should_transpile { let parsed = deno_ast::parse_module(ParseParams { specifier: module_specifier.to_string(), text_info: SourceTextInfo::from_string(code), media_type, capture_tokens: false, scope_analysis: false, maybe_syntax: None, })?; parsed.transpile(&Default::default())?.text } else { code }; let module = ModuleSource { code: code.into_bytes().into_boxed_slice(), module_type, module_url_specified: module_specifier.to_string(), module_url_found: module_specifier.to_string(), }; Ok(module) } .boxed_local() }}
fn main() -> Result<(), Error> { let args: Vec<String> = std::env::args().collect(); if args.len() < 2 { println!("Usage: target/examples/debug/ts_module_loader <path_to_module>"); std::process::exit(1); } let main_url = args[1].clone(); println!("Run {}", main_url);
let mut js_runtime = JsRuntime::new(RuntimeOptions { module_loader: Some(Rc::new(TypescriptModuleLoader)), ..Default::default() });
let main_module = resolve_path(&main_url)?;
let future = async move { let mod_id = js_runtime.load_main_module(&main_module, None).await?; let result = js_runtime.mod_evaluate(mod_id); js_runtime.run_event_loop(false).await?; result.await? };
tokio::runtime::Builder::new_current_thread() .enable_all() .build() .unwrap() .block_on(future)}
deno

Version Info

Tagged at
a year ago