diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2021-10-18 19:36:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-18 19:36:28 +0200 |
commit | 617eeabe8369d7bfca7951d1cd55ac58ede1f9fb (patch) | |
tree | 61cfd7b8a5a0230528ed9547c12fcd7183125c6a /cli/main.rs | |
parent | 5a48d41bddf599b14dd9019ff49821c436ce4542 (diff) |
feat(unstable): Node CJS and ESM resolvers for compat mode (#12424)
This commit adds CJS and ESM Node resolvers to the "--compat" mode.
The functionality is spread across "cli/compat" module and Node compatibility
layer in "deno_std/node"; this stems from the fact that ES module resolution
can only be implemented in Rust as it needs to directly integrated with
"deno_core"; however "deno_std/node" already provided CJS module resolution.
Currently this resolution is only active when running a files using
"deno run --compat --unstable <filename>", and is not available in other
subcommands, which will be changed in follow up commits.
Diffstat (limited to 'cli/main.rs')
-rw-r--r-- | cli/main.rs | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/cli/main.rs b/cli/main.rs index 8a85cacfb..9dd7a354e 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -1092,6 +1092,11 @@ async fn run_command( return run_with_watch(flags, run_flags.script).await; } + // TODO(bartlomieju): it should not be resolved here if we're in compat mode + // because it might be a bare specifier + // TODO(bartlomieju): actually I think it will also fail if there's an import + // map specified and bare specifier is used on the command line - this should + // probably call `ProcState::resolve` instead let main_module = resolve_url_or_path(&run_flags.script)?; let ps = ProcState::build(flags.clone()).await?; let permissions = Permissions::from_options(&flags.clone().into()); @@ -1114,10 +1119,41 @@ async fn run_command( }; debug!("main_module {}", main_module); + if flags.compat { + // TODO(bartlomieju): fix me + assert_eq!(main_module.scheme(), "file"); + + // Set up Node globals worker.execute_side_module(&compat::GLOBAL_URL).await?; + // And `module` module that we'll use for checking which + // loader to use and potentially load CJS module with. + // This allows to skip permission check for `--allow-net` + // which would otherwise be requested by dynamically importing + // this file. + worker.execute_side_module(&compat::MODULE_URL).await?; + + let use_esm_loader = compat::check_if_should_use_esm_loader( + &mut worker.js_runtime, + &main_module.to_file_path().unwrap().display().to_string(), + ) + .await?; + + if use_esm_loader { + // ES module execution in Node compatiblity mode + worker.execute_main_module(&main_module).await?; + } else { + // CJS module execution in Node compatiblity mode + compat::load_cjs_module( + &mut worker.js_runtime, + &main_module.to_file_path().unwrap().display().to_string(), + )?; + } + } else { + // Regular ES module execution + worker.execute_main_module(&main_module).await?; } - worker.execute_main_module(&main_module).await?; + worker.execute_script( &located_script_name!(), "window.dispatchEvent(new Event('load'))", |