Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Resolver control by environment variable "LLRT_PLATFORM" #690

Merged
merged 4 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,10 @@ Space-delimited list of hosts or socket paths which should be denied for network

Set a timeout in seconds for idle sockets being kept-alive. Default timeout is 15 seconds

### `LLRT_PLATFORM=value`

Used to explicitly specify a preferred platform for the Node.js package resolver. The default is `browser`. If `node` is specified, "node" takes precedence in the search path. If a value other than `browser` or `node` is specified, it will behave as if "browser" was specified.

### `LLRT_TLS_VERSION=value`

Set the TLS version to be used for network connections. By default only TLS 1.2 is enabled. TLS 1.3 can also be enabled by setting this variable to `1.3`
Expand Down
3 changes: 3 additions & 0 deletions llrt_core/src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ pub const ENV_LLRT_EXTRA_CA_CERTS: &str = "LLRT_EXTRA_CA_CERTS";
//log
pub const ENV_LLRT_LOG: &str = "LLRT_LOG";

//module
pub const ENV_LLRT_PLATFORM: &str = "LLRT_PLATFORM";

//vm
pub const ENV_LLRT_GC_THRESHOLD_MB: &str = "LLRT_GC_THRESHOLD_MB";
2 changes: 2 additions & 0 deletions llrt_core/src/module_loader/loader.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use once_cell::sync::Lazy;
use rquickjs::{loader::Loader, Ctx, Function, Module, Object, Result, Value};
use std::{
Expand Down
15 changes: 15 additions & 0 deletions llrt_core/src/module_loader/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use std::env;

use once_cell::sync::Lazy;

use crate::environment;

pub mod loader;
pub mod resolver;

// added when .cjs files are imported
pub const CJS_IMPORT_PREFIX: &str = "__cjs:";
// added to force CJS imports in loader
pub const CJS_LOADER_PREFIX: &str = "__cjsm:";

pub static LLRT_PLATFORM: Lazy<String> = Lazy::new(|| {
richarddavison marked this conversation as resolved.
Show resolved Hide resolved
env::var(environment::ENV_LLRT_PLATFORM)
.ok()
.filter(|platform| platform == "node")
.unwrap_or_else(|| "browser".to_string())
});
26 changes: 17 additions & 9 deletions llrt_core/src/module_loader/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{
utils::io::{is_supported_ext, JS_EXTENSIONS, SUPPORTED_EXTENSIONS},
};

use super::CJS_IMPORT_PREFIX;
use super::{CJS_IMPORT_PREFIX, LLRT_PLATFORM};

include!(concat!(env!("OUT_DIR"), "/bytecode_cache.rs"));

Expand Down Expand Up @@ -433,7 +433,8 @@ fn load_package_imports(ctx: &Ctx<'_>, x: &str, dir: &str) -> Result<Option<Stri
if let Some(module_path) = package_imports_resolve(&package_json, x) {
trace!("| load_package_imports(6): {}", module_path);
let dir = path.as_ref().trim_end_matches("package.json");
return Ok(Some(correct_extensions([dir, module_path].concat()).into()));
let module_path = to_abs_path(correct_extensions([dir, module_path].concat()))?;
return Ok(Some(module_path.into()));
}
};

Expand Down Expand Up @@ -512,7 +513,10 @@ fn load_package_exports<'a>(

let (module_path, is_cjs) = package_exports_resolve(&package_json, name, is_esm)?;

let module_path = correct_extensions([dir, "/", scope, "/", module_path].concat());
let module_path = to_abs_path(correct_extensions(
[dir, "/", scope, "/", module_path].concat(),
))?;

let prefix = if is_cjs && is_esm {
CJS_LOADER_PREFIX
} else {
Expand Down Expand Up @@ -584,9 +588,9 @@ fn package_exports_resolve<'a>(

if let Some(BorrowedValue::Object(exports)) = map.get("exports") {
if let Some(BorrowedValue::Object(name)) = exports.get(modules_name) {
// Check for exports -> name -> browser -> [import | require]
if let Some(BorrowedValue::Object(browser)) = name.get("browser") {
if let Some(BorrowedValue::String(ident)) = browser.get(ident) {
// Check for exports -> name -> platform(browser or node) -> [import | require]
if let Some(BorrowedValue::Object(platform)) = name.get(LLRT_PLATFORM.as_str()) {
if let Some(BorrowedValue::String(ident)) = platform.get(ident) {
return Ok((ident.as_ref(), is_cjs));
}
}
Expand Down Expand Up @@ -624,9 +628,9 @@ fn package_exports_resolve<'a>(
}
}
}
// Check for browser field
if let Some(BorrowedValue::String(browser)) = map.get("browser") {
return Ok((browser.as_ref(), is_cjs));
// Check for platform(browser or node) field
if let Some(BorrowedValue::String(platform)) = map.get(LLRT_PLATFORM.as_str()) {
return Ok((platform.as_ref(), is_cjs));
}
// [ESM only] Check for module field
if is_esm {
Expand All @@ -650,6 +654,10 @@ fn package_imports_resolve<'a>(
if let BorrowedValue::Object(map) = package_json {
if let Some(BorrowedValue::Object(imports)) = map.get("imports") {
if let Some(BorrowedValue::Object(name)) = imports.get(modules_name) {
// Check for imports -> name -> platform(browser or node)
if let Some(BorrowedValue::String(platform)) = name.get(LLRT_PLATFORM.as_str()) {
return Some(platform.as_ref());
}
// Check for imports -> name -> require
if let Some(BorrowedValue::String(require)) = name.get("require") {
return Some(require.as_ref());
Expand Down
Loading