| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -76,6 +76,21 @@ $ node --completion-bash > node_bash_completion | |||
| 76 | 76 | $ source node_bash_completion | |
| 77 | 77 | ``` | |
| 78 | 78 | ||
| 79 | + ### `-u`, `--conditions=condition` | ||
| 80 | + <!-- YAML | ||
| 81 | + added: REPLACEME | ||
| 82 | + --> | ||
| 83 | + | ||
| 84 | + > Stability: 1 - Experimental | ||
| 85 | + | ||
| 86 | + Enable experimental support for custom conditional exports resolution | ||
| 87 | + conditions. | ||
| 88 | + | ||
| 89 | + Any number of custom string condition names are permitted. | ||
| 90 | + | ||
| 91 | + The default Node.js conditions of `"node"`, `"default"`, `"import"`, and | ||
| 92 | + `"require"` will always apply as defined. | ||
| 93 | + | ||
| 79 | 94 | ### `--cpu-prof` | |
| 80 | 95 | <!-- YAML | |
| 81 | 96 | added: v12.0.0 | |
@@ -1199,6 +1214,7 @@ node --require "./a.js" --require "./b.js" | |||
| 1199 | 1214 | ||
| 1200 | 1215 | Node.js options that are allowed are: | |
| 1201 | 1216 | <!-- node-options-node start --> | |
| 1217 | + * `--conditions`, `-u` | ||
| 1202 | 1218 | * `--diagnostic-dir` | |
| 1203 | 1219 | * `--disable-proto` | |
| 1204 | 1220 | * `--enable-fips` | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -501,6 +501,21 @@ a nested conditional does not have any mapping it will continue checking | |||
| 501 | 501 | the remaining conditions of the parent condition. In this way nested | |
| 502 | 502 | conditions behave analogously to nested JavaScript `if` statements. | |
| 503 | 503 | ||
| 504 | + #### Resolving user conditions | ||
| 505 | + | ||
| 506 | + When running Node.js, custom user conditions can be added with the | ||
| 507 | + `--conditions` or `-u` flag: | ||
| 508 | + | ||
| 509 | + ```bash | ||
| 510 | + node --conditions=development main.js | ||
| 511 | + ``` | ||
| 512 | + | ||
| 513 | + which would then resolve the `"development"` condition in package imports and | ||
| 514 | + exports, while resolving the existing `"node"`, `"default"`, `"import"`, and | ||
| 515 | + `"require"` conditions as appropriate. | ||
| 516 | + | ||
| 517 | + Any number of custom conditions can be set with repeat flags. | ||
| 518 | + | ||
| 504 | 519 | #### Self-referencing a package using its name | |
| 505 | 520 | ||
| 506 | 521 | Within a package, the values defined in the package’s | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -78,6 +78,10 @@ Aborting instead of exiting causes a core file to be generated for analysis. | |||
| 78 | 78 | .It Fl -completion-bash | |
| 79 | 79 | Print source-able bash completion script for Node.js. | |
| 80 | 80 | . | |
| 81 | + .It Fl u , Fl -conditions Ar string | ||
| 82 | + Use custom conditional exports conditions | ||
| 83 | + .Ar string | ||
| 84 | + . | ||
| 81 | 85 | .It Fl -cpu-prof | |
| 82 | 86 | Start the V8 CPU profiler on start up, and write the CPU profile to disk | |
| 83 | 87 | before exit. If | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -84,6 +84,7 @@ const manifest = getOptionValue('--experimental-policy') ? | |||
| 84 | 84 | require('internal/process/policy').manifest : | |
| 85 | 85 | null; | |
| 86 | 86 | const { compileFunction } = internalBinding('contextify'); | |
| 87 | + const userConditions = getOptionValue('--conditions'); | ||
| 87 | 88 | ||
| 88 | 89 | // Whether any user-provided CJS modules had been loaded (executed). | |
| 89 | 90 | // Used for internal assertions. | |
@@ -477,8 +478,12 @@ function applyExports(basePath, expansion) { | |||
| 477 | 478 | if (typeof pkgExports === 'object') { | |
| 478 | 479 | if (ObjectPrototypeHasOwnProperty(pkgExports, mappingKey)) { | |
| 479 | 480 | const mapping = pkgExports[mappingKey]; | |
| 480 | - return resolveExportsTarget(pathToFileURL(basePath + '/'), mapping, '', | ||
| 481 | - mappingKey); | ||
| 481 | + const resolved = resolveExportsTarget( | ||
| 482 | + pathToFileURL(basePath + '/'), mapping, '', mappingKey); | ||
| 483 | + if (resolved === null || resolved === undefined) | ||
| 484 | + throw new ERR_PACKAGE_PATH_NOT_EXPORTED( | ||
| 485 | + basePath, mappingKey); | ||
| 486 | + return resolved; | ||
| 482 | 487 | } | |
| 483 | 488 | ||
| 484 | 489 | let dirMatch = ''; | |
@@ -495,6 +500,9 @@ function applyExports(basePath, expansion) { | |||
| 495 | 500 | const subpath = StringPrototypeSlice(mappingKey, dirMatch.length); | |
| 496 | 501 | const resolved = resolveExportsTarget(pathToFileURL(basePath + '/'), | |
| 497 | 502 | mapping, subpath, mappingKey); | |
| 503 | + if (resolved === null || resolved === undefined) | ||
| 504 | + throw new ERR_PACKAGE_PATH_NOT_EXPORTED( | ||
| 505 | + basePath, mappingKey + subpath); | ||
| 498 | 506 | // Extension searching for folder exports only | |
| 499 | 507 | const rc = stat(resolved); | |
| 500 | 508 | if (rc === 0) return resolved; | |
@@ -582,21 +590,29 @@ function resolveExportsTarget(baseUrl, target, subpath, mappingKey) { | |||
| 582 | 590 | throw new ERR_INVALID_MODULE_SPECIFIER(mappingKey + subpath, reason); | |
| 583 | 591 | } else if (ArrayIsArray(target)) { | |
| 584 | 592 | if (target.length === 0) | |
| 585 | - throw new ERR_PACKAGE_PATH_NOT_EXPORTED( | ||
| 586 | - baseUrl.pathname, mappingKey + subpath); | ||
| 593 | + return null; | ||
| 587 | 594 | let lastException; | |
| 588 | 595 | for (const targetValue of target) { | |
| 596 | + let resolved; | ||
| 589 | 597 | try { | |
| 590 | - return resolveExportsTarget(baseUrl, targetValue, subpath, mappingKey); | ||
| 598 | + resolved = resolveExportsTarget(baseUrl, targetValue, subpath, | ||
| 599 | + mappingKey); | ||
| 591 | 600 | } catch (e) { | |
| 592 | 601 | lastException = e; | |
| 593 | - if (e.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED' && | ||
| 594 | - e.code !== 'ERR_INVALID_PACKAGE_TARGET') | ||
| 602 | + if (e.code !== 'ERR_INVALID_PACKAGE_TARGET') | ||
| 595 | 603 | throw e; | |
| 596 | 604 | } | |
| 605 | + if (resolved === undefined) | ||
| 606 | + continue; | ||
| 607 | + if (resolved === null) { | ||
| 608 | + lastException = null; | ||
| 609 | + continue; | ||
| 610 | + } | ||
| 611 | + return resolved; | ||
| 597 | 612 | } | |
| 598 | 613 | // Throw last fallback error | |
| 599 | - assert(lastException !== undefined); | ||
| 614 | + if (lastException === undefined || lastException === null) | ||
| 615 | + return lastException; | ||
| 600 | 616 | throw lastException; | |
| 601 | 617 | } else if (typeof target === 'object' && target !== null) { | |
| 602 | 618 | const keys = ObjectKeys(target); | |
@@ -605,30 +621,17 @@ function resolveExportsTarget(baseUrl, target, subpath, mappingKey) { | |||
| 605 | 621 | 'contain numeric property keys.'); | |
| 606 | 622 | } | |
| 607 | 623 | for (const p of keys) { | |
| 608 | - switch (p) { | ||
| 609 | - case 'node': | ||
| 610 | - case 'require': | ||
| 611 | - try { | ||
| 612 | - return resolveExportsTarget(baseUrl, target[p], subpath, | ||
| 613 | - mappingKey); | ||
| 614 | - } catch (e) { | ||
| 615 | - if (e.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') throw e; | ||
| 616 | - } | ||
| 617 | - break; | ||
| 618 | - case 'default': | ||
| 619 | - try { | ||
| 620 | - return resolveExportsTarget(baseUrl, target.default, subpath, | ||
| 621 | - mappingKey); | ||
| 622 | - } catch (e) { | ||
| 623 | - if (e.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') throw e; | ||
| 624 | - } | ||
| 624 | + if (cjsConditions.has(p) || p === 'default') { | ||
| 625 | + const resolved = resolveExportsTarget(baseUrl, target[p], subpath, | ||
| 626 | + mappingKey); | ||
| 627 | + if (resolved === undefined) | ||
| 628 | + continue; | ||
| 629 | + return resolved; | ||
| 625 | 630 | } | |
| 626 | 631 | } | |
| 627 | - throw new ERR_PACKAGE_PATH_NOT_EXPORTED( | ||
| 628 | - baseUrl.pathname, mappingKey + subpath); | ||
| 632 | + return undefined; | ||
| 629 | 633 | } else if (target === null) { | |
| 630 | - throw new ERR_PACKAGE_PATH_NOT_EXPORTED( | ||
| 631 | - baseUrl.pathname, mappingKey + subpath); | ||
| 634 | + return null; | ||
| 632 | 635 | } | |
| 633 | 636 | throw new ERR_INVALID_PACKAGE_TARGET(baseUrl.pathname, mappingKey, target); | |
| 634 | 637 | } | |
@@ -985,8 +988,7 @@ Module._load = function(request, parent, isMain) { | |||
| 985 | 988 | return module.exports; | |
| 986 | 989 | }; | |
| 987 | 990 | ||
| 988 | - // TODO: Use this set when resolving pkg#exports conditions. | ||
| 989 | - const cjsConditions = new SafeSet(['require', 'node']); | ||
| 991 | + const cjsConditions = new SafeSet(['require', 'node', ...userConditions]); | ||
| 990 | 992 | Module._resolveFilename = function(request, parent, isMain, options) { | |
| 991 | 993 | if (NativeModule.canBeRequiredByUsers(request)) { | |
| 992 | 994 | return request; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -51,7 +51,8 @@ const { | |||
| 51 | 51 | const { Module: CJSModule } = require('internal/modules/cjs/loader'); | |
| 52 | 52 | ||
| 53 | 53 | const packageJsonReader = require('internal/modules/package_json_reader'); | |
| 54 | - const DEFAULT_CONDITIONS = ObjectFreeze(['node', 'import']); | ||
| 54 | + const userConditions = getOptionValue('--conditions'); | ||
| 55 | + const DEFAULT_CONDITIONS = ObjectFreeze(['node', 'import', ...userConditions]); | ||
| 55 | 56 | const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS); | |
| 56 | 57 | ||
| 57 | 58 | ||
@@ -359,12 +360,9 @@ function isArrayIndex(key) { | |||
| 359 | 360 | function resolvePackageTarget( | |
| 360 | 361 | packageJSONUrl, target, subpath, packageSubpath, base, internal, conditions) { | |
| 361 | 362 | if (typeof target === 'string') { | |
| 362 | - const resolved = resolvePackageTargetString( | ||
| 363 | + return finalizeResolution(resolvePackageTargetString( | ||
| 363 | 364 | target, subpath, packageSubpath, packageJSONUrl, base, internal, | |
| 364 | - conditions); | ||
| 365 | - if (resolved === null) | ||
| 366 | - return null; | ||
| 367 | - return finalizeResolution(resolved, base); | ||
| 365 | + conditions), base); | ||
| 368 | 366 | } else if (ArrayIsArray(target)) { | |
| 369 | 367 | if (target.length === 0) | |
| 370 | 368 | return null; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -281,6 +281,11 @@ DebugOptionsParser::DebugOptionsParser() { | |||
| 281 | 281 | } | |
| 282 | 282 | ||
| 283 | 283 | EnvironmentOptionsParser::EnvironmentOptionsParser() { | |
| 284 | + AddOption("--conditions", | ||
| 285 | + "additional user conditions for conditional exports and imports", | ||
| 286 | + &EnvironmentOptions::conditions, | ||
| 287 | + kAllowedInEnvironment); | ||
| 288 | + AddAlias("-u", "--conditions"); | ||
| 284 | 289 | AddOption("--diagnostic-dir", | |
| 285 | 290 | "set dir for all output files" | |
| 286 | 291 | " (default: current working directory)", | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -100,6 +100,7 @@ class DebugOptions : public Options { | |||
| 100 | 100 | class EnvironmentOptions : public Options { | |
| 101 | 101 | public: | |
| 102 | 102 | bool abort_on_uncaught_exception = false; | |
| 103 | + std::vector<std::string> conditions; | ||
| 103 | 104 | bool enable_source_maps = false; | |
| 104 | 105 | bool experimental_json_modules = false; | |
| 105 | 106 | bool experimental_modules = false; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,10 @@ | |||
| 1 | + // Flags: --conditions=custom-condition -u another | ||
| 2 | + import { mustCall } from '../common/index.mjs'; | ||
| 3 | + import { strictEqual } from 'assert'; | ||
| 4 | + import { requireFixture, importFixture } from '../fixtures/pkgexports.mjs'; | ||
| 5 | + [requireFixture, importFixture].forEach((loadFixture) => { | ||
| 6 | + loadFixture('pkgexports/condition') | ||
| 7 | + .then(mustCall((actual) => { | ||
| 8 | + strictEqual(actual.default, 'from custom condition'); | ||
| 9 | + })); | ||
| 10 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments