Fix dynamic import base path problem for REPL and eval (#2757)

This commit is contained in:
Kevin (Kun) "Kassimo" Qian 2019-08-09 16:33:59 -07:00 committed by Ryan Dahl
parent 83d5362f1d
commit 286ee1d8b6
8 changed files with 33 additions and 3 deletions

View File

@ -9,8 +9,10 @@ use deno::RecursiveLoad;
use deno::StartupData;
use futures::Async;
use futures::Future;
use std::env;
use std::sync::Arc;
use std::sync::Mutex;
use url::Url;
/// Wraps deno::Isolate to provide source maps, ops for the CLI, and
/// high-level module loading
@ -55,9 +57,11 @@ impl Worker {
Self { isolate, state }
}
/// Same as execute2() but the filename defaults to "<anonymous>".
/// Same as execute2() but the filename defaults to "$CWD/__anonymous__".
pub fn execute(&mut self, js_source: &str) -> Result<(), ErrBox> {
self.execute2("<anonymous>", js_source)
let path = env::current_dir().unwrap().join("__anonymous__");
let url = Url::from_file_path(path).unwrap();
self.execute2(url.as_str(), js_source)
}
/// Executes the provided JavaScript source code. The js_filename argument is

View File

@ -46,6 +46,10 @@ impl fmt::Display for ModuleResolutionError {
pub struct ModuleSpecifier(Url);
impl ModuleSpecifier {
fn is_dummy_specifier(specifier: &str) -> bool {
specifier == "<unknown>"
}
pub fn as_url(&self) -> &Url {
&self.0
}
@ -80,7 +84,18 @@ impl ModuleSpecifier {
// 3. Return the result of applying the URL parser to specifier with base
// URL as the base URL.
Err(ParseError::RelativeUrlWithoutBase) => {
let base = Url::parse(base).map_err(InvalidBaseUrl)?;
let base = if ModuleSpecifier::is_dummy_specifier(base) {
// Handle <unknown> case, happening under e.g. repl.
// Use CWD for such case.
// Forcefully join base to current dir.
// Otherwise, later joining in Url would be interpreted in
// the parent directory (appending trailing slash does not work)
let path = current_dir().unwrap().join(base);
Url::from_file_path(path).unwrap()
} else {
Url::parse(base).map_err(InvalidBaseUrl)?
};
base.join(&specifier).map_err(InvalidUrl)?
}

View File

@ -0,0 +1 @@
{ isMod4: true }

View File

@ -0,0 +1,2 @@
args: eval import('./tests/subdir/mod4.js').then(console.log)
output: tests/041_dyn_import_eval.out

View File

@ -0,0 +1,2 @@
args: run --reload tests/042_dyn_import_evalcontext.ts
output: tests/042_dyn_import_evalcontext.ts.out

View File

@ -0,0 +1,4 @@
// @ts-ignore
Deno.core.evalContext(
"(async () => console.log(await import('./tests/subdir/mod4.js')))()"
);

View File

@ -0,0 +1 @@
{ isMod4: true }

View File

@ -60,6 +60,7 @@ class TestIntegrations(DenoTestCase):
if not args:
return
# TODO(kevinkassimo): better args parsing with quotation marks.
args = args.split(" ")
check_stderr = str2bool(test.get("check_stderr", "false"))
stderr = subprocess.STDOUT if check_stderr else open(os.devnull, 'w')