Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
c72a678
doc: add missing link for v13.11.0 changelog
MylesBorins Mar 12, 2020
397cbca
meta: move inactive collaborators to emeriti
Trott Mar 8, 2020
19fee76
doc: add Ruben to TSC
mhdawson Mar 11, 2020
cd0982a
lib: change var to let/const
himself65 Mar 2, 2020
2262e7c
test: fix test-tls-env-extra-ca-file-load
ebickle Mar 3, 2020
d497f26
src: refactor to more safe method
gengjiawen Mar 4, 2020
08edf53
test: `buffer.write` with longer string scenario
HarshithaKP Mar 6, 2020
435341a
lib: use spread operator on cluster
himself65 Mar 6, 2020
2069c4e
build: disable libstdc++ debug containers globally
bnoordhuis Jan 3, 2020
53fd0d8
util: use a global symbol for `util.promisify.custom`
ExE-Boss Feb 7, 2020
5080734
doc: expand fs.watch caveats
bzoz Mar 10, 2020
1ecd407
repl: align preview with the actual executed code
BridgeAR Feb 24, 2020
ed83a1c
test: refactor and simplify test-repl-preview
BridgeAR Mar 9, 2020
597bcb5
doc: update conditional exports recommendations
guybedford Mar 4, 2020
e83dcde
worker: allow URL in Worker constructor
aduh95 Feb 6, 2020
c0af3ac
test: use portable EOL
HarshithaKP Mar 5, 2020
d2fea9f
http2: rename counter in `mapToHeaders` inner loop
mkrawczuk Feb 28, 2020
fd80c21
test: add new scenario for async-local storage
HarshithaKP Mar 4, 2020
ae90bcc
deps: V8: cherry-pick f9257802c1c0
mmarchini Mar 10, 2020
fa1fa31
util: text decoding allows SharedArrayBuffer
bfarias-godaddy Mar 11, 2020
3e9012a
esm: port loader code to JS
addaleax Mar 7, 2020
09ca76b
test: verify that WASI errors are rethrown
cjihrig Mar 9, 2020
bee1261
deps: upgrade to libuv 1.35.0
cjihrig Mar 11, 2020
963ce08
tools: update to [email protected]
Trott Mar 14, 2020
fbcf602
test: make test-memory-usage predictable
mmarchini Mar 12, 2020
7fc5e6d
src: fix warn_unused_result compiler warning
cjihrig Mar 13, 2020
df1d4f7
test: workaround for V8 8.1 inspector pause issue
mmarchini Mar 12, 2020
c00ce7b
src: find .text section using dl_iterate_phdr
Mar 13, 2020
1950c08
src: unconditionally include report feature
cjihrig Mar 13, 2020
96ad768
build: remove node_report option in node.gyp
cjihrig Mar 13, 2020
074c3c1
build: make --without-report a no-op
cjihrig Mar 13, 2020
76781bd
test: remove common.skipIfReportDisabled()
cjihrig Mar 13, 2020
cd388b2
doc,lib,src,test: make --experimental-report a nop
cjihrig Mar 13, 2020
2e1fb2b
doc: update stability of report features
cjihrig Mar 13, 2020
59a21e2
n-api: fix comment on expected N-API version
mhdawson Mar 12, 2020
5adaf10
tools: update [email protected]
Trott Mar 14, 2020
b5b7bf5
src,cli: support compact (one-line) JSON reports
sam-github Mar 13, 2020
11ed1e6
deps,doc: move openssl maintenance guide to doc
sam-github Mar 11, 2020
71a2fa2
errors: drop pronouns from ERR_WORKER_PATH message
cjihrig Mar 15, 2020
1476182
src: handle NULL env scenario
himself65 Mar 12, 2020
05fd160
test: use Promise.all() in test-hash-seed
Trott Mar 14, 2020
ef32069
http: don't emit 'finish' after 'error'
ronag Mar 14, 2020
36ba54e
lib: add option to disable __proto__
devsnek Mar 15, 2020
b875346
doc: complete n-api version matrix
Mar 16, 2020
d2ce8e9
doc: fix some 404 links
watson Mar 11, 2020
dedd219
tools: fixup icutrim.py use of string and bytes objects
jmercier-lbi Feb 6, 2020
7904ecd
deps: update to uvwasi 0.0.6
cjihrig Mar 15, 2020
1c4a112
src: clean up stream_base.h and stream-base-inl.h
jasnell Mar 16, 2020
569e555
doc: update security release process
sam-github Feb 7, 2020
f873d87
src: prefer OnScopeLeave over shared_ptr<void>
addaleax Mar 13, 2020
3825afe
deps: upgrade to c-ares v1.16.0
addaleax Mar 13, 2020
79fdc6b
cli: allow --huge-max-old-generation-size in NODE_OPTIONS
addaleax Mar 13, 2020
4d173ea
test: uv_tty_init returns EBADF on IBM i
dmabupt Mar 18, 2020
243d0d4
src: add debug option to report large page stats
Mar 17, 2020
8ea5ffc
build: expand ASAN acronym in configure help
sam-github Mar 17, 2020
e16964e
deps: minor ICU fixes: maint docs/tool, downloader
srl295 Mar 18, 2020
2cb9f7a
deps: update to ICU 66.1
srl295 Mar 18, 2020
11650c6
src: update comment for SetImmediate()
addaleax Mar 16, 2020
bd55a9a
src: avoid Isolate::GetCurrent() for platform implementation
addaleax Mar 14, 2020
85bdb42
Revert "build: add asan check in Github action"
mmarchini Mar 11, 2020
bdcc11f
test: replace Map with Array in cluster-net-listen tests
Trott Mar 18, 2020
2e28783
test: replace countdown with Promise.all() in cluster-net-listen tests
Trott Mar 19, 2020
7356c43
module: add hook for global preload code
hybrist Mar 3, 2020
3878d8d
deps: upgrade openssl sources to 1.1.1e
hassaanp Mar 17, 2020
d719f87
deps: adjust openssl configuration for 1.1.1e
hassaanp Mar 18, 2020
d640426
deps: update archs files for OpenSSL-1.1.1e
hassaanp Mar 18, 2020
fcf9b46
test: discard data received by client
hassaanp Mar 19, 2020
76a7386
test: end tls connection with some data
sam-github Mar 20, 2020
2fe351f
src: delete CallbackInfo when cleared from cleanup hook
addaleax Mar 21, 2020
2bcf535
src: simplify IsolateData shortcut accesses
addaleax Mar 21, 2020
6f06cf0
src: delete BaseObjectWeakPtr data when pointee is gone
addaleax Mar 20, 2020
2f73e6e
test: use mustCall in place of countdown in timers test
Trott Mar 22, 2020
fbdc4f5
deps: upgrade npm to 6.14.1
isaacs Feb 27, 2020
eef4721
deps: update npm to 6.14.3
MylesBorins Mar 19, 2020
8201704
deps: remove *.pyc files from deps/npm
bnoordhuis Mar 20, 2020
6387cf8
deps: update term-size with signed version
rvagg Jan 30, 2020
f8a020e
build: macOS package notarization
rvagg Jan 22, 2020
99f260f
doc: official macOS builds now on 10.15 + Xcode 11
rvagg Mar 4, 2020
471a5d8
doc: add note re term-size commit on top of npm
rvagg Mar 21, 2020
23ba088
stream: don't emit 'finish' after 'error'
ronag Mar 14, 2020
4ca3030
doc: import clarifications with links to MDN
aldeed Mar 18, 2020
81183ca
build: annotate markdown lint failures in pull requests
richardlau Mar 20, 2020
bbea3f2
doc: improve wording in esm.md
Trott Mar 22, 2020
dfcc3e8
doc: improve wording in vm.md
Trott Mar 22, 2020
07e4131
test: refactoring / cleanup on child-process tests
jasnell Mar 23, 2020
99a7636
doc: fix lint warning in doc/api/esm.md
richardlau Mar 24, 2020
b5e4adf
doc: add new TSC members
mhdawson Mar 24, 2020
0185e3a
stream: add pipeline test for destroy of returned stream
ronag Mar 22, 2020
b7a8878
stream: fix pipeline with dest in objectMode
ronag Mar 21, 2020
28e298f
report: handle on-fatalerror better
HarshithaKP Mar 16, 2020
e9e12b8
src: use single ObjectTemplate for TextDecoder
addaleax Mar 22, 2020
94952b4
src: enhance C++ sprintf utility
himself65 Mar 20, 2020
6693b40
doc: simplify and correct example descriptions in net.md
Trott Mar 24, 2020
3e002c3
doc: update async_hooks.md
Doc999tor Mar 20, 2020
9fda912
doc: trim wording in n-api.md text about exceptions
Trott Mar 24, 2020
6168bd5
doc: remove unnecessary "obvious(ly)" modifiers in esm.md
Trott Mar 24, 2020
40a9289
doc: remove extraneous sentence in events.md
Trott Mar 24, 2020
deab08b
deps: upgrade npm to 6.14.4
ruyadorno Mar 26, 2020
56da8df
stream: emit 'pause' on unpipe
ronag Mar 24, 2020
f6a339f
2020-03-26 Version 13.12.0 (Current)
MylesBorins Mar 24, 2020
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
Prev Previous commit
Next Next commit
module: add hook for global preload code
PR-URL: #32068
Reviewed-By: Bradley Farias <[email protected]>
Reviewed-By: Geoffrey Booth <[email protected]>
  • Loading branch information
hybrist authored and MylesBorins committed Mar 24, 2020
commit 7356c43997d791206bd3f1477ad420f34249517f
33 changes: 33 additions & 0 deletions doc/api/esm.md
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,39 @@ export async function transformSource(source,
}
```

#### <code>getGlobalPreloadCode</code> hook

> Note: The loaders API is being redesigned. This hook may disappear or its
> signature may change. Do not rely on the API described below.

Sometimes it can be necessary to run some code inside of the same global scope
that the application will run in. This hook allows to return a string that will
be ran as sloppy-mode script on startup.

Similar to how CommonJS wrappers work, the code runs in an implicit function
scope. The only argument is a `require`-like function that can be used to load
builtins like "fs": `getBuiltin(request: string)`.

If the code needs more advanced `require` features, it will have to construct
its own `require` using `module.createRequire()`.

```js
/**
* @returns {string} Code to run before application startup
*/
export function getGlobalPreloadCode() {
return `\
globalThis.someInjectedProperty = 42;
console.log('I just set some globals!');

const { createRequire } = getBuiltin('module');

const require = createRequire(process.cwd + '/<preload>');
// [...]
`;
}
```

#### <code>dynamicInstantiate</code> hook

> Note: The loaders API is being redesigned. This hook may disappear or its
Expand Down
51 changes: 50 additions & 1 deletion lib/internal/modules/esm/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {
} = primordials;

const {
ERR_INVALID_ARG_VALUE,
ERR_INVALID_RETURN_PROPERTY,
ERR_INVALID_RETURN_PROPERTY_VALUE,
ERR_INVALID_RETURN_VALUE,
Expand Down Expand Up @@ -47,6 +48,14 @@ class Loader {
// Map of already-loaded CJS modules to use
this.cjsCache = new SafeMap();

// This hook is called before the first root module is imported. It's a
// function that returns a piece of code that runs as a sloppy-mode script.
// The script may evaluate to a function that can be called with a
// `getBuiltin` helper that can be used to retrieve builtins.
// If the hook returns `null` instead of a source string, it opts out of
// running any preload code.
// The preload code runs as soon as the hook module has finished evaluating.
this._getGlobalPreloadCode = null;
// The resolver has the signature
// (specifier : string, parentURL : string, defaultResolve)
// -> Promise<{ url : string }>
Expand Down Expand Up @@ -168,7 +177,16 @@ class Loader {
return module.getNamespace();
}

hook({ resolve, dynamicInstantiate, getFormat, getSource, transformSource }) {
hook(hooks) {
const {
resolve,
dynamicInstantiate,
getFormat,
getSource,
transformSource,
getGlobalPreloadCode,
} = hooks;

// Use .bind() to avoid giving access to the Loader instance when called.
if (resolve !== undefined)
this._resolve = FunctionPrototypeBind(resolve, null);
Expand All @@ -185,6 +203,37 @@ class Loader {
if (transformSource !== undefined) {
this._transformSource = FunctionPrototypeBind(transformSource, null);
}
if (getGlobalPreloadCode !== undefined) {
this._getGlobalPreloadCode =
FunctionPrototypeBind(getGlobalPreloadCode, null);
}
}

runGlobalPreloadCode() {
if (!this._getGlobalPreloadCode) {
return;
}
const preloadCode = this._getGlobalPreloadCode();
if (preloadCode === null) {
return;
}

if (typeof preloadCode !== 'string') {
throw new ERR_INVALID_RETURN_VALUE(
'string', 'loader getGlobalPreloadCode', preloadCode);
}
const { compileFunction } = require('vm');
const preloadInit = compileFunction(preloadCode, ['getBuiltin'], {
filename: '<preload>',
});
const { NativeModule } = require('internal/bootstrap/loaders');

preloadInit.call(globalThis, (builtinName) => {
if (NativeModule.canBeRequiredByUsers(builtinName)) {
return require(builtinName);
}
throw new ERR_INVALID_ARG_VALUE('builtinName', builtinName);
});
}

async getModuleJob(specifier, parentURL) {
Expand Down
1 change: 1 addition & 0 deletions lib/internal/process/esm_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ async function initializeLoader() {
await ESMLoader.import(userLoader, pathToFileURL(cwd).href);
ESMLoader = new Loader();
ESMLoader.hook(hooks);
ESMLoader.runGlobalPreloadCode();
return exports.ESMLoader = ESMLoader;
})();
}
32 changes: 32 additions & 0 deletions test/es-module/test-esm-loader-side-effect.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Flags: --experimental-loader ./test/fixtures/es-module-loaders/loader-side-effect.mjs --require ./test/fixtures/es-module-loaders/loader-side-effect-require-preload.js
import { allowGlobals, mustCall } from '../common/index.mjs';
import assert from 'assert';
import { fileURLToPath } from 'url';
import { Worker, isMainThread, parentPort } from 'worker_threads';

/* global implicitGlobalProperty */
assert.strictEqual(globalThis.implicitGlobalProperty, 42);
allowGlobals(implicitGlobalProperty);

/* global implicitGlobalConst */
assert.strictEqual(implicitGlobalConst, 42 * 42);
allowGlobals(implicitGlobalConst);

/* global explicitGlobalProperty */
assert.strictEqual(globalThis.explicitGlobalProperty, 42 * 42 * 42);
allowGlobals(explicitGlobalProperty);

/* global preloadOrder */
assert.deepStrictEqual(globalThis.preloadOrder, ['--require', 'loader']);
allowGlobals(preloadOrder);

if (isMainThread) {
const worker = new Worker(fileURLToPath(import.meta.url));
const promise = new Promise((resolve, reject) => {
worker.on('message', resolve);
worker.on('error', reject);
});
promise.then(mustCall());
} else {
parentPort.postMessage('worker done');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* This file is combined with `loader-side-effect.mjs` via `--require`. Its
* purpose is to test execution order of the two kinds of preload code.
*/

(globalThis.preloadOrder || (globalThis.preloadOrder = [])).push('--require');
32 changes: 32 additions & 0 deletions test/fixtures/es-module-loaders/loader-side-effect.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Arrow function so it closes over the this-value of the preload scope.
const globalPreload = () => {
/* global getBuiltin */
const assert = getBuiltin('assert');
const vm = getBuiltin('vm');

assert.strictEqual(typeof require, 'undefined');
assert.strictEqual(typeof module, 'undefined');
assert.strictEqual(typeof exports, 'undefined');
assert.strictEqual(typeof __filename, 'undefined');
assert.strictEqual(typeof __dirname, 'undefined');

assert.strictEqual(this, globalThis);
(globalThis.preloadOrder || (globalThis.preloadOrder = [])).push('loader');

vm.runInThisContext(`\
var implicitGlobalProperty = 42;
const implicitGlobalConst = 42 * 42;
`);

assert.strictEqual(globalThis.implicitGlobalProperty, 42);
(implicitGlobalProperty).foo = 'bar'; // assert: not strict mode

globalThis.explicitGlobalProperty = 42 * 42 * 42;
}

export function getGlobalPreloadCode() {
return `\
<!-- assert: inside of script goal -->
(${globalPreload.toString()})();
`;
}