| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 8192dd6 commit 8d33f78
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,7 +21,7 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { | |||
| 21 | 21 | debug = fn; | |
| 22 | 22 | }); | |
| 23 | 23 | ||
| 24 | - const { ModuleWrap, kEvaluated } = internalBinding('module_wrap'); | ||
| 24 | + const { ModuleWrap, kInstantiated } = internalBinding('module_wrap'); | ||
| 25 | 25 | ||
| 26 | 26 | const { decorateErrorStack, kEmptyObject } = require('internal/util'); | |
| 27 | 27 | const { | |
@@ -346,10 +346,26 @@ class ModuleJobSync extends ModuleJobBase { | |||
| 346 | 346 | } | |
| 347 | 347 | ||
| 348 | 348 | async run() { | |
| 349 | + // This path is hit by a require'd module that is imported again. | ||
| 349 | 350 | const status = this.module.getStatus(); | |
| 350 | - assert(status === kEvaluated, | ||
| 351 | - `A require()-d module that is imported again must be evaluated. Status = ${status}`); | ||
| 352 | - return { __proto__: null, module: this.module }; | ||
| 351 | + if (status > kInstantiated) { | ||
| 352 | + if (this.evaluationPromise) { | ||
| 353 | + await this.evaluationPromise; | ||
| 354 | + } | ||
| 355 | + return { __proto__: null, module: this.module }; | ||
| 356 | + } else if (status === kInstantiated) { | ||
| 357 | + // The evaluation may have been canceled because instantiateSync() detected TLA first. | ||
| 358 | + // But when it is imported again, it's fine to re-evaluate it asynchronously. | ||
| 359 | + const timeout = -1; | ||
| 360 | + const breakOnSigint = false; | ||
| 361 | + this.evaluationPromise = this.module.evaluate(timeout, breakOnSigint); | ||
| 362 | + await this.evaluationPromise; | ||
| 363 | + this.evaluationPromise = undefined; | ||
| 364 | + return { __proto__: null, module: this.module }; | ||
| 365 | + } | ||
| 366 | + | ||
| 367 | + assert.fail('Unexpected status of a module that is imported again after being required. ' + | ||
| 368 | + `Status = ${status}`); | ||
| 353 | 369 | } | |
| 354 | 370 | ||
| 355 | 371 | runSync() { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,35 @@ | |||
| 1 | + // This tests that after failing to require an ESM that contains TLA, | ||
| 2 | + // retrying with import() still works, and produces consistent results. | ||
| 3 | + 'use strict'; | ||
| 4 | + const common = require('../common'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + | ||
| 7 | + const { exportedReject } = require('../fixtures/es-modules/tla/export-promise.mjs'); | ||
| 8 | + | ||
| 9 | + assert.throws(() => { | ||
| 10 | + require('../fixtures/es-modules/tla/await-export-promise.mjs'); | ||
| 11 | + }, { | ||
| 12 | + code: 'ERR_REQUIRE_ASYNC_MODULE' | ||
| 13 | + }); | ||
| 14 | + | ||
| 15 | + const interval = setInterval(() => {}, 1000); // Keep the test running, because await alone doesn't. | ||
| 16 | + const err = new Error('rejected'); | ||
| 17 | + | ||
| 18 | + const p1 = import('../fixtures/es-modules/tla/await-export-promise.mjs') | ||
| 19 | + .then(common.mustNotCall(), common.mustCall((e) => { | ||
| 20 | + assert.strictEqual(e, err); | ||
| 21 | + })); | ||
| 22 | + | ||
| 23 | + const p2 = import('../fixtures/es-modules/tla/await-export-promise.mjs') | ||
| 24 | + .then(common.mustNotCall(), common.mustCall((e) => { | ||
| 25 | + assert.strictEqual(e, err); | ||
| 26 | + })); | ||
| 27 | + | ||
| 28 | + const p3 = import('../fixtures/es-modules/tla/await-export-promise.mjs') | ||
| 29 | + .then(common.mustNotCall(), common.mustCall((e) => { | ||
| 30 | + assert.strictEqual(e, err); | ||
| 31 | + })); | ||
| 32 | + | ||
| 33 | + exportedReject(err); | ||
| 34 | + | ||
| 35 | + Promise.all([p1, p2, p3]).then(common.mustCall(() => { clearInterval(interval); })); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,32 @@ | |||
| 1 | + // This tests that after failing to require an ESM that contains TLA, | ||
| 2 | + // retrying with import() still works, and produces consistent results. | ||
| 3 | + 'use strict'; | ||
| 4 | + const common = require('../common'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + | ||
| 7 | + const { exportedResolve } = require('../fixtures/es-modules/tla/export-promise.mjs'); | ||
| 8 | + | ||
| 9 | + assert.throws(() => { | ||
| 10 | + require('../fixtures/es-modules/tla/await-export-promise.mjs'); | ||
| 11 | + }, { | ||
| 12 | + code: 'ERR_REQUIRE_ASYNC_MODULE' | ||
| 13 | + }); | ||
| 14 | + | ||
| 15 | + const interval = setInterval(() => {}, 1000); // Keep the test running, because await alone doesn't. | ||
| 16 | + const value = { hello: 'world' }; | ||
| 17 | + | ||
| 18 | + const p1 = import('../fixtures/es-modules/tla/await-export-promise.mjs').then(common.mustCall((ns) => { | ||
| 19 | + assert.strictEqual(ns.default, value); | ||
| 20 | + }), common.mustNotCall()); | ||
| 21 | + | ||
| 22 | + const p2 = import('../fixtures/es-modules/tla/await-export-promise.mjs').then(common.mustCall((ns) => { | ||
| 23 | + assert.strictEqual(ns.default, value); | ||
| 24 | + }), common.mustNotCall()); | ||
| 25 | + | ||
| 26 | + const p3 = import('../fixtures/es-modules/tla/await-export-promise.mjs').then(common.mustCall((ns) => { | ||
| 27 | + assert.strictEqual(ns.default, value); | ||
| 28 | + }), common.mustNotCall()); | ||
| 29 | + | ||
| 30 | + exportedResolve(value); | ||
| 31 | + | ||
| 32 | + Promise.all([p1, p2, p3]).then(common.mustCall(() => { clearInterval(interval); })); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,26 @@ | |||
| 1 | + // This tests that after loading a ESM with import() and then retrying | ||
| 2 | + // with require(), it errors as expected, and produces consistent results. | ||
| 3 | + 'use strict'; | ||
| 4 | + const common = require('../common'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + | ||
| 7 | + let ns; | ||
| 8 | + async function test() { | ||
| 9 | + const newNs = await import('../fixtures/es-modules/tla/export-async.mjs'); | ||
| 10 | + if (ns === undefined) { | ||
| 11 | + ns = newNs; | ||
| 12 | + } else { | ||
| 13 | + // Check that re-evalaution is returning the same namespace. | ||
| 14 | + assert.strictEqual(ns, newNs); | ||
| 15 | + } | ||
| 16 | + assert.strictEqual(ns.hello, 'world'); | ||
| 17 | + | ||
| 18 | + assert.throws(() => { | ||
| 19 | + require('../fixtures/es-modules/tla/export-async.mjs'); | ||
| 20 | + }, { | ||
| 21 | + code: 'ERR_REQUIRE_ASYNC_MODULE' | ||
| 22 | + }); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + // Run the test twice to check consistency after caching. | ||
| 26 | + test().then(common.mustCall(test)).catch(common.mustNotCall()); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,25 @@ | |||
| 1 | + // This tests that after failing to require an ESM that contains TLA, | ||
| 2 | + // retrying with import() still works, and produces consistent results. | ||
| 3 | + 'use strict'; | ||
| 4 | + const common = require('../common'); | ||
| 5 | + const assert = require('assert'); | ||
| 6 | + | ||
| 7 | + let ns; | ||
| 8 | + async function test() { | ||
| 9 | + assert.throws(() => { | ||
| 10 | + require('../fixtures/es-modules/tla/export-async.mjs'); | ||
| 11 | + }, { | ||
| 12 | + code: 'ERR_REQUIRE_ASYNC_MODULE' | ||
| 13 | + }); | ||
| 14 | + const newNs = await import('../fixtures/es-modules/tla/export-async.mjs'); | ||
| 15 | + if (ns === undefined) { | ||
| 16 | + ns = newNs; | ||
| 17 | + } else { | ||
| 18 | + // Check that re-evalaution is returning the same namespace. | ||
| 19 | + assert.strictEqual(ns, newNs); | ||
| 20 | + } | ||
| 21 | + assert.strictEqual(ns.hello, 'world'); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + // Run the test twice to check consistency after caching. | ||
| 25 | + test().then(common.mustCall(test)).catch(common.mustNotCall()); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,4 @@ | |||
| 1 | + import promise from './export-promise.mjs'; | ||
| 2 | + let result; | ||
| 3 | + result = await promise; | ||
| 4 | + export default result; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + let hello = await Promise.resolve('world'); | ||
| 2 | + export { hello }; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,8 @@ | |||
| 1 | + let exportedResolve; | ||
| 2 | + let exportedReject; | ||
| 3 | + const promise = new Promise((resolve, reject) => { | ||
| 4 | + exportedResolve = resolve; | ||
| 5 | + exportedReject = reject; | ||
| 6 | + }); | ||
| 7 | + export default promise; | ||
| 8 | + export { exportedResolve, exportedReject }; | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments