diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2022-02-27 14:38:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-27 14:38:45 +0100 |
commit | a65ce33fabb44bb2d9ed04773f7f334ed9c9a6b5 (patch) | |
tree | f5c169945377c3f806b514162408b81b5611ad44 /cli/proc_state.rs | |
parent | 4bea1d06c7ddb177ed20e0f32b70d7ff889871ab (diff) |
feat(compat): CJS/ESM interoperability (#13553)
This commit adds CJS/ESM interoperability when running in --compat mode.
Before executing files, they are analyzed and all CommonJS modules are
transformed on the fly to a ES modules. This is done by utilizing analyze_cjs()
functionality from deno_ast. After discovering exports and reexports, an ES
module is rendered and saved in memory for later use.
There's a caveat that all files ending with ".js" extension are considered as
CommonJS modules (unless there's a related "package.json" with "type": "module").
Diffstat (limited to 'cli/proc_state.rs')
-rw-r--r-- | cli/proc_state.rs | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/cli/proc_state.rs b/cli/proc_state.rs index 36c7e08d4..8933cb986 100644 --- a/cli/proc_state.rs +++ b/cli/proc_state.rs @@ -340,6 +340,34 @@ impl ProcState { None, ) .await; + + let needs_cjs_esm_translation = graph + .modules() + .iter() + .any(|m| m.kind == ModuleKind::CommonJs); + + if needs_cjs_esm_translation { + for module in graph.modules() { + // TODO(bartlomieju): this is overly simplistic heuristic, once we are + // in compat mode, all files ending with plain `.js` extension are + // considered CommonJs modules. Which leads to situation where valid + // ESM modules with `.js` extension might undergo translation (it won't + // work in this situation). + if module.kind == ModuleKind::CommonJs { + let translated_source = compat::translate_cjs_to_esm( + &self.file_fetcher, + &module.specifier, + module.maybe_source.as_ref().unwrap().to_string(), + module.media_type, + ) + .await?; + let mut graph_data = self.graph_data.write(); + graph_data + .add_cjs_esm_translation(&module.specifier, translated_source); + } + } + } + // If there was a locker, validate the integrity of all the modules in the // locker. graph_lock_or_exit(&graph); @@ -506,7 +534,14 @@ impl ProcState { | MediaType::Unknown | MediaType::Cjs | MediaType::Mjs - | MediaType::Json => code.as_ref().clone(), + | MediaType::Json => { + if let Some(source) = graph_data.get_cjs_esm_translation(&specifier) + { + source.to_owned() + } else { + code.as_ref().clone() + } + } MediaType::Dts => "".to_string(), _ => { let emit_path = self |