/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
libs/core/examples/ts_module_loader.rs
185 строк
5 KB
Bartek Iwańczuk
Revert module loader hooks stack (#34077)
15 май 2026, 18:34
Не верифицирован
15 май 2026, 18:34
3333711
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. 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). // NB(bartlomieju): this is fine for example code #![allow(clippy::print_stdout, reason = "example code")] #![allow(clippy::disallowed_methods, reason = "example code")] use std::borrow::Cow; use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; use anyhow::Context; use deno_ast::MediaType; use deno_ast::ParseParams; use deno_ast::SourceMapOption; use deno_core::JsRuntime; use deno_core::ModuleLoadOptions; use deno_core::ModuleLoadReferrer; use deno_core::ModuleLoadResponse; use deno_core::ModuleLoader; use deno_core::ModuleSource; use deno_core::ModuleSourceCode; use deno_core::ModuleSpecifier; use deno_core::ModuleType; use deno_core::ResolutionKind; use deno_core::RuntimeOptions; use deno_core::error::ModuleLoaderError; use deno_core::resolve_import; use deno_core::resolve_path; use deno_error::JsErrorBox; // TODO(bartlomieju): this is duplicated in `testing/checkin` type SourceMapStore = Rc<RefCell<HashMap<String, Vec<u8>>>>; // TODO(bartlomieju): this is duplicated in `testing/checkin` struct TypescriptModuleLoader { source_maps: SourceMapStore, } // TODO(bartlomieju): this is duplicated in `testing/checkin` impl ModuleLoader for TypescriptModuleLoader { fn resolve( &self, specifier: &str, referrer: &str, _kind: ResolutionKind, ) -> Result<ModuleSpecifier, ModuleLoaderError> { resolve_import(specifier, referrer).map_err(JsErrorBox::from_err) } fn load( &self, module_specifier: &ModuleSpecifier, _maybe_referrer: Option<&ModuleLoadReferrer>, _options: ModuleLoadOptions, ) -> ModuleLoadResponse { let source_maps = self.source_maps.clone(); fn load( source_maps: SourceMapStore, module_specifier: &ModuleSpecifier, ) -> Result<ModuleSource, ModuleLoaderError> { let path = module_specifier .to_file_path() .map_err(|_| JsErrorBox::generic("Only file:// URLs are supported."))?; let media_type = MediaType::from_path(&path); let (module_type, should_transpile) = match MediaType::from_path(&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), _ => { return Err(JsErrorBox::generic(format!( "Unknown extension {:?}", path.extension() ))); } }; let code = std::fs::read_to_string(&path).map_err(JsErrorBox::from_err)?; let code = if should_transpile { let parsed = deno_ast::parse_module(ParseParams { specifier: module_specifier.clone(), text: code.into(), media_type, capture_tokens: false, scope_analysis: false, maybe_syntax: None, }) .map_err(JsErrorBox::from_err)?; let res = parsed .transpile( &deno_ast::TranspileOptions { imports_not_used_as_values: deno_ast::ImportsNotUsedAsValues::Remove, decorators: deno_ast::DecoratorsTranspileOption::Ecma, ..Default::default() }, &deno_ast::TranspileModuleOptions { module_kind: None }, &deno_ast::EmitOptions { source_map: SourceMapOption::Separate, inline_sources: true, ..Default::default() }, ) .map_err(JsErrorBox::from_err)?; let res = res.into_source(); let source_map = res.source_map.unwrap().into_bytes(); source_maps .borrow_mut() .insert(module_specifier.to_string(), source_map); res.text } else { code }; Ok(ModuleSource::new( module_type, ModuleSourceCode::String(code.into()), module_specifier, None, )) } ModuleLoadResponse::Sync(load(source_maps, module_specifier)) } fn get_source_map(&self, specifier: &str) -> Option<Cow<'_, [u8]>> { self .source_maps .borrow() .get(specifier) .map(|v| v.clone().into()) } } fn main() -> Result<(), anyhow::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]; println!("Run {main_url}"); let source_map_store = Rc::new(RefCell::new(HashMap::new())); let mut js_runtime = JsRuntime::new(RuntimeOptions { module_loader: Some(Rc::new(TypescriptModuleLoader { source_maps: source_map_store, })), ..Default::default() }); let main_module = resolve_path( main_url, &std::env::current_dir().context("Unable to get CWD")?, )?; let future = async move { let mod_id = js_runtime.load_main_es_module(&main_module).await?; let result = js_runtime.mod_evaluate(mod_id); js_runtime.run_event_loop(Default::default()).await?; result.await }; tokio::runtime::Builder::new_current_thread() .enable_all() .build() .unwrap() .block_on(future) .map_err(|e| e.into()) }