| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 56bd9a8 commit fe69198
14 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1008,8 +1008,12 @@ _isImports_, _conditions_) | |||
| 1008 | 1008 | > 5. Let _packageURL_ be the result of **LOOKUP\_PACKAGE\_SCOPE**(_url_). | |
| 1009 | 1009 | > 6. Let _pjson_ be the result of **READ\_PACKAGE\_JSON**(_packageURL_). | |
| 1010 | 1010 | > 7. If _pjson?.type_ exists and is _"module"_, then | |
| 1011 | - > 1. If _url_ ends in _".js"_, then | ||
| 1012 | - > 1. Return _"module"_. | ||
| 1011 | + > 1. If _url_ ends in _".js"_ or has no file extension, then | ||
| 1012 | + > 1. If `--experimental-wasm-modules` is enabled and the file at _url_ | ||
| 1013 | + > contains the header for a WebAssembly module, then | ||
| 1014 | + > 1. Return _"wasm"_. | ||
| 1015 | + > 2. Otherwise, | ||
| 1016 | + > 1. Return _"module"_. | ||
| 1013 | 1017 | > 2. Return **undefined**. | |
| 1014 | 1018 | > 8. Otherwise, | |
| 1015 | 1019 | > 1. Return **undefined**. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1686,13 +1686,7 @@ E('ERR_UNHANDLED_ERROR', | |||
| 1686 | 1686 | E('ERR_UNKNOWN_BUILTIN_MODULE', 'No such built-in module: %s', Error); | |
| 1687 | 1687 | E('ERR_UNKNOWN_CREDENTIAL', '%s identifier does not exist: %s', Error); | |
| 1688 | 1688 | E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s', TypeError); | |
| 1689 | - E('ERR_UNKNOWN_FILE_EXTENSION', (ext, path, suggestion) => { | ||
| 1690 | - let msg = `Unknown file extension "${ext}" for ${path}`; | ||
| 1691 | - if (suggestion) { | ||
| 1692 | - msg += `. ${suggestion}`; | ||
| 1693 | - } | ||
| 1694 | - return msg; | ||
| 1695 | - }, TypeError); | ||
| 1689 | + E('ERR_UNKNOWN_FILE_EXTENSION', 'Unknown file extension "%s" for %s', TypeError); | ||
| 1696 | 1690 | E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s for URL %s', | |
| 1697 | 1691 | RangeError); | |
| 1698 | 1692 | E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,7 +9,6 @@ const { | |||
| 9 | 9 | StringPrototypeCharCodeAt, | |
| 10 | 10 | StringPrototypeSlice, | |
| 11 | 11 | } = primordials; | |
| 12 | - const { basename, relative } = require('path'); | ||
| 13 | 12 | const { getOptionValue } = require('internal/options'); | |
| 14 | 13 | const { | |
| 15 | 14 | extensionFormatMap, | |
@@ -25,7 +24,7 @@ const experimentalSpecifierResolution = | |||
| 25 | 24 | const defaultTypeFlag = getOptionValue('--experimental-default-type'); | |
| 26 | 25 | // The next line is where we flip the default to ES modules someday. | |
| 27 | 26 | const defaultType = defaultTypeFlag === 'module' ? 'module' : 'commonjs'; | |
| 28 | - const { getPackageType, getPackageScopeConfig } = require('internal/modules/esm/resolve'); | ||
| 27 | + const { getPackageType } = require('internal/modules/esm/resolve'); | ||
| 29 | 28 | const { fileURLToPath } = require('internal/url'); | |
| 30 | 29 | const { ERR_UNKNOWN_FILE_EXTENSION } = require('internal/errors').codes; | |
| 31 | 30 | ||
@@ -115,17 +114,16 @@ function getFileProtocolModuleFormat(url, context, ignoreErrors) { | |||
| 115 | 114 | if (defaultType === 'commonjs') { // Legacy behavior | |
| 116 | 115 | if (packageType === 'none' || packageType === 'commonjs') { | |
| 117 | 116 | return 'commonjs'; | |
| 118 | - } | ||
| 119 | - // If package type is `module`, fall through to the error case below | ||
| 120 | - } else { // Else defaultType === 'module' | ||
| 121 | - if (underNodeModules(url)) { // Exception for package scopes under `node_modules` | ||
| 122 | - return 'commonjs'; | ||
| 123 | - } | ||
| 124 | - if (packageType === 'none' || packageType === 'module') { | ||
| 125 | - return getFormatOfExtensionlessFile(url); | ||
| 126 | - } // Else packageType === 'commonjs' | ||
| 127 | - return 'commonjs'; | ||
| 117 | + } // Else packageType === 'module' | ||
| 118 | + return getFormatOfExtensionlessFile(url); | ||
| 119 | + } // Else defaultType === 'module' | ||
| 120 | + if (underNodeModules(url)) { // Exception for package scopes under `node_modules` | ||
| 121 | + return packageType === 'module' ? getFormatOfExtensionlessFile(url) : 'commonjs'; | ||
| 128 | 122 | } | |
| 123 | + if (packageType === 'none' || packageType === 'module') { | ||
| 124 | + return getFormatOfExtensionlessFile(url); | ||
| 125 | + } // Else packageType === 'commonjs' | ||
| 126 | + return 'commonjs'; | ||
| 129 | 127 | } | |
| 130 | 128 | ||
| 131 | 129 | const format = extensionFormatMap[ext]; | |
@@ -135,17 +133,7 @@ function getFileProtocolModuleFormat(url, context, ignoreErrors) { | |||
| 135 | 133 | // Explicit undefined return indicates load hook should rerun format check | |
| 136 | 134 | if (ignoreErrors) { return undefined; } | |
| 137 | 135 | const filepath = fileURLToPath(url); | |
| 138 | - let suggestion = ''; | ||
| 139 | - if (getPackageType(url) === 'module' && ext === '') { | ||
| 140 | - const config = getPackageScopeConfig(url); | ||
| 141 | - const fileBasename = basename(filepath); | ||
| 142 | - const relativePath = StringPrototypeSlice(relative(config.pjsonPath, filepath), 1); | ||
| 143 | - suggestion = 'Loading extensionless files is not supported inside of "type":"module" package.json contexts ' + | ||
| 144 | - `without --experimental-default-type=module. The package.json file ${config.pjsonPath} caused this "type":"module" ` + | ||
| 145 | - `context. Try changing ${filepath} to have a file extension. Note the "bin" field of package.json can point ` + | ||
| 146 | - `to a file with an extension, for example {"type":"module","bin":{"${fileBasename}":"${relativePath}.js"}}`; | ||
| 147 | - } | ||
| 148 | - throw new ERR_UNKNOWN_FILE_EXTENSION(ext, filepath, suggestion); | ||
| 136 | + throw new ERR_UNKNOWN_FILE_EXTENSION(ext, filepath); | ||
| 149 | 137 | } | |
| 150 | 138 | ||
| 151 | 139 | return getLegacyExtensionFormat(ext) ?? null; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,106 @@ | |||
| 1 | + // Flags: --experimental-wasm-modules | ||
| 2 | + import { mustNotCall, spawnPromisified } from '../common/index.mjs'; | ||
| 3 | + import * as fixtures from '../common/fixtures.mjs'; | ||
| 4 | + import { describe, it } from 'node:test'; | ||
| 5 | + import { match, ok, strictEqual } from 'node:assert'; | ||
| 6 | + | ||
| 7 | + describe('extensionless ES modules within a "type": "module" package scope', { concurrency: true }, () => { | ||
| 8 | + it('should run as the entry point', async () => { | ||
| 9 | + const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ | ||
| 10 | + fixtures.path('es-modules/package-type-module/noext-esm'), | ||
| 11 | + ]); | ||
| 12 | + | ||
| 13 | + strictEqual(stderr, ''); | ||
| 14 | + strictEqual(stdout, 'executed\n'); | ||
| 15 | + strictEqual(code, 0); | ||
| 16 | + strictEqual(signal, null); | ||
| 17 | + }); | ||
| 18 | + | ||
| 19 | + it('should be importable', async () => { | ||
| 20 | + const { default: defaultExport } = | ||
| 21 | + await import(fixtures.fileURL('es-modules/package-type-module/noext-esm')); | ||
| 22 | + strictEqual(defaultExport, 'module'); | ||
| 23 | + }); | ||
| 24 | + | ||
| 25 | + it('should be importable from a module scope under node_modules', async () => { | ||
| 26 | + const { default: defaultExport } = | ||
| 27 | + await import(fixtures.fileURL( | ||
| 28 | + 'es-modules/package-type-module/node_modules/dep-with-package-json-type-module/noext-esm')); | ||
| 29 | + strictEqual(defaultExport, 'module'); | ||
| 30 | + }); | ||
| 31 | + }); | ||
| 32 | + describe('extensionless Wasm modules within a "type": "module" package scope', { concurrency: true }, () => { | ||
| 33 | + it('should run as the entry point', async () => { | ||
| 34 | + const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ | ||
| 35 | + '--experimental-wasm-modules', | ||
| 36 | + '--no-warnings', | ||
| 37 | + fixtures.path('es-modules/package-type-module/noext-wasm'), | ||
| 38 | + ]); | ||
| 39 | + | ||
| 40 | + strictEqual(stderr, ''); | ||
| 41 | + strictEqual(stdout, 'executed\n'); | ||
| 42 | + strictEqual(code, 0); | ||
| 43 | + strictEqual(signal, null); | ||
| 44 | + }); | ||
| 45 | + | ||
| 46 | + it('should be importable', async () => { | ||
| 47 | + const { add } = await import(fixtures.fileURL('es-modules/package-type-module/noext-wasm')); | ||
| 48 | + strictEqual(add(1, 2), 3); | ||
| 49 | + }); | ||
| 50 | + | ||
| 51 | + it('should be importable from a module scope under node_modules', async () => { | ||
| 52 | + const { add } = await import(fixtures.fileURL( | ||
| 53 | + 'es-modules/package-type-module/node_modules/dep-with-package-json-type-module/noext-wasm')); | ||
| 54 | + strictEqual(add(1, 2), 3); | ||
| 55 | + }); | ||
| 56 | + }); | ||
| 57 | + | ||
| 58 | + describe('extensionless ES modules within no package scope', { concurrency: true }, () => { | ||
| 59 | + // This succeeds with `--experimental-default-type=module` | ||
| 60 | + it('should error as the entry point', async () => { | ||
| 61 | + const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ | ||
| 62 | + fixtures.path('es-modules/noext-esm'), | ||
| 63 | + ]); | ||
| 64 | + | ||
| 65 | + match(stderr, /SyntaxError/); | ||
| 66 | + strictEqual(stdout, ''); | ||
| 67 | + strictEqual(code, 1); | ||
| 68 | + strictEqual(signal, null); | ||
| 69 | + }); | ||
| 70 | + | ||
| 71 | + // This succeeds with `--experimental-default-type=module` | ||
| 72 | + it('should error on import', async () => { | ||
| 73 | + try { | ||
| 74 | + await import(fixtures.fileURL('es-modules/noext-esm')); | ||
| 75 | + mustNotCall(); | ||
| 76 | + } catch (err) { | ||
| 77 | + ok(err instanceof SyntaxError); | ||
| 78 | + } | ||
| 79 | + }); | ||
| 80 | + }); | ||
| 81 | + | ||
| 82 | + describe('extensionless Wasm within no package scope', { concurrency: true }, () => { | ||
| 83 | + // This succeeds with `--experimental-default-type=module` | ||
| 84 | + it('should error as the entry point', async () => { | ||
| 85 | + const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ | ||
| 86 | + '--experimental-wasm-modules', | ||
| 87 | + '--no-warnings', | ||
| 88 | + fixtures.path('es-modules/noext-wasm'), | ||
| 89 | + ]); | ||
| 90 | + | ||
| 91 | + match(stderr, /SyntaxError/); | ||
| 92 | + strictEqual(stdout, ''); | ||
| 93 | + strictEqual(code, 1); | ||
| 94 | + strictEqual(signal, null); | ||
| 95 | + }); | ||
| 96 | + | ||
| 97 | + // This succeeds with `--experimental-default-type=module` | ||
| 98 | + it('should error on import', async () => { | ||
| 99 | + try { | ||
| 100 | + await import(fixtures.fileURL('es-modules/noext-wasm')); | ||
| 101 | + mustNotCall(); | ||
| 102 | + } catch (err) { | ||
| 103 | + ok(err instanceof SyntaxError); | ||
| 104 | + } | ||
| 105 | + }); | ||
| 106 | + }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,6 +24,14 @@ describe('the type flag should change the interpretation of certain files within | |||
| 24 | 24 | strictEqual(defaultExport, 'module'); | |
| 25 | 25 | }); | |
| 26 | 26 | ||
| 27 | + it('should import an extensionless JavaScript file within a "type": "module" scope under node_modules', | ||
| 28 | + async () => { | ||
| 29 | + const { default: defaultExport } = | ||
| 30 | + await import(fixtures.fileURL( | ||
| 31 | + 'es-modules/package-type-module/node_modules/dep-with-package-json-type-module/noext-esm')); | ||
| 32 | + strictEqual(defaultExport, 'module'); | ||
| 33 | + }); | ||
| 34 | + | ||
| 27 | 35 | it('should run as Wasm an extensionless Wasm file within a "type": "module" scope', async () => { | |
| 28 | 36 | const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ | |
| 29 | 37 | '--experimental-default-type=module', | |
@@ -42,6 +50,13 @@ describe('the type flag should change the interpretation of certain files within | |||
| 42 | 50 | const { add } = await import(fixtures.fileURL('es-modules/package-type-module/noext-wasm')); | |
| 43 | 51 | strictEqual(add(1, 2), 3); | |
| 44 | 52 | }); | |
| 53 | + | ||
| 54 | + it('should import an extensionless Wasm file within a "type": "module" scope under node_modules', | ||
| 55 | + async () => { | ||
| 56 | + const { add } = await import(fixtures.fileURL( | ||
| 57 | + 'es-modules/package-type-module/node_modules/dep-with-package-json-type-module/noext-wasm')); | ||
| 58 | + strictEqual(add(1, 2), 3); | ||
| 59 | + }); | ||
| 45 | 60 | }); | |
| 46 | 61 | ||
| 47 | 62 | describe(`the type flag should change the interpretation of certain files within a package scope that lacks a | |
@@ -112,7 +127,7 @@ describe(`the type flag should NOT change the interpretation of certain files wi | |||
| 112 | 127 | async () => { | |
| 113 | 128 | const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ | |
| 114 | 129 | '--experimental-default-type=module', | |
| 115 | - fixtures.path('es-modules/package-type-module/node_modules/dep-with-package-json/run.js'), | ||
| 130 | + fixtures.path('es-modules/package-type-module/node_modules/dep-with-package-json-without-type/run.js'), | ||
| 116 | 131 | ]); | |
| 117 | 132 | ||
| 118 | 133 | strictEqual(stderr, ''); | |
@@ -124,15 +139,16 @@ describe(`the type flag should NOT change the interpretation of certain files wi | |||
| 124 | 139 | it(`should import as CommonJS a .js file within a package scope that has no defined "type" and is under | |
| 125 | 140 | node_modules`, async () => { | |
| 126 | 141 | const { default: defaultExport } = | |
| 127 | - await import(fixtures.fileURL('es-modules/package-type-module/node_modules/dep-with-package-json/run.js')); | ||
| 142 | + await import(fixtures.fileURL( | ||
| 143 | + 'es-modules/package-type-module/node_modules/dep-with-package-json-without-type/run.js')); | ||
| 128 | 144 | strictEqual(defaultExport, 42); | |
| 129 | 145 | }); | |
| 130 | 146 | ||
| 131 | 147 | it(`should run as CommonJS an extensionless JavaScript file within a package scope that has no defined "type" and is | |
| 132 | 148 | under node_modules`, async () => { | |
| 133 | 149 | const { code, signal, stdout, stderr } = await spawnPromisified(process.execPath, [ | |
| 134 | 150 | '--experimental-default-type=module', | |
| 135 | - fixtures.path('es-modules/package-type-module/node_modules/dep-with-package-json/noext-cjs'), | ||
| 151 | + fixtures.path('es-modules/package-type-module/node_modules/dep-with-package-json-without-type/noext-cjs'), | ||
| 136 | 152 | ]); | |
| 137 | 153 | ||
| 138 | 154 | strictEqual(stderr, ''); | |
@@ -144,7 +160,8 @@ describe(`the type flag should NOT change the interpretation of certain files wi | |||
| 144 | 160 | it(`should import as CommonJS an extensionless JavaScript file within a package scope that has no defined "type" and | |
| 145 | 161 | is under node_modules`, async () => { | |
| 146 | 162 | const { default: defaultExport } = | |
| 147 | - await import(fixtures.fileURL('es-modules/package-type-module/node_modules/dep-with-package-json/noext-cjs')); | ||
| 163 | + await import(fixtures.fileURL( | ||
| 164 | + 'es-modules/package-type-module/node_modules/dep-with-package-json-without-type/noext-cjs')); | ||
| 148 | 165 | strictEqual(defaultExport, 42); | |
| 149 | 166 | }); | |
| 150 | 167 | }); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,14 +7,11 @@ const { execPath } = require('node:process'); | |||
| 7 | 7 | const { describe, it } = require('node:test'); | |
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | - // In a "type": "module" package scope, files with unknown extensions or no | ||
| 11 | - // extensions should throw; both when used as a main entry point and also when | ||
| 12 | - // referenced via `import`. | ||
| 13 | - describe('ESM: extensionless and unknown specifiers', { concurrency: true }, () => { | ||
| 10 | + // In a "type": "module" package scope, files with unknown extensions should throw; | ||
| 11 | + // both when used as a main entry point and also when referenced via `import`. | ||
| 12 | + describe('ESM: unknown specifiers', { concurrency: true }, () => { | ||
| 14 | 13 | for ( | |
| 15 | 14 | const fixturePath of [ | |
| 16 | - '/es-modules/package-type-module/noext-esm', | ||
| 17 | - '/es-modules/package-type-module/imports-noext.mjs', | ||
| 18 | 15 | '/es-modules/package-type-module/extension.unknown', | |
| 19 | 16 | '/es-modules/package-type-module/imports-unknownext.mjs', | |
| 20 | 17 | ] | |
@@ -27,10 +24,6 @@ describe('ESM: extensionless and unknown specifiers', { concurrency: true }, () | |||
| 27 | 24 | assert.strictEqual(signal, null); | |
| 28 | 25 | assert.strictEqual(stdout, ''); | |
| 29 | 26 | assert.match(stderr, /ERR_UNKNOWN_FILE_EXTENSION/); | |
| 30 | - if (fixturePath.includes('noext')) { | ||
| 31 | - // Check for explanation to users | ||
| 32 | - assert.match(stderr, /extensionless/); | ||
| 33 | - } | ||
| 34 | 27 | }); | |
| 35 | 28 | } | |
| 36 | 29 | }); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments