GeezerVison is showing github.com — esm: skip file: URL conversion to path when possible · nodejs/node@dfa4444
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/modules/esm/get_format.js +29-3Lines changed: 29 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 4 | 4 | ObjectPrototypeHasOwnProperty, | 5 | 5 | PromisePrototypeThen, | 6 | 6 | PromiseResolve, | | 7 | + StringPrototypeCharCodeAt, | 7 | 8 | StringPrototypeSlice, | 8 | 9 | } = primordials; | 9 | | -const { basename, extname, relative } = require('path'); | | 10 | +const { basename, relative } = require('path'); | 10 | 11 | const { getOptionValue } = require('internal/options'); | 11 | 12 | const { | 12 | 13 | extensionFormatMap, | @@ -44,15 +45,38 @@ function getDataProtocolModuleFormat(parsed) { | 44 | 45 | return mimeToFormat(mime); | 45 | 46 | } | 46 | 47 |
| | 48 | +const DOT_CODE = 46; | | 49 | +const SLASH_CODE = 47; | | 50 | + | | 51 | +/** | | 52 | + * Returns the file extension from a URL. Should give similar result to | | 53 | + * `require('node:path').extname(require('node:url').fileURLToPath(url))` | | 54 | + * when used with a `file:` URL. | | 55 | + * @param {URL} url | | 56 | + * @returns {string} | | 57 | + */ | | 58 | +function extname(url) { | | 59 | + const { pathname } = url; | | 60 | + for (let i = pathname.length - 1; i > 0; i--) { | | 61 | + switch (StringPrototypeCharCodeAt(pathname, i)) { | | 62 | + case SLASH_CODE: | | 63 | + return ''; | | 64 | + | | 65 | + case DOT_CODE: | | 66 | + return StringPrototypeCharCodeAt(pathname, i - 1) === SLASH_CODE ? '' : StringPrototypeSlice(pathname, i); | | 67 | + } | | 68 | + } | | 69 | + return ''; | | 70 | +} | | 71 | + | 47 | 72 | /** | 48 | 73 | * @param {URL} url | 49 | 74 | * @param {{parentURL: string}} context | 50 | 75 | * @param {boolean} ignoreErrors | 51 | 76 | * @returns {string} | 52 | 77 | */ | 53 | 78 | function getFileProtocolModuleFormat(url, context, ignoreErrors) { | 54 | | - const filepath = fileURLToPath(url); | 55 | | - const ext = extname(filepath); | | 79 | + const ext = extname(url); | 56 | 80 | if (ext === '.js') { | 57 | 81 | return getPackageType(url) === 'module' ? 'module' : 'commonjs'; | 58 | 82 | } | @@ -63,6 +87,7 @@ function getFileProtocolModuleFormat(url, context, ignoreErrors) { | 63 | 87 | if (experimentalSpecifierResolution !== 'node') { | 64 | 88 | // Explicit undefined return indicates load hook should rerun format check | 65 | 89 | if (ignoreErrors) return undefined; | | 90 | + const filepath = fileURLToPath(url); | 66 | 91 | let suggestion = ''; | 67 | 92 | if (getPackageType(url) === 'module' && ext === '') { | 68 | 93 | const config = getPackageScopeConfig(url); | @@ -128,4 +153,5 @@ module.exports = { | 128 | 153 | defaultGetFormat, | 129 | 154 | defaultGetFormatWithoutErrors, | 130 | 155 | extensionFormatMap, | | 156 | + extname, | 131 | 157 | }; |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/modules/esm/translators.js +2-5Lines changed: 2 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -35,8 +35,7 @@ const { | 35 | 35 | Module: CJSModule, | 36 | 36 | cjsParseCache, | 37 | 37 | } = require('internal/modules/cjs/loader'); | 38 | | -const internalURLModule = require('internal/url'); | 39 | | -const { fileURLToPath, URL } = require('url'); | | 38 | +const { fileURLToPath, URL } = require('internal/url'); | 40 | 39 | let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { | 41 | 40 | debug = fn; | 42 | 41 | }); | @@ -147,9 +146,7 @@ translators.set('commonjs', async function commonjsStrategy(url, source, | 147 | 146 | isMain) { | 148 | 147 | debug(`Translating CJSModule ${url}`); | 149 | 148 |
| 150 | | - let filename = internalURLModule.fileURLToPath(new URL(url)); | 151 | | - if (isWindows) | 152 | | - filename = StringPrototypeReplaceAll(filename, '/', '\\'); | | 149 | + const filename = fileURLToPath(new URL(url)); | 153 | 150 |
| 154 | 151 | if (!cjsParse) await initCJSParse(); | 155 | 152 | const { module, exportNames } = cjsPreparseModuleExports(filename); | |
Collapse file Copy file name to clipboard +27Lines changed: 27 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +// Flags: --expose-internals | | 2 | +'use strict'; | | 3 | +require('../common'); | | 4 | +const assert = require('node:assert'); | | 5 | +const path = require('node:path'); | | 6 | +const { extname } = require('node:internal/modules/esm/get_format'); | | 7 | +const { fileURLToPath } = require('node:url'); | | 8 | + | | 9 | +[ | | 10 | + 'file:///c:/path/to/file', | | 11 | + 'file:///c:/path/to/file.ext', | | 12 | + 'file:///c:/path.to/file.ext', | | 13 | + 'file:///c:/path.to/file', | | 14 | + 'file:///c:/path.to/.file', | | 15 | + 'file:///c:/path.to/.file.ext', | | 16 | + 'file:///c:/path/to/f.ext', | | 17 | + 'file:///c:/path/to/..ext', | | 18 | + 'file:///c:/path/to/..', | | 19 | + 'file:///c:/file', | | 20 | + 'file:///c:/file.ext', | | 21 | + 'file:///c:/.file', | | 22 | + 'file:///c:/.file.ext', | | 23 | +].forEach((input) => { | | 24 | + const inputAsURL = new URL(input); | | 25 | + const inputAsPath = fileURLToPath(inputAsURL); | | 26 | + assert.strictEqual(extname(inputAsURL), path.extname(inputAsPath)); | | 27 | +}); |
|