| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 2bce35b commit b97c7be
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,6 +19,7 @@ const { globalIgnores } = await importEslintTool('eslint/config'); | |||
| 19 | 19 | const { default: js } = await importEslintTool('@eslint/js'); | |
| 20 | 20 | const { default: babelEslintParser } = await importEslintTool('@babel/eslint-parser'); | |
| 21 | 21 | const babelPluginSyntaxImportSource = resolveEslintTool('@babel/plugin-syntax-import-source'); | |
| 22 | + const babelPluginImportDefer = resolveEslintTool('@babel/plugin-syntax-import-defer'); | ||
| 22 | 23 | const { default: jsdoc } = await importEslintTool('eslint-plugin-jsdoc'); | |
| 23 | 24 | const { default: regexpPlugin } = await importEslintTool('eslint-plugin-regexp'); | |
| 24 | 25 | const { default: markdown } = await importEslintTool('@eslint/markdown'); | |
@@ -105,6 +106,7 @@ export default [ | |||
| 105 | 106 | babelOptions: { | |
| 106 | 107 | plugins: [ | |
| 107 | 108 | babelPluginSyntaxImportSource, | |
| 109 | + babelPluginImportDefer, | ||
| 108 | 110 | ], | |
| 109 | 111 | }, | |
| 110 | 112 | requireConfigFile: false, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,7 @@ const { | |||
| 28 | 28 | kErrored, | |
| 29 | 29 | kEvaluated, | |
| 30 | 30 | kEvaluating, | |
| 31 | + kDeferPhase, | ||
| 31 | 32 | kEvaluationPhase, | |
| 32 | 33 | kInstantiated, | |
| 33 | 34 | kUninstantiated, | |
@@ -164,7 +165,7 @@ class ModuleJobBase { | |||
| 164 | 165 | debug(`ModuleJobBase.syncLink() ${this.url} -> ${request.specifier}`, job); | |
| 165 | 166 | assert(!isPromise(job)); | |
| 166 | 167 | assert(job.module instanceof ModuleWrap); | |
| 167 | - if (request.phase === kEvaluationPhase) { | ||
| 168 | + if (this.shouldRunModule(request.phase)) { | ||
| 168 | 169 | ArrayPrototypePush(evaluationDepJobs, job); | |
| 169 | 170 | } | |
| 170 | 171 | modules[idx] = job.module; | |
@@ -199,6 +200,13 @@ class ModuleJobBase { | |||
| 199 | 200 | } | |
| 200 | 201 | } | |
| 201 | 202 | } | |
| 203 | + | ||
| 204 | + shouldLinkModule(phase) { | ||
| 205 | + return phase >= kDeferPhase; | ||
| 206 | + } | ||
| 207 | + shouldRunModule(phase) { | ||
| 208 | + return phase === kEvaluationPhase; | ||
| 209 | + } | ||
| 202 | 210 | } | |
| 203 | 211 | ||
| 204 | 212 | /* A ModuleJob tracks the loading of a single Module, and the ModuleJobs of | |
@@ -227,7 +235,7 @@ class ModuleJob extends ModuleJobBase { | |||
| 227 | 235 | this.modulePromise = PromiseResolve(moduleOrModulePromise); | |
| 228 | 236 | } | |
| 229 | 237 | ||
| 230 | - if (this.phase === kEvaluationPhase) { | ||
| 238 | + if (this.shouldLinkModule(this.phase)) { | ||
| 231 | 239 | // Promise for the list of all dependencyJobs. | |
| 232 | 240 | this.linked = this.link(requestType); | |
| 233 | 241 | // This promise is awaited later anyway, so silence | |
@@ -279,7 +287,7 @@ class ModuleJob extends ModuleJobBase { | |||
| 279 | 287 | const dependencyJobPromise = this.loader.getOrCreateModuleJob(this.url, request, requestType); | |
| 280 | 288 | const modulePromise = PromisePrototypeThen(dependencyJobPromise, (job) => { | |
| 281 | 289 | debug(`ModuleJob.asyncLink() ${this.url} -> ${request.specifier}`, job); | |
| 282 | - if (request.phase === kEvaluationPhase) { | ||
| 290 | + if (this.shouldRunModule(request.phase)) { | ||
| 283 | 291 | ArrayPrototypePush(evaluationDepJobs, job); | |
| 284 | 292 | } | |
| 285 | 293 | return job.modulePromise; | |
@@ -380,7 +388,7 @@ class ModuleJob extends ModuleJobBase { | |||
| 380 | 388 | } | |
| 381 | 389 | ||
| 382 | 390 | runSync(parent) { | |
| 383 | - assert(this.phase === kEvaluationPhase); | ||
| 391 | + assert(this.shouldRunModule(this.phase)); | ||
| 384 | 392 | assert(this.module instanceof ModuleWrap); | |
| 385 | 393 | let status = this.module.getStatus(); | |
| 386 | 394 | ||
@@ -427,7 +435,7 @@ class ModuleJob extends ModuleJobBase { | |||
| 427 | 435 | ||
| 428 | 436 | async run(isEntryPoint = false) { | |
| 429 | 437 | debug('ModuleJob.run()', this.module); | |
| 430 | - assert(this.phase === kEvaluationPhase); | ||
| 438 | + assert(this.shouldRunModule(this.phase)); | ||
| 431 | 439 | await this.#instantiate(); | |
| 432 | 440 | if (isEntryPoint) { | |
| 433 | 441 | globalThis[entry_point_module_private_symbol] = this.module; | |
@@ -475,7 +483,7 @@ class ModuleJobSync extends ModuleJobBase { | |||
| 475 | 483 | assert(this.module instanceof ModuleWrap); | |
| 476 | 484 | this.linked = undefined; | |
| 477 | 485 | this.type = importAttributes.type; | |
| 478 | - if (phase === kEvaluationPhase) { | ||
| 486 | + if (this.shouldLinkModule(phase)) { | ||
| 479 | 487 | this.linked = this.link(requestType); | |
| 480 | 488 | } | |
| 481 | 489 | } | |
@@ -494,7 +502,7 @@ class ModuleJobSync extends ModuleJobBase { | |||
| 494 | 502 | } | |
| 495 | 503 | ||
| 496 | 504 | async run() { | |
| 497 | - assert(this.phase === kEvaluationPhase); | ||
| 505 | + assert(this.shouldRunModule(this.phase)); | ||
| 498 | 506 | // This path is hit by a require'd module that is imported again. | |
| 499 | 507 | const status = this.module.getStatus(); | |
| 500 | 508 | debug('ModuleJobSync.run()', status, this.module); | |
@@ -523,7 +531,7 @@ class ModuleJobSync extends ModuleJobBase { | |||
| 523 | 531 | ||
| 524 | 532 | runSync(parent) { | |
| 525 | 533 | debug('ModuleJobSync.runSync()', this.module); | |
| 526 | - assert(this.phase === kEvaluationPhase); | ||
| 534 | + assert(this.shouldRunModule(this.phase)); | ||
| 527 | 535 | // TODO(joyeecheung): add the error decoration logic from the async instantiate. | |
| 528 | 536 | this.module.instantiate(); | |
| 529 | 537 | // If --experimental-print-required-tla is true, proceeds to evaluation even | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -555,6 +555,8 @@ ModulePhase to_phase_constant(ModuleImportPhase phase) { | |||
| 555 | 555 | switch (phase) { | |
| 556 | 556 | case ModuleImportPhase::kEvaluation: | |
| 557 | 557 | return kEvaluationPhase; | |
| 558 | + case ModuleImportPhase::kDefer: | ||
| 559 | + return kDeferPhase; | ||
| 558 | 560 | case ModuleImportPhase::kSource: | |
| 559 | 561 | return kSourcePhase; | |
| 560 | 562 | default: | |
@@ -1682,6 +1684,7 @@ void ModuleWrap::CreatePerContextProperties(Local<Object> target, | |||
| 1682 | 1684 | V(Module::Status, kErrored); | |
| 1683 | 1685 | ||
| 1684 | 1686 | V(ModulePhase, kEvaluationPhase); | |
| 1687 | + V(ModulePhase, kDeferPhase); | ||
| 1685 | 1688 | V(ModulePhase, kSourcePhase); | |
| 1686 | 1689 | #undef V | |
| 1687 | 1690 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,7 +35,8 @@ enum HostDefinedOptions : int { | |||
| 35 | 35 | ||
| 36 | 36 | enum ModulePhase : int { | |
| 37 | 37 | kSourcePhase = 1, | |
| 38 | - kEvaluationPhase = 2, | ||
| 38 | + kDeferPhase = 2, | ||
| 39 | + kEvaluationPhase = 3, | ||
| 39 | 40 | }; | |
| 40 | 41 | ||
| 41 | 42 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,25 @@ | |||
| 1 | + // Flags: --js-defer-import-eval | ||
| 2 | + | ||
| 3 | + // Tests that defer import actually evaluates the imported module | ||
| 4 | + // only when properties that it exports are accessed. | ||
| 5 | + | ||
| 6 | + import '../common/index.mjs'; | ||
| 7 | + import * as assert from 'assert'; | ||
| 8 | + | ||
| 9 | + globalThis.eval_list = []; | ||
| 10 | + | ||
| 11 | + import defer * as deferred from '../fixtures/es-modules/module-deferred-eval.mjs'; | ||
| 12 | + | ||
| 13 | + assert.strictEqual(globalThis.eval_list.length, 0); | ||
| 14 | + | ||
| 15 | + // Attempts to define a property on the deferred module. This should | ||
| 16 | + // trigger its execution, similar to accessing the `foo` property. | ||
| 17 | + assert.throws(() => Object.defineProperty(deferred.prop, 'newProp', { value: 15 }), TypeError); | ||
| 18 | + | ||
| 19 | + assert.strictEqual(deferred.foo, 42); | ||
| 20 | + | ||
| 21 | + // Check that the module has been evaluated at this point. | ||
| 22 | + assert.partialDeepStrictEqual(['defer-1'], globalThis.eval_list); | ||
| 23 | + | ||
| 24 | + // Clean-up | ||
| 25 | + delete globalThis.eval_list; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,9 @@ | |||
| 1 | + // Flags: --js-defer-import-eval | ||
| 2 | + | ||
| 3 | + import '../common/index.mjs'; | ||
| 4 | + | ||
| 5 | + import defer * as deferred from '../fixtures/es-modules/module-with-module-tree.mjs'; | ||
| 6 | + | ||
| 7 | + console.log(deferred.bar); | ||
| 8 | + | ||
| 9 | + delete globalThis.eval_list; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,8 @@ | |||
| 1 | + if (!globalThis.eval_list) { | ||
| 2 | + globalThis.eval_list = []; | ||
| 3 | + } | ||
| 4 | + globalThis.eval_list.push('defer-1'); | ||
| 5 | + | ||
| 6 | + export const foo = 42; | ||
| 7 | + | ||
| 8 | + console.log('executed'); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + import './module-deferred-eval.mjs'; | ||
| 2 | + | ||
| 3 | + export const bar = 64; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,6 +5,7 @@ | |||
| 5 | 5 | "dependencies": { | |
| 6 | 6 | "@babel/core": "^8.0.0-rc.6", | |
| 7 | 7 | "@babel/eslint-parser": "^8.0.0-rc.6", | |
| 8 | + "@babel/plugin-syntax-import-defer": "^8.0.0-rc.6", | ||
| 8 | 9 | "@babel/plugin-syntax-import-source": "^8.0.0-rc.6", | |
| 9 | 10 | "@eslint/js": "^10.0.1", | |
| 10 | 11 | "@eslint/markdown": "^8.0.2", | |
| Back | FazBrowse Home | New Git URL |
0 commit comments