summaryrefslogtreecommitdiff
path: root/cli/proc_state.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2022-02-27 14:38:45 +0100
committerGitHub <noreply@github.com>2022-02-27 14:38:45 +0100
commita65ce33fabb44bb2d9ed04773f7f334ed9c9a6b5 (patch)
treef5c169945377c3f806b514162408b81b5611ad44 /cli/proc_state.rs
parent4bea1d06c7ddb177ed20e0f32b70d7ff889871ab (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.rs37
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