Skip to content

Commit 163e95d

Browse files
authored
fix(compile): use a temporary directory with a node_modules folder when compiling npm specifiers (#32084)
1 parent f88d88f commit 163e95d

File tree

7 files changed

+296
-206
lines changed

7 files changed

+296
-206
lines changed

cli/main.rs

Lines changed: 68 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -112,26 +112,28 @@ fn spawn_subcommand<F: Future<Output = T> + 'static, T: SubcommandOutput>(
112112
}
113113

114114
async fn run_subcommand(
115-
flags: Arc<Flags>,
115+
flags: Flags,
116116
unconfigured_runtime: Option<UnconfiguredRuntime>,
117117
roots: LibWorkerFactoryRoots,
118118
) -> Result<i32, AnyError> {
119119
let handle = match flags.subcommand.clone() {
120120
DenoSubcommand::Add(add_flags) => spawn_subcommand(async {
121-
tools::pm::add(flags, add_flags, tools::pm::AddCommandName::Add).await
121+
tools::pm::add(Arc::new(flags), add_flags, tools::pm::AddCommandName::Add)
122+
.await
123+
}),
124+
DenoSubcommand::Audit(audit_flags) => spawn_subcommand(async {
125+
tools::pm::audit(Arc::new(flags), audit_flags).await
122126
}),
123-
DenoSubcommand::Audit(audit_flags) => {
124-
spawn_subcommand(async { tools::pm::audit(flags, audit_flags).await })
125-
}
126127
DenoSubcommand::ApproveScripts(approve_scripts_flags) => {
127128
spawn_subcommand(async move {
128-
tools::pm::approve_scripts(flags, approve_scripts_flags).await
129+
tools::pm::approve_scripts(Arc::new(flags), approve_scripts_flags).await
129130
})
130131
}
131-
DenoSubcommand::Remove(remove_flags) => {
132-
spawn_subcommand(async { tools::pm::remove(flags, remove_flags).await })
133-
}
132+
DenoSubcommand::Remove(remove_flags) => spawn_subcommand(async {
133+
tools::pm::remove(Arc::new(flags), remove_flags).await
134+
}),
134135
DenoSubcommand::Bench(bench_flags) => spawn_subcommand(async {
136+
let flags = Arc::new(flags);
135137
if bench_flags.watch.is_some() {
136138
tools::bench::run_benchmarks_with_watch(flags, bench_flags)
137139
.boxed_local()
@@ -145,51 +147,41 @@ async fn run_subcommand(
145147
"⚠️ {} is experimental and subject to changes",
146148
colors::cyan("deno bundle")
147149
);
148-
tools::bundle::bundle(flags, bundle_flags).await
150+
tools::bundle::bundle(Arc::new(flags), bundle_flags).await
149151
}),
150152
DenoSubcommand::Deploy(deploy_flags) => spawn_subcommand(async move {
151-
tools::deploy::deploy(Arc::unwrap_or_clone(flags), deploy_flags).await
153+
tools::deploy::deploy(flags, deploy_flags).await
154+
}),
155+
DenoSubcommand::Doc(doc_flags) => spawn_subcommand(async {
156+
tools::doc::doc(Arc::new(flags), doc_flags).await
152157
}),
153-
DenoSubcommand::Doc(doc_flags) => {
154-
spawn_subcommand(async { tools::doc::doc(flags, doc_flags).await })
155-
}
156158
DenoSubcommand::Eval(eval_flags) => spawn_subcommand(async {
157-
tools::run::eval_command(flags, eval_flags).await
159+
tools::run::eval_command(Arc::new(flags), eval_flags).await
158160
}),
159161
DenoSubcommand::Cache(cache_flags) => spawn_subcommand(async move {
160162
tools::installer::install_from_entrypoints(
161-
flags,
163+
Arc::new(flags),
162164
self::args::InstallEntrypointsFlags {
163165
entrypoints: cache_flags.files,
164166
lockfile_only: false,
165167
},
166168
)
167169
.await
168170
}),
169-
DenoSubcommand::Check(check_flags) => {
170-
spawn_subcommand(
171-
async move { tools::check::check(flags, check_flags).await },
172-
)
173-
}
174-
DenoSubcommand::Clean(clean_flags) => {
175-
spawn_subcommand(
176-
async move { tools::clean::clean(flags, clean_flags).await },
177-
)
178-
}
171+
DenoSubcommand::Check(check_flags) => spawn_subcommand(async move {
172+
tools::check::check(Arc::new(flags), check_flags).await
173+
}),
174+
DenoSubcommand::Clean(clean_flags) => spawn_subcommand(async move {
175+
tools::clean::clean(Arc::new(flags), clean_flags).await
176+
}),
179177
DenoSubcommand::Compile(compile_flags) => spawn_subcommand(async {
180-
if compile_flags.eszip {
181-
tools::compile::compile_eszip(flags, compile_flags)
182-
.boxed_local()
183-
.await
184-
} else {
185-
tools::compile::compile(flags, compile_flags).await
186-
}
178+
tools::compile::compile(flags, compile_flags).await
187179
}),
188180
DenoSubcommand::Coverage(coverage_flags) => spawn_subcommand(async move {
189181
let reporter =
190182
crate::tools::coverage::reporter::create(coverage_flags.r#type.clone());
191183
tools::coverage::cover_files(
192-
flags,
184+
Arc::new(flags),
193185
coverage_flags.files.include,
194186
coverage_flags.files.ignore,
195187
coverage_flags.include,
@@ -198,19 +190,17 @@ async fn run_subcommand(
198190
&[&*reporter],
199191
)
200192
}),
201-
DenoSubcommand::Fmt(fmt_flags) => {
202-
spawn_subcommand(
203-
async move { tools::fmt::format(flags, fmt_flags).await },
204-
)
205-
}
193+
DenoSubcommand::Fmt(fmt_flags) => spawn_subcommand(async move {
194+
tools::fmt::format(Arc::new(flags), fmt_flags).await
195+
}),
206196
DenoSubcommand::Init(init_flags) => {
207197
spawn_subcommand(async { tools::init::init_project(init_flags).await })
208198
}
209-
DenoSubcommand::Info(info_flags) => {
210-
spawn_subcommand(async { tools::info::info(flags, info_flags).await })
211-
}
199+
DenoSubcommand::Info(info_flags) => spawn_subcommand(async {
200+
tools::info::info(Arc::new(flags), info_flags).await
201+
}),
212202
DenoSubcommand::Install(install_flags) => spawn_subcommand(async {
213-
tools::installer::install_command(flags, install_flags).await
203+
tools::installer::install_command(Arc::new(flags), install_flags).await
214204
}),
215205
DenoSubcommand::JSONReference(json_reference) => {
216206
spawn_subcommand(async move {
@@ -220,10 +210,10 @@ async fn run_subcommand(
220210
})
221211
}
222212
DenoSubcommand::Jupyter(jupyter_flags) => spawn_subcommand(async {
223-
tools::jupyter::kernel(flags, jupyter_flags).await
213+
tools::jupyter::kernel(Arc::new(flags), jupyter_flags).await
224214
}),
225215
DenoSubcommand::Uninstall(uninstall_flags) => spawn_subcommand(async {
226-
tools::installer::uninstall(flags, uninstall_flags).await
216+
tools::installer::uninstall(Arc::new(flags), uninstall_flags).await
227217
}),
228218
DenoSubcommand::Lsp => spawn_subcommand(async move {
229219
if std::io::stderr().is_terminal() {
@@ -246,20 +236,20 @@ async fn run_subcommand(
246236
);
247237
Ok(())
248238
} else {
249-
tools::lint::lint(flags, lint_flags).await
239+
tools::lint::lint(Arc::new(flags), lint_flags).await
250240
}
251241
}),
252-
DenoSubcommand::Outdated(update_flags) => {
242+
DenoSubcommand::Outdated(update_flags) => spawn_subcommand(async move {
243+
tools::pm::outdated(Arc::new(flags), update_flags).await
244+
}),
245+
DenoSubcommand::Repl(repl_flags) => spawn_subcommand(async move {
246+
tools::repl::run(Arc::new(flags), repl_flags).await
247+
}),
248+
DenoSubcommand::X(x_flags) => {
253249
spawn_subcommand(
254-
async move { tools::pm::outdated(flags, update_flags).await },
250+
async move { tools::x::run(Arc::new(flags), x_flags).await },
255251
)
256252
}
257-
DenoSubcommand::Repl(repl_flags) => {
258-
spawn_subcommand(async move { tools::repl::run(flags, repl_flags).await })
259-
}
260-
DenoSubcommand::X(x_flags) => {
261-
spawn_subcommand(async move { tools::x::run(flags, x_flags).await })
262-
}
263253
DenoSubcommand::Run(run_flags) => spawn_subcommand(async move {
264254
if run_flags.print_task_list {
265255
let task_flags = TaskFlags {
@@ -270,7 +260,7 @@ async fn run_subcommand(
270260
filter: None,
271261
eval: false,
272262
};
273-
let mut flags = flags.deref().clone();
263+
let mut flags = flags;
274264
flags.subcommand = DenoSubcommand::Task(task_flags.clone());
275265
writeln!(
276266
&mut std::io::stdout(),
@@ -284,14 +274,20 @@ async fn run_subcommand(
284274
.map(|_| 1)
285275
} else if run_flags.is_stdin() {
286276
// these futures are boxed to prevent stack overflows on Windows
287-
tools::run::run_from_stdin(flags.clone(), unconfigured_runtime, roots)
277+
tools::run::run_from_stdin(Arc::new(flags), unconfigured_runtime, roots)
288278
.boxed_local()
289279
.await
290280
} else if flags.eszip {
291-
tools::run::run_eszip(flags, run_flags, unconfigured_runtime, roots)
292-
.boxed_local()
293-
.await
281+
tools::run::run_eszip(
282+
Arc::new(flags),
283+
run_flags,
284+
unconfigured_runtime,
285+
roots,
286+
)
287+
.boxed_local()
288+
.await
294289
} else {
290+
let flags = Arc::new(flags);
295291
let result = tools::run::run_script(
296292
WorkerExecutionMode::Run,
297293
flags.clone(),
@@ -393,10 +389,16 @@ async fn run_subcommand(
393389
}
394390
}),
395391
DenoSubcommand::Serve(serve_flags) => spawn_subcommand(async move {
396-
tools::serve::serve(flags, serve_flags, unconfigured_runtime, roots).await
392+
tools::serve::serve(
393+
Arc::new(flags),
394+
serve_flags,
395+
unconfigured_runtime,
396+
roots,
397+
)
398+
.await
397399
}),
398400
DenoSubcommand::Task(task_flags) => spawn_subcommand(async {
399-
tools::task::execute_script(flags, task_flags).await
401+
tools::task::execute_script(Arc::new(flags), task_flags).await
400402
}),
401403
DenoSubcommand::Test(test_flags) => {
402404
spawn_subcommand(async {
@@ -420,9 +422,9 @@ async fn run_subcommand(
420422
}
421423

422424
if test_flags.watch.is_some() {
423-
tools::test::run_tests_with_watch(flags, test_flags).await
425+
tools::test::run_tests_with_watch(Arc::new(flags), test_flags).await
424426
} else {
425-
tools::test::run_tests(flags, test_flags).await
427+
tools::test::run_tests(Arc::new(flags), test_flags).await
426428
}
427429
})
428430
}
@@ -446,7 +448,7 @@ async fn run_subcommand(
446448
}),
447449
#[cfg(feature = "upgrade")]
448450
DenoSubcommand::Upgrade(upgrade_flags) => spawn_subcommand(async {
449-
tools::upgrade::upgrade(flags, upgrade_flags).await
451+
tools::upgrade::upgrade(Arc::new(flags), upgrade_flags).await
450452
}),
451453
#[cfg(not(feature = "upgrade"))]
452454
DenoSubcommand::Upgrade(_) => exit_with_message(
@@ -458,7 +460,7 @@ async fn run_subcommand(
458460
1,
459461
),
460462
DenoSubcommand::Publish(publish_flags) => spawn_subcommand(async {
461-
tools::publish::publish(flags, publish_flags).await
463+
tools::publish::publish(Arc::new(flags), publish_flags).await
462464
}),
463465
DenoSubcommand::Help(help_flags) => spawn_subcommand(async move {
464466
use std::io::Write;
@@ -679,7 +681,7 @@ pub fn main() {
679681
}
680682

681683
(
682-
run_subcommand(Arc::new(flags), waited_unconfigured_runtime, roots).await,
684+
run_subcommand(flags, waited_unconfigured_runtime, roots).await,
683685
initial_cwd,
684686
)
685687
};

cli/tools/compile.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ use std::sync::Arc;
99

1010
use deno_ast::MediaType;
1111
use deno_ast::ModuleSpecifier;
12+
use deno_config::deno_json::NodeModulesDirMode;
1213
use deno_core::anyhow::Context;
1314
use deno_core::anyhow::anyhow;
1415
use deno_core::anyhow::bail;
1516
use deno_core::error::AnyError;
17+
use deno_core::futures::FutureExt;
1618
use deno_graph::GraphKind;
1719
use deno_npm_installer::graph::NpmCachingStrategy;
1820
use deno_path_util::resolve_url_or_path;
@@ -24,12 +26,44 @@ use rand::Rng;
2426
use super::installer::BinNameResolver;
2527
use crate::args::CliOptions;
2628
use crate::args::CompileFlags;
29+
use crate::args::ConfigFlag;
2730
use crate::args::Flags;
2831
use crate::factory::CliFactory;
2932
use crate::standalone::binary::WriteBinOptions;
3033
use crate::standalone::binary::is_standalone_binary;
34+
use crate::util::temp::create_temp_node_modules_dir;
3135

3236
pub async fn compile(
37+
mut flags: Flags,
38+
compile_flags: CompileFlags,
39+
) -> Result<(), AnyError> {
40+
// use a temporary directory with a node_modules folder when the user
41+
// specifies an npm package for better compatibility
42+
let _temp_dir =
43+
if compile_flags.source_file.to_lowercase().starts_with("npm:")
44+
&& flags.node_modules_dir.is_none()
45+
&& !matches!(flags.config_flag, ConfigFlag::Path(_))
46+
{
47+
let temp_node_modules_dir = create_temp_node_modules_dir()
48+
.context("Failed creating temp directory for node_modules folder.")?;
49+
flags.initial_cwd = Some(temp_node_modules_dir.parent().to_path_buf());
50+
flags.internal.root_node_modules_dir_override =
51+
Some(temp_node_modules_dir.node_modules_dir_path().to_path_buf());
52+
flags.node_modules_dir = Some(NodeModulesDirMode::Auto);
53+
Some(temp_node_modules_dir)
54+
} else {
55+
None
56+
};
57+
let flags = Arc::new(flags);
58+
// boxed_local() is to avoid large futures
59+
if compile_flags.eszip {
60+
compile_eszip(flags, compile_flags).boxed_local().await
61+
} else {
62+
compile_binary(flags, compile_flags).boxed_local().await
63+
}
64+
}
65+
66+
async fn compile_binary(
3367
flags: Arc<Flags>,
3468
compile_flags: CompileFlags,
3569
) -> Result<(), AnyError> {
@@ -172,7 +206,7 @@ pub async fn compile(
172206
Ok(())
173207
}
174208

175-
pub async fn compile_eszip(
209+
async fn compile_eszip(
176210
flags: Arc<Flags>,
177211
compile_flags: CompileFlags,
178212
) -> Result<(), AnyError> {

0 commit comments

Comments
 (0)