refactor(ext/node): untangle dependencies between js files (#18284)

Moving some code around in `ext/node` is it's a bit better well defined
and makes it possible for others to embed it.

I expect to see no difference in startup perf with this change.
This commit is contained in:
Bartek Iwańczuk 2023-03-20 14:05:13 -04:00 committed by GitHub
parent d78db7c091
commit cd53ab5427
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 385 additions and 395 deletions

View file

@ -362,8 +362,7 @@ fn create_cli_snapshot(snapshot_path: PathBuf) {
deno_io::deno_io::init_ops(Default::default()),
deno_fs::deno_fs::init_ops::<PermissionsContainer>(false),
deno_flash::deno_flash::init_ops::<PermissionsContainer>(false), // No --unstable
deno_node::deno_node_loading::init_ops::<PermissionsContainer>(None), // No --unstable.
deno_node::deno_node::init_ops(),
deno_node::deno_node::init_ops::<PermissionsContainer>(None),
cli::init_ops_and_esm(), // NOTE: This needs to be init_ops_and_esm!
];

View file

@ -680,7 +680,9 @@ pub fn translate_cjs_to_esm(
let mut handled_reexports: HashSet<String> = HashSet::default();
let mut source = vec![
r#"const require = Deno[Deno.internal].require.Module.createRequire(import.meta.url);"#.to_string(),
r#"import {createRequire as __internalCreateRequire} from "node:module";
const require = __internalCreateRequire(import.meta.url);"#
.to_string(),
];
let analysis = perform_cjs_analysis(

View file

@ -1,10 +0,0 @@
import { fromFileUrl } from "../../../../test_util/std/path/mod.ts";
const DENO_NODE_COMPAT_URL = Deno.env.get("DENO_NODE_COMPAT_URL");
const moduleAllUrl = `${DENO_NODE_COMPAT_URL}node/module_all.ts`;
let moduleName = import.meta.resolve(Deno.args[0]);
moduleName = fromFileUrl(moduleName);
const moduleAll = await import(moduleAllUrl);
Deno[Deno.internal].node.initialize(moduleAll.default);
Deno[Deno.internal].require.Module._load(moduleName, null, true);

View file

@ -507,6 +507,7 @@ impl ReplSession {
deno_node::initialize_runtime(
&mut self.worker.js_runtime,
self.proc_state.options.has_node_modules_dir(),
None,
)?;
self.has_initialized_node_runtime = true;
}

View file

@ -301,10 +301,8 @@ impl CliMainWorker {
}
fn initialize_main_module_for_node(&mut self) -> Result<(), AnyError> {
deno_node::initialize_runtime(
&mut self.worker.js_runtime,
self.ps.options.has_node_modules_dir(),
)?;
let mut maybe_binary_command_name = None;
if let DenoSubcommand::Run(flags) = self.ps.options.sub_command() {
if let Ok(pkg_ref) = NpmPackageReqReference::from_str(&flags.script) {
// if the user ran a binary command, we'll need to set process.argv[0]
@ -313,12 +311,16 @@ impl CliMainWorker {
.sub_path
.as_deref()
.unwrap_or(pkg_ref.req.name.as_str());
deno_node::initialize_binary_command(
&mut self.worker.js_runtime,
binary_name,
)?;
maybe_binary_command_name = Some(binary_name.to_string());
}
}
deno_node::initialize_runtime(
&mut self.worker.js_runtime,
self.ps.options.has_node_modules_dir(),
maybe_binary_command_name,
)?;
Ok(())
}
@ -627,6 +629,7 @@ fn create_web_worker_pre_execute_module_callback(
deno_node::initialize_runtime(
&mut worker.js_runtime,
ps.options.has_node_modules_dir(),
None,
)?;
}

View file

@ -95,6 +95,7 @@ fn op_node_build_os() -> String {
deno_core::extension!(deno_node,
deps = [ deno_io, deno_fs ],
parameters = [P: NodePermissions],
ops = [
crypto::op_node_create_decipheriv,
crypto::op_node_cipheriv_encrypt,
@ -119,10 +120,36 @@ deno_core::extension!(deno_node,
idna::op_node_idna_punycode_decode,
idna::op_node_idna_punycode_encode,
op_node_build_os,
ops::op_require_init_paths,
ops::op_require_node_module_paths<P>,
ops::op_require_proxy_path,
ops::op_require_is_deno_dir_package,
ops::op_require_resolve_deno_dir,
ops::op_require_is_request_relative,
ops::op_require_resolve_lookup_paths,
ops::op_require_try_self_parent_path<P>,
ops::op_require_try_self<P>,
ops::op_require_real_path<P>,
ops::op_require_path_is_absolute,
ops::op_require_path_dirname,
ops::op_require_stat<P>,
ops::op_require_path_resolve,
ops::op_require_path_basename,
ops::op_require_read_file<P>,
ops::op_require_as_file_path,
ops::op_require_resolve_exports<P>,
ops::op_require_read_closest_package_json<P>,
ops::op_require_read_package_scope<P>,
ops::op_require_package_imports_resolve<P>,
ops::op_require_break_on_next_statement,
],
esm_entry_point = "ext:deno_node/module_all.ts",
esm_entry_point = "ext:deno_node/02_init.js",
esm = [
dir "polyfills",
"00_globals.js",
"01_require.js",
"02_init.js",
"_core.ts",
"_events.mjs",
"_fs/_fs_access.ts",
@ -305,7 +332,6 @@ deno_core::extension!(deno_node,
"internal/util/inspect.mjs",
"internal/util/types.ts",
"internal/validators.mjs",
"module_all.ts",
"net.ts",
"os.ts",
"path.ts",
@ -344,35 +370,6 @@ deno_core::extension!(deno_node,
"worker_threads.ts",
"zlib.ts",
],
);
deno_core::extension!(deno_node_loading,
parameters = [P: NodePermissions],
ops = [
ops::op_require_init_paths,
ops::op_require_node_module_paths<P>,
ops::op_require_proxy_path,
ops::op_require_is_deno_dir_package,
ops::op_require_resolve_deno_dir,
ops::op_require_is_request_relative,
ops::op_require_resolve_lookup_paths,
ops::op_require_try_self_parent_path<P>,
ops::op_require_try_self<P>,
ops::op_require_real_path<P>,
ops::op_require_path_is_absolute,
ops::op_require_path_dirname,
ops::op_require_stat<P>,
ops::op_require_path_resolve,
ops::op_require_path_basename,
ops::op_require_read_file<P>,
ops::op_require_as_file_path,
ops::op_require_resolve_exports<P>,
ops::op_require_read_closest_package_json<P>,
ops::op_require_read_package_scope<P>,
ops::op_require_package_imports_resolve<P>,
ops::op_require_break_on_next_statement,
],
esm = ["01_node.js", "02_require.js", "module_es_shim.js"],
options = {
maybe_npm_resolver: Option<Rc<dyn RequireNpmResolver>>,
},
@ -386,16 +383,24 @@ deno_core::extension!(deno_node_loading,
pub fn initialize_runtime(
js_runtime: &mut JsRuntime,
uses_local_node_modules_dir: bool,
maybe_binary_command_name: Option<String>,
) -> Result<(), AnyError> {
let argv0 = if let Some(binary_command_name) = maybe_binary_command_name {
format!("\"{}\"", binary_command_name)
} else {
"undefined".to_string()
};
let source_code = &format!(
r#"(function loadBuiltinNodeModules(nodeGlobalThisName, usesLocalNodeModulesDir) {{
Deno[Deno.internal].node.initialize(Deno[Deno.internal].nodeModuleAll, nodeGlobalThisName);
if (usesLocalNodeModulesDir) {{
Deno[Deno.internal].require.setUsesLocalNodeModulesDir();
}}
}})('{}', {});"#,
r#"(function loadBuiltinNodeModules(nodeGlobalThisName, usesLocalNodeModulesDir, argv0) {{
Deno[Deno.internal].node.initialize(
nodeGlobalThisName,
usesLocalNodeModulesDir,
argv0
);
}})('{}', {}, {});"#,
NODE_GLOBAL_THIS_NAME.as_str(),
uses_local_node_modules_dir,
argv0
);
js_runtime.execute_script(&located_script_name!(), source_code)?;
@ -413,12 +418,9 @@ pub fn load_cjs_module(
}
let source_code = &format!(
r#"(function loadCjsModule(module, inspectBrk) {{
if (inspectBrk) {{
Deno[Deno.internal].require.setInspectBrk();
}}
Deno[Deno.internal].require.Module._load(module, null, {main});
}})('{module}', {inspect_brk});"#,
r#"(function loadCjsModule(moduleName, isMain, inspectBrk) {{
Deno[Deno.internal].node.loadCjsModule(moduleName, isMain, inspectBrk);
}})('{module}', {main}, {inspect_brk});"#,
main = main,
module = escape_for_single_quote_string(module),
inspect_brk = inspect_brk,
@ -427,21 +429,3 @@ pub fn load_cjs_module(
js_runtime.execute_script(&located_script_name!(), source_code)?;
Ok(())
}
pub fn initialize_binary_command(
js_runtime: &mut JsRuntime,
binary_name: &str,
) -> Result<(), AnyError> {
// overwrite what's done in deno_std in order to set the binary arg name
let source_code = &format!(
r#"(function initializeBinaryCommand(binaryName) {{
const process = Deno[Deno.internal].node.globalThis.process;
Object.defineProperty(process.argv, "0", {{
get: () => binaryName,
}});
}})('{binary_name}');"#,
);
js_runtime.execute_script(&located_script_name!(), source_code)?;
Ok(())
}

View file

@ -1,20 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
const internals = globalThis.__bootstrap.internals;
const m = internals.require.Module;
export const _cache = m._cache;
export const _extensions = m._extensions;
export const _findPath = m._findPath;
export const _initPaths = m._initPaths;
export const _load = m._load;
export const _nodeModulePaths = m._nodeModulePaths;
export const _pathCache = m._pathCache;
export const _preloadModules = m._preloadModules;
export const _resolveFilename = m._resolveFilename;
export const _resolveLookupPaths = m._resolveLookupPaths;
export const builtinModules = m.builtinModules;
export const createRequire = m.createRequire;
export const globalPaths = m.globalPaths;
export const Module = m.Module;
export const wrap = m.wrap;
export default m;

View file

@ -93,7 +93,7 @@ pub static SUPPORTED_BUILTIN_NODE_MODULES: &[NodeModulePolyfill] = &[
},
NodeModulePolyfill {
name: "module",
specifier: "ext:deno_node_loading/module_es_shim.js",
specifier: "ext:deno_node/01_require.js",
},
NodeModulePolyfill {
name: "net",

View file

@ -2,14 +2,9 @@
// deno-lint-ignore-file
const internals = globalThis.__bootstrap.internals;
const primordials = globalThis.__bootstrap.primordials;
const {
ArrayPrototypePush,
ArrayPrototypeFilter,
ObjectEntries,
ObjectCreate,
ObjectDefineProperty,
Proxy,
ReflectDefineProperty,
ReflectDeleteProperty,
@ -22,13 +17,6 @@ const {
SetPrototypeHas,
} = primordials;
function assert(cond) {
if (!cond) {
throw Error("assert");
}
}
let initialized = false;
const nodeGlobals = {};
const nodeGlobalThis = new Proxy(globalThis, {
get(target, prop) {
@ -81,41 +69,4 @@ const nodeGlobalThis = new Proxy(globalThis, {
},
});
const nativeModuleExports = ObjectCreate(null);
const builtinModules = [];
function initialize(nodeModules, nodeGlobalThisName) {
assert(!initialized);
initialized = true;
for (const [name, exports] of ObjectEntries(nodeModules)) {
nativeModuleExports[name] = exports;
ArrayPrototypePush(builtinModules, name);
}
nodeGlobals.Buffer = nativeModuleExports["buffer"].Buffer;
nodeGlobals.clearImmediate = nativeModuleExports["timers"].clearImmediate;
nodeGlobals.clearInterval = nativeModuleExports["timers"].clearInterval;
nodeGlobals.clearTimeout = nativeModuleExports["timers"].clearTimeout;
nodeGlobals.console = nativeModuleExports["console"];
nodeGlobals.global = nodeGlobalThis;
nodeGlobals.process = nativeModuleExports["process"];
nodeGlobals.setImmediate = nativeModuleExports["timers"].setImmediate;
nodeGlobals.setInterval = nativeModuleExports["timers"].setInterval;
nodeGlobals.setTimeout = nativeModuleExports["timers"].setTimeout;
// add a hidden global for the esm code to use in order to reliably
// get node's globalThis
ObjectDefineProperty(globalThis, nodeGlobalThisName, {
enumerable: false,
writable: false,
value: nodeGlobalThis,
});
// FIXME(bartlomieju): not nice to depend on `Deno` namespace here
internals.__bootstrapNodeProcess(Deno.args, Deno.version);
}
internals.node = {
globalThis: nodeGlobalThis,
initialize,
nativeModuleExports,
builtinModules,
};
export { nodeGlobals, nodeGlobalThis };

View file

@ -19,6 +19,7 @@ const {
ObjectPrototypeHasOwnProperty,
ObjectSetPrototypeOf,
ObjectKeys,
ObjectEntries,
ObjectPrototype,
ObjectCreate,
Proxy,
@ -39,7 +40,202 @@ const {
Error,
TypeError,
} = primordials;
const node = internals.node;
import { nodeGlobalThis } from "ext:deno_node/00_globals.js";
import _httpAgent from "ext:deno_node/_http_agent.mjs";
import _httpOutgoing from "ext:deno_node/_http_outgoing.ts";
import _streamDuplex from "ext:deno_node/internal/streams/duplex.mjs";
import _streamPassthrough from "ext:deno_node/internal/streams/passthrough.mjs";
import _streamReadable from "ext:deno_node/internal/streams/readable.mjs";
import _streamTransform from "ext:deno_node/internal/streams/transform.mjs";
import _streamWritable from "ext:deno_node/internal/streams/writable.mjs";
import assert from "ext:deno_node/assert.ts";
import assertStrict from "ext:deno_node/assert/strict.ts";
import asyncHooks from "ext:deno_node/async_hooks.ts";
import buffer from "ext:deno_node/buffer.ts";
import childProcess from "ext:deno_node/child_process.ts";
import cluster from "ext:deno_node/cluster.ts";
import console from "ext:deno_node/console.ts";
import constants from "ext:deno_node/constants.ts";
import crypto from "ext:deno_node/crypto.ts";
import dgram from "ext:deno_node/dgram.ts";
import diagnosticsChannel from "ext:deno_node/diagnostics_channel.ts";
import dns from "ext:deno_node/dns.ts";
import dnsPromises from "ext:deno_node/dns/promises.ts";
import domain from "ext:deno_node/domain.ts";
import events from "ext:deno_node/events.ts";
import fs from "ext:deno_node/fs.ts";
import fsPromises from "ext:deno_node/fs/promises.ts";
import http from "ext:deno_node/http.ts";
import http2 from "ext:deno_node/http2.ts";
import https from "ext:deno_node/https.ts";
import inspector from "ext:deno_node/inspector.ts";
import internalCp from "ext:deno_node/internal/child_process.ts";
import internalCryptoCertificate from "ext:deno_node/internal/crypto/certificate.ts";
import internalCryptoCipher from "ext:deno_node/internal/crypto/cipher.ts";
import internalCryptoDiffiehellman from "ext:deno_node/internal/crypto/diffiehellman.ts";
import internalCryptoHash from "ext:deno_node/internal/crypto/hash.ts";
import internalCryptoHkdf from "ext:deno_node/internal/crypto/hkdf.ts";
import internalCryptoKeygen from "ext:deno_node/internal/crypto/keygen.ts";
import internalCryptoKeys from "ext:deno_node/internal/crypto/keys.ts";
import internalCryptoPbkdf2 from "ext:deno_node/internal/crypto/pbkdf2.ts";
import internalCryptoRandom from "ext:deno_node/internal/crypto/random.ts";
import internalCryptoScrypt from "ext:deno_node/internal/crypto/scrypt.ts";
import internalCryptoSig from "ext:deno_node/internal/crypto/sig.ts";
import internalCryptoUtil from "ext:deno_node/internal/crypto/util.ts";
import internalCryptoX509 from "ext:deno_node/internal/crypto/x509.ts";
import internalDgram from "ext:deno_node/internal/dgram.ts";
import internalDnsPromises from "ext:deno_node/internal/dns/promises.ts";
import internalErrors from "ext:deno_node/internal/errors.ts";
import internalEventTarget from "ext:deno_node/internal/event_target.mjs";
import internalFsUtils from "ext:deno_node/internal/fs/utils.mjs";
import internalHttp from "ext:deno_node/internal/http.ts";
import internalReadlineUtils from "ext:deno_node/internal/readline/utils.mjs";
import internalStreamsAddAbortSignal from "ext:deno_node/internal/streams/add-abort-signal.mjs";
import internalStreamsBufferList from "ext:deno_node/internal/streams/buffer_list.mjs";
import internalStreamsLazyTransform from "ext:deno_node/internal/streams/lazy_transform.mjs";
import internalStreamsState from "ext:deno_node/internal/streams/state.mjs";
import internalTestBinding from "ext:deno_node/internal/test/binding.ts";
import internalTimers from "ext:deno_node/internal/timers.mjs";
import internalUtil from "ext:deno_node/internal/util.mjs";
import internalUtilInspect from "ext:deno_node/internal/util/inspect.mjs";
import net from "ext:deno_node/net.ts";
import os from "ext:deno_node/os.ts";
import pathPosix from "ext:deno_node/path/posix.ts";
import pathWin32 from "ext:deno_node/path/win32.ts";
import path from "ext:deno_node/path.ts";
import perfHooks from "ext:deno_node/perf_hooks.ts";
import punycode from "ext:deno_node/punycode.ts";
import process from "ext:deno_node/process.ts";
import querystring from "ext:deno_node/querystring.ts";
import readline from "ext:deno_node/readline.ts";
import readlinePromises from "ext:deno_node/readline/promises.ts";
import repl from "ext:deno_node/repl.ts";
import stream from "ext:deno_node/stream.ts";
import streamConsumers from "ext:deno_node/stream/consumers.mjs";
import streamPromises from "ext:deno_node/stream/promises.mjs";
import streamWeb from "ext:deno_node/stream/web.ts";
import stringDecoder from "ext:deno_node/string_decoder.ts";
import sys from "ext:deno_node/sys.ts";
import timers from "ext:deno_node/timers.ts";
import timersPromises from "ext:deno_node/timers/promises.ts";
import tls from "ext:deno_node/tls.ts";
import tty from "ext:deno_node/tty.ts";
import url from "ext:deno_node/url.ts";
import utilTypes from "ext:deno_node/util/types.ts";
import util from "ext:deno_node/util.ts";
import v8 from "ext:deno_node/v8.ts";
import vm from "ext:deno_node/vm.ts";
import workerThreads from "ext:deno_node/worker_threads.ts";
import wasi from "ext:deno_node/wasi.ts";
import zlib from "ext:deno_node/zlib.ts";
const nativeModuleExports = ObjectCreate(null);
const builtinModules = [];
function setupBuiltinModules() {
const nodeModules = {
"_http_agent": _httpAgent,
"_http_outgoing": _httpOutgoing,
"_stream_duplex": _streamDuplex,
"_stream_passthrough": _streamPassthrough,
"_stream_readable": _streamReadable,
"_stream_transform": _streamTransform,
"_stream_writable": _streamWritable,
assert,
"assert/strict": assertStrict,
"async_hooks": asyncHooks,
buffer,
crypto,
console,
constants,
child_process: childProcess,
cluster,
dgram,
diagnostics_channel: diagnosticsChannel,
dns,
"dns/promises": dnsPromises,
domain,
events,
fs,
"fs/promises": fsPromises,
http,
http2,
https,
inspector,
"internal/child_process": internalCp,
"internal/crypto/certificate": internalCryptoCertificate,
"internal/crypto/cipher": internalCryptoCipher,
"internal/crypto/diffiehellman": internalCryptoDiffiehellman,
"internal/crypto/hash": internalCryptoHash,
"internal/crypto/hkdf": internalCryptoHkdf,
"internal/crypto/keygen": internalCryptoKeygen,
"internal/crypto/keys": internalCryptoKeys,
"internal/crypto/pbkdf2": internalCryptoPbkdf2,
"internal/crypto/random": internalCryptoRandom,
"internal/crypto/scrypt": internalCryptoScrypt,
"internal/crypto/sig": internalCryptoSig,
"internal/crypto/util": internalCryptoUtil,
"internal/crypto/x509": internalCryptoX509,
"internal/dgram": internalDgram,
"internal/dns/promises": internalDnsPromises,
"internal/errors": internalErrors,
"internal/event_target": internalEventTarget,
"internal/fs/utils": internalFsUtils,
"internal/http": internalHttp,
"internal/readline/utils": internalReadlineUtils,
"internal/streams/add-abort-signal": internalStreamsAddAbortSignal,
"internal/streams/buffer_list": internalStreamsBufferList,
"internal/streams/lazy_transform": internalStreamsLazyTransform,
"internal/streams/state": internalStreamsState,
"internal/test/binding": internalTestBinding,
"internal/timers": internalTimers,
"internal/util/inspect": internalUtilInspect,
"internal/util": internalUtil,
net,
os,
"path/posix": pathPosix,
"path/win32": pathWin32,
path,
perf_hooks: perfHooks,
process,
get punycode() {
process.emitWarning(
"The `punycode` module is deprecated. Please use a userland " +
"alternative instead.",
"DeprecationWarning",
"DEP0040",
);
return punycode;
},
querystring,
readline,
"readline/promises": readlinePromises,
repl,
stream,
"stream/consumers": streamConsumers,
"stream/promises": streamPromises,
"stream/web": streamWeb,
string_decoder: stringDecoder,
sys,
timers,
"timers/promises": timersPromises,
tls,
tty,
url,
util,
"util/types": utilTypes,
v8,
vm,
wasi,
worker_threads: workerThreads,
zlib,
};
for (const [name, moduleExports] of ObjectEntries(nodeModules)) {
nativeModuleExports[name] = moduleExports;
ArrayPrototypePush(builtinModules, name);
}
}
setupBuiltinModules();
// Map used to store CJS parsing data.
const cjsParseCache = new SafeWeakMap();
@ -55,12 +251,6 @@ function pathResolve(...args) {
return ops.op_require_path_resolve(args);
}
function assert(cond) {
if (!cond) {
throw Error("assert");
}
}
const nativeModulePolyfill = new SafeMap();
const relativeResolveCache = ObjectCreate(null);
@ -149,7 +339,7 @@ function tryPackage(requestPath, exts, isMain, originalPath) {
err.requestPath = originalPath;
throw err;
} else {
node.globalThis.process.emitWarning(
nodeGlobalThis.process.emitWarning(
`Invalid 'main' field in '${packageJsonPath}' of '${pkg}'. ` +
"Please either fix that or report it to the module author",
"DeprecationWarning",
@ -221,7 +411,7 @@ function getExportsForCircularRequire(module) {
}
function emitCircularRequireWarning(prop) {
node.globalThis.process.emitWarning(
nodeGlobalThis.process.emitWarning(
`Accessing non-existent property '${String(prop)}' of module exports ` +
"inside circular dependency",
);
@ -262,7 +452,7 @@ function Module(id = "", parent) {
this.children = [];
}
Module.builtinModules = node.builtinModules;
Module.builtinModules = builtinModules;
Module._extensions = ObjectCreate(null);
Module._cache = ObjectCreate(null);
@ -498,7 +688,7 @@ Module._load = function (request, parent, isMain) {
const module = cachedModule || new Module(filename, parent);
if (isMain) {
node.globalThis.process.mainModule = module;
nodeGlobalThis.process.mainModule = module;
mainModule = module;
module.id = ".";
}
@ -639,7 +829,10 @@ Module._resolveFilename = function (
};
Module.prototype.load = function (filename) {
assert(!this.loaded);
if (this.loaded) {
throw Error("Module already loaded");
}
this.filename = filename;
this.paths = Module._nodeModulePaths(
pathDirname(filename),
@ -717,7 +910,7 @@ function wrapSafe(
const wrapper = Module.wrap(content);
const [f, err] = core.evalContext(wrapper, `file://${filename}`);
if (err) {
if (node.globalThis.process.mainModule === cjsModuleInstance) {
if (nodeGlobalThis.process.mainModule === cjsModuleInstance) {
enrichCJSError(err.thrown);
}
throw err.thrown;
@ -749,7 +942,7 @@ Module.prototype._compile = function (content, filename) {
this,
filename,
dirname,
node.globalThis,
nodeGlobalThis,
);
if (requireDepth === 0) {
statCache = null;
@ -802,7 +995,7 @@ Module._extensions[".node"] = function (module, filename) {
if (filename.endsWith("fsevents.node")) {
throw new Error("Using fsevents module is currently not supported");
}
module.exports = ops.op_napi_open(filename, node.globalThis);
module.exports = ops.op_napi_open(filename, nodeGlobalThis);
};
function createRequireFromPath(filename) {
@ -887,13 +1080,13 @@ Module.syncBuiltinESMExports = function syncBuiltinESMExports() {
Module.Module = Module;
node.nativeModuleExports.module = Module;
nativeModuleExports.module = Module;
function loadNativeModule(_id, request) {
if (nativeModulePolyfill.has(request)) {
return nativeModulePolyfill.get(request);
}
const modExports = node.nativeModuleExports[request];
const modExports = nativeModuleExports[request];
if (modExports) {
const nodeMod = new Module(request);
nodeMod.exports = modExports;
@ -905,7 +1098,7 @@ function loadNativeModule(_id, request) {
}
function nativeModuleCanBeRequiredByUsers(request) {
return !!node.nativeModuleExports[request];
return !!nativeModuleExports[request];
}
function readPackageScope() {
@ -923,7 +1116,9 @@ function packageSpecifierSubPath(specifier) {
return ArrayPrototypeJoin(parts, "/");
}
internals.require = {
// This is a temporary namespace, that will be removed when initializing
// in `02_init.js`.
internals.requireImpl = {
setUsesLocalNodeModulesDir() {
usesLocalNodeModulesDir = true;
},
@ -931,8 +1126,21 @@ internals.require = {
hasInspectBrk = true;
},
Module,
wrapSafe,
toRealPath,
cjsParseCache,
readPackageScope,
nativeModuleExports,
};
export { builtinModules, createRequire, Module };
export const _cache = Module._cache;
export const _extensions = Module._extensions;
export const _findPath = Module._findPath;
export const _initPaths = Module._initPaths;
export const _load = Module._load;
export const _nodeModulePaths = Module._nodeModulePaths;
export const _pathCache = Module._pathCache;
export const _preloadModules = Module._preloadModules;
export const _resolveFilename = Module._resolveFilename;
export const _resolveLookupPaths = Module._resolveLookupPaths;
export const globalPaths = Module.globalPaths;
export const wrap = Module.wrap;
export default Module;

View file

@ -0,0 +1,62 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file
const internals = globalThis.__bootstrap.internals;
const requireImpl = internals.requireImpl;
const primordials = globalThis.__bootstrap.primordials;
const { ObjectDefineProperty } = primordials;
import { nodeGlobals, nodeGlobalThis } from "ext:deno_node/00_globals.js";
import "ext:deno_node/01_require.js";
let initialized = false;
function initialize(
nodeGlobalThisName,
usesLocalNodeModulesDir,
argv0,
) {
if (initialized) {
throw Error("Node runtime already initialized");
}
initialized = true;
if (usesLocalNodeModulesDir) {
requireImpl.setUsesLocalNodeModulesDir();
}
const nativeModuleExports = requireImpl.nativeModuleExports;
nodeGlobals.Buffer = nativeModuleExports["buffer"].Buffer;
nodeGlobals.clearImmediate = nativeModuleExports["timers"].clearImmediate;
nodeGlobals.clearInterval = nativeModuleExports["timers"].clearInterval;
nodeGlobals.clearTimeout = nativeModuleExports["timers"].clearTimeout;
nodeGlobals.console = nativeModuleExports["console"];
nodeGlobals.global = nodeGlobalThis;
nodeGlobals.process = nativeModuleExports["process"];
nodeGlobals.setImmediate = nativeModuleExports["timers"].setImmediate;
nodeGlobals.setInterval = nativeModuleExports["timers"].setInterval;
nodeGlobals.setTimeout = nativeModuleExports["timers"].setTimeout;
// add a hidden global for the esm code to use in order to reliably
// get node's globalThis
ObjectDefineProperty(globalThis, nodeGlobalThisName, {
enumerable: false,
writable: false,
value: nodeGlobalThis,
});
// FIXME(bartlomieju): not nice to depend on `Deno` namespace here
// but it's the only way to get `args` and `version` and this point.
internals.__bootstrapNodeProcess(argv0, Deno.args, Deno.version);
// `Deno[Deno.internal].requireImpl` will be unreachable after this line.
delete internals.requireImpl;
}
function loadCjsModule(moduleName, isMain, inspectBrk) {
if (inspectBrk) {
requireImpl.setInspectBrk();
}
requireImpl.Module._load(moduleName, null, { main: isMain });
}
internals.node = {
initialize,
loadCjsModule,
};

View file

@ -1,191 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
const internals = globalThis.__bootstrap.internals;
import _httpAgent from "ext:deno_node/_http_agent.mjs";
import _httpOutgoing from "ext:deno_node/_http_outgoing.ts";
import _streamDuplex from "ext:deno_node/internal/streams/duplex.mjs";
import _streamPassthrough from "ext:deno_node/internal/streams/passthrough.mjs";
import _streamReadable from "ext:deno_node/internal/streams/readable.mjs";
import _streamTransform from "ext:deno_node/internal/streams/transform.mjs";
import _streamWritable from "ext:deno_node/internal/streams/writable.mjs";
import assert from "ext:deno_node/assert.ts";
import assertStrict from "ext:deno_node/assert/strict.ts";
import asyncHooks from "ext:deno_node/async_hooks.ts";
import buffer from "ext:deno_node/buffer.ts";
import childProcess from "ext:deno_node/child_process.ts";
import cluster from "ext:deno_node/cluster.ts";
import console from "ext:deno_node/console.ts";
import constants from "ext:deno_node/constants.ts";
import crypto from "ext:deno_node/crypto.ts";
import dgram from "ext:deno_node/dgram.ts";
import diagnosticsChannel from "ext:deno_node/diagnostics_channel.ts";
import dns from "ext:deno_node/dns.ts";
import dnsPromises from "ext:deno_node/dns/promises.ts";
import domain from "ext:deno_node/domain.ts";
import events from "ext:deno_node/events.ts";
import fs from "ext:deno_node/fs.ts";
import fsPromises from "ext:deno_node/fs/promises.ts";
import http from "ext:deno_node/http.ts";
import http2 from "ext:deno_node/http2.ts";
import https from "ext:deno_node/https.ts";
import inspector from "ext:deno_node/inspector.ts";
import internalCp from "ext:deno_node/internal/child_process.ts";
import internalCryptoCertificate from "ext:deno_node/internal/crypto/certificate.ts";
import internalCryptoCipher from "ext:deno_node/internal/crypto/cipher.ts";
import internalCryptoDiffiehellman from "ext:deno_node/internal/crypto/diffiehellman.ts";
import internalCryptoHash from "ext:deno_node/internal/crypto/hash.ts";
import internalCryptoHkdf from "ext:deno_node/internal/crypto/hkdf.ts";
import internalCryptoKeygen from "ext:deno_node/internal/crypto/keygen.ts";
import internalCryptoKeys from "ext:deno_node/internal/crypto/keys.ts";
import internalCryptoPbkdf2 from "ext:deno_node/internal/crypto/pbkdf2.ts";
import internalCryptoRandom from "ext:deno_node/internal/crypto/random.ts";
import internalCryptoScrypt from "ext:deno_node/internal/crypto/scrypt.ts";
import internalCryptoSig from "ext:deno_node/internal/crypto/sig.ts";
import internalCryptoUtil from "ext:deno_node/internal/crypto/util.ts";
import internalCryptoX509 from "ext:deno_node/internal/crypto/x509.ts";
import internalDgram from "ext:deno_node/internal/dgram.ts";
import internalDnsPromises from "ext:deno_node/internal/dns/promises.ts";
import internalErrors from "ext:deno_node/internal/errors.ts";
import internalEventTarget from "ext:deno_node/internal/event_target.mjs";
import internalFsUtils from "ext:deno_node/internal/fs/utils.mjs";
import internalHttp from "ext:deno_node/internal/http.ts";
import internalReadlineUtils from "ext:deno_node/internal/readline/utils.mjs";
import internalStreamsAddAbortSignal from "ext:deno_node/internal/streams/add-abort-signal.mjs";
import internalStreamsBufferList from "ext:deno_node/internal/streams/buffer_list.mjs";
import internalStreamsLazyTransform from "ext:deno_node/internal/streams/lazy_transform.mjs";
import internalStreamsState from "ext:deno_node/internal/streams/state.mjs";
import internalTestBinding from "ext:deno_node/internal/test/binding.ts";
import internalTimers from "ext:deno_node/internal/timers.mjs";
import internalUtil from "ext:deno_node/internal/util.mjs";
import internalUtilInspect from "ext:deno_node/internal/util/inspect.mjs";
import net from "ext:deno_node/net.ts";
import os from "ext:deno_node/os.ts";
import pathPosix from "ext:deno_node/path/posix.ts";
import pathWin32 from "ext:deno_node/path/win32.ts";
import path from "ext:deno_node/path.ts";
import perfHooks from "ext:deno_node/perf_hooks.ts";
import punycode from "ext:deno_node/punycode.ts";
import process from "ext:deno_node/process.ts";
import querystring from "ext:deno_node/querystring.ts";
import readline from "ext:deno_node/readline.ts";
import readlinePromises from "ext:deno_node/readline/promises.ts";
import repl from "ext:deno_node/repl.ts";
import stream from "ext:deno_node/stream.ts";
import streamConsumers from "ext:deno_node/stream/consumers.mjs";
import streamPromises from "ext:deno_node/stream/promises.mjs";
import streamWeb from "ext:deno_node/stream/web.ts";
import stringDecoder from "ext:deno_node/string_decoder.ts";
import sys from "ext:deno_node/sys.ts";
import timers from "ext:deno_node/timers.ts";
import timersPromises from "ext:deno_node/timers/promises.ts";
import tls from "ext:deno_node/tls.ts";
import tty from "ext:deno_node/tty.ts";
import url from "ext:deno_node/url.ts";
import utilTypes from "ext:deno_node/util/types.ts";
import util from "ext:deno_node/util.ts";
import v8 from "ext:deno_node/v8.ts";
import vm from "ext:deno_node/vm.ts";
import workerThreads from "ext:deno_node/worker_threads.ts";
import wasi from "ext:deno_node/wasi.ts";
import zlib from "ext:deno_node/zlib.ts";
// Canonical mapping of supported modules
const moduleAll = {
"_http_agent": _httpAgent,
"_http_outgoing": _httpOutgoing,
"_stream_duplex": _streamDuplex,
"_stream_passthrough": _streamPassthrough,
"_stream_readable": _streamReadable,
"_stream_transform": _streamTransform,
"_stream_writable": _streamWritable,
assert,
"assert/strict": assertStrict,
"async_hooks": asyncHooks,
buffer,
crypto,
console,
constants,
child_process: childProcess,
cluster,
dgram,
diagnostics_channel: diagnosticsChannel,
dns,
"dns/promises": dnsPromises,
domain,
events,
fs,
"fs/promises": fsPromises,
http,
http2,
https,
inspector,
"internal/child_process": internalCp,
"internal/crypto/certificate": internalCryptoCertificate,
"internal/crypto/cipher": internalCryptoCipher,
"internal/crypto/diffiehellman": internalCryptoDiffiehellman,
"internal/crypto/hash": internalCryptoHash,
"internal/crypto/hkdf": internalCryptoHkdf,
"internal/crypto/keygen": internalCryptoKeygen,
"internal/crypto/keys": internalCryptoKeys,
"internal/crypto/pbkdf2": internalCryptoPbkdf2,
"internal/crypto/random": internalCryptoRandom,
"internal/crypto/scrypt": internalCryptoScrypt,
"internal/crypto/sig": internalCryptoSig,
"internal/crypto/util": internalCryptoUtil,
"internal/crypto/x509": internalCryptoX509,
"internal/dgram": internalDgram,
"internal/dns/promises": internalDnsPromises,
"internal/errors": internalErrors,
"internal/event_target": internalEventTarget,
"internal/fs/utils": internalFsUtils,
"internal/http": internalHttp,
"internal/readline/utils": internalReadlineUtils,
"internal/streams/add-abort-signal": internalStreamsAddAbortSignal,
"internal/streams/buffer_list": internalStreamsBufferList,
"internal/streams/lazy_transform": internalStreamsLazyTransform,
"internal/streams/state": internalStreamsState,
"internal/test/binding": internalTestBinding,
"internal/timers": internalTimers,
"internal/util/inspect": internalUtilInspect,
"internal/util": internalUtil,
net,
os,
"path/posix": pathPosix,
"path/win32": pathWin32,
path,
perf_hooks: perfHooks,
process,
get punycode() {
process.emitWarning(
"The `punycode` module is deprecated. Please use a userland " +
"alternative instead.",
"DeprecationWarning",
"DEP0040",
);
return punycode;
},
querystring,
readline,
"readline/promises": readlinePromises,
repl,
stream,
"stream/consumers": streamConsumers,
"stream/promises": streamPromises,
"stream/web": streamWeb,
string_decoder: stringDecoder,
sys,
timers,
"timers/promises": timersPromises,
tls,
tty,
url,
util,
"util/types": utilTypes,
v8,
vm,
wasi,
worker_threads: workerThreads,
zlib,
} as Record<string, unknown>;
internals.nodeModuleAll = moduleAll;
export default moduleAll;

View file

@ -72,28 +72,6 @@ const notImplementedEvents = [
export const argv: string[] = [];
// Overwrites the 1st item with getter.
// TODO(bartlomieju): added "configurable: true" to make this work for binary
// commands, but that is probably a wrong solution
// TODO(bartlomieju): move the configuration for all "argv" to
// "internals.__bootstrapNodeProcess"
Object.defineProperty(argv, "0", {
get: () => {
return Deno.execPath();
},
configurable: true,
});
// Overwrites the 2st item with getter.
Object.defineProperty(argv, "1", {
get: () => {
if (Deno.mainModule.startsWith("file:")) {
return fromFileUrl(Deno.mainModule);
} else {
return join(Deno.cwd(), "$deno$node.js");
}
},
});
/** https://nodejs.org/api/process.html#process_process_exit_code */
export const exit = (code?: number | string) => {
if (code || code === 0) {
@ -686,9 +664,35 @@ export const removeAllListeners = process.removeAllListeners;
// Should be called only once, in `runtime/js/99_main.js` when the runtime is
// bootstrapped.
internals.__bootstrapNodeProcess = function (
argv0: string | undefined,
args: string[],
denoVersions: Record<string, string>,
) {
// Overwrites the 1st item with getter.
if (typeof argv0 === "string") {
Object.defineProperty(argv, "0", {
get: () => {
return argv0;
},
});
} else {
Object.defineProperty(argv, "0", {
get: () => {
return Deno.execPath();
},
});
}
// Overwrites the 2st item with getter.
Object.defineProperty(argv, "1", {
get: () => {
if (Deno.mainModule.startsWith("file:")) {
return fromFileUrl(Deno.mainModule);
} else {
return join(Deno.cwd(), "$deno$node.js");
}
},
});
for (let i = 0; i < args.length; i++) {
argv[i + 2] = args[i];
}

View file

@ -296,8 +296,7 @@ mod startup_snapshot {
runtime::init_ops_and_esm(),
// FIXME(bartlomieju): these extensions are specified last, because they
// depend on `runtime`, even though it should be other way around
deno_node::deno_node_loading::init_ops_and_esm::<Permissions>(None),
deno_node::deno_node::init_ops_and_esm(),
deno_node::deno_node::init_ops_and_esm::<Permissions>(None),
#[cfg(not(feature = "snapshot_from_snapshot"))]
runtime_main::init_ops_and_esm(),
];

View file

@ -435,10 +435,9 @@ impl WebWorker {
deno_io::deno_io::init_ops(Some(options.stdio)),
deno_fs::deno_fs::init_ops::<PermissionsContainer>(unstable),
deno_flash::deno_flash::init_ops::<PermissionsContainer>(unstable),
deno_node::deno_node_loading::init_ops::<PermissionsContainer>(
deno_node::deno_node::init_ops::<PermissionsContainer>(
options.npm_resolver,
),
deno_node::deno_node::init_ops(),
// Runtime ops that are always initialized for WebWorkers
ops::web_worker::deno_web_worker::init_ops(),
ops::runtime::deno_runtime::init_ops(main_module.clone()),

View file

@ -257,10 +257,9 @@ impl MainWorker {
deno_io::deno_io::init_ops(Some(options.stdio)),
deno_fs::deno_fs::init_ops::<PermissionsContainer>(unstable),
deno_flash::deno_flash::init_ops::<PermissionsContainer>(unstable),
deno_node::deno_node_loading::init_ops::<PermissionsContainer>(
deno_node::deno_node::init_ops::<PermissionsContainer>(
options.npm_resolver,
),
deno_node::deno_node::init_ops(),
// Ops from this crate
ops::runtime::deno_runtime::init_ops(main_module.clone()),
ops::worker_host::deno_worker_host::init_ops(