From c2a6c453c325a3a8c6ff3bc95a6c43885a66b3b4 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Wed, 26 Mar 2025 19:24:02 +0900 Subject: [PATCH 01/38] `prefer-module`: Support `import.meta.{dirname,filename}` --- rules/prefer-module.js | 204 ++++++++++++++++++- test/prefer-module.js | 48 +++++ test/snapshots/prefer-module.js.md | 285 +++++++++++++++++++++++++++ test/snapshots/prefer-module.js.snap | Bin 4060 -> 4818 bytes 4 files changed, 536 insertions(+), 1 deletion(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index db58aabb85..5707126aaa 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -1,7 +1,10 @@ +import {findVariable, getPropertyName} from '@eslint-community/eslint-utils'; import isShadowed from './utils/is-shadowed.js'; import assertToken from './utils/assert-token.js'; import {getCallExpressionTokens} from './utils/index.js'; -import {isStaticRequire, isReferenceIdentifier, isFunction} from './ast/index.js'; +import { + isStaticRequire, isReferenceIdentifier, isFunction, isLiteral, +} from './ast/index.js'; import {removeParentheses, replaceReferenceIdentifier, removeSpacesAfter} from './fix/index.js'; const ERROR_USE_STRICT_DIRECTIVE = 'error/use-strict-directive'; @@ -14,6 +17,9 @@ const SUGGESTION_IMPORT_META_FILENAME = 'suggestion/import-meta-filename'; const SUGGESTION_IMPORT_META_URL_TO_FILENAME = 'suggestion/import-meta-url-to-filename'; const SUGGESTION_IMPORT = 'suggestion/import'; const SUGGESTION_EXPORT = 'suggestion/export'; +const SUGGESTION_IMPORT_META = 'suggestion/import.meta'; +const SUGGESTION_IMPORT_META_DIRNAME_FROM_URL = 'suggestion/import-meta-dirname-from-url'; +const SUGGESTION_IMPORT_META_FILENAME_FROM_URL = 'suggestion/import-meta-filename-from-url'; const messages = { [ERROR_USE_STRICT_DIRECTIVE]: 'Do not use "use strict" directive.', [ERROR_GLOBAL_RETURN]: '"return" should be used inside a function.', @@ -25,6 +31,9 @@ const messages = { [SUGGESTION_IMPORT_META_URL_TO_FILENAME]: 'Replace `__filename` with `…(import.meta.url)`.', [SUGGESTION_IMPORT]: 'Switch to `import`.', [SUGGESTION_EXPORT]: 'Switch to `export`.', + [SUGGESTION_IMPORT_META]: 'Switch to `import.meta.{{name}}`.', + [SUGGESTION_IMPORT_META_DIRNAME_FROM_URL]: 'Replace `…(import.meta.url)` with `import.meta.dirname`.', + [SUGGESTION_IMPORT_META_FILENAME_FROM_URL]: 'Replace `…(import.meta.url)` with `import.meta.filename`.', }; const suggestions = new Map([ @@ -198,6 +207,86 @@ const isTopLevelReturnStatement = node => { return true; }; +const isImportMeta = node => + node.type === 'MetaProperty' + && node.meta.name === 'import' + && node.property.name === 'meta'; + +/** @returns {node is import('estree').NewExpression} */ +const isNewURL = node => + node.type === 'NewExpression' + && node.callee.type === 'Identifier' + && node.callee.name === 'URL'; + +/** @returns {node is import('estree').MemberExpression} */ +const isAccessPathname = node => + node.type === 'MemberExpression' + && getPropertyName(node) === 'pathname'; + +function isCallNodeBuiltinModule(node, propertyName, nodeModuleName, sourceCode) { + if (node.type !== 'CallExpression') { + return false; + } + + /** @type {{callee: import('estree').Expression}} */ + const {callee} = node; + if (callee.type === 'MemberExpression') { + // Check for nodeModuleName.propertyName(...); + if (callee.object.type !== 'Identifier') { + return false; + } + + if (getPropertyName(callee) !== propertyName) { + return false; + } + + const specifier = getImportSpecifier(callee.object); + return specifier?.type === 'ImportDefaultSpecifier' || specifier?.type === 'ImportNamespaceSpecifier'; + } + + if (callee.type === 'Identifier') { + // Check for propertyName(...); + const specifier = getImportSpecifier(callee); + + return specifier?.type === 'ImportSpecifier' && specifier.imported.name === propertyName; + } + + return false; + + function getImportSpecifier(node) { + const scope = sourceCode.getScope(node); + const variable = findVariable(scope, node); + if (!variable || variable.defs.length !== 1) { + return; + } + + /** @type {import('eslint').Scope.Definition} */ + const define = variable.defs[0]; + if ( + define.type !== 'ImportBinding' + || (define.parent.source.value !== nodeModuleName && define.parent.source.value !== 'node:' + nodeModuleName) + ) { + return; + } + + return define.node; + } +} + +/** + @returns {node is import('estree').SimpleCallExpression} + */ +function isCallFileURLToPath(node, sourceCode) { + return isCallNodeBuiltinModule(node, 'fileURLToPath', 'url', sourceCode); +} + +/** + @returns {node is import('estree').SimpleCallExpression} + */ +function isCallPathDirname(node, sourceCode) { + return isCallNodeBuiltinModule(node, 'dirname', 'path', sourceCode); +} + function fixDefaultExport(node, sourceCode) { return function * (fixer) { yield fixer.replaceText(node, 'export default '); @@ -358,6 +447,119 @@ function create(context) { return problem; }); + + context.on('MetaProperty', node => { + if (!isImportMeta(node)) { + return; + } + + /** @type {{parent?: import('estree').Node}} */ + const {parent} = node; + if ( + parent.type !== 'MemberExpression' + || parent.object !== node + ) { + return; + } + + /** @type {import('estree').Node} */ + const targetNode = parent.parent; + + const propertyName = getPropertyName(parent); + if (propertyName === 'url') { + if ( + isCallFileURLToPath(targetNode, sourceCode) + && targetNode.arguments[0] === parent + ) { + // Report `fileURLToPath(import.meta.url)` + return buildProblemForFilename(targetNode); + } + + if (isNewURL(targetNode, sourceCode)) { + const verifyURLUsage = problemBuilder => { + const urlParent = targetNode.parent; + if ( + ( + // `fileURLToPath(new URL(...))` + isCallFileURLToPath(urlParent, sourceCode) + && urlParent.arguments[0] === targetNode + ) + // `new URL(...).pathname` + || isAccessPathname(urlParent) + ) { + return problemBuilder(urlParent); + } + }; + + if (targetNode.arguments[0] === parent) { + // Verify `new URL(import.meta.url)` + return verifyURLUsage(buildProblemForFilename); + } + + if ( + isLiteral(targetNode.arguments[0], '.') + && targetNode.arguments[1] === parent + ) { + // Verify `new URL('.', import.meta.url)` + return verifyURLUsage(urlParent => buildProblem(urlParent, 'dirname')); + } + } + } + + if ( + propertyName === 'filename' + && isCallPathDirname(targetNode, sourceCode) + && targetNode.arguments[0] === parent + ) { + // Report `path.dirname(import.meta.filename)` + return buildProblem(targetNode, 'dirname'); + } + + /** + @param { import('estree').Node} node + */ + function buildProblemForFilename(node) { + /** @type {import('estree').Node} */ + const {parent} = node; + if ( + isCallPathDirname(parent, sourceCode) + && parent.arguments[0] === node + ) { + // Report `path.dirname(node)` + return buildProblem(parent, 'dirname'); + } + + return buildProblem(node, 'filename'); + } + + /** + @param { import('estree').Node} node + @param {'dirname' | 'filename'} name + */ + function buildProblem(node, name) { + const problem = { + node, + messageId: SUGGESTION_IMPORT_META, + data: {name}, + }; + const fix = fixer => + fixer.replaceText(node, `import.meta.${name}`); + + if (filename.endsWith('.mjs')) { + problem.fix = fix; + } else { + problem.suggest = [{ + messageId: + name === 'dirname' + ? SUGGESTION_IMPORT_META_DIRNAME_FROM_URL + : SUGGESTION_IMPORT_META_FILENAME_FROM_URL, + fix, + }]; + } + + return problem; + } + }); } /** @type {import('eslint').Rule.RuleModule} */ diff --git a/test/prefer-module.js b/test/prefer-module.js index 563a95719a..c2d1cd7b62 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -307,3 +307,51 @@ test.snapshot({ }, ], }); + +// `exports` and `module` +test.snapshot({ + valid: [ + 'const __dirname = import.meta.dirname;', + 'const __filename = import.meta.filename;', + outdent` + import path from "path"; + const dirUrl = path.dirname(import.meta.url); + `, + 'const url = import.meta.url;', + ], + invalid: [ + outdent` + import path from "path"; + import { fileURLToPath } from "url"; + const dirname1 = path.dirname(fileURLToPath(import.meta.url)); + const dirname2 = path.dirname(import.meta.filename); + const dirname3 = path.dirname(new URL(import.meta.url).pathname); + const dirname4 = new URL(".", import.meta.url).pathname; + const dirname5 = fileURLToPath(new URL(".", import.meta.url)); + `, + outdent` + import { fileURLToPath } from "url"; + const filename1 = fileURLToPath(import.meta.url); + const filename2 = fileURLToPath(new URL(import.meta.url)); + const filename3 = new URL(import.meta.url).pathname; + `, + outdent` + import path from "node:path"; + import { fileURLToPath } from "node:url"; + const dirname = path.dirname(fileURLToPath(import.meta.url)); + `, + outdent` + import { fileURLToPath } from "node:url"; + const filename = fileURLToPath(import.meta.url); + `, + outdent` + import * as path from "node:path"; + import url from "node:url"; + const dirname = path.dirname(url.fileURLToPath(import.meta.url)); + `, + outdent` + import url from "node:url"; + const filename = url.fileURLToPath(import.meta.url); + `, + ], +}); diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 56457b3304..26a9b3bdfb 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1914,3 +1914,288 @@ Generated by [AVA](https://avajs.dev). Suggestion 1/1: Switch to \`import\`.␊ 1 | import "lodash"␊ ` + +## invalid(1): import path from "path"; import { fileURLToPath } from "url"; const dirname1 = path.dirname(fileURLToPath(import.meta.url)); const dirname2 = path.dirname(import.meta.filename); const dirname3 = path.dirname(new URL(import.meta.url).pathname); const dirname4 = new URL(".", import.meta.url).pathname; const dirname5 = fileURLToPath(new URL(".", import.meta.url)); + +> Input + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + ` + +> Error 1/5 + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + > 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = import.meta.dirname;␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + ` + +> Error 2/5 + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + > 4 | const dirname2 = path.dirname(import.meta.filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = import.meta.dirname;␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + ` + +> Error 3/5 + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + > 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = import.meta.dirname;␊ + 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + ` + +> Error 4/5 + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + > 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = import.meta.dirname;␊ + 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + ` + +> Error 5/5 + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + > 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ + 7 | const dirname5 = import.meta.dirname;␊ + ` + +## invalid(2): import { fileURLToPath } from "url"; const filename1 = fileURLToPath(import.meta.url); const filename2 = fileURLToPath(new URL(import.meta.url)); const filename3 = new URL(import.meta.url).pathname; + +> Input + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename1 = fileURLToPath(import.meta.url);␊ + 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ + 4 | const filename3 = new URL(import.meta.url).pathname;␊ + ` + +> Error 1/3 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + > 2 | const filename1 = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ + 4 | const filename3 = new URL(import.meta.url).pathname;␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename1 = import.meta.filename;␊ + 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ + 4 | const filename3 = new URL(import.meta.url).pathname;␊ + ` + +> Error 2/3 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename1 = fileURLToPath(import.meta.url);␊ + > 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + 4 | const filename3 = new URL(import.meta.url).pathname;␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename1 = fileURLToPath(import.meta.url);␊ + 3 | const filename2 = import.meta.filename;␊ + 4 | const filename3 = new URL(import.meta.url).pathname;␊ + ` + +> Error 3/3 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename1 = fileURLToPath(import.meta.url);␊ + 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ + > 4 | const filename3 = new URL(import.meta.url).pathname;␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename1 = fileURLToPath(import.meta.url);␊ + 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ + 4 | const filename3 = import.meta.filename;␊ + ` + +## invalid(3): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); + +> Input + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + ` + +> Error 1/1 + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const dirname = import.meta.dirname;␊ + ` + +## invalid(4): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); + +> Input + + `␊ + 1 | import { fileURLToPath } from "node:url";␊ + 2 | const filename = fileURLToPath(import.meta.url);␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath } from "node:url";␊ + > 2 | const filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ + 1 | import { fileURLToPath } from "node:url";␊ + 2 | const filename = import.meta.filename;␊ + ` + +## invalid(5): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); + +> Input + + `␊ + 1 | import * as path from "node:path";␊ + 2 | import url from "node:url";␊ + 3 | const dirname = path.dirname(url.fileURLToPath(import.meta.url));␊ + ` + +> Error 1/1 + + `␊ + 1 | import * as path from "node:path";␊ + 2 | import url from "node:url";␊ + > 3 | const dirname = path.dirname(url.fileURLToPath(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import * as path from "node:path";␊ + 2 | import url from "node:url";␊ + 3 | const dirname = import.meta.dirname;␊ + ` + +## invalid(6): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); + +> Input + + `␊ + 1 | import url from "node:url";␊ + 2 | const filename = url.fileURLToPath(import.meta.url);␊ + ` + +> Error 1/1 + + `␊ + 1 | import url from "node:url";␊ + > 2 | const filename = url.fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ + 1 | import url from "node:url";␊ + 2 | const filename = import.meta.filename;␊ + ` diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 062d9ab1a22e04b56f667d486a538169ff6eedfa..929800814d9f9b3d7922dfcd4872c684554238d4 100644 GIT binary patch literal 4818 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 literal 4060 zcmV<24m)r$D&xH5VrfmSv?$ zSK4+rb03Qc00000000B+U0ZV;M-|rEmBdmJ2𝔰>2moG1|4|k#?okWsL+5zTnu2 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 OH}?PAhV(ylng9T6Y0ZfM From 0bc4a017247b7b54568f6fb055cfde8ab982789a Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Wed, 26 Mar 2025 19:34:27 +0900 Subject: [PATCH 02/38] chore: fix linting errors --- scripts/create-rule.js | 3 +-- scripts/internal-rules/no-restricted-property-access.js | 3 +-- scripts/internal-rules/no-test-only.js | 3 +-- scripts/internal-rules/prefer-fixer-remove-range.js | 3 +-- scripts/internal-rules/prefer-negative-boolean-attribute.js | 3 +-- test/integration/projects.js | 3 +-- test/unit/get-documentation-url.js | 3 +-- 7 files changed, 7 insertions(+), 14 deletions(-) diff --git a/scripts/create-rule.js b/scripts/create-rule.js index 3ec6a4aba3..c90a2dbca0 100644 --- a/scripts/create-rule.js +++ b/scripts/create-rule.js @@ -1,13 +1,12 @@ #!/usr/bin/env node import fs from 'node:fs'; import path from 'node:path'; -import {fileURLToPath} from 'node:url'; import enquirer from 'enquirer'; import {template} from 'lodash-es'; import openEditor from 'open-editor'; import spawn from 'nano-spawn'; -const dirname = path.dirname(fileURLToPath(import.meta.url)); +const {dirname} = import.meta; const ROOT = path.join(dirname, '..'); function checkFiles(ruleId) { diff --git a/scripts/internal-rules/no-restricted-property-access.js b/scripts/internal-rules/no-restricted-property-access.js index a9baf09055..5f9f844755 100644 --- a/scripts/internal-rules/no-restricted-property-access.js +++ b/scripts/internal-rules/no-restricted-property-access.js @@ -1,9 +1,8 @@ import path from 'node:path'; -import {fileURLToPath} from 'node:url'; import {isMemberExpression} from '../../rules/ast/index.js'; import {removeMemberExpressionProperty} from '../../rules/fix/index.js'; -const messageId = path.basename(fileURLToPath(import.meta.url), '.js'); +const messageId = path.basename(import.meta.filename, '.js'); const properties = new Map([ ['range', 'sourceCode.getRange'], diff --git a/scripts/internal-rules/no-test-only.js b/scripts/internal-rules/no-test-only.js index 0901903edf..061e08ab1b 100644 --- a/scripts/internal-rules/no-test-only.js +++ b/scripts/internal-rules/no-test-only.js @@ -1,7 +1,6 @@ import path from 'node:path'; -import {fileURLToPath} from 'node:url'; -const messageId = path.basename(fileURLToPath(import.meta.url), '.js'); +const messageId = path.basename(import.meta.filename, '.js'); const config = { create(context) { diff --git a/scripts/internal-rules/prefer-fixer-remove-range.js b/scripts/internal-rules/prefer-fixer-remove-range.js index 3d43824cd9..126fc1a394 100644 --- a/scripts/internal-rules/prefer-fixer-remove-range.js +++ b/scripts/internal-rules/prefer-fixer-remove-range.js @@ -1,9 +1,8 @@ import path from 'node:path'; -import {fileURLToPath} from 'node:url'; import {isMethodCall, isLiteral} from '../../rules/ast/index.js'; import {removeArgument} from '../../rules/fix/index.js'; -const messageId = path.basename(fileURLToPath(import.meta.url), '.js'); +const messageId = path.basename(import.meta.filename, '.js'); const config = { create(context) { diff --git a/scripts/internal-rules/prefer-negative-boolean-attribute.js b/scripts/internal-rules/prefer-negative-boolean-attribute.js index 50e22e60ca..fc6beebfa9 100644 --- a/scripts/internal-rules/prefer-negative-boolean-attribute.js +++ b/scripts/internal-rules/prefer-negative-boolean-attribute.js @@ -1,7 +1,6 @@ import path from 'node:path'; -import {fileURLToPath} from 'node:url'; -const messageId = path.basename(fileURLToPath(import.meta.url), '.js'); +const messageId = path.basename(import.meta.filename, '.js'); const shouldReport = (string, value) => { const index = string.indexOf(`=${value}]`); diff --git a/test/integration/projects.js b/test/integration/projects.js index 1dbb1fd76f..2153c0c3fa 100644 --- a/test/integration/projects.js +++ b/test/integration/projects.js @@ -1,7 +1,6 @@ import path from 'node:path'; -import {fileURLToPath} from 'node:url'; -const dirname = path.dirname(fileURLToPath(import.meta.url)); +const {dirname} = import.meta; function normalizeProject(project) { if (typeof project === 'string') { diff --git a/test/unit/get-documentation-url.js b/test/unit/get-documentation-url.js index a8f3819eb3..30620eb95b 100644 --- a/test/unit/get-documentation-url.js +++ b/test/unit/get-documentation-url.js @@ -1,9 +1,8 @@ -import url from 'node:url'; import test from 'ava'; import getDocumentationUrl from '../../rules/utils/get-documentation-url.js'; import packageJson from '../../package.json' with {type: 'json'}; -const filename = url.fileURLToPath(import.meta.url).replace(/\.js$/, '.js'); +const filename = import.meta.filename.replace(/\.js$/, '.js'); test('returns the URL of the a named rule\'s documentation', t => { const url = `https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v${packageJson.version}/docs/rules/foo.md`; From 7107b20f9b48c7e15ef6d5748523b93551b3aab6 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Wed, 26 Mar 2025 19:41:19 +0900 Subject: [PATCH 03/38] chore: revert `test/unit/get-documentation-url.js` --- test/unit/get-documentation-url.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/unit/get-documentation-url.js b/test/unit/get-documentation-url.js index 30620eb95b..8e7609f53d 100644 --- a/test/unit/get-documentation-url.js +++ b/test/unit/get-documentation-url.js @@ -1,8 +1,10 @@ +import url from 'node:url'; import test from 'ava'; import getDocumentationUrl from '../../rules/utils/get-documentation-url.js'; import packageJson from '../../package.json' with {type: 'json'}; -const filename = import.meta.filename.replace(/\.js$/, '.js'); +// eslint-disable-next-line unicorn/prefer-module -- We still use Node.js v18 for CI. +const filename = url.fileURLToPath(import.meta.url).replace(/\.js$/, '.js'); test('returns the URL of the a named rule\'s documentation', t => { const url = `https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v${packageJson.version}/docs/rules/foo.md`; From 9e1bff8181b914d8f285e97cc804d0f14af906b5 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Wed, 26 Mar 2025 21:06:57 +0900 Subject: [PATCH 04/38] feat: check for filename vars --- rules/prefer-module.js | 98 +++++++++++++++++------- test/prefer-module.js | 16 ++++ test/snapshots/prefer-module.js.md | 110 +++++++++++++++++++++++++++ test/snapshots/prefer-module.js.snap | Bin 4818 -> 5049 bytes 4 files changed, 195 insertions(+), 29 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 5707126aaa..7809103751 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -448,7 +448,7 @@ function create(context) { return problem; }); - context.on('MetaProperty', node => { + context.on('MetaProperty', function * (node) { if (!isImportMeta(node)) { return; } @@ -471,55 +471,95 @@ function create(context) { isCallFileURLToPath(targetNode, sourceCode) && targetNode.arguments[0] === parent ) { + yield * processFilenameExpression(targetNode); // Report `fileURLToPath(import.meta.url)` - return buildProblemForFilename(targetNode); + yield buildProblemForFilename(targetNode); + return; } if (isNewURL(targetNode, sourceCode)) { - const verifyURLUsage = problemBuilder => { - const urlParent = targetNode.parent; - if ( - ( - // `fileURLToPath(new URL(...))` - isCallFileURLToPath(urlParent, sourceCode) - && urlParent.arguments[0] === targetNode - ) - // `new URL(...).pathname` - || isAccessPathname(urlParent) - ) { - return problemBuilder(urlParent); - } - }; + const urlParent = targetNode.parent; + const isURLToPath = () => ( + ( + // `fileURLToPath(new URL(...))` + isCallFileURLToPath(urlParent, sourceCode) + && urlParent.arguments[0] === targetNode + ) + // `new URL(...).pathname` + || isAccessPathname(urlParent) + ); if (targetNode.arguments[0] === parent) { - // Verify `new URL(import.meta.url)` - return verifyURLUsage(buildProblemForFilename); + if (isURLToPath()) { + yield * processFilenameExpression(urlParent); + // Report `new URL(import.meta.url).pathname` or `fileURLToPath(new URL(import.meta.url))` + yield buildProblemForFilename(urlParent); + } + + return; } if ( isLiteral(targetNode.arguments[0], '.') && targetNode.arguments[1] === parent - ) { - // Verify `new URL('.', import.meta.url)` - return verifyURLUsage(urlParent => buildProblem(urlParent, 'dirname')); + && isURLToPath()) { + // Report `new URL(".", import.meta.url).pathname` or `fileURLToPath(new URL(".", import.meta.url))` + yield buildProblem(urlParent, 'dirname'); } } + + return; } - if ( - propertyName === 'filename' - && isCallPathDirname(targetNode, sourceCode) - && targetNode.arguments[0] === parent - ) { - // Report `path.dirname(import.meta.filename)` - return buildProblem(targetNode, 'dirname'); + if (propertyName === 'filename') { + yield * processFilenameExpression(parent); + if ( + isCallPathDirname(targetNode, sourceCode) + && targetNode.arguments[0] === parent + ) { + // Report `path.dirname(import.meta.filename)` + yield buildProblem(targetNode, 'dirname'); + } + } + + /** + @param { import('estree').Expression} node + */ + function * processFilenameExpression(node) { + /** @type {{parent: import('estree').Node}} */ + const {parent} = node; + if (parent.type !== 'VariableDeclarator' || parent.init !== node || parent.id.type !== 'Identifier') { + return; + } + + /** @type {import('eslint').Scope.Variable|null} */ + const variable = findVariable(sourceCode.getScope(parent.id), parent.id); + if (!variable) { + return; + } + + for (const reference of variable.references) { + if (!reference.isReadOnly()) { + continue; + } + + /** @type {{parent: import('estree').Node}} */ + const {parent} = reference.identifier; + if ( + isCallPathDirname(parent, sourceCode) + && parent.arguments[0] === reference.identifier + ) { + // Report `path.dirname(identifier)` + yield buildProblem(parent, 'dirname'); + } + } } /** @param { import('estree').Node} node */ function buildProblemForFilename(node) { - /** @type {import('estree').Node} */ + /** @type {{parent: import('estree').Node}} */ const {parent} = node; if ( isCallPathDirname(parent, sourceCode) diff --git a/test/prefer-module.js b/test/prefer-module.js index c2d1cd7b62..89f3723081 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -353,5 +353,21 @@ test.snapshot({ import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); `, + outdent` + import path from "node:path"; + import { fileURLToPath } from "node:url"; + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + `, + outdent` + import path from "node:path"; + const __filename = new URL(import.meta.url).pathname; + const __dirname = path.dirname(__filename); + `, + outdent` + import path from "node:path"; + const __filename = import.meta.filename; + const __dirname = path.dirname(__filename); + `, ], }); diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 26a9b3bdfb..944e038d24 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -2199,3 +2199,113 @@ Generated by [AVA](https://avajs.dev). 1 | import url from "node:url";␊ 2 | const filename = import.meta.filename;␊ ` + +## invalid(7): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); + +> Input + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = fileURLToPath(import.meta.url);␊ + 4 | const __dirname = path.dirname(__filename);␊ + ` + +> Error 1/2 + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + > 3 | const __filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + 4 | const __dirname = path.dirname(__filename);␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = import.meta.filename;␊ + 4 | const __dirname = path.dirname(__filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = fileURLToPath(import.meta.url);␊ + > 4 | const __dirname = path.dirname(__filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = fileURLToPath(import.meta.url);␊ + 4 | const __dirname = import.meta.dirname;␊ + ` + +## invalid(8): import path from "node:path"; const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); + +> Input + + `␊ + 1 | import path from "node:path";␊ + 2 | const __filename = new URL(import.meta.url).pathname;␊ + 3 | const __dirname = path.dirname(__filename);␊ + ` + +> Error 1/2 + + `␊ + 1 | import path from "node:path";␊ + > 2 | const __filename = new URL(import.meta.url).pathname;␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + 3 | const __dirname = path.dirname(__filename);␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ + 1 | import path from "node:path";␊ + 2 | const __filename = import.meta.filename;␊ + 3 | const __dirname = path.dirname(__filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | import path from "node:path";␊ + 2 | const __filename = new URL(import.meta.url).pathname;␊ + > 3 | const __dirname = path.dirname(__filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "node:path";␊ + 2 | const __filename = new URL(import.meta.url).pathname;␊ + 3 | const __dirname = import.meta.dirname;␊ + ` + +## invalid(9): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); + +> Input + + `␊ + 1 | import path from "node:path";␊ + 2 | const __filename = import.meta.filename;␊ + 3 | const __dirname = path.dirname(__filename);␊ + ` + +> Error 1/1 + + `␊ + 1 | import path from "node:path";␊ + 2 | const __filename = import.meta.filename;␊ + > 3 | const __dirname = path.dirname(__filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "node:path";␊ + 2 | const __filename = import.meta.filename;␊ + 3 | const __dirname = import.meta.dirname;␊ + ` diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 929800814d9f9b3d7922dfcd4872c684554238d4..77cd803e3b2313ec682cf20db8e5e69998325e67 100644 GIT binary patch literal 5049 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 From fd842aa789442ffedcfc8cccebe119450eb79492 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Wed, 26 Mar 2025 21:17:23 +0900 Subject: [PATCH 05/38] test: fix comment --- test/prefer-module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/prefer-module.js b/test/prefer-module.js index 89f3723081..337f2689a5 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -308,7 +308,7 @@ test.snapshot({ ], }); -// `exports` and `module` +// `import.meta.dirname` and `import.meta.filename` test.snapshot({ valid: [ 'const __dirname = import.meta.dirname;', From 93c7dac4715b15b11ca7b97fd1c4fb58b7153d81 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Wed, 26 Mar 2025 21:26:23 +0900 Subject: [PATCH 06/38] docs: add `import.meta.{dirname,filename}` --- docs/rules/prefer-module.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/rules/prefer-module.md b/docs/rules/prefer-module.md index a90f2b9886..11409b0412 100644 --- a/docs/rules/prefer-module.md +++ b/docs/rules/prefer-module.md @@ -62,6 +62,14 @@ Prefer using the [JavaScript module](https://developer.mozilla.org/en-US/docs/We `export …` should be used in JavaScript modules. +1. Disallows `fileURLToPath(import.meta.url)` and similar operations. + + Starting with Node.js 20.11, [`import.meta.dirname`](https://nodejs.org/api/esm.html#importmetadirname) and [`import.meta.filename`](https://nodejs.org/api/esm.html#importmetafilename) have been introduced in ES modules. + + `fileURLToPath(import.meta.url)` can be replaced by `import.meta.filename`. + + `path.dirname(import.meta.filename)` can be replaced by `import.meta.dirname`. + *`.cjs` files are ignored.* ## Fail From e0981502d89145525853e342db749643c4112da9 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Wed, 26 Mar 2025 22:39:38 +0900 Subject: [PATCH 07/38] fix: allow `new URL()` operations --- rules/prefer-module.js | 79 +++++++++----------- test/prefer-module.js | 6 +- test/snapshots/prefer-module.js.md | 105 +++++---------------------- test/snapshots/prefer-module.js.snap | Bin 5049 -> 4912 bytes 4 files changed, 57 insertions(+), 133 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 7809103751..55ac546113 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -471,29 +471,28 @@ function create(context) { isCallFileURLToPath(targetNode, sourceCode) && targetNode.arguments[0] === parent ) { - yield * processFilenameExpression(targetNode); // Report `fileURLToPath(import.meta.url)` - yield buildProblemForFilename(targetNode); + yield * iterateProblemsFromFilename(targetNode, { + reportFilenameNode: true, + }); return; } if (isNewURL(targetNode, sourceCode)) { const urlParent = targetNode.parent; - const isURLToPath = () => ( - ( - // `fileURLToPath(new URL(...))` - isCallFileURLToPath(urlParent, sourceCode) - && urlParent.arguments[0] === targetNode - ) - // `new URL(...).pathname` - || isAccessPathname(urlParent) - ); if (targetNode.arguments[0] === parent) { - if (isURLToPath()) { - yield * processFilenameExpression(urlParent); - // Report `new URL(import.meta.url).pathname` or `fileURLToPath(new URL(import.meta.url))` - yield buildProblemForFilename(urlParent); + if ( + isCallFileURLToPath(urlParent, sourceCode) + && urlParent.arguments[0] === targetNode + ) { + // Report `fileURLToPath(new URL(import.meta.url))` + yield * iterateProblemsFromFilename(urlParent, { + reportFilenameNode: true, + }); + } else if (isAccessPathname(urlParent)) { + // Process for `new URL(import.meta.url).pathname` + yield * iterateProblemsFromFilename(urlParent); } return; @@ -502,8 +501,10 @@ function create(context) { if ( isLiteral(targetNode.arguments[0], '.') && targetNode.arguments[1] === parent - && isURLToPath()) { - // Report `new URL(".", import.meta.url).pathname` or `fileURLToPath(new URL(".", import.meta.url))` + && isCallFileURLToPath(urlParent, sourceCode) + && urlParent.arguments[0] === targetNode + ) { + // Report `fileURLToPath(new URL(".", import.meta.url))` yield buildProblem(urlParent, 'dirname'); } } @@ -512,22 +513,31 @@ function create(context) { } if (propertyName === 'filename') { - yield * processFilenameExpression(parent); - if ( - isCallPathDirname(targetNode, sourceCode) - && targetNode.arguments[0] === parent - ) { - // Report `path.dirname(import.meta.filename)` - yield buildProblem(targetNode, 'dirname'); - } + yield * iterateProblemsFromFilename(parent); } /** + Iterates over reports where a given filename expression node + would be used to convert it to a dirname. @param { import('estree').Expression} node */ - function * processFilenameExpression(node) { + function * iterateProblemsFromFilename(node, {reportFilenameNode = false} = {}) { /** @type {{parent: import('estree').Node}} */ const {parent} = node; + + if ( + isCallPathDirname(parent, sourceCode) + && parent.arguments[0] === node + ) { + // Report `path.dirname(filename)` + yield buildProblem(parent, 'dirname'); + return; + } + + if (reportFilenameNode) { + yield buildProblem(node, 'filename'); + } + if (parent.type !== 'VariableDeclarator' || parent.init !== node || parent.id.type !== 'Identifier') { return; } @@ -555,23 +565,6 @@ function create(context) { } } - /** - @param { import('estree').Node} node - */ - function buildProblemForFilename(node) { - /** @type {{parent: import('estree').Node}} */ - const {parent} = node; - if ( - isCallPathDirname(parent, sourceCode) - && parent.arguments[0] === node - ) { - // Report `path.dirname(node)` - return buildProblem(parent, 'dirname'); - } - - return buildProblem(node, 'filename'); - } - /** @param { import('estree').Node} node @param {'dirname' | 'filename'} name diff --git a/test/prefer-module.js b/test/prefer-module.js index 337f2689a5..fc62256f39 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -318,6 +318,8 @@ test.snapshot({ const dirUrl = path.dirname(import.meta.url); `, 'const url = import.meta.url;', + 'const dirname = new URL(".", import.meta.url).pathname;', + 'const filename = new URL(import.meta.url).pathname;', ], invalid: [ outdent` @@ -326,14 +328,12 @@ test.snapshot({ const dirname1 = path.dirname(fileURLToPath(import.meta.url)); const dirname2 = path.dirname(import.meta.filename); const dirname3 = path.dirname(new URL(import.meta.url).pathname); - const dirname4 = new URL(".", import.meta.url).pathname; - const dirname5 = fileURLToPath(new URL(".", import.meta.url)); + const dirname4 = fileURLToPath(new URL(".", import.meta.url)); `, outdent` import { fileURLToPath } from "url"; const filename1 = fileURLToPath(import.meta.url); const filename2 = fileURLToPath(new URL(import.meta.url)); - const filename3 = new URL(import.meta.url).pathname; `, outdent` import path from "node:path"; diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 944e038d24..4f45788170 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1915,7 +1915,7 @@ Generated by [AVA](https://avajs.dev). 1 | import "lodash"␊ ` -## invalid(1): import path from "path"; import { fileURLToPath } from "url"; const dirname1 = path.dirname(fileURLToPath(import.meta.url)); const dirname2 = path.dirname(import.meta.filename); const dirname3 = path.dirname(new URL(import.meta.url).pathname); const dirname4 = new URL(".", import.meta.url).pathname; const dirname5 = fileURLToPath(new URL(".", import.meta.url)); +## invalid(1): import path from "path"; import { fileURLToPath } from "url"; const dirname1 = path.dirname(fileURLToPath(import.meta.url)); const dirname2 = path.dirname(import.meta.filename); const dirname3 = path.dirname(new URL(import.meta.url).pathname); const dirname4 = fileURLToPath(new URL(".", import.meta.url)); > Input @@ -1925,11 +1925,10 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ ` -> Error 1/5 +> Error 1/4 `␊ 1 | import path from "path";␊ @@ -1938,8 +1937,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -1948,11 +1946,10 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname1 = import.meta.dirname;␊ 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ ` -> Error 2/5 +> Error 2/4 `␊ 1 | import path from "path";␊ @@ -1961,8 +1958,7 @@ Generated by [AVA](https://avajs.dev). > 4 | const dirname2 = path.dirname(import.meta.filename);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -1971,11 +1967,10 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ 4 | const dirname2 = import.meta.dirname;␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ ` -> Error 3/5 +> Error 3/4 `␊ 1 | import path from "path";␊ @@ -1984,8 +1979,7 @@ Generated by [AVA](https://avajs.dev). 4 | const dirname2 = path.dirname(import.meta.filename);␊ > 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ - 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -1994,11 +1988,10 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = import.meta.dirname;␊ - 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ ` -> Error 4/5 +> Error 4/4 `␊ 1 | import path from "path";␊ @@ -2006,31 +1999,7 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - > 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ - 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = import.meta.dirname;␊ - 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ - ` - -> Error 5/5 - - `␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - > 7 | const dirname5 = fileURLToPath(new URL(".", import.meta.url));␊ + > 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ ␊ --------------------------------------------------------------------------------␊ @@ -2040,11 +2009,10 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = new URL(".", import.meta.url).pathname;␊ - 7 | const dirname5 = import.meta.dirname;␊ + 6 | const dirname4 = import.meta.dirname;␊ ` -## invalid(2): import { fileURLToPath } from "url"; const filename1 = fileURLToPath(import.meta.url); const filename2 = fileURLToPath(new URL(import.meta.url)); const filename3 = new URL(import.meta.url).pathname; +## invalid(2): import { fileURLToPath } from "url"; const filename1 = fileURLToPath(import.meta.url); const filename2 = fileURLToPath(new URL(import.meta.url)); > Input @@ -2052,58 +2020,36 @@ Generated by [AVA](https://avajs.dev). 1 | import { fileURLToPath } from "url";␊ 2 | const filename1 = fileURLToPath(import.meta.url);␊ 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ - 4 | const filename3 = new URL(import.meta.url).pathname;␊ ` -> Error 1/3 +> Error 1/2 `␊ 1 | import { fileURLToPath } from "url";␊ > 2 | const filename1 = fileURLToPath(import.meta.url);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ - 4 | const filename3 = new URL(import.meta.url).pathname;␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ 1 | import { fileURLToPath } from "url";␊ 2 | const filename1 = import.meta.filename;␊ 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ - 4 | const filename3 = new URL(import.meta.url).pathname;␊ ` -> Error 2/3 +> Error 2/2 `␊ 1 | import { fileURLToPath } from "url";␊ 2 | const filename1 = fileURLToPath(import.meta.url);␊ > 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ - 4 | const filename3 = new URL(import.meta.url).pathname;␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ 1 | import { fileURLToPath } from "url";␊ 2 | const filename1 = fileURLToPath(import.meta.url);␊ 3 | const filename2 = import.meta.filename;␊ - 4 | const filename3 = new URL(import.meta.url).pathname;␊ - ` - -> Error 3/3 - - `␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const filename1 = fileURLToPath(import.meta.url);␊ - 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ - > 4 | const filename3 = new URL(import.meta.url).pathname;␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const filename1 = fileURLToPath(import.meta.url);␊ - 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ - 4 | const filename3 = import.meta.filename;␊ ` ## invalid(3): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -2255,22 +2201,7 @@ Generated by [AVA](https://avajs.dev). 3 | const __dirname = path.dirname(__filename);␊ ` -> Error 1/2 - - `␊ - 1 | import path from "node:path";␊ - > 2 | const __filename = new URL(import.meta.url).pathname;␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ - 3 | const __dirname = path.dirname(__filename);␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ - 1 | import path from "node:path";␊ - 2 | const __filename = import.meta.filename;␊ - 3 | const __dirname = path.dirname(__filename);␊ - ` - -> Error 2/2 +> Error 1/1 `␊ 1 | import path from "node:path";␊ diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 77cd803e3b2313ec682cf20db8e5e69998325e67..1791e2af1209ca04f76fbc2bea6a09f280a6c55a 100644 GIT binary patch literal 4912 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 literal 5049 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 Date: Thu, 27 Mar 2025 08:50:00 +0900 Subject: [PATCH 08/38] fix: support for `new URL('./', ...)` and add tests --- rules/prefer-module.js | 12 ++- test/prefer-module.js | 17 ++++ test/snapshots/prefer-module.js.md | 113 +++++++++++++++++++++++++-- test/snapshots/prefer-module.js.snap | Bin 4912 -> 5085 bytes 4 files changed, 135 insertions(+), 7 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 55ac546113..fdf5382ca1 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -3,7 +3,7 @@ import isShadowed from './utils/is-shadowed.js'; import assertToken from './utils/assert-token.js'; import {getCallExpressionTokens} from './utils/index.js'; import { - isStaticRequire, isReferenceIdentifier, isFunction, isLiteral, + isStaticRequire, isReferenceIdentifier, isFunction, } from './ast/index.js'; import {removeParentheses, replaceReferenceIdentifier, removeSpacesAfter} from './fix/index.js'; @@ -207,6 +207,14 @@ const isTopLevelReturnStatement = node => { return true; }; +const isParentLiteral = node => { + if (node?.type !== 'Literal') { + return false; + } + + return node.value === '.' || node.value === './'; +}; + const isImportMeta = node => node.type === 'MetaProperty' && node.meta.name === 'import' @@ -499,7 +507,7 @@ function create(context) { } if ( - isLiteral(targetNode.arguments[0], '.') + isParentLiteral(targetNode.arguments[0]) && targetNode.arguments[1] === parent && isCallFileURLToPath(urlParent, sourceCode) && urlParent.arguments[0] === targetNode diff --git a/test/prefer-module.js b/test/prefer-module.js index fc62256f39..44695c97d9 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -320,6 +320,7 @@ test.snapshot({ 'const url = import.meta.url;', 'const dirname = new URL(".", import.meta.url).pathname;', 'const filename = new URL(import.meta.url).pathname;', + 'const filename = fileURLToPath(import.meta.url);', // `fileURLToPath` is not imported ], invalid: [ outdent` @@ -329,6 +330,7 @@ test.snapshot({ const dirname2 = path.dirname(import.meta.filename); const dirname3 = path.dirname(new URL(import.meta.url).pathname); const dirname4 = fileURLToPath(new URL(".", import.meta.url)); + const dirname5 = fileURLToPath(new URL("./", import.meta.url)); `, outdent` import { fileURLToPath } from "url"; @@ -369,5 +371,20 @@ test.snapshot({ const __filename = import.meta.filename; const __dirname = path.dirname(__filename); `, + { + // .mjs file will be auto-fixed + code: outdent` + import path from "node:path"; + import { fileURLToPath } from "node:url"; + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + `, + filename: 'foo.mjs', + }, + outdent` + // path is not imported + import { fileURLToPath } from "node:url"; + const dirname = path.dirname(fileURLToPath(import.meta.url)); + `, ], }); diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 4f45788170..615ddd53a6 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1915,7 +1915,7 @@ Generated by [AVA](https://avajs.dev). 1 | import "lodash"␊ ` -## invalid(1): import path from "path"; import { fileURLToPath } from "url"; const dirname1 = path.dirname(fileURLToPath(import.meta.url)); const dirname2 = path.dirname(import.meta.filename); const dirname3 = path.dirname(new URL(import.meta.url).pathname); const dirname4 = fileURLToPath(new URL(".", import.meta.url)); +## invalid(1): import path from "path"; import { fileURLToPath } from "url"; const dirname1 = path.dirname(fileURLToPath(import.meta.url)); const dirname2 = path.dirname(import.meta.filename); const dirname3 = path.dirname(new URL(import.meta.url).pathname); const dirname4 = fileURLToPath(new URL(".", import.meta.url)); const dirname5 = fileURLToPath(new URL("./", import.meta.url)); > Input @@ -1926,9 +1926,10 @@ Generated by [AVA](https://avajs.dev). 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ + 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ` -> Error 1/4 +> Error 1/5 `␊ 1 | import path from "path";␊ @@ -1938,6 +1939,7 @@ Generated by [AVA](https://avajs.dev). 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ + 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -1947,9 +1949,10 @@ Generated by [AVA](https://avajs.dev). 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ + 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ` -> Error 2/4 +> Error 2/5 `␊ 1 | import path from "path";␊ @@ -1959,6 +1962,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ + 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -1968,9 +1972,10 @@ Generated by [AVA](https://avajs.dev). 4 | const dirname2 = import.meta.dirname;␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ + 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ` -> Error 3/4 +> Error 3/5 `␊ 1 | import path from "path";␊ @@ -1980,6 +1985,7 @@ Generated by [AVA](https://avajs.dev). > 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ + 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -1989,9 +1995,10 @@ Generated by [AVA](https://avajs.dev). 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = import.meta.dirname;␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ + 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ` -> Error 4/4 +> Error 4/5 `␊ 1 | import path from "path";␊ @@ -2001,6 +2008,7 @@ Generated by [AVA](https://avajs.dev). 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ > 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -2010,6 +2018,30 @@ Generated by [AVA](https://avajs.dev). 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = import.meta.dirname;␊ + 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ + ` + +> Error 5/5 + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ + > 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ + 4 | const dirname2 = path.dirname(import.meta.filename);␊ + 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ + 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ + 7 | const dirname5 = import.meta.dirname;␊ ` ## invalid(2): import { fileURLToPath } from "url"; const filename1 = fileURLToPath(import.meta.url); const filename2 = fileURLToPath(new URL(import.meta.url)); @@ -2240,3 +2272,74 @@ Generated by [AVA](https://avajs.dev). 2 | const __filename = import.meta.filename;␊ 3 | const __dirname = import.meta.dirname;␊ ` + +## invalid(10): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); + +> Input + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = fileURLToPath(import.meta.url);␊ + 4 | const __dirname = path.dirname(__filename);␊ + ` + +> Filename + + `␊ + foo.mjs␊ + ` + +> Output + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = import.meta.filename;␊ + 4 | const __dirname = import.meta.dirname;␊ + ` + +> Error 1/2 + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + > 3 | const __filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + 4 | const __dirname = path.dirname(__filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = fileURLToPath(import.meta.url);␊ + > 4 | const __dirname = path.dirname(__filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + ` + +## invalid(11): // path is not imported import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); + +> Input + + `␊ + 1 | // path is not imported␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + ` + +> Error 1/1 + + `␊ + 1 | // path is not imported␊ + 2 | import { fileURLToPath } from "node:url";␊ + > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ + 1 | // path is not imported␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const dirname = path.dirname(import.meta.filename);␊ + ` diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 1791e2af1209ca04f76fbc2bea6a09f280a6c55a..104d644eb5a4df278d12fdbfed0e1caea75f39e2 100644 GIT binary patch literal 5085 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 From e82b01998283d6192e1c2ba5fde4322462427f02 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Thu, 27 Mar 2025 09:04:39 +0900 Subject: [PATCH 09/38] fix: update error messages --- rules/prefer-module.js | 8 +++--- test/snapshots/prefer-module.js.md | 36 +++++++++++++-------------- test/snapshots/prefer-module.js.snap | Bin 5085 -> 5098 bytes 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index fdf5382ca1..9250f6a8b7 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -10,6 +10,8 @@ import {removeParentheses, replaceReferenceIdentifier, removeSpacesAfter} from ' const ERROR_USE_STRICT_DIRECTIVE = 'error/use-strict-directive'; const ERROR_GLOBAL_RETURN = 'error/global-return'; const ERROR_IDENTIFIER = 'error/identifier'; +const ERROR_CALC_DIRNAME = 'error/calc-dirname'; +const ERROR_CALC_FILENAME = 'error/calc-filename'; const SUGGESTION_USE_STRICT_DIRECTIVE = 'suggestion/use-strict-directive'; const SUGGESTION_IMPORT_META_DIRNAME = 'suggestion/import-meta-dirname'; const SUGGESTION_IMPORT_META_URL_TO_DIRNAME = 'suggestion/import-meta-url-to-dirname'; @@ -17,13 +19,14 @@ const SUGGESTION_IMPORT_META_FILENAME = 'suggestion/import-meta-filename'; const SUGGESTION_IMPORT_META_URL_TO_FILENAME = 'suggestion/import-meta-url-to-filename'; const SUGGESTION_IMPORT = 'suggestion/import'; const SUGGESTION_EXPORT = 'suggestion/export'; -const SUGGESTION_IMPORT_META = 'suggestion/import.meta'; const SUGGESTION_IMPORT_META_DIRNAME_FROM_URL = 'suggestion/import-meta-dirname-from-url'; const SUGGESTION_IMPORT_META_FILENAME_FROM_URL = 'suggestion/import-meta-filename-from-url'; const messages = { [ERROR_USE_STRICT_DIRECTIVE]: 'Do not use "use strict" directive.', [ERROR_GLOBAL_RETURN]: '"return" should be used inside a function.', [ERROR_IDENTIFIER]: 'Do not use "{{name}}".', + [ERROR_CALC_DIRNAME]: 'Do not construct dirname.', + [ERROR_CALC_FILENAME]: 'Do not construct filename using `fileURLToPath()`.', [SUGGESTION_USE_STRICT_DIRECTIVE]: 'Remove "use strict" directive.', [SUGGESTION_IMPORT_META_DIRNAME]: 'Replace `__dirname` with `import.meta.dirname`.', [SUGGESTION_IMPORT_META_URL_TO_DIRNAME]: 'Replace `__dirname` with `…(import.meta.url)`.', @@ -31,7 +34,6 @@ const messages = { [SUGGESTION_IMPORT_META_URL_TO_FILENAME]: 'Replace `__filename` with `…(import.meta.url)`.', [SUGGESTION_IMPORT]: 'Switch to `import`.', [SUGGESTION_EXPORT]: 'Switch to `export`.', - [SUGGESTION_IMPORT_META]: 'Switch to `import.meta.{{name}}`.', [SUGGESTION_IMPORT_META_DIRNAME_FROM_URL]: 'Replace `…(import.meta.url)` with `import.meta.dirname`.', [SUGGESTION_IMPORT_META_FILENAME_FROM_URL]: 'Replace `…(import.meta.url)` with `import.meta.filename`.', }; @@ -580,7 +582,7 @@ function create(context) { function buildProblem(node, name) { const problem = { node, - messageId: SUGGESTION_IMPORT_META, + messageId: name === 'dirname' ? ERROR_CALC_DIRNAME : ERROR_CALC_FILENAME, data: {name}, }; const fix = fixer => diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 615ddd53a6..981fd24787 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1935,7 +1935,7 @@ Generated by [AVA](https://avajs.dev). 1 | import path from "path";␊ 2 | import { fileURLToPath } from "url";␊ > 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ @@ -1959,7 +1959,7 @@ Generated by [AVA](https://avajs.dev). 2 | import { fileURLToPath } from "url";␊ 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ > 4 | const dirname2 = path.dirname(import.meta.filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ @@ -1983,7 +1983,7 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ 4 | const dirname2 = path.dirname(import.meta.filename);␊ > 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ␊ @@ -2007,7 +2007,7 @@ Generated by [AVA](https://avajs.dev). 4 | const dirname2 = path.dirname(import.meta.filename);␊ 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ > 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ␊ --------------------------------------------------------------------------------␊ @@ -2031,7 +2031,7 @@ Generated by [AVA](https://avajs.dev). 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ > 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -2059,7 +2059,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | import { fileURLToPath } from "url";␊ > 2 | const filename1 = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ ␊ --------------------------------------------------------------------------------␊ @@ -2075,7 +2075,7 @@ Generated by [AVA](https://avajs.dev). 1 | import { fileURLToPath } from "url";␊ 2 | const filename1 = fileURLToPath(import.meta.url);␊ > 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ @@ -2100,7 +2100,7 @@ Generated by [AVA](https://avajs.dev). 1 | import path from "node:path";␊ 2 | import { fileURLToPath } from "node:url";␊ > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -2123,7 +2123,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | import { fileURLToPath } from "node:url";␊ > 2 | const filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ @@ -2147,7 +2147,7 @@ Generated by [AVA](https://avajs.dev). 1 | import * as path from "node:path";␊ 2 | import url from "node:url";␊ > 3 | const dirname = path.dirname(url.fileURLToPath(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -2170,7 +2170,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | import url from "node:url";␊ > 2 | const filename = url.fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ @@ -2195,7 +2195,7 @@ Generated by [AVA](https://avajs.dev). 1 | import path from "node:path";␊ 2 | import { fileURLToPath } from "node:url";␊ > 3 | const __filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ 4 | const __dirname = path.dirname(__filename);␊ ␊ --------------------------------------------------------------------------------␊ @@ -2213,7 +2213,7 @@ Generated by [AVA](https://avajs.dev). 2 | import { fileURLToPath } from "node:url";␊ 3 | const __filename = fileURLToPath(import.meta.url);␊ > 4 | const __dirname = path.dirname(__filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -2239,7 +2239,7 @@ Generated by [AVA](https://avajs.dev). 1 | import path from "node:path";␊ 2 | const __filename = new URL(import.meta.url).pathname;␊ > 3 | const __dirname = path.dirname(__filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -2264,7 +2264,7 @@ Generated by [AVA](https://avajs.dev). 1 | import path from "node:path";␊ 2 | const __filename = import.meta.filename;␊ > 3 | const __dirname = path.dirname(__filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ @@ -2305,7 +2305,7 @@ Generated by [AVA](https://avajs.dev). 1 | import path from "node:path";␊ 2 | import { fileURLToPath } from "node:url";␊ > 3 | const __filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ 4 | const __dirname = path.dirname(__filename);␊ ` @@ -2316,7 +2316,7 @@ Generated by [AVA](https://avajs.dev). 2 | import { fileURLToPath } from "node:url";␊ 3 | const __filename = fileURLToPath(import.meta.url);␊ > 4 | const __dirname = path.dirname(__filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.dirname\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` ## invalid(11): // path is not imported import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -2335,7 +2335,7 @@ Generated by [AVA](https://avajs.dev). 1 | // path is not imported␊ 2 | import { fileURLToPath } from "node:url";␊ > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Switch to \`import.meta.filename\`.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 104d644eb5a4df278d12fdbfed0e1caea75f39e2..0143811d2beee63fa440ea502f3ef2608240f24e 100644 GIT binary patch delta 4526 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 Date: Thu, 27 Mar 2025 18:25:27 +0900 Subject: [PATCH 10/38] change to always auto-fix --- rules/prefer-module.js | 24 +--- test/snapshots/prefer-module.js.md | 199 +++++++++++---------------- test/snapshots/prefer-module.js.snap | Bin 5098 -> 5051 bytes 3 files changed, 86 insertions(+), 137 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 9250f6a8b7..e1c8aa7ab8 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -19,8 +19,6 @@ const SUGGESTION_IMPORT_META_FILENAME = 'suggestion/import-meta-filename'; const SUGGESTION_IMPORT_META_URL_TO_FILENAME = 'suggestion/import-meta-url-to-filename'; const SUGGESTION_IMPORT = 'suggestion/import'; const SUGGESTION_EXPORT = 'suggestion/export'; -const SUGGESTION_IMPORT_META_DIRNAME_FROM_URL = 'suggestion/import-meta-dirname-from-url'; -const SUGGESTION_IMPORT_META_FILENAME_FROM_URL = 'suggestion/import-meta-filename-from-url'; const messages = { [ERROR_USE_STRICT_DIRECTIVE]: 'Do not use "use strict" directive.', [ERROR_GLOBAL_RETURN]: '"return" should be used inside a function.', @@ -34,8 +32,6 @@ const messages = { [SUGGESTION_IMPORT_META_URL_TO_FILENAME]: 'Replace `__filename` with `…(import.meta.url)`.', [SUGGESTION_IMPORT]: 'Switch to `import`.', [SUGGESTION_EXPORT]: 'Switch to `export`.', - [SUGGESTION_IMPORT_META_DIRNAME_FROM_URL]: 'Replace `…(import.meta.url)` with `import.meta.dirname`.', - [SUGGESTION_IMPORT_META_FILENAME_FROM_URL]: 'Replace `…(import.meta.url)` with `import.meta.filename`.', }; const suggestions = new Map([ @@ -580,27 +576,13 @@ function create(context) { @param {'dirname' | 'filename'} name */ function buildProblem(node, name) { - const problem = { + return { node, messageId: name === 'dirname' ? ERROR_CALC_DIRNAME : ERROR_CALC_FILENAME, data: {name}, + fix: fixer => + fixer.replaceText(node, `import.meta.${name}`), }; - const fix = fixer => - fixer.replaceText(node, `import.meta.${name}`); - - if (filename.endsWith('.mjs')) { - problem.fix = fix; - } else { - problem.suggest = [{ - messageId: - name === 'dirname' - ? SUGGESTION_IMPORT_META_DIRNAME_FROM_URL - : SUGGESTION_IMPORT_META_FILENAME_FROM_URL, - fix, - }]; - } - - return problem; } }); } diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 981fd24787..33dfe580df 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1929,6 +1929,18 @@ Generated by [AVA](https://avajs.dev). 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ` +> Output + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname1 = import.meta.dirname;␊ + 4 | const dirname2 = import.meta.dirname;␊ + 5 | const dirname3 = import.meta.dirname;␊ + 6 | const dirname4 = import.meta.dirname;␊ + 7 | const dirname5 = import.meta.dirname;␊ + ` + > Error 1/5 `␊ @@ -1940,16 +1952,6 @@ Generated by [AVA](https://avajs.dev). 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = import.meta.dirname;␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ` > Error 2/5 @@ -1963,16 +1965,6 @@ Generated by [AVA](https://avajs.dev). 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = import.meta.dirname;␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ` > Error 3/5 @@ -1986,16 +1978,6 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = import.meta.dirname;␊ - 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ` > Error 4/5 @@ -2009,16 +1991,6 @@ Generated by [AVA](https://avajs.dev). > 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = import.meta.dirname;␊ - 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ ` > Error 5/5 @@ -2032,16 +2004,6 @@ Generated by [AVA](https://avajs.dev). 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ > 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - 7 | const dirname5 = import.meta.dirname;␊ ` ## invalid(2): import { fileURLToPath } from "url"; const filename1 = fileURLToPath(import.meta.url); const filename2 = fileURLToPath(new URL(import.meta.url)); @@ -2054,6 +2016,14 @@ Generated by [AVA](https://avajs.dev). 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ ` +> Output + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename1 = import.meta.filename;␊ + 3 | const filename2 = import.meta.filename;␊ + ` + > Error 1/2 `␊ @@ -2061,12 +2031,6 @@ Generated by [AVA](https://avajs.dev). > 2 | const filename1 = fileURLToPath(import.meta.url);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const filename1 = import.meta.filename;␊ - 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ ` > Error 2/2 @@ -2076,12 +2040,6 @@ Generated by [AVA](https://avajs.dev). 2 | const filename1 = fileURLToPath(import.meta.url);␊ > 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const filename1 = fileURLToPath(import.meta.url);␊ - 3 | const filename2 = import.meta.filename;␊ ` ## invalid(3): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -2094,6 +2052,14 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ ` +> Output + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const dirname = import.meta.dirname;␊ + ` + > Error 1/1 `␊ @@ -2101,12 +2067,6 @@ Generated by [AVA](https://avajs.dev). 2 | import { fileURLToPath } from "node:url";␊ > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const dirname = import.meta.dirname;␊ ` ## invalid(4): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); @@ -2118,17 +2078,19 @@ Generated by [AVA](https://avajs.dev). 2 | const filename = fileURLToPath(import.meta.url);␊ ` +> Output + + `␊ + 1 | import { fileURLToPath } from "node:url";␊ + 2 | const filename = import.meta.filename;␊ + ` + > Error 1/1 `␊ 1 | import { fileURLToPath } from "node:url";␊ > 2 | const filename = fileURLToPath(import.meta.url);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ - 1 | import { fileURLToPath } from "node:url";␊ - 2 | const filename = import.meta.filename;␊ ` ## invalid(5): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); @@ -2141,6 +2103,14 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname = path.dirname(url.fileURLToPath(import.meta.url));␊ ` +> Output + + `␊ + 1 | import * as path from "node:path";␊ + 2 | import url from "node:url";␊ + 3 | const dirname = import.meta.dirname;␊ + ` + > Error 1/1 `␊ @@ -2148,12 +2118,6 @@ Generated by [AVA](https://avajs.dev). 2 | import url from "node:url";␊ > 3 | const dirname = path.dirname(url.fileURLToPath(import.meta.url));␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import * as path from "node:path";␊ - 2 | import url from "node:url";␊ - 3 | const dirname = import.meta.dirname;␊ ` ## invalid(6): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); @@ -2165,17 +2129,19 @@ Generated by [AVA](https://avajs.dev). 2 | const filename = url.fileURLToPath(import.meta.url);␊ ` +> Output + + `␊ + 1 | import url from "node:url";␊ + 2 | const filename = import.meta.filename;␊ + ` + > Error 1/1 `␊ 1 | import url from "node:url";␊ > 2 | const filename = url.fileURLToPath(import.meta.url);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ - 1 | import url from "node:url";␊ - 2 | const filename = import.meta.filename;␊ ` ## invalid(7): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -2189,6 +2155,15 @@ Generated by [AVA](https://avajs.dev). 4 | const __dirname = path.dirname(__filename);␊ ` +> Output + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = import.meta.filename;␊ + 4 | const __dirname = import.meta.dirname;␊ + ` + > Error 1/2 `␊ @@ -2197,13 +2172,6 @@ Generated by [AVA](https://avajs.dev). > 3 | const __filename = fileURLToPath(import.meta.url);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ 4 | const __dirname = path.dirname(__filename);␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const __filename = import.meta.filename;␊ - 4 | const __dirname = path.dirname(__filename);␊ ` > Error 2/2 @@ -2214,13 +2182,6 @@ Generated by [AVA](https://avajs.dev). 3 | const __filename = fileURLToPath(import.meta.url);␊ > 4 | const __dirname = path.dirname(__filename);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const __filename = fileURLToPath(import.meta.url);␊ - 4 | const __dirname = import.meta.dirname;␊ ` ## invalid(8): import path from "node:path"; const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); @@ -2233,6 +2194,14 @@ Generated by [AVA](https://avajs.dev). 3 | const __dirname = path.dirname(__filename);␊ ` +> Output + + `␊ + 1 | import path from "node:path";␊ + 2 | const __filename = new URL(import.meta.url).pathname;␊ + 3 | const __dirname = import.meta.dirname;␊ + ` + > Error 1/1 `␊ @@ -2240,12 +2209,6 @@ Generated by [AVA](https://avajs.dev). 2 | const __filename = new URL(import.meta.url).pathname;␊ > 3 | const __dirname = path.dirname(__filename);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "node:path";␊ - 2 | const __filename = new URL(import.meta.url).pathname;␊ - 3 | const __dirname = import.meta.dirname;␊ ` ## invalid(9): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); @@ -2258,6 +2221,14 @@ Generated by [AVA](https://avajs.dev). 3 | const __dirname = path.dirname(__filename);␊ ` +> Output + + `␊ + 1 | import path from "node:path";␊ + 2 | const __filename = import.meta.filename;␊ + 3 | const __dirname = import.meta.dirname;␊ + ` + > Error 1/1 `␊ @@ -2265,12 +2236,6 @@ Generated by [AVA](https://avajs.dev). 2 | const __filename = import.meta.filename;␊ > 3 | const __dirname = path.dirname(__filename);␊ | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.dirname\`.␊ - 1 | import path from "node:path";␊ - 2 | const __filename = import.meta.filename;␊ - 3 | const __dirname = import.meta.dirname;␊ ` ## invalid(10): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -2329,6 +2294,14 @@ Generated by [AVA](https://avajs.dev). 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ ` +> Output + + `␊ + 1 | // path is not imported␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const dirname = path.dirname(import.meta.filename);␊ + ` + > Error 1/1 `␊ @@ -2336,10 +2309,4 @@ Generated by [AVA](https://avajs.dev). 2 | import { fileURLToPath } from "node:url";␊ > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/1: Replace \`…(import.meta.url)\` with \`import.meta.filename\`.␊ - 1 | // path is not imported␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const dirname = path.dirname(import.meta.filename);␊ ` diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 0143811d2beee63fa440ea502f3ef2608240f24e..feb08fd9296196840ff0371572ab29f87e13e456 100644 GIT binary patch literal 5051 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 Reu)h-{tu^9738nX0031siMap( literal 5098 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 Date: Thu, 27 Mar 2025 18:25:46 +0900 Subject: [PATCH 11/38] split test cases --- test/prefer-module.js | 39 +++-- test/snapshots/prefer-module.js.md | 232 +++++++++++++-------------- test/snapshots/prefer-module.js.snap | Bin 5051 -> 4958 bytes 3 files changed, 137 insertions(+), 134 deletions(-) diff --git a/test/prefer-module.js b/test/prefer-module.js index 44695c97d9..d4ef0f7781 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -326,16 +326,31 @@ test.snapshot({ outdent` import path from "path"; import { fileURLToPath } from "url"; - const dirname1 = path.dirname(fileURLToPath(import.meta.url)); - const dirname2 = path.dirname(import.meta.filename); - const dirname3 = path.dirname(new URL(import.meta.url).pathname); - const dirname4 = fileURLToPath(new URL(".", import.meta.url)); - const dirname5 = fileURLToPath(new URL("./", import.meta.url)); + const dirname = path.dirname(fileURLToPath(import.meta.url)); + `, + outdent` + import path from "path"; + const dirname = path.dirname(import.meta.filename); + `, + outdent` + import path from "path"; + const dirname = path.dirname(new URL(import.meta.url).pathname); + `, + outdent` + import { fileURLToPath } from "url"; + const dirname = fileURLToPath(new URL(".", import.meta.url)); + `, + outdent` + import { fileURLToPath } from "url"; + const dirname = fileURLToPath(new URL("./", import.meta.url)); + `, + outdent` + import { fileURLToPath } from "url"; + const filename = fileURLToPath(import.meta.url); `, outdent` import { fileURLToPath } from "url"; - const filename1 = fileURLToPath(import.meta.url); - const filename2 = fileURLToPath(new URL(import.meta.url)); + const filename = fileURLToPath(new URL(import.meta.url)); `, outdent` import path from "node:path"; @@ -371,16 +386,6 @@ test.snapshot({ const __filename = import.meta.filename; const __dirname = path.dirname(__filename); `, - { - // .mjs file will be auto-fixed - code: outdent` - import path from "node:path"; - import { fileURLToPath } from "node:url"; - const __filename = fileURLToPath(import.meta.url); - const __dirname = path.dirname(__filename); - `, - filename: 'foo.mjs', - }, outdent` // path is not imported import { fileURLToPath } from "node:url"; diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 33dfe580df..25d27bb927 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1915,18 +1915,14 @@ Generated by [AVA](https://avajs.dev). 1 | import "lodash"␊ ` -## invalid(1): import path from "path"; import { fileURLToPath } from "url"; const dirname1 = path.dirname(fileURLToPath(import.meta.url)); const dirname2 = path.dirname(import.meta.filename); const dirname3 = path.dirname(new URL(import.meta.url).pathname); const dirname4 = fileURLToPath(new URL(".", import.meta.url)); const dirname5 = fileURLToPath(new URL("./", import.meta.url)); +## invalid(1): import path from "path"; import { fileURLToPath } from "url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); > Input `␊ 1 | import path from "path";␊ 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ + 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ ` > Output @@ -1934,115 +1930,163 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | import path from "path";␊ 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = import.meta.dirname;␊ - 4 | const dirname2 = import.meta.dirname;␊ - 5 | const dirname3 = import.meta.dirname;␊ - 6 | const dirname4 = import.meta.dirname;␊ - 7 | const dirname5 = import.meta.dirname;␊ + 3 | const dirname = import.meta.dirname;␊ ` -> Error 1/5 +> Error 1/1 `␊ 1 | import path from "path";␊ 2 | import { fileURLToPath } from "url";␊ - > 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ + > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -> Error 2/5 +## invalid(2): import path from "path"; const dirname = path.dirname(import.meta.filename); + +> Input `␊ 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - > 4 | const dirname2 = path.dirname(import.meta.filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ + 2 | const dirname = path.dirname(import.meta.filename);␊ ` -> Error 3/5 +> Output `␊ 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - > 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ + 2 | const dirname = import.meta.dirname;␊ ` -> Error 4/5 +> Error 1/1 `␊ 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - > 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ + > 2 | const dirname = path.dirname(import.meta.filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -> Error 5/5 +## invalid(3): import path from "path"; const dirname = path.dirname(new URL(import.meta.url).pathname); + +> Input `␊ 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname1 = path.dirname(fileURLToPath(import.meta.url));␊ - 4 | const dirname2 = path.dirname(import.meta.filename);␊ - 5 | const dirname3 = path.dirname(new URL(import.meta.url).pathname);␊ - 6 | const dirname4 = fileURLToPath(new URL(".", import.meta.url));␊ - > 7 | const dirname5 = fileURLToPath(new URL("./", import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + 2 | const dirname = path.dirname(new URL(import.meta.url).pathname);␊ + ` + +> Output + + `␊ + 1 | import path from "path";␊ + 2 | const dirname = import.meta.dirname;␊ ` -## invalid(2): import { fileURLToPath } from "url"; const filename1 = fileURLToPath(import.meta.url); const filename2 = fileURLToPath(new URL(import.meta.url)); +> Error 1/1 + + `␊ + 1 | import path from "path";␊ + > 2 | const dirname = path.dirname(new URL(import.meta.url).pathname);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(4): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); > Input `␊ 1 | import { fileURLToPath } from "url";␊ - 2 | const filename1 = fileURLToPath(import.meta.url);␊ - 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ + 2 | const dirname = fileURLToPath(new URL(".", import.meta.url));␊ ` > Output `␊ 1 | import { fileURLToPath } from "url";␊ - 2 | const filename1 = import.meta.filename;␊ - 3 | const filename2 = import.meta.filename;␊ + 2 | const dirname = import.meta.dirname;␊ ` -> Error 1/2 +> Error 1/1 `␊ 1 | import { fileURLToPath } from "url";␊ - > 2 | const filename1 = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ + > 2 | const dirname = fileURLToPath(new URL(".", import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -> Error 2/2 +## invalid(5): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL("./", import.meta.url)); + +> Input `␊ 1 | import { fileURLToPath } from "url";␊ - 2 | const filename1 = fileURLToPath(import.meta.url);␊ - > 3 | const filename2 = fileURLToPath(new URL(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 2 | const dirname = fileURLToPath(new URL("./", import.meta.url));␊ ` -## invalid(3): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); +> Output + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + > 2 | const dirname = fileURLToPath(new URL("./", import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(6): import { fileURLToPath } from "url"; const filename = fileURLToPath(import.meta.url); + +> Input + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename = fileURLToPath(import.meta.url);␊ + ` + +> Output + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + > 2 | const filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(7): import { fileURLToPath } from "url"; const filename = fileURLToPath(new URL(import.meta.url)); + +> Input + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename = fileURLToPath(new URL(import.meta.url));␊ + ` + +> Output + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + > 2 | const filename = fileURLToPath(new URL(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(8): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); > Input @@ -2069,7 +2113,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(4): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); +## invalid(9): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); > Input @@ -2093,7 +2137,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(5): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); +## invalid(10): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); > Input @@ -2120,7 +2164,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(6): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); +## invalid(11): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); > Input @@ -2144,7 +2188,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(7): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); +## invalid(12): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); > Input @@ -2184,7 +2228,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(8): import path from "node:path"; const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); +## invalid(13): import path from "node:path"; const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); > Input @@ -2211,7 +2255,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(9): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); +## invalid(14): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); > Input @@ -2238,53 +2282,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(10): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); - -> Input - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const __filename = fileURLToPath(import.meta.url);␊ - 4 | const __dirname = path.dirname(__filename);␊ - ` - -> Filename - - `␊ - foo.mjs␊ - ` - -> Output - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const __filename = import.meta.filename;␊ - 4 | const __dirname = import.meta.dirname;␊ - ` - -> Error 1/2 - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - > 3 | const __filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - 4 | const __dirname = path.dirname(__filename);␊ - ` - -> Error 2/2 - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const __filename = fileURLToPath(import.meta.url);␊ - > 4 | const __dirname = path.dirname(__filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(11): // path is not imported import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); +## invalid(15): // path is not imported import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); > Input diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index feb08fd9296196840ff0371572ab29f87e13e456..5cda2362cb7d58dd1c0bb3c0c2d415736595f380 100644 GIT binary patch literal 4958 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 Reu)h-{tu^9738nX0031siMap( From d7d508c9496e88f04e206a328e93268dae926985 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Thu, 27 Mar 2025 21:30:33 +0900 Subject: [PATCH 12/38] support `process.getBuiltinModule()` --- rules/prefer-module.js | 104 +++++++++++++++++-------- test/prefer-module.js | 48 +++++++++++- test/snapshots/prefer-module.js.md | 109 ++++++++++++++++++++++++--- test/snapshots/prefer-module.js.snap | Bin 4958 -> 5175 bytes 4 files changed, 216 insertions(+), 45 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index e1c8aa7ab8..984b0c41d2 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -3,7 +3,7 @@ import isShadowed from './utils/is-shadowed.js'; import assertToken from './utils/assert-token.js'; import {getCallExpressionTokens} from './utils/index.js'; import { - isStaticRequire, isReferenceIdentifier, isFunction, + isStaticRequire, isReferenceIdentifier, isFunction, isMemberExpression, } from './ast/index.js'; import {removeParentheses, replaceReferenceIdentifier, removeSpacesAfter} from './fix/index.js'; @@ -229,53 +229,97 @@ const isAccessPathname = node => node.type === 'MemberExpression' && getPropertyName(node) === 'pathname'; -function isCallNodeBuiltinModule(node, propertyName, nodeModuleName, sourceCode) { +function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode) { if (node.type !== 'CallExpression') { return false; } - /** @type {{callee: import('estree').Expression}} */ - const {callee} = node; - if (callee.type === 'MemberExpression') { - // Check for nodeModuleName.propertyName(...); - if (callee.object.type !== 'Identifier') { + const visited = new Set(); + + return checkExpression(node.callee, 'property'); + + /** @param {import('estree').Expression} node */ + function checkExpression(node, checkKind) { + if (node.type === 'MemberExpression') { + if (checkKind !== 'property' || getPropertyName(node) !== propertyName) { + return false; + } + + return checkExpression(node.object, 'module'); + } + + if (node.type === 'CallExpression') { + if (checkKind !== 'module') { + return false; + } + + // Check process.getBuiltinModule('x') + return ( + isMemberExpression(node.callee, {property: 'getBuiltinModule', object: 'process'}) + && isModuleLiteral(node.arguments[0]) + ); + } + + if (node.type !== 'Identifier') { return false; } - if (getPropertyName(callee) !== propertyName) { + if (visited.has(node)) { return false; } - const specifier = getImportSpecifier(callee.object); - return specifier?.type === 'ImportDefaultSpecifier' || specifier?.type === 'ImportNamespaceSpecifier'; + visited.add(node); + + const variable = findVariable(sourceCode.getScope(node), node); + if (!variable || variable.defs.length !== 1) { + return; + } + + return checkDefinition(variable.defs[0], checkKind); } - if (callee.type === 'Identifier') { - // Check for propertyName(...); - const specifier = getImportSpecifier(callee); + /** @param {import('eslint').Scope.Definition} define */ + function checkDefinition(define, checkKind) { + if (define.type === 'ImportBinding') { + if (!isModuleLiteral(define.parent.source)) { + return false; + } - return specifier?.type === 'ImportSpecifier' && specifier.imported.name === propertyName; + const specifier = define.node; + return checkKind === 'module' + ? (specifier?.type === 'ImportDefaultSpecifier' || specifier?.type === 'ImportNamespaceSpecifier') + : (specifier?.type === 'ImportSpecifier' && specifier.imported.name === propertyName); + } + + return define.type === 'Variable' && checkPattern(define.name, checkKind); } - return false; + /** @param {import('estree').Identifier | import('estree').ObjectPattern} node */ + function checkPattern(node, checkKind) { + /** @type {{parent?: import('estree').Node}} */ + const {parent} = node; + if (parent.type === 'VariableDeclarator') { + if (!parent.init || parent.id !== node) { + return false; + } - function getImportSpecifier(node) { - const scope = sourceCode.getScope(node); - const variable = findVariable(scope, node); - if (!variable || variable.defs.length !== 1) { - return; + return checkExpression(parent.init, checkKind); } - /** @type {import('eslint').Scope.Definition} */ - const define = variable.defs[0]; - if ( - define.type !== 'ImportBinding' - || (define.parent.source.value !== nodeModuleName && define.parent.source.value !== 'node:' + nodeModuleName) - ) { - return; + if (parent.type === 'Property') { + if (checkKind !== 'property' || parent.value !== node || getPropertyName(parent) !== propertyName) { + return false; + } + + // Check for ObjectPattern + return checkPattern(parent.parent, 'module'); } - return define.node; + return false; + } + + function isModuleLiteral(node) { + return node?.type === 'Literal' && nodeModuleNames.includes(node.value); } } @@ -283,14 +327,14 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleName, sourceCode) @returns {node is import('estree').SimpleCallExpression} */ function isCallFileURLToPath(node, sourceCode) { - return isCallNodeBuiltinModule(node, 'fileURLToPath', 'url', sourceCode); + return isCallNodeBuiltinModule(node, 'fileURLToPath', ['url', 'node:url'], sourceCode); } /** @returns {node is import('estree').SimpleCallExpression} */ function isCallPathDirname(node, sourceCode) { - return isCallNodeBuiltinModule(node, 'dirname', 'path', sourceCode); + return isCallNodeBuiltinModule(node, 'dirname', ['path', 'node:path'], sourceCode); } function fixDefaultExport(node, sourceCode) { diff --git a/test/prefer-module.js b/test/prefer-module.js index d4ef0f7781..493218a839 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -321,6 +321,37 @@ test.snapshot({ 'const dirname = new URL(".", import.meta.url).pathname;', 'const filename = new URL(import.meta.url).pathname;', 'const filename = fileURLToPath(import.meta.url);', // `fileURLToPath` is not imported + 'const dirname = path.dirname(import.meta.filename);', // `path` is not imported + outdent` + // path is not initialized + let path; + const dirname = path.dirname(import.meta.filename); + `, + outdent` + // path is unknown property + const { path } = process.getBuiltinModule("node:path"); + const dirname = path.dirname(import.meta.filename); + `, + outdent` + const { dirname } = process.getBuiltinModule("node:path"); + // dirname()() is unknown + const x = dirname(x)(import.meta.filename); + `, + outdent` + // path is unknown + const path = new X(); + const dirname = path.dirname(import.meta.filename); + `, + outdent` + // path is unknown + const path = path; + const dirname = path.dirname(import.meta.filename); + `, + outdent` + // path is unknown + const [path] = process.getBuiltinModule("node:path"); + const dirname = path.dirname(import.meta.filename); + `, ], invalid: [ outdent` @@ -387,9 +418,20 @@ test.snapshot({ const __dirname = path.dirname(__filename); `, outdent` - // path is not imported - import { fileURLToPath } from "node:url"; - const dirname = path.dirname(fileURLToPath(import.meta.url)); + const path = process.getBuiltinModule("node:path"); + const { fileURLToPath } = process.getBuiltinModule("node:url"); + const filename = fileURLToPath(import.meta.url); + const dirname = path.dirname(filename); + `, + outdent` + const path = process.getBuiltinModule("path"); + const { fileURLToPath } = process.getBuiltinModule("url"); + const filename = fileURLToPath(import.meta.url); + const dirname = path.dirname(filename); + `, + outdent` + const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); + const dirname = process.getBuiltinModule("node:path").dirname(filename); `, ], }); diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 25d27bb927..b5d4886d18 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -2282,29 +2282,114 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(15): // path is not imported import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); +## invalid(15): const path = process.getBuiltinModule("node:path"); const { fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); > Input `␊ - 1 | // path is not imported␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + 1 | const path = process.getBuiltinModule("node:path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + 4 | const dirname = path.dirname(filename);␊ ` > Output `␊ - 1 | // path is not imported␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const dirname = path.dirname(import.meta.filename);␊ + 1 | const path = process.getBuiltinModule("node:path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ + 3 | const filename = import.meta.filename;␊ + 4 | const dirname = import.meta.dirname;␊ ` -> Error 1/1 +> Error 1/2 `␊ - 1 | // path is not imported␊ - 2 | import { fileURLToPath } from "node:url";␊ - > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 1 | const path = process.getBuiltinModule("node:path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ + > 3 | const filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 4 | const dirname = path.dirname(filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | const path = process.getBuiltinModule("node:path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + > 4 | const dirname = path.dirname(filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(16): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); + +> Input + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + 4 | const dirname = path.dirname(filename);␊ + ` + +> Output + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + 3 | const filename = import.meta.filename;␊ + 4 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/2 + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + > 3 | const filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 4 | const dirname = path.dirname(filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + > 4 | const dirname = path.dirname(filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(17): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); + +> Input + + `␊ + 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ + 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ + ` + +> Output + + `␊ + 1 | const filename = import.meta.filename;␊ + 2 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/2 + + `␊ + > 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ + > 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 5cda2362cb7d58dd1c0bb3c0c2d415736595f380..63edad2333c8d6284be530479156f0227687331a 100644 GIT binary patch literal 5175 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 literal 4958 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 Date: Sat, 29 Mar 2025 17:28:46 +0900 Subject: [PATCH 13/38] use ast utils and some refactor --- rules/prefer-module.js | 51 +++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 984b0c41d2..d027bbf8eb 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -3,7 +3,7 @@ import isShadowed from './utils/is-shadowed.js'; import assertToken from './utils/assert-token.js'; import {getCallExpressionTokens} from './utils/index.js'; import { - isStaticRequire, isReferenceIdentifier, isFunction, isMemberExpression, + isStaticRequire, isReferenceIdentifier, isFunction, isMemberExpression, isNewExpression, isMethodCall, } from './ast/index.js'; import {removeParentheses, replaceReferenceIdentifier, removeSpacesAfter} from './fix/index.js'; @@ -218,17 +218,6 @@ const isImportMeta = node => && node.meta.name === 'import' && node.property.name === 'meta'; -/** @returns {node is import('estree').NewExpression} */ -const isNewURL = node => - node.type === 'NewExpression' - && node.callee.type === 'Identifier' - && node.callee.name === 'URL'; - -/** @returns {node is import('estree').MemberExpression} */ -const isAccessPathname = node => - node.type === 'MemberExpression' - && getPropertyName(node) === 'pathname'; - function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode) { if (node.type !== 'CallExpression') { return false; @@ -255,7 +244,13 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode // Check process.getBuiltinModule('x') return ( - isMemberExpression(node.callee, {property: 'getBuiltinModule', object: 'process'}) + isMethodCall(node, { + object: 'process', + method: 'getBuiltinModule', + argumentsLength: 1, + optionalMember: false, + optionalCall: false, + }) && isModuleLiteral(node.arguments[0]) ); } @@ -299,7 +294,12 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode /** @type {{parent?: import('estree').Node}} */ const {parent} = node; if (parent.type === 'VariableDeclarator') { - if (!parent.init || parent.id !== node) { + if ( + !parent.init + || parent.id !== node + || parent.parent.type !== 'VariableDeclaration' + || parent.parent.kind !== 'const' + ) { return false; } @@ -528,7 +528,7 @@ function create(context) { return; } - if (isNewURL(targetNode, sourceCode)) { + if (isNewExpression(targetNode, {name: 'URL', minimumArguments: 1})) { const urlParent = targetNode.parent; if (targetNode.arguments[0] === parent) { @@ -540,7 +540,7 @@ function create(context) { yield * iterateProblemsFromFilename(urlParent, { reportFilenameNode: true, }); - } else if (isAccessPathname(urlParent)) { + } else if (isMemberExpression(urlParent, {property: 'pathname'})) { // Process for `new URL(import.meta.url).pathname` yield * iterateProblemsFromFilename(urlParent); } @@ -555,7 +555,7 @@ function create(context) { && urlParent.arguments[0] === targetNode ) { // Report `fileURLToPath(new URL(".", import.meta.url))` - yield buildProblem(urlParent, 'dirname'); + yield getProblem(urlParent, 'dirname'); } } @@ -580,15 +580,21 @@ function create(context) { && parent.arguments[0] === node ) { // Report `path.dirname(filename)` - yield buildProblem(parent, 'dirname'); + yield getProblem(parent, 'dirname'); return; } if (reportFilenameNode) { - yield buildProblem(node, 'filename'); + yield getProblem(node, 'filename'); } - if (parent.type !== 'VariableDeclarator' || parent.init !== node || parent.id.type !== 'Identifier') { + if ( + parent.type !== 'VariableDeclarator' + || parent.init !== node + || parent.id.type !== 'Identifier' + || parent.parent.type !== 'VariableDeclaration' + || parent.parent.kind !== 'const' + ) { return; } @@ -610,7 +616,7 @@ function create(context) { && parent.arguments[0] === reference.identifier ) { // Report `path.dirname(identifier)` - yield buildProblem(parent, 'dirname'); + yield getProblem(parent, 'dirname'); } } } @@ -619,11 +625,10 @@ function create(context) { @param { import('estree').Node} node @param {'dirname' | 'filename'} name */ - function buildProblem(node, name) { + function getProblem(node, name) { return { node, messageId: name === 'dirname' ? ERROR_CALC_DIRNAME : ERROR_CALC_FILENAME, - data: {name}, fix: fixer => fixer.replaceText(node, `import.meta.${name}`), }; From c600810d9de26147a5f6241776f1b811c47743dc Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 20:24:44 +0800 Subject: [PATCH 14/38] Fix style --- rules/prefer-module.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index d027bbf8eb..8fcd8f55a9 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -567,10 +567,10 @@ function create(context) { } /** - Iterates over reports where a given filename expression node - would be used to convert it to a dirname. - @param { import('estree').Expression} node - */ + Iterates over reports where a given filename expression node + would be used to convert it to a dirname. + @param { import('estree').Expression} node + */ function * iterateProblemsFromFilename(node, {reportFilenameNode = false} = {}) { /** @type {{parent: import('estree').Node}} */ const {parent} = node; @@ -622,9 +622,9 @@ function create(context) { } /** - @param { import('estree').Node} node - @param {'dirname' | 'filename'} name - */ + @param { import('estree').Node} node + @param {'dirname' | 'filename'} name + */ function getProblem(node, name) { return { node, From bfdbd2da76d8cafc3d7a6314a473045a077cdeaa Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 20:32:51 +0800 Subject: [PATCH 15/38] Ignore computed and optional --- rules/prefer-module.js | 7 +++++-- test/prefer-module.js | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 8fcd8f55a9..f4b9e4bddb 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -219,7 +219,7 @@ const isImportMeta = node => && node.property.name === 'meta'; function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode) { - if (node.type !== 'CallExpression') { + if (!(node.type === 'CallExpression' && !node.optional)) { return false; } @@ -230,7 +230,10 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode /** @param {import('estree').Expression} node */ function checkExpression(node, checkKind) { if (node.type === 'MemberExpression') { - if (checkKind !== 'property' || getPropertyName(node) !== propertyName) { + if (!( + checkKind === 'property' + && isMemberExpression(node, {property: propertyName, computed: false, optional: false}) + )) { return false; } diff --git a/test/prefer-module.js b/test/prefer-module.js index 493218a839..38250b05e3 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -352,6 +352,22 @@ test.snapshot({ const [path] = process.getBuiltinModule("node:path"); const dirname = path.dirname(import.meta.filename); `, + outdent` + import path from "path"; + const dirname = path?.dirname(import.meta.filename); + `, + outdent` + import path from "path"; + const dirname = path[dirname](import.meta.filename); + `, + outdent` + import path from "path"; + const dirname = path["dirname"](import.meta.filename); + `, + outdent` + import path from "path"; + const dirname = path.dirname?.(import.meta.filename); + `, ], invalid: [ outdent` From c4dba435941de023c5c330ce799f6c31f5206d29 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 20:39:41 +0800 Subject: [PATCH 16/38] Strict `Property` check --- rules/prefer-module.js | 8 ++- test/prefer-module.js | 12 ++++ test/snapshots/prefer-module.js.md | 96 +++++++++++++++++++++++++++ test/snapshots/prefer-module.js.snap | Bin 5175 -> 5274 bytes 4 files changed, 115 insertions(+), 1 deletion(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index f4b9e4bddb..c3ccded548 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -310,7 +310,13 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode } if (parent.type === 'Property') { - if (checkKind !== 'property' || parent.value !== node || getPropertyName(parent) !== propertyName) { + if (!( + checkKind === 'property' + && parent.value === node + && !parent.computed + && parent.key.type === 'Identifier' + && parent.key.name === propertyName + )) { return false; } diff --git a/test/prefer-module.js b/test/prefer-module.js index 38250b05e3..becb34c69d 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -368,6 +368,14 @@ test.snapshot({ import path from "path"; const dirname = path.dirname?.(import.meta.filename); `, + outdent` + const { [fileURLToPath]: fileURLToPath } = process.getBuiltinModule("node:url"); + const filename = fileURLToPath(import.meta.url); + `, + outdent` + const { ["fileURLToPath"]: fileURLToPath } = process.getBuiltinModule("node:url"); + const filename = fileURLToPath(import.meta.url); + `, ], invalid: [ outdent` @@ -439,6 +447,10 @@ test.snapshot({ const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); `, + outdent` + const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); + const filename = renamed(import.meta.url); + `, outdent` const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index b5d4886d18..4acb437d5d 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -2322,6 +2322,102 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` +## invalid(16): const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); + +> Input + + `␊ + 1 | const { fileURLToPath: renamed } = process.getBuiltinModule("node:url");␊ + 2 | const filename = renamed(import.meta.url);␊ + ` + +> Output + + `␊ + 1 | const { fileURLToPath: renamed } = process.getBuiltinModule("node:url");␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | const { fileURLToPath: renamed } = process.getBuiltinModule("node:url");␊ + > 2 | const filename = renamed(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(17): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); + +> Input + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + 4 | const dirname = path.dirname(filename);␊ + ` + +> Output + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + 3 | const filename = import.meta.filename;␊ + 4 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/2 + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + > 3 | const filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 4 | const dirname = path.dirname(filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + > 4 | const dirname = path.dirname(filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(18): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); + +> Input + + `␊ + 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ + 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ + ` + +> Output + + `␊ + 1 | const filename = import.meta.filename;␊ + 2 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/2 + + `␊ + > 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ + > 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + ## invalid(16): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); > Input diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 63edad2333c8d6284be530479156f0227687331a..eb97e42977fc5b6e32eb698888188cca43a83d78 100644 GIT binary patch literal 5274 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 literal 5175 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 From d21168a3ebfe85f92e32c930f639a686eb5ba81f Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 20:40:23 +0800 Subject: [PATCH 17/38] Code style --- rules/prefer-module.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index c3ccded548..c1270241c2 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -333,15 +333,15 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode } /** - @returns {node is import('estree').SimpleCallExpression} - */ +@returns {node is import('estree').SimpleCallExpression} +*/ function isCallFileURLToPath(node, sourceCode) { return isCallNodeBuiltinModule(node, 'fileURLToPath', ['url', 'node:url'], sourceCode); } /** - @returns {node is import('estree').SimpleCallExpression} - */ +@returns {node is import('estree').SimpleCallExpression} +*/ function isCallPathDirname(node, sourceCode) { return isCallNodeBuiltinModule(node, 'dirname', ['path', 'node:path'], sourceCode); } From f611d8a46dbed56d47e2dca4a36ecf64069f70fa Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 20:45:48 +0800 Subject: [PATCH 18/38] Test other `MetaProperty` --- test/prefer-module.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/prefer-module.js b/test/prefer-module.js index becb34c69d..9620504b38 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -376,6 +376,14 @@ test.snapshot({ const { ["fileURLToPath"]: fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); `, + outdent` + import {fileURLToPath} from "node:url"; + class Foo { + constructor() { + const filename = fileURLToPath(new.target.url) + } + } + `, ], invalid: [ outdent` From 5df79f19d606b6fa576bee0a123cf6c7d169a6b2 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 20:53:19 +0800 Subject: [PATCH 19/38] Stricter property access --- rules/prefer-module.js | 28 +++++++++++++++------------- test/prefer-module.js | 8 ++++++++ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index c1270241c2..1a71299838 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -1,4 +1,4 @@ -import {findVariable, getPropertyName} from '@eslint-community/eslint-utils'; +import {findVariable} from '@eslint-community/eslint-utils'; import isShadowed from './utils/is-shadowed.js'; import assertToken from './utils/assert-token.js'; import {getCallExpressionTokens} from './utils/index.js'; @@ -512,23 +512,25 @@ function create(context) { return; } - /** @type {{parent?: import('estree').Node}} */ - const {parent} = node; - if ( - parent.type !== 'MemberExpression' - || parent.object !== node - ) { + /** @type {import('estree').Node} */ + const memberExpression = node.parent; + if (!isMemberExpression(memberExpression, { + properties: ['url', 'filename'], + computed: false, + optional: false, + })) { return; } /** @type {import('estree').Node} */ - const targetNode = parent.parent; + const targetNode = memberExpression.parent; - const propertyName = getPropertyName(parent); + const propertyName = memberExpression.property.name; if (propertyName === 'url') { + // `fileURLToPath(import.meta.url)` if ( isCallFileURLToPath(targetNode, sourceCode) - && targetNode.arguments[0] === parent + && targetNode.arguments[0] === memberExpression ) { // Report `fileURLToPath(import.meta.url)` yield * iterateProblemsFromFilename(targetNode, { @@ -540,7 +542,7 @@ function create(context) { if (isNewExpression(targetNode, {name: 'URL', minimumArguments: 1})) { const urlParent = targetNode.parent; - if (targetNode.arguments[0] === parent) { + if (targetNode.arguments[0] === memberExpression) { if ( isCallFileURLToPath(urlParent, sourceCode) && urlParent.arguments[0] === targetNode @@ -559,7 +561,7 @@ function create(context) { if ( isParentLiteral(targetNode.arguments[0]) - && targetNode.arguments[1] === parent + && targetNode.arguments[1] === memberExpression && isCallFileURLToPath(urlParent, sourceCode) && urlParent.arguments[0] === targetNode ) { @@ -572,7 +574,7 @@ function create(context) { } if (propertyName === 'filename') { - yield * iterateProblemsFromFilename(parent); + yield * iterateProblemsFromFilename(memberExpression); } /** diff --git a/test/prefer-module.js b/test/prefer-module.js index 9620504b38..c8a4b573b1 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -384,6 +384,14 @@ test.snapshot({ } } `, + outdent` + import {fileURLToPath} from "node:url"; + const filename = fileURLToPath(import.meta?.url) + `, + outdent` + import {fileURLToPath} from "node:url"; + const filename = fileURLToPath(import.meta['url']) + `, ], invalid: [ outdent` From 585235058cafbb7eeeeb7e82a5e4f791712be047 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 20:54:13 +0800 Subject: [PATCH 20/38] Minor tweak --- rules/prefer-module.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 1a71299838..92f10ffa3e 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -522,11 +522,11 @@ function create(context) { return; } - /** @type {import('estree').Node} */ - const targetNode = memberExpression.parent; - const propertyName = memberExpression.property.name; if (propertyName === 'url') { + /** @type {import('estree').Node} */ + const targetNode = memberExpression.parent; + // `fileURLToPath(import.meta.url)` if ( isCallFileURLToPath(targetNode, sourceCode) From a7293cda92ea08667c91d205769043e90e238a90 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 20:59:09 +0800 Subject: [PATCH 21/38] `CALC` -> `CALCULATE` --- rules/prefer-module.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 92f10ffa3e..9ff0588ea4 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -10,8 +10,8 @@ import {removeParentheses, replaceReferenceIdentifier, removeSpacesAfter} from ' const ERROR_USE_STRICT_DIRECTIVE = 'error/use-strict-directive'; const ERROR_GLOBAL_RETURN = 'error/global-return'; const ERROR_IDENTIFIER = 'error/identifier'; -const ERROR_CALC_DIRNAME = 'error/calc-dirname'; -const ERROR_CALC_FILENAME = 'error/calc-filename'; +const ERROR_CALCULATE_DIRNAME = 'error/calculate-dirname'; +const ERROR_CALCULATE_FILENAME = 'error/calculate-filename'; const SUGGESTION_USE_STRICT_DIRECTIVE = 'suggestion/use-strict-directive'; const SUGGESTION_IMPORT_META_DIRNAME = 'suggestion/import-meta-dirname'; const SUGGESTION_IMPORT_META_URL_TO_DIRNAME = 'suggestion/import-meta-url-to-dirname'; @@ -23,8 +23,8 @@ const messages = { [ERROR_USE_STRICT_DIRECTIVE]: 'Do not use "use strict" directive.', [ERROR_GLOBAL_RETURN]: '"return" should be used inside a function.', [ERROR_IDENTIFIER]: 'Do not use "{{name}}".', - [ERROR_CALC_DIRNAME]: 'Do not construct dirname.', - [ERROR_CALC_FILENAME]: 'Do not construct filename using `fileURLToPath()`.', + [ERROR_CALCULATE_DIRNAME]: 'Do not construct dirname.', + [ERROR_CALCULATE_FILENAME]: 'Do not construct filename using `fileURLToPath()`.', [SUGGESTION_USE_STRICT_DIRECTIVE]: 'Remove "use strict" directive.', [SUGGESTION_IMPORT_META_DIRNAME]: 'Replace `__dirname` with `import.meta.dirname`.', [SUGGESTION_IMPORT_META_URL_TO_DIRNAME]: 'Replace `__dirname` with `…(import.meta.url)`.', @@ -639,9 +639,8 @@ function create(context) { function getProblem(node, name) { return { node, - messageId: name === 'dirname' ? ERROR_CALC_DIRNAME : ERROR_CALC_FILENAME, - fix: fixer => - fixer.replaceText(node, `import.meta.${name}`), + messageId: name === 'dirname' ? ERROR_CALCULATE_DIRNAME : ERROR_CALCULATE_FILENAME, + fix: fixer => fixer.replaceText(node, `import.meta.${name}`), }; } }); From e9f4a57b695de80f5affd43ba2c74714ab055178 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 21:06:47 +0800 Subject: [PATCH 22/38] Stricter --- rules/prefer-module.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 9ff0588ea4..5710a2dc7c 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -527,7 +527,7 @@ function create(context) { /** @type {import('estree').Node} */ const targetNode = memberExpression.parent; - // `fileURLToPath(import.meta.url)` + // `url.fileURLToPath(import.meta.url)` if ( isCallFileURLToPath(targetNode, sourceCode) && targetNode.arguments[0] === memberExpression @@ -551,7 +551,7 @@ function create(context) { yield * iterateProblemsFromFilename(urlParent, { reportFilenameNode: true, }); - } else if (isMemberExpression(urlParent, {property: 'pathname'})) { + } else if (isMemberExpression(urlParent, {property: 'pathname', computed: false, optional: false})) { // Process for `new URL(import.meta.url).pathname` yield * iterateProblemsFromFilename(urlParent); } From 5847068e2fd24bc6d24643d35394e638a0a8a35f Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 21:09:40 +0800 Subject: [PATCH 23/38] Stricter `new URL()` check --- rules/prefer-module.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 5710a2dc7c..36b4565046 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -539,10 +539,10 @@ function create(context) { return; } - if (isNewExpression(targetNode, {name: 'URL', minimumArguments: 1})) { + if (isNewExpression(targetNode, {name: 'URL', minimumArguments: 1, maximumArguments: 2})) { const urlParent = targetNode.parent; - if (targetNode.arguments[0] === memberExpression) { + if (targetNode.arguments.length === 1 && targetNode.arguments[0] === memberExpression) { if ( isCallFileURLToPath(urlParent, sourceCode) && urlParent.arguments[0] === targetNode @@ -560,7 +560,8 @@ function create(context) { } if ( - isParentLiteral(targetNode.arguments[0]) + targetNode.arguments.length === 2 + && isParentLiteral(targetNode.arguments[0]) && targetNode.arguments[1] === memberExpression && isCallFileURLToPath(urlParent, sourceCode) && urlParent.arguments[0] === targetNode From d490f06fbc7d43d8c7f4918094c49eddba44c917 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 21:15:51 +0800 Subject: [PATCH 24/38] Stricter check `url.fileURLToPath` and `path.dirname` --- rules/prefer-module.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 36b4565046..711963d6e7 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -3,7 +3,13 @@ import isShadowed from './utils/is-shadowed.js'; import assertToken from './utils/assert-token.js'; import {getCallExpressionTokens} from './utils/index.js'; import { - isStaticRequire, isReferenceIdentifier, isFunction, isMemberExpression, isNewExpression, isMethodCall, + isStaticRequire, + isReferenceIdentifier, + isFunction, + isMemberExpression, + isCallExpression, + isNewExpression, + isMethodCall, } from './ast/index.js'; import {removeParentheses, replaceReferenceIdentifier, removeSpacesAfter} from './fix/index.js'; @@ -219,7 +225,7 @@ const isImportMeta = node => && node.property.name === 'meta'; function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode) { - if (!(node.type === 'CallExpression' && !node.optional)) { + if (!isCallExpression(node, {optional: false, argumentsLength: 1})) { return false; } @@ -532,13 +538,15 @@ function create(context) { isCallFileURLToPath(targetNode, sourceCode) && targetNode.arguments[0] === memberExpression ) { - // Report `fileURLToPath(import.meta.url)` yield * iterateProblemsFromFilename(targetNode, { reportFilenameNode: true, }); return; } + // `new URL(import.meta.url)` + // `new URL('.', import.meta.url)` + // `new URL('./', import.meta.url)` if (isNewExpression(targetNode, {name: 'URL', minimumArguments: 1, maximumArguments: 2})) { const urlParent = targetNode.parent; From 2908767f207c11d09a4f69588dda717d2d4208ac Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 21:20:27 +0800 Subject: [PATCH 25/38] Function renaming --- rules/prefer-module.js | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 711963d6e7..712057593e 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -224,7 +224,7 @@ const isImportMeta = node => && node.meta.name === 'import' && node.property.name === 'meta'; -function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode) { +function isNodeBuiltinModuleFunctionCall(node, {modules, functionName, sourceCode}) { if (!isCallExpression(node, {optional: false, argumentsLength: 1})) { return false; } @@ -238,7 +238,7 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode if (node.type === 'MemberExpression') { if (!( checkKind === 'property' - && isMemberExpression(node, {property: propertyName, computed: false, optional: false}) + && isMemberExpression(node, {property: functionName, computed: false, optional: false}) )) { return false; } @@ -292,7 +292,7 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode const specifier = define.node; return checkKind === 'module' ? (specifier?.type === 'ImportDefaultSpecifier' || specifier?.type === 'ImportNamespaceSpecifier') - : (specifier?.type === 'ImportSpecifier' && specifier.imported.name === propertyName); + : (specifier?.type === 'ImportSpecifier' && specifier.imported.name === functionName); } return define.type === 'Variable' && checkPattern(define.name, checkKind); @@ -321,7 +321,7 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode && parent.value === node && !parent.computed && parent.key.type === 'Identifier' - && parent.key.name === propertyName + && parent.key.name === functionName )) { return false; } @@ -334,22 +334,30 @@ function isCallNodeBuiltinModule(node, propertyName, nodeModuleNames, sourceCode } function isModuleLiteral(node) { - return node?.type === 'Literal' && nodeModuleNames.includes(node.value); + return node?.type === 'Literal' && modules.has(node.value); } } /** @returns {node is import('estree').SimpleCallExpression} */ -function isCallFileURLToPath(node, sourceCode) { - return isCallNodeBuiltinModule(node, 'fileURLToPath', ['url', 'node:url'], sourceCode); +function isUrlFileURLToPathCall(node, sourceCode) { + return isNodeBuiltinModuleFunctionCall(node, { + modules: new Set(['url', 'node:url']), + functionName: 'fileURLToPath', + sourceCode, + }); } /** @returns {node is import('estree').SimpleCallExpression} */ -function isCallPathDirname(node, sourceCode) { - return isCallNodeBuiltinModule(node, 'dirname', ['path', 'node:path'], sourceCode); +function isPathDirnameCall(node, sourceCode) { + return isNodeBuiltinModuleFunctionCall(node, { + modules: new Set(['path', 'node:path']), + functionName: 'dirname', + sourceCode, + }); } function fixDefaultExport(node, sourceCode) { @@ -535,7 +543,7 @@ function create(context) { // `url.fileURLToPath(import.meta.url)` if ( - isCallFileURLToPath(targetNode, sourceCode) + isUrlFileURLToPathCall(targetNode, sourceCode) && targetNode.arguments[0] === memberExpression ) { yield * iterateProblemsFromFilename(targetNode, { @@ -552,7 +560,7 @@ function create(context) { if (targetNode.arguments.length === 1 && targetNode.arguments[0] === memberExpression) { if ( - isCallFileURLToPath(urlParent, sourceCode) + isUrlFileURLToPathCall(urlParent, sourceCode) && urlParent.arguments[0] === targetNode ) { // Report `fileURLToPath(new URL(import.meta.url))` @@ -571,7 +579,7 @@ function create(context) { targetNode.arguments.length === 2 && isParentLiteral(targetNode.arguments[0]) && targetNode.arguments[1] === memberExpression - && isCallFileURLToPath(urlParent, sourceCode) + && isUrlFileURLToPathCall(urlParent, sourceCode) && urlParent.arguments[0] === targetNode ) { // Report `fileURLToPath(new URL(".", import.meta.url))` @@ -596,7 +604,7 @@ function create(context) { const {parent} = node; if ( - isCallPathDirname(parent, sourceCode) + isPathDirnameCall(parent, sourceCode) && parent.arguments[0] === node ) { // Report `path.dirname(filename)` @@ -632,7 +640,7 @@ function create(context) { /** @type {{parent: import('estree').Node}} */ const {parent} = reference.identifier; if ( - isCallPathDirname(parent, sourceCode) + isPathDirnameCall(parent, sourceCode) && parent.arguments[0] === reference.identifier ) { // Report `path.dirname(identifier)` From 0bb4574c9934ebd88877f75815958dd6e4a5e5e0 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 21:26:17 +0800 Subject: [PATCH 26/38] Rename and comments --- rules/prefer-module.js | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 712057593e..8f2df5316a 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -556,34 +556,39 @@ function create(context) { // `new URL('.', import.meta.url)` // `new URL('./', import.meta.url)` if (isNewExpression(targetNode, {name: 'URL', minimumArguments: 1, maximumArguments: 2})) { - const urlParent = targetNode.parent; + const newUrl = targetNode.parent; + // `new URL(import.meta.url)` if (targetNode.arguments.length === 1 && targetNode.arguments[0] === memberExpression) { + // `url.fileURLToPath(new URL(import.meta.url))` if ( - isUrlFileURLToPathCall(urlParent, sourceCode) - && urlParent.arguments[0] === targetNode + isUrlFileURLToPathCall(newUrl, sourceCode) + && newUrl.arguments[0] === targetNode ) { - // Report `fileURLToPath(new URL(import.meta.url))` - yield * iterateProblemsFromFilename(urlParent, { + yield * iterateProblemsFromFilename(newUrl, { reportFilenameNode: true, }); - } else if (isMemberExpression(urlParent, {property: 'pathname', computed: false, optional: false})) { - // Process for `new URL(import.meta.url).pathname` - yield * iterateProblemsFromFilename(urlParent); + return; } - return; + // `new URL(import.meta.url).pathname` + if (isMemberExpression(newUrl, {property: 'pathname', computed: false, optional: false})) { + // Process for `new URL(import.meta.url).pathname` + yield * iterateProblemsFromFilename(newUrl); + return; + } } + // `url.fileURLToPath(new URL(".", import.meta.url))` + // `url.fileURLToPath(new URL("./", import.meta.url))` if ( targetNode.arguments.length === 2 && isParentLiteral(targetNode.arguments[0]) && targetNode.arguments[1] === memberExpression - && isUrlFileURLToPathCall(urlParent, sourceCode) - && urlParent.arguments[0] === targetNode + && isUrlFileURLToPathCall(newUrl, sourceCode) + && newUrl.arguments[0] === targetNode ) { - // Report `fileURLToPath(new URL(".", import.meta.url))` - yield getProblem(urlParent, 'dirname'); + yield getProblem(newUrl, 'dirname'); } } From b6a0b5433855c0ba9f4e8f51c23f7707c60771cf Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 21:27:54 +0800 Subject: [PATCH 27/38] Revert rename, misunderstanding --- rules/prefer-module.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 8f2df5316a..3c15d3b182 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -556,25 +556,25 @@ function create(context) { // `new URL('.', import.meta.url)` // `new URL('./', import.meta.url)` if (isNewExpression(targetNode, {name: 'URL', minimumArguments: 1, maximumArguments: 2})) { - const newUrl = targetNode.parent; + const urlParent = targetNode.parent; // `new URL(import.meta.url)` if (targetNode.arguments.length === 1 && targetNode.arguments[0] === memberExpression) { // `url.fileURLToPath(new URL(import.meta.url))` if ( - isUrlFileURLToPathCall(newUrl, sourceCode) - && newUrl.arguments[0] === targetNode + isUrlFileURLToPathCall(urlParent, sourceCode) + && urlParent.arguments[0] === targetNode ) { - yield * iterateProblemsFromFilename(newUrl, { + yield * iterateProblemsFromFilename(urlParent, { reportFilenameNode: true, }); return; } // `new URL(import.meta.url).pathname` - if (isMemberExpression(newUrl, {property: 'pathname', computed: false, optional: false})) { + if (isMemberExpression(urlParent, {property: 'pathname', computed: false, optional: false})) { // Process for `new URL(import.meta.url).pathname` - yield * iterateProblemsFromFilename(newUrl); + yield * iterateProblemsFromFilename(urlParent); return; } } @@ -585,10 +585,10 @@ function create(context) { targetNode.arguments.length === 2 && isParentLiteral(targetNode.arguments[0]) && targetNode.arguments[1] === memberExpression - && isUrlFileURLToPathCall(newUrl, sourceCode) - && newUrl.arguments[0] === targetNode + && isUrlFileURLToPathCall(urlParent, sourceCode) + && urlParent.arguments[0] === targetNode ) { - yield getProblem(newUrl, 'dirname'); + yield getProblem(urlParent, 'dirname'); } } From 3ccba7301b319779474c01fb660bcf0774f42c11 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 21:31:35 +0800 Subject: [PATCH 28/38] Remove misleading `targetNode` --- rules/prefer-module.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 3c15d3b182..2e69f8cbbf 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -538,15 +538,12 @@ function create(context) { const propertyName = memberExpression.property.name; if (propertyName === 'url') { - /** @type {import('estree').Node} */ - const targetNode = memberExpression.parent; - // `url.fileURLToPath(import.meta.url)` if ( - isUrlFileURLToPathCall(targetNode, sourceCode) - && targetNode.arguments[0] === memberExpression + isUrlFileURLToPathCall(memberExpression.parent, sourceCode) + && memberExpression.parent.arguments[0] === memberExpression ) { - yield * iterateProblemsFromFilename(targetNode, { + yield * iterateProblemsFromFilename(memberExpression.parent, { reportFilenameNode: true, }); return; @@ -555,15 +552,16 @@ function create(context) { // `new URL(import.meta.url)` // `new URL('.', import.meta.url)` // `new URL('./', import.meta.url)` - if (isNewExpression(targetNode, {name: 'URL', minimumArguments: 1, maximumArguments: 2})) { - const urlParent = targetNode.parent; + if (isNewExpression(memberExpression.parent, {name: 'URL', minimumArguments: 1, maximumArguments: 2})) { + const newUrl = memberExpression.parent; + const urlParent = newUrl.parent; // `new URL(import.meta.url)` - if (targetNode.arguments.length === 1 && targetNode.arguments[0] === memberExpression) { + if (newUrl.arguments.length === 1 && newUrl.arguments[0] === memberExpression) { // `url.fileURLToPath(new URL(import.meta.url))` if ( isUrlFileURLToPathCall(urlParent, sourceCode) - && urlParent.arguments[0] === targetNode + && urlParent.arguments[0] === newUrl ) { yield * iterateProblemsFromFilename(urlParent, { reportFilenameNode: true, @@ -582,11 +580,11 @@ function create(context) { // `url.fileURLToPath(new URL(".", import.meta.url))` // `url.fileURLToPath(new URL("./", import.meta.url))` if ( - targetNode.arguments.length === 2 - && isParentLiteral(targetNode.arguments[0]) - && targetNode.arguments[1] === memberExpression + newUrl.arguments.length === 2 + && isParentLiteral(newUrl.arguments[0]) + && newUrl.arguments[1] === memberExpression && isUrlFileURLToPathCall(urlParent, sourceCode) - && urlParent.arguments[0] === targetNode + && urlParent.arguments[0] === newUrl ) { yield getProblem(urlParent, 'dirname'); } From f97138d2651370bba85b732f1410e92caba6b693 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 21:35:21 +0800 Subject: [PATCH 29/38] Comment tweak --- rules/prefer-module.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 2e69f8cbbf..08be2c2f85 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -606,11 +606,11 @@ function create(context) { /** @type {{parent: import('estree').Node}} */ const {parent} = node; + // `path.dirname(filename)` if ( isPathDirnameCall(parent, sourceCode) && parent.arguments[0] === node ) { - // Report `path.dirname(filename)` yield getProblem(parent, 'dirname'); return; } From 78169281fcea9f8025875a40fea90668e274e73d Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 29 Mar 2025 21:43:55 +0800 Subject: [PATCH 30/38] Broken case --- test/prefer-module.js | 4 + test/snapshots/prefer-module.js.md | 126 +++++++++------------------ test/snapshots/prefer-module.js.snap | Bin 5274 -> 5279 bytes 3 files changed, 43 insertions(+), 87 deletions(-) diff --git a/test/prefer-module.js b/test/prefer-module.js index c8a4b573b1..f75c56b725 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -407,6 +407,10 @@ test.snapshot({ import path from "path"; const dirname = path.dirname(new URL(import.meta.url).pathname); `, + outdent` + import path from "path"; + const not_dirname = path.dirname(new URL(import.meta.url).pathname); + `, outdent` import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 4acb437d5d..13b8c9bba6 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1990,7 +1990,31 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(4): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); +## invalid(4): import path from "path"; const not_dirname = path.dirname(new URL(import.meta.url).pathname); + +> Input + + `␊ + 1 | import path from "path";␊ + 2 | const not_dirname = path.dirname(new URL(import.meta.url).pathname);␊ + ` + +> Output + + `␊ + 1 | import path from "path";␊ + 2 | const not_dirname = import.meta.dirname;␊ + ` + +> Error 1/1 + + `␊ + 1 | import path from "path";␊ + > 2 | const not_dirname = path.dirname(new URL(import.meta.url).pathname);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(5): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); > Input @@ -2014,7 +2038,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(5): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL("./", import.meta.url)); +## invalid(6): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL("./", import.meta.url)); > Input @@ -2038,7 +2062,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(6): import { fileURLToPath } from "url"; const filename = fileURLToPath(import.meta.url); +## invalid(7): import { fileURLToPath } from "url"; const filename = fileURLToPath(import.meta.url); > Input @@ -2062,7 +2086,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(7): import { fileURLToPath } from "url"; const filename = fileURLToPath(new URL(import.meta.url)); +## invalid(8): import { fileURLToPath } from "url"; const filename = fileURLToPath(new URL(import.meta.url)); > Input @@ -2086,7 +2110,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(8): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); +## invalid(9): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); > Input @@ -2113,7 +2137,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(9): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); +## invalid(10): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); > Input @@ -2137,7 +2161,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(10): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); +## invalid(11): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); > Input @@ -2164,7 +2188,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(11): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); +## invalid(12): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); > Input @@ -2188,7 +2212,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(12): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); +## invalid(13): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); > Input @@ -2228,7 +2252,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(13): import path from "node:path"; const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); +## invalid(14): import path from "node:path"; const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); > Input @@ -2255,7 +2279,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(14): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); +## invalid(15): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); > Input @@ -2282,7 +2306,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(15): const path = process.getBuiltinModule("node:path"); const { fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); +## invalid(16): const path = process.getBuiltinModule("node:path"); const { fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); > Input @@ -2322,7 +2346,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(16): const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); +## invalid(17): const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); > Input @@ -2346,79 +2370,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(17): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); - -> Input - - `␊ - 1 | const path = process.getBuiltinModule("path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ - 3 | const filename = fileURLToPath(import.meta.url);␊ - 4 | const dirname = path.dirname(filename);␊ - ` - -> Output - - `␊ - 1 | const path = process.getBuiltinModule("path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ - 3 | const filename = import.meta.filename;␊ - 4 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/2 - - `␊ - 1 | const path = process.getBuiltinModule("path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ - > 3 | const filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - 4 | const dirname = path.dirname(filename);␊ - ` - -> Error 2/2 - - `␊ - 1 | const path = process.getBuiltinModule("path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ - 3 | const filename = fileURLToPath(import.meta.url);␊ - > 4 | const dirname = path.dirname(filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(18): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); - -> Input - - `␊ - 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ - 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ - ` - -> Output - - `␊ - 1 | const filename = import.meta.filename;␊ - 2 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/2 - - `␊ - > 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ - ` - -> Error 2/2 - - `␊ - 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ - > 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(16): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); +## invalid(18): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); > Input @@ -2458,7 +2410,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(17): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); +## invalid(19): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); > Input diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index eb97e42977fc5b6e32eb698888188cca43a83d78..eca2a05fbad4c756fee9cabb16df941ee8739e53 100644 GIT binary patch literal 5279 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 From c3bcf1c7cf2f9984604118c3638eb89b92be0995 Mon Sep 17 00:00:00 2001 From: fisker Date: Sun, 30 Mar 2025 03:46:54 +0800 Subject: [PATCH 31/38] False alarm --- rules/prefer-module.js | 2 +- test/prefer-module.js | 4 -- test/snapshots/prefer-module.js.md | 54 ++++++++------------------- test/snapshots/prefer-module.js.snap | Bin 5279 -> 5237 bytes 4 files changed, 16 insertions(+), 44 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 08be2c2f85..9721bd46f3 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -251,7 +251,7 @@ function isNodeBuiltinModuleFunctionCall(node, {modules, functionName, sourceCod return false; } - // Check process.getBuiltinModule('x') + // `process.getBuiltinModule('x')` return ( isMethodCall(node, { object: 'process', diff --git a/test/prefer-module.js b/test/prefer-module.js index f75c56b725..c8a4b573b1 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -407,10 +407,6 @@ test.snapshot({ import path from "path"; const dirname = path.dirname(new URL(import.meta.url).pathname); `, - outdent` - import path from "path"; - const not_dirname = path.dirname(new URL(import.meta.url).pathname); - `, outdent` import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 13b8c9bba6..3380062900 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1990,31 +1990,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(4): import path from "path"; const not_dirname = path.dirname(new URL(import.meta.url).pathname); - -> Input - - `␊ - 1 | import path from "path";␊ - 2 | const not_dirname = path.dirname(new URL(import.meta.url).pathname);␊ - ` - -> Output - - `␊ - 1 | import path from "path";␊ - 2 | const not_dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import path from "path";␊ - > 2 | const not_dirname = path.dirname(new URL(import.meta.url).pathname);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(5): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); +## invalid(4): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); > Input @@ -2038,7 +2014,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(6): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL("./", import.meta.url)); +## invalid(5): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL("./", import.meta.url)); > Input @@ -2062,7 +2038,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(7): import { fileURLToPath } from "url"; const filename = fileURLToPath(import.meta.url); +## invalid(6): import { fileURLToPath } from "url"; const filename = fileURLToPath(import.meta.url); > Input @@ -2086,7 +2062,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(8): import { fileURLToPath } from "url"; const filename = fileURLToPath(new URL(import.meta.url)); +## invalid(7): import { fileURLToPath } from "url"; const filename = fileURLToPath(new URL(import.meta.url)); > Input @@ -2110,7 +2086,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(9): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); +## invalid(8): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); > Input @@ -2137,7 +2113,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(10): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); +## invalid(9): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); > Input @@ -2161,7 +2137,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(11): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); +## invalid(10): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); > Input @@ -2188,7 +2164,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(12): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); +## invalid(11): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); > Input @@ -2212,7 +2188,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(13): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); +## invalid(12): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); > Input @@ -2252,7 +2228,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(14): import path from "node:path"; const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); +## invalid(13): import path from "node:path"; const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); > Input @@ -2279,7 +2255,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(15): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); +## invalid(14): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); > Input @@ -2306,7 +2282,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(16): const path = process.getBuiltinModule("node:path"); const { fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); +## invalid(15): const path = process.getBuiltinModule("node:path"); const { fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); > Input @@ -2346,7 +2322,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(17): const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); +## invalid(16): const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); > Input @@ -2370,7 +2346,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(18): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); +## invalid(17): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); > Input @@ -2410,7 +2386,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(19): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); +## invalid(18): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); > Input diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index eca2a05fbad4c756fee9cabb16df941ee8739e53..59cb787045d7df18079674d524ae1af4f24bf8c7 100644 GIT binary patch literal 5237 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 Date: Sun, 30 Mar 2025 03:48:11 +0800 Subject: [PATCH 32/38] One more test --- test/prefer-module.js | 4 ++++ test/snapshots/prefer-module.js.md | 28 +++++++++++++++++++++++++-- test/snapshots/prefer-module.js.snap | Bin 5237 -> 5284 bytes 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/test/prefer-module.js b/test/prefer-module.js index c8a4b573b1..080049cd98 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -467,6 +467,10 @@ test.snapshot({ const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); `, + outdent` + import { fileURLToPath as renamed } from "node:url"; + const filename = renamed(import.meta.url); + `, outdent` const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 3380062900..7cbb49a8d2 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -2346,7 +2346,31 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(17): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); +## invalid(17): import { fileURLToPath as renamed } from "node:url"; const filename = renamed(import.meta.url); + +> Input + + `␊ + 1 | import { fileURLToPath as renamed } from "node:url";␊ + 2 | const filename = renamed(import.meta.url);␊ + ` + +> Output + + `␊ + 1 | import { fileURLToPath as renamed } from "node:url";␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath as renamed } from "node:url";␊ + > 2 | const filename = renamed(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(18): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); > Input @@ -2386,7 +2410,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(18): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); +## invalid(19): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); > Input diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 59cb787045d7df18079674d524ae1af4f24bf8c7..9aae14dfd32026a7d5bca229027c9b220780a16c 100644 GIT binary patch literal 5284 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 Date: Sun, 30 Mar 2025 10:42:11 +0900 Subject: [PATCH 33/38] ignore URL.pathname --- rules/prefer-module.js | 27 +++------ test/prefer-module.js | 13 ++--- test/snapshots/prefer-module.js.md | 81 +++++---------------------- test/snapshots/prefer-module.js.snap | Bin 5284 -> 5199 bytes 4 files changed, 28 insertions(+), 93 deletions(-) diff --git a/rules/prefer-module.js b/rules/prefer-module.js index 9721bd46f3..d38ad32311 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -557,24 +557,15 @@ function create(context) { const urlParent = newUrl.parent; // `new URL(import.meta.url)` - if (newUrl.arguments.length === 1 && newUrl.arguments[0] === memberExpression) { - // `url.fileURLToPath(new URL(import.meta.url))` - if ( - isUrlFileURLToPathCall(urlParent, sourceCode) - && urlParent.arguments[0] === newUrl - ) { - yield * iterateProblemsFromFilename(urlParent, { - reportFilenameNode: true, - }); - return; - } - - // `new URL(import.meta.url).pathname` - if (isMemberExpression(urlParent, {property: 'pathname', computed: false, optional: false})) { - // Process for `new URL(import.meta.url).pathname` - yield * iterateProblemsFromFilename(urlParent); - return; - } + if (newUrl.arguments.length === 1 && newUrl.arguments[0] === memberExpression // `url.fileURLToPath(new URL(import.meta.url))` + + && isUrlFileURLToPathCall(urlParent, sourceCode) + && urlParent.arguments[0] === newUrl + ) { + yield * iterateProblemsFromFilename(urlParent, { + reportFilenameNode: true, + }); + return; } // `url.fileURLToPath(new URL(".", import.meta.url))` diff --git a/test/prefer-module.js b/test/prefer-module.js index 080049cd98..6420076126 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -322,6 +322,10 @@ test.snapshot({ 'const filename = new URL(import.meta.url).pathname;', 'const filename = fileURLToPath(import.meta.url);', // `fileURLToPath` is not imported 'const dirname = path.dirname(import.meta.filename);', // `path` is not imported + outdent` + import path from "path"; + const not_dirname = path.dirname(new URL(import.meta.url).pathname); // It is the same as dirname on macOS but returns different results on Windows. + `, outdent` // path is not initialized let path; @@ -403,10 +407,6 @@ test.snapshot({ import path from "path"; const dirname = path.dirname(import.meta.filename); `, - outdent` - import path from "path"; - const dirname = path.dirname(new URL(import.meta.url).pathname); - `, outdent` import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); @@ -447,11 +447,6 @@ test.snapshot({ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); `, - outdent` - import path from "node:path"; - const __filename = new URL(import.meta.url).pathname; - const __dirname = path.dirname(__filename); - `, outdent` import path from "node:path"; const __filename = import.meta.filename; diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 7cbb49a8d2..1758729ffc 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1966,31 +1966,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(3): import path from "path"; const dirname = path.dirname(new URL(import.meta.url).pathname); - -> Input - - `␊ - 1 | import path from "path";␊ - 2 | const dirname = path.dirname(new URL(import.meta.url).pathname);␊ - ` - -> Output - - `␊ - 1 | import path from "path";␊ - 2 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import path from "path";␊ - > 2 | const dirname = path.dirname(new URL(import.meta.url).pathname);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(4): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); +## invalid(3): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); > Input @@ -2014,7 +1990,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(5): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL("./", import.meta.url)); +## invalid(4): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL("./", import.meta.url)); > Input @@ -2038,7 +2014,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(6): import { fileURLToPath } from "url"; const filename = fileURLToPath(import.meta.url); +## invalid(5): import { fileURLToPath } from "url"; const filename = fileURLToPath(import.meta.url); > Input @@ -2062,7 +2038,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(7): import { fileURLToPath } from "url"; const filename = fileURLToPath(new URL(import.meta.url)); +## invalid(6): import { fileURLToPath } from "url"; const filename = fileURLToPath(new URL(import.meta.url)); > Input @@ -2086,7 +2062,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(8): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); +## invalid(7): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); > Input @@ -2113,7 +2089,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(9): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); +## invalid(8): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); > Input @@ -2137,7 +2113,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(10): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); +## invalid(9): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); > Input @@ -2164,7 +2140,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(11): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); +## invalid(10): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); > Input @@ -2188,7 +2164,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(12): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); +## invalid(11): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); > Input @@ -2228,34 +2204,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(13): import path from "node:path"; const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); - -> Input - - `␊ - 1 | import path from "node:path";␊ - 2 | const __filename = new URL(import.meta.url).pathname;␊ - 3 | const __dirname = path.dirname(__filename);␊ - ` - -> Output - - `␊ - 1 | import path from "node:path";␊ - 2 | const __filename = new URL(import.meta.url).pathname;␊ - 3 | const __dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import path from "node:path";␊ - 2 | const __filename = new URL(import.meta.url).pathname;␊ - > 3 | const __dirname = path.dirname(__filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(14): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); +## invalid(12): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); > Input @@ -2282,7 +2231,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(15): const path = process.getBuiltinModule("node:path"); const { fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); +## invalid(13): const path = process.getBuiltinModule("node:path"); const { fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); > Input @@ -2322,7 +2271,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(16): const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); +## invalid(14): const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); > Input @@ -2346,7 +2295,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(17): import { fileURLToPath as renamed } from "node:url"; const filename = renamed(import.meta.url); +## invalid(15): import { fileURLToPath as renamed } from "node:url"; const filename = renamed(import.meta.url); > Input @@ -2370,7 +2319,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ ` -## invalid(18): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); +## invalid(16): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); > Input @@ -2410,7 +2359,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ ` -## invalid(19): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); +## invalid(17): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); > Input diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 9aae14dfd32026a7d5bca229027c9b220780a16c..1c74d78c18ad657f73bb68bdc86561b4278807df 100644 GIT binary patch literal 5199 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 Date: Mon, 31 Mar 2025 17:27:51 +0900 Subject: [PATCH 34/38] add `prefer-import-meta-properties`, and revert `prefer-module` --- docs/rules/prefer-import-meta-properties.md | 43 ++ readme.md | 1 + rules/index.js | 2 + rules/prefer-import-meta-properties.js | 318 ++++++++++++ rules/prefer-module.js | 299 +---------- scripts/create-rule.js | 3 +- .../no-restricted-property-access.js | 3 +- scripts/internal-rules/no-test-only.js | 3 +- .../prefer-fixer-remove-range.js | 3 +- .../prefer-negative-boolean-attribute.js | 3 +- test/integration/projects.js | 3 +- test/prefer-import-meta-properties.js | 174 +++++++ test/prefer-module.js | 171 ------- .../prefer-import-meta-properties.js.md | 481 ++++++++++++++++++ .../prefer-import-meta-properties.js.snap | Bin 0 -> 1417 bytes test/snapshots/prefer-module.js.md | 476 ----------------- test/snapshots/prefer-module.js.snap | Bin 5199 -> 4060 bytes test/unit/get-documentation-url.js | 1 - 18 files changed, 1032 insertions(+), 952 deletions(-) create mode 100644 docs/rules/prefer-import-meta-properties.md create mode 100644 rules/prefer-import-meta-properties.js create mode 100644 test/prefer-import-meta-properties.js create mode 100644 test/snapshots/prefer-import-meta-properties.js.md create mode 100644 test/snapshots/prefer-import-meta-properties.js.snap diff --git a/docs/rules/prefer-import-meta-properties.md b/docs/rules/prefer-import-meta-properties.md new file mode 100644 index 0000000000..632ef96cca --- /dev/null +++ b/docs/rules/prefer-import-meta-properties.md @@ -0,0 +1,43 @@ +# Prefer `import.meta.{dirname,filename}` over legacy techniques for getting file paths + +🚫 This rule is _disabled_ in the ✅ `recommended` [config](https://github.com/sindresorhus/eslint-plugin-unicorn#recommended-config). + +🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix). + + + + +Starting with Node.js 20.11, [`import.meta.dirname`](https://nodejs.org/api/esm.html#importmetadirname) and [`import.meta.filename`](https://nodejs.org/api/esm.html#importmetafilename) have been introduced in ES modules. + +> `import.meta.filename` is the same as the `url.fileURLToPath()` of the `import.meta.url`.\ +> `import.meta.dirname` is the same as the `path.dirname()` of the `import.meta.filename`. + +This rule replaces those codes written in the legacy way with `import.meta.{dirname,filename}`. + + + +## Examples + +```js +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +// ❌ +const filename = fileURLToPath(import.meta.url); + +// ✅ +const filename = import.meta.filename; +``` + +```js +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +// ❌ +const dirname = path.dirname(fileURLToPath(import.meta.url)); +const dirname = path.dirname(import.meta.filename); +const dirname = fileURLToPath(new URL(".", import.meta.url)); + +// ✅ +const dirname = import.meta.dirname; +``` diff --git a/readme.md b/readme.md index 197ae1eaa7..4863efcc22 100644 --- a/readme.md +++ b/readme.md @@ -141,6 +141,7 @@ export default [ | [prefer-event-target](docs/rules/prefer-event-target.md) | Prefer `EventTarget` over `EventEmitter`. | ✅ | | | | [prefer-export-from](docs/rules/prefer-export-from.md) | Prefer `export…from` when re-exporting. | ✅ | 🔧 | 💡 | | [prefer-global-this](docs/rules/prefer-global-this.md) | Prefer `globalThis` over `window`, `self`, and `global`. | ✅ | 🔧 | | +| [prefer-import-meta-properties](docs/rules/prefer-import-meta-properties.md) | Prefer `import.meta.{dirname,filename}` over legacy techniques for getting file paths. | | 🔧 | | | [prefer-includes](docs/rules/prefer-includes.md) | Prefer `.includes()` over `.indexOf()`, `.lastIndexOf()`, and `Array#some()` when checking for existence or non-existence. | ✅ | 🔧 | 💡 | | [prefer-json-parse-buffer](docs/rules/prefer-json-parse-buffer.md) | Prefer reading a JSON file as a buffer. | | 🔧 | | | [prefer-keyboard-event-key](docs/rules/prefer-keyboard-event-key.md) | Prefer `KeyboardEvent#key` over `KeyboardEvent#keyCode`. | ✅ | 🔧 | | diff --git a/rules/index.js b/rules/index.js index 5624349240..df308d4abf 100644 --- a/rules/index.js +++ b/rules/index.js @@ -86,6 +86,7 @@ import preferDomNodeTextContent from './prefer-dom-node-text-content.js'; import preferEventTarget from './prefer-event-target.js'; import preferExportFrom from './prefer-export-from.js'; import preferGlobalThis from './prefer-global-this.js'; +import preferImportMetaProperties from './prefer-import-meta-properties.js'; import preferIncludes from './prefer-includes.js'; import preferJsonParseBuffer from './prefer-json-parse-buffer.js'; import preferKeyboardEventKey from './prefer-keyboard-event-key.js'; @@ -215,6 +216,7 @@ const rules = { 'prefer-event-target': createRule(preferEventTarget, 'prefer-event-target'), 'prefer-export-from': createRule(preferExportFrom, 'prefer-export-from'), 'prefer-global-this': createRule(preferGlobalThis, 'prefer-global-this'), + 'prefer-import-meta-properties': createRule(preferImportMetaProperties, 'prefer-import-meta-properties'), 'prefer-includes': createRule(preferIncludes, 'prefer-includes'), 'prefer-json-parse-buffer': createRule(preferJsonParseBuffer, 'prefer-json-parse-buffer'), 'prefer-keyboard-event-key': createRule(preferKeyboardEventKey, 'prefer-keyboard-event-key'), diff --git a/rules/prefer-import-meta-properties.js b/rules/prefer-import-meta-properties.js new file mode 100644 index 0000000000..7d4f91e67e --- /dev/null +++ b/rules/prefer-import-meta-properties.js @@ -0,0 +1,318 @@ +import {findVariable} from '@eslint-community/eslint-utils'; +import { + isMemberExpression, + isCallExpression, + isNewExpression, + isMethodCall, +} from './ast/index.js'; + +const ERROR_CALCULATE_DIRNAME = 'error/calculate-dirname'; +const ERROR_CALCULATE_FILENAME = 'error/calculate-filename'; +const messages = { + [ERROR_CALCULATE_DIRNAME]: 'Do not construct dirname.', + [ERROR_CALCULATE_FILENAME]: 'Do not construct filename using `fileURLToPath()`.', +}; + +const isParentLiteral = node => { + if (node?.type !== 'Literal') { + return false; + } + + return node.value === '.' || node.value === './'; +}; + +const isImportMeta = node => + node.type === 'MetaProperty' + && node.meta.name === 'import' + && node.property.name === 'meta'; + +function isNodeBuiltinModuleFunctionCall(node, {modules, functionName, sourceCode}) { + if (!isCallExpression(node, {optional: false, argumentsLength: 1})) { + return false; + } + + const visited = new Set(); + + return checkExpression(node.callee, 'property'); + + /** @param {import('estree').Expression} node */ + function checkExpression(node, checkKind) { + if (node.type === 'MemberExpression') { + if (!( + checkKind === 'property' + && isMemberExpression(node, {property: functionName, computed: false, optional: false}) + )) { + return false; + } + + return checkExpression(node.object, 'module'); + } + + if (node.type === 'CallExpression') { + if (checkKind !== 'module') { + return false; + } + + // `process.getBuiltinModule('x')` + return ( + isMethodCall(node, { + object: 'process', + method: 'getBuiltinModule', + argumentsLength: 1, + optionalMember: false, + optionalCall: false, + }) + && isModuleLiteral(node.arguments[0]) + ); + } + + if (node.type !== 'Identifier') { + return false; + } + + if (visited.has(node)) { + return false; + } + + visited.add(node); + + const variable = findVariable(sourceCode.getScope(node), node); + if (!variable || variable.defs.length !== 1) { + return; + } + + return checkDefinition(variable.defs[0], checkKind); + } + + /** @param {import('eslint').Scope.Definition} define */ + function checkDefinition(define, checkKind) { + if (define.type === 'ImportBinding') { + if (!isModuleLiteral(define.parent.source)) { + return false; + } + + const specifier = define.node; + return checkKind === 'module' + ? (specifier?.type === 'ImportDefaultSpecifier' || specifier?.type === 'ImportNamespaceSpecifier') + : (specifier?.type === 'ImportSpecifier' && specifier.imported.name === functionName); + } + + return define.type === 'Variable' && checkPattern(define.name, checkKind); + } + + /** @param {import('estree').Identifier | import('estree').ObjectPattern} node */ + function checkPattern(node, checkKind) { + /** @type {{parent?: import('estree').Node}} */ + const {parent} = node; + if (parent.type === 'VariableDeclarator') { + if ( + !parent.init + || parent.id !== node + || parent.parent.type !== 'VariableDeclaration' + || parent.parent.kind !== 'const' + ) { + return false; + } + + return checkExpression(parent.init, checkKind); + } + + if (parent.type === 'Property') { + if (!( + checkKind === 'property' + && parent.value === node + && !parent.computed + && parent.key.type === 'Identifier' + && parent.key.name === functionName + )) { + return false; + } + + // Check for ObjectPattern + return checkPattern(parent.parent, 'module'); + } + + return false; + } + + function isModuleLiteral(node) { + return node?.type === 'Literal' && modules.has(node.value); + } +} + +/** +@returns {node is import('estree').SimpleCallExpression} +*/ +function isUrlFileURLToPathCall(node, sourceCode) { + return isNodeBuiltinModuleFunctionCall(node, { + modules: new Set(['url', 'node:url']), + functionName: 'fileURLToPath', + sourceCode, + }); +} + +/** +@returns {node is import('estree').SimpleCallExpression} +*/ +function isPathDirnameCall(node, sourceCode) { + return isNodeBuiltinModuleFunctionCall(node, { + modules: new Set(['path', 'node:path']), + functionName: 'dirname', + sourceCode, + }); +} + +function create(context) { + const {sourceCode} = context; + + context.on('MetaProperty', function * (node) { + if (!isImportMeta(node)) { + return; + } + + /** @type {import('estree').Node} */ + const memberExpression = node.parent; + if (!isMemberExpression(memberExpression, { + properties: ['url', 'filename'], + computed: false, + optional: false, + })) { + return; + } + + const propertyName = memberExpression.property.name; + if (propertyName === 'url') { + // `url.fileURLToPath(import.meta.url)` + if ( + isUrlFileURLToPathCall(memberExpression.parent, sourceCode) + && memberExpression.parent.arguments[0] === memberExpression + ) { + yield * iterateProblemsFromFilename(memberExpression.parent, { + reportFilenameNode: true, + }); + return; + } + + // `new URL(import.meta.url)` + // `new URL('.', import.meta.url)` + // `new URL('./', import.meta.url)` + if (isNewExpression(memberExpression.parent, {name: 'URL', minimumArguments: 1, maximumArguments: 2})) { + const newUrl = memberExpression.parent; + const urlParent = newUrl.parent; + + // `new URL(import.meta.url)` + if (newUrl.arguments.length === 1 && newUrl.arguments[0] === memberExpression // `url.fileURLToPath(new URL(import.meta.url))` + + && isUrlFileURLToPathCall(urlParent, sourceCode) + && urlParent.arguments[0] === newUrl + ) { + yield * iterateProblemsFromFilename(urlParent, { + reportFilenameNode: true, + }); + return; + } + + // `url.fileURLToPath(new URL(".", import.meta.url))` + // `url.fileURLToPath(new URL("./", import.meta.url))` + if ( + newUrl.arguments.length === 2 + && isParentLiteral(newUrl.arguments[0]) + && newUrl.arguments[1] === memberExpression + && isUrlFileURLToPathCall(urlParent, sourceCode) + && urlParent.arguments[0] === newUrl + ) { + yield getProblem(urlParent, 'dirname'); + } + } + + return; + } + + if (propertyName === 'filename') { + yield * iterateProblemsFromFilename(memberExpression); + } + + /** + Iterates over reports where a given filename expression node + would be used to convert it to a dirname. + @param { import('estree').Expression} node + */ + function * iterateProblemsFromFilename(node, {reportFilenameNode = false} = {}) { + /** @type {{parent: import('estree').Node}} */ + const {parent} = node; + + // `path.dirname(filename)` + if ( + isPathDirnameCall(parent, sourceCode) + && parent.arguments[0] === node + ) { + yield getProblem(parent, 'dirname'); + return; + } + + if (reportFilenameNode) { + yield getProblem(node, 'filename'); + } + + if ( + parent.type !== 'VariableDeclarator' + || parent.init !== node + || parent.id.type !== 'Identifier' + || parent.parent.type !== 'VariableDeclaration' + || parent.parent.kind !== 'const' + ) { + return; + } + + /** @type {import('eslint').Scope.Variable|null} */ + const variable = findVariable(sourceCode.getScope(parent.id), parent.id); + if (!variable) { + return; + } + + for (const reference of variable.references) { + if (!reference.isReadOnly()) { + continue; + } + + /** @type {{parent: import('estree').Node}} */ + const {parent} = reference.identifier; + if ( + isPathDirnameCall(parent, sourceCode) + && parent.arguments[0] === reference.identifier + ) { + // Report `path.dirname(identifier)` + yield getProblem(parent, 'dirname'); + } + } + } + + /** + @param { import('estree').Node} node + @param {'dirname' | 'filename'} name + */ + function getProblem(node, name) { + return { + node, + messageId: name === 'dirname' ? ERROR_CALCULATE_DIRNAME : ERROR_CALCULATE_FILENAME, + fix: fixer => fixer.replaceText(node, `import.meta.${name}`), + }; + } + }); +} + +/** @type {import('eslint').Rule.RuleModule} */ +const config = { + create, + meta: { + type: 'suggestion', + docs: { + description: 'Prefer `import.meta.{dirname,filename}` over legacy techniques for getting file paths.', + recommended: false, + }, + fixable: 'code', + messages, + }, +}; + +export default config; diff --git a/rules/prefer-module.js b/rules/prefer-module.js index d38ad32311..db58aabb85 100644 --- a/rules/prefer-module.js +++ b/rules/prefer-module.js @@ -1,23 +1,12 @@ -import {findVariable} from '@eslint-community/eslint-utils'; import isShadowed from './utils/is-shadowed.js'; import assertToken from './utils/assert-token.js'; import {getCallExpressionTokens} from './utils/index.js'; -import { - isStaticRequire, - isReferenceIdentifier, - isFunction, - isMemberExpression, - isCallExpression, - isNewExpression, - isMethodCall, -} from './ast/index.js'; +import {isStaticRequire, isReferenceIdentifier, isFunction} from './ast/index.js'; import {removeParentheses, replaceReferenceIdentifier, removeSpacesAfter} from './fix/index.js'; const ERROR_USE_STRICT_DIRECTIVE = 'error/use-strict-directive'; const ERROR_GLOBAL_RETURN = 'error/global-return'; const ERROR_IDENTIFIER = 'error/identifier'; -const ERROR_CALCULATE_DIRNAME = 'error/calculate-dirname'; -const ERROR_CALCULATE_FILENAME = 'error/calculate-filename'; const SUGGESTION_USE_STRICT_DIRECTIVE = 'suggestion/use-strict-directive'; const SUGGESTION_IMPORT_META_DIRNAME = 'suggestion/import-meta-dirname'; const SUGGESTION_IMPORT_META_URL_TO_DIRNAME = 'suggestion/import-meta-url-to-dirname'; @@ -29,8 +18,6 @@ const messages = { [ERROR_USE_STRICT_DIRECTIVE]: 'Do not use "use strict" directive.', [ERROR_GLOBAL_RETURN]: '"return" should be used inside a function.', [ERROR_IDENTIFIER]: 'Do not use "{{name}}".', - [ERROR_CALCULATE_DIRNAME]: 'Do not construct dirname.', - [ERROR_CALCULATE_FILENAME]: 'Do not construct filename using `fileURLToPath()`.', [SUGGESTION_USE_STRICT_DIRECTIVE]: 'Remove "use strict" directive.', [SUGGESTION_IMPORT_META_DIRNAME]: 'Replace `__dirname` with `import.meta.dirname`.', [SUGGESTION_IMPORT_META_URL_TO_DIRNAME]: 'Replace `__dirname` with `…(import.meta.url)`.', @@ -211,155 +198,6 @@ const isTopLevelReturnStatement = node => { return true; }; -const isParentLiteral = node => { - if (node?.type !== 'Literal') { - return false; - } - - return node.value === '.' || node.value === './'; -}; - -const isImportMeta = node => - node.type === 'MetaProperty' - && node.meta.name === 'import' - && node.property.name === 'meta'; - -function isNodeBuiltinModuleFunctionCall(node, {modules, functionName, sourceCode}) { - if (!isCallExpression(node, {optional: false, argumentsLength: 1})) { - return false; - } - - const visited = new Set(); - - return checkExpression(node.callee, 'property'); - - /** @param {import('estree').Expression} node */ - function checkExpression(node, checkKind) { - if (node.type === 'MemberExpression') { - if (!( - checkKind === 'property' - && isMemberExpression(node, {property: functionName, computed: false, optional: false}) - )) { - return false; - } - - return checkExpression(node.object, 'module'); - } - - if (node.type === 'CallExpression') { - if (checkKind !== 'module') { - return false; - } - - // `process.getBuiltinModule('x')` - return ( - isMethodCall(node, { - object: 'process', - method: 'getBuiltinModule', - argumentsLength: 1, - optionalMember: false, - optionalCall: false, - }) - && isModuleLiteral(node.arguments[0]) - ); - } - - if (node.type !== 'Identifier') { - return false; - } - - if (visited.has(node)) { - return false; - } - - visited.add(node); - - const variable = findVariable(sourceCode.getScope(node), node); - if (!variable || variable.defs.length !== 1) { - return; - } - - return checkDefinition(variable.defs[0], checkKind); - } - - /** @param {import('eslint').Scope.Definition} define */ - function checkDefinition(define, checkKind) { - if (define.type === 'ImportBinding') { - if (!isModuleLiteral(define.parent.source)) { - return false; - } - - const specifier = define.node; - return checkKind === 'module' - ? (specifier?.type === 'ImportDefaultSpecifier' || specifier?.type === 'ImportNamespaceSpecifier') - : (specifier?.type === 'ImportSpecifier' && specifier.imported.name === functionName); - } - - return define.type === 'Variable' && checkPattern(define.name, checkKind); - } - - /** @param {import('estree').Identifier | import('estree').ObjectPattern} node */ - function checkPattern(node, checkKind) { - /** @type {{parent?: import('estree').Node}} */ - const {parent} = node; - if (parent.type === 'VariableDeclarator') { - if ( - !parent.init - || parent.id !== node - || parent.parent.type !== 'VariableDeclaration' - || parent.parent.kind !== 'const' - ) { - return false; - } - - return checkExpression(parent.init, checkKind); - } - - if (parent.type === 'Property') { - if (!( - checkKind === 'property' - && parent.value === node - && !parent.computed - && parent.key.type === 'Identifier' - && parent.key.name === functionName - )) { - return false; - } - - // Check for ObjectPattern - return checkPattern(parent.parent, 'module'); - } - - return false; - } - - function isModuleLiteral(node) { - return node?.type === 'Literal' && modules.has(node.value); - } -} - -/** -@returns {node is import('estree').SimpleCallExpression} -*/ -function isUrlFileURLToPathCall(node, sourceCode) { - return isNodeBuiltinModuleFunctionCall(node, { - modules: new Set(['url', 'node:url']), - functionName: 'fileURLToPath', - sourceCode, - }); -} - -/** -@returns {node is import('estree').SimpleCallExpression} -*/ -function isPathDirnameCall(node, sourceCode) { - return isNodeBuiltinModuleFunctionCall(node, { - modules: new Set(['path', 'node:path']), - functionName: 'dirname', - sourceCode, - }); -} - function fixDefaultExport(node, sourceCode) { return function * (fixer) { yield fixer.replaceText(node, 'export default '); @@ -520,141 +358,6 @@ function create(context) { return problem; }); - - context.on('MetaProperty', function * (node) { - if (!isImportMeta(node)) { - return; - } - - /** @type {import('estree').Node} */ - const memberExpression = node.parent; - if (!isMemberExpression(memberExpression, { - properties: ['url', 'filename'], - computed: false, - optional: false, - })) { - return; - } - - const propertyName = memberExpression.property.name; - if (propertyName === 'url') { - // `url.fileURLToPath(import.meta.url)` - if ( - isUrlFileURLToPathCall(memberExpression.parent, sourceCode) - && memberExpression.parent.arguments[0] === memberExpression - ) { - yield * iterateProblemsFromFilename(memberExpression.parent, { - reportFilenameNode: true, - }); - return; - } - - // `new URL(import.meta.url)` - // `new URL('.', import.meta.url)` - // `new URL('./', import.meta.url)` - if (isNewExpression(memberExpression.parent, {name: 'URL', minimumArguments: 1, maximumArguments: 2})) { - const newUrl = memberExpression.parent; - const urlParent = newUrl.parent; - - // `new URL(import.meta.url)` - if (newUrl.arguments.length === 1 && newUrl.arguments[0] === memberExpression // `url.fileURLToPath(new URL(import.meta.url))` - - && isUrlFileURLToPathCall(urlParent, sourceCode) - && urlParent.arguments[0] === newUrl - ) { - yield * iterateProblemsFromFilename(urlParent, { - reportFilenameNode: true, - }); - return; - } - - // `url.fileURLToPath(new URL(".", import.meta.url))` - // `url.fileURLToPath(new URL("./", import.meta.url))` - if ( - newUrl.arguments.length === 2 - && isParentLiteral(newUrl.arguments[0]) - && newUrl.arguments[1] === memberExpression - && isUrlFileURLToPathCall(urlParent, sourceCode) - && urlParent.arguments[0] === newUrl - ) { - yield getProblem(urlParent, 'dirname'); - } - } - - return; - } - - if (propertyName === 'filename') { - yield * iterateProblemsFromFilename(memberExpression); - } - - /** - Iterates over reports where a given filename expression node - would be used to convert it to a dirname. - @param { import('estree').Expression} node - */ - function * iterateProblemsFromFilename(node, {reportFilenameNode = false} = {}) { - /** @type {{parent: import('estree').Node}} */ - const {parent} = node; - - // `path.dirname(filename)` - if ( - isPathDirnameCall(parent, sourceCode) - && parent.arguments[0] === node - ) { - yield getProblem(parent, 'dirname'); - return; - } - - if (reportFilenameNode) { - yield getProblem(node, 'filename'); - } - - if ( - parent.type !== 'VariableDeclarator' - || parent.init !== node - || parent.id.type !== 'Identifier' - || parent.parent.type !== 'VariableDeclaration' - || parent.parent.kind !== 'const' - ) { - return; - } - - /** @type {import('eslint').Scope.Variable|null} */ - const variable = findVariable(sourceCode.getScope(parent.id), parent.id); - if (!variable) { - return; - } - - for (const reference of variable.references) { - if (!reference.isReadOnly()) { - continue; - } - - /** @type {{parent: import('estree').Node}} */ - const {parent} = reference.identifier; - if ( - isPathDirnameCall(parent, sourceCode) - && parent.arguments[0] === reference.identifier - ) { - // Report `path.dirname(identifier)` - yield getProblem(parent, 'dirname'); - } - } - } - - /** - @param { import('estree').Node} node - @param {'dirname' | 'filename'} name - */ - function getProblem(node, name) { - return { - node, - messageId: name === 'dirname' ? ERROR_CALCULATE_DIRNAME : ERROR_CALCULATE_FILENAME, - fix: fixer => fixer.replaceText(node, `import.meta.${name}`), - }; - } - }); } /** @type {import('eslint').Rule.RuleModule} */ diff --git a/scripts/create-rule.js b/scripts/create-rule.js index c90a2dbca0..3ec6a4aba3 100644 --- a/scripts/create-rule.js +++ b/scripts/create-rule.js @@ -1,12 +1,13 @@ #!/usr/bin/env node import fs from 'node:fs'; import path from 'node:path'; +import {fileURLToPath} from 'node:url'; import enquirer from 'enquirer'; import {template} from 'lodash-es'; import openEditor from 'open-editor'; import spawn from 'nano-spawn'; -const {dirname} = import.meta; +const dirname = path.dirname(fileURLToPath(import.meta.url)); const ROOT = path.join(dirname, '..'); function checkFiles(ruleId) { diff --git a/scripts/internal-rules/no-restricted-property-access.js b/scripts/internal-rules/no-restricted-property-access.js index 5f9f844755..a9baf09055 100644 --- a/scripts/internal-rules/no-restricted-property-access.js +++ b/scripts/internal-rules/no-restricted-property-access.js @@ -1,8 +1,9 @@ import path from 'node:path'; +import {fileURLToPath} from 'node:url'; import {isMemberExpression} from '../../rules/ast/index.js'; import {removeMemberExpressionProperty} from '../../rules/fix/index.js'; -const messageId = path.basename(import.meta.filename, '.js'); +const messageId = path.basename(fileURLToPath(import.meta.url), '.js'); const properties = new Map([ ['range', 'sourceCode.getRange'], diff --git a/scripts/internal-rules/no-test-only.js b/scripts/internal-rules/no-test-only.js index 061e08ab1b..0901903edf 100644 --- a/scripts/internal-rules/no-test-only.js +++ b/scripts/internal-rules/no-test-only.js @@ -1,6 +1,7 @@ import path from 'node:path'; +import {fileURLToPath} from 'node:url'; -const messageId = path.basename(import.meta.filename, '.js'); +const messageId = path.basename(fileURLToPath(import.meta.url), '.js'); const config = { create(context) { diff --git a/scripts/internal-rules/prefer-fixer-remove-range.js b/scripts/internal-rules/prefer-fixer-remove-range.js index 126fc1a394..3d43824cd9 100644 --- a/scripts/internal-rules/prefer-fixer-remove-range.js +++ b/scripts/internal-rules/prefer-fixer-remove-range.js @@ -1,8 +1,9 @@ import path from 'node:path'; +import {fileURLToPath} from 'node:url'; import {isMethodCall, isLiteral} from '../../rules/ast/index.js'; import {removeArgument} from '../../rules/fix/index.js'; -const messageId = path.basename(import.meta.filename, '.js'); +const messageId = path.basename(fileURLToPath(import.meta.url), '.js'); const config = { create(context) { diff --git a/scripts/internal-rules/prefer-negative-boolean-attribute.js b/scripts/internal-rules/prefer-negative-boolean-attribute.js index fc6beebfa9..50e22e60ca 100644 --- a/scripts/internal-rules/prefer-negative-boolean-attribute.js +++ b/scripts/internal-rules/prefer-negative-boolean-attribute.js @@ -1,6 +1,7 @@ import path from 'node:path'; +import {fileURLToPath} from 'node:url'; -const messageId = path.basename(import.meta.filename, '.js'); +const messageId = path.basename(fileURLToPath(import.meta.url), '.js'); const shouldReport = (string, value) => { const index = string.indexOf(`=${value}]`); diff --git a/test/integration/projects.js b/test/integration/projects.js index 2153c0c3fa..1dbb1fd76f 100644 --- a/test/integration/projects.js +++ b/test/integration/projects.js @@ -1,6 +1,7 @@ import path from 'node:path'; +import {fileURLToPath} from 'node:url'; -const {dirname} = import.meta; +const dirname = path.dirname(fileURLToPath(import.meta.url)); function normalizeProject(project) { if (typeof project === 'string') { diff --git a/test/prefer-import-meta-properties.js b/test/prefer-import-meta-properties.js new file mode 100644 index 0000000000..4fe2977401 --- /dev/null +++ b/test/prefer-import-meta-properties.js @@ -0,0 +1,174 @@ +import outdent from 'outdent'; +import {getTester} from './utils/test.js'; + +const {test} = getTester(import.meta); + +test.snapshot({ + valid: [ + 'const __dirname = import.meta.dirname;', + 'const __filename = import.meta.filename;', + outdent` + import path from "path"; + const dirUrl = path.dirname(import.meta.url); + `, + 'const url = import.meta.url;', + 'const dirname = new URL(".", import.meta.url).pathname;', + 'const filename = new URL(import.meta.url).pathname;', + 'const filename = fileURLToPath(import.meta.url);', // `fileURLToPath` is not imported + 'const dirname = path.dirname(import.meta.filename);', // `path` is not imported + outdent` + import path from "path"; + const not_dirname = path.dirname(new URL(import.meta.url).pathname); // It is the same as dirname on macOS but returns different results on Windows. + `, + outdent` + // path is not initialized + let path; + const dirname = path.dirname(import.meta.filename); + `, + outdent` + // path is unknown property + const { path } = process.getBuiltinModule("node:path"); + const dirname = path.dirname(import.meta.filename); + `, + outdent` + const { dirname } = process.getBuiltinModule("node:path"); + // dirname()() is unknown + const x = dirname(x)(import.meta.filename); + `, + outdent` + // path is unknown + const path = new X(); + const dirname = path.dirname(import.meta.filename); + `, + outdent` + // path is unknown + const path = path; + const dirname = path.dirname(import.meta.filename); + `, + outdent` + // path is unknown + const [path] = process.getBuiltinModule("node:path"); + const dirname = path.dirname(import.meta.filename); + `, + outdent` + import path from "path"; + const dirname = path?.dirname(import.meta.filename); + `, + outdent` + import path from "path"; + const dirname = path[dirname](import.meta.filename); + `, + outdent` + import path from "path"; + const dirname = path["dirname"](import.meta.filename); + `, + outdent` + import path from "path"; + const dirname = path.dirname?.(import.meta.filename); + `, + outdent` + const { [fileURLToPath]: fileURLToPath } = process.getBuiltinModule("node:url"); + const filename = fileURLToPath(import.meta.url); + `, + outdent` + const { ["fileURLToPath"]: fileURLToPath } = process.getBuiltinModule("node:url"); + const filename = fileURLToPath(import.meta.url); + `, + outdent` + import {fileURLToPath} from "node:url"; + class Foo { + constructor() { + const filename = fileURLToPath(new.target.url) + } + } + `, + outdent` + import {fileURLToPath} from "node:url"; + const filename = fileURLToPath(import.meta?.url) + `, + outdent` + import {fileURLToPath} from "node:url"; + const filename = fileURLToPath(import.meta['url']) + `, + ], + invalid: [ + outdent` + import path from "path"; + import { fileURLToPath } from "url"; + const dirname = path.dirname(fileURLToPath(import.meta.url)); + `, + outdent` + import path from "path"; + const dirname = path.dirname(import.meta.filename); + `, + outdent` + import { fileURLToPath } from "url"; + const dirname = fileURLToPath(new URL(".", import.meta.url)); + `, + outdent` + import { fileURLToPath } from "url"; + const dirname = fileURLToPath(new URL("./", import.meta.url)); + `, + outdent` + import { fileURLToPath } from "url"; + const filename = fileURLToPath(import.meta.url); + `, + outdent` + import { fileURLToPath } from "url"; + const filename = fileURLToPath(new URL(import.meta.url)); + `, + outdent` + import path from "node:path"; + import { fileURLToPath } from "node:url"; + const dirname = path.dirname(fileURLToPath(import.meta.url)); + `, + outdent` + import { fileURLToPath } from "node:url"; + const filename = fileURLToPath(import.meta.url); + `, + outdent` + import * as path from "node:path"; + import url from "node:url"; + const dirname = path.dirname(url.fileURLToPath(import.meta.url)); + `, + outdent` + import url from "node:url"; + const filename = url.fileURLToPath(import.meta.url); + `, + outdent` + import path from "node:path"; + import { fileURLToPath } from "node:url"; + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + `, + outdent` + import path from "node:path"; + const __filename = import.meta.filename; + const __dirname = path.dirname(__filename); + `, + outdent` + const path = process.getBuiltinModule("node:path"); + const { fileURLToPath } = process.getBuiltinModule("node:url"); + const filename = fileURLToPath(import.meta.url); + const dirname = path.dirname(filename); + `, + outdent` + const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); + const filename = renamed(import.meta.url); + `, + outdent` + import { fileURLToPath as renamed } from "node:url"; + const filename = renamed(import.meta.url); + `, + outdent` + const path = process.getBuiltinModule("path"); + const { fileURLToPath } = process.getBuiltinModule("url"); + const filename = fileURLToPath(import.meta.url); + const dirname = path.dirname(filename); + `, + outdent` + const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); + const dirname = process.getBuiltinModule("node:path").dirname(filename); + `, + ], +}); diff --git a/test/prefer-module.js b/test/prefer-module.js index 6420076126..563a95719a 100644 --- a/test/prefer-module.js +++ b/test/prefer-module.js @@ -307,174 +307,3 @@ test.snapshot({ }, ], }); - -// `import.meta.dirname` and `import.meta.filename` -test.snapshot({ - valid: [ - 'const __dirname = import.meta.dirname;', - 'const __filename = import.meta.filename;', - outdent` - import path from "path"; - const dirUrl = path.dirname(import.meta.url); - `, - 'const url = import.meta.url;', - 'const dirname = new URL(".", import.meta.url).pathname;', - 'const filename = new URL(import.meta.url).pathname;', - 'const filename = fileURLToPath(import.meta.url);', // `fileURLToPath` is not imported - 'const dirname = path.dirname(import.meta.filename);', // `path` is not imported - outdent` - import path from "path"; - const not_dirname = path.dirname(new URL(import.meta.url).pathname); // It is the same as dirname on macOS but returns different results on Windows. - `, - outdent` - // path is not initialized - let path; - const dirname = path.dirname(import.meta.filename); - `, - outdent` - // path is unknown property - const { path } = process.getBuiltinModule("node:path"); - const dirname = path.dirname(import.meta.filename); - `, - outdent` - const { dirname } = process.getBuiltinModule("node:path"); - // dirname()() is unknown - const x = dirname(x)(import.meta.filename); - `, - outdent` - // path is unknown - const path = new X(); - const dirname = path.dirname(import.meta.filename); - `, - outdent` - // path is unknown - const path = path; - const dirname = path.dirname(import.meta.filename); - `, - outdent` - // path is unknown - const [path] = process.getBuiltinModule("node:path"); - const dirname = path.dirname(import.meta.filename); - `, - outdent` - import path from "path"; - const dirname = path?.dirname(import.meta.filename); - `, - outdent` - import path from "path"; - const dirname = path[dirname](import.meta.filename); - `, - outdent` - import path from "path"; - const dirname = path["dirname"](import.meta.filename); - `, - outdent` - import path from "path"; - const dirname = path.dirname?.(import.meta.filename); - `, - outdent` - const { [fileURLToPath]: fileURLToPath } = process.getBuiltinModule("node:url"); - const filename = fileURLToPath(import.meta.url); - `, - outdent` - const { ["fileURLToPath"]: fileURLToPath } = process.getBuiltinModule("node:url"); - const filename = fileURLToPath(import.meta.url); - `, - outdent` - import {fileURLToPath} from "node:url"; - class Foo { - constructor() { - const filename = fileURLToPath(new.target.url) - } - } - `, - outdent` - import {fileURLToPath} from "node:url"; - const filename = fileURLToPath(import.meta?.url) - `, - outdent` - import {fileURLToPath} from "node:url"; - const filename = fileURLToPath(import.meta['url']) - `, - ], - invalid: [ - outdent` - import path from "path"; - import { fileURLToPath } from "url"; - const dirname = path.dirname(fileURLToPath(import.meta.url)); - `, - outdent` - import path from "path"; - const dirname = path.dirname(import.meta.filename); - `, - outdent` - import { fileURLToPath } from "url"; - const dirname = fileURLToPath(new URL(".", import.meta.url)); - `, - outdent` - import { fileURLToPath } from "url"; - const dirname = fileURLToPath(new URL("./", import.meta.url)); - `, - outdent` - import { fileURLToPath } from "url"; - const filename = fileURLToPath(import.meta.url); - `, - outdent` - import { fileURLToPath } from "url"; - const filename = fileURLToPath(new URL(import.meta.url)); - `, - outdent` - import path from "node:path"; - import { fileURLToPath } from "node:url"; - const dirname = path.dirname(fileURLToPath(import.meta.url)); - `, - outdent` - import { fileURLToPath } from "node:url"; - const filename = fileURLToPath(import.meta.url); - `, - outdent` - import * as path from "node:path"; - import url from "node:url"; - const dirname = path.dirname(url.fileURLToPath(import.meta.url)); - `, - outdent` - import url from "node:url"; - const filename = url.fileURLToPath(import.meta.url); - `, - outdent` - import path from "node:path"; - import { fileURLToPath } from "node:url"; - const __filename = fileURLToPath(import.meta.url); - const __dirname = path.dirname(__filename); - `, - outdent` - import path from "node:path"; - const __filename = import.meta.filename; - const __dirname = path.dirname(__filename); - `, - outdent` - const path = process.getBuiltinModule("node:path"); - const { fileURLToPath } = process.getBuiltinModule("node:url"); - const filename = fileURLToPath(import.meta.url); - const dirname = path.dirname(filename); - `, - outdent` - const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); - const filename = renamed(import.meta.url); - `, - outdent` - import { fileURLToPath as renamed } from "node:url"; - const filename = renamed(import.meta.url); - `, - outdent` - const path = process.getBuiltinModule("path"); - const { fileURLToPath } = process.getBuiltinModule("url"); - const filename = fileURLToPath(import.meta.url); - const dirname = path.dirname(filename); - `, - outdent` - const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); - const dirname = process.getBuiltinModule("node:path").dirname(filename); - `, - ], -}); diff --git a/test/snapshots/prefer-import-meta-properties.js.md b/test/snapshots/prefer-import-meta-properties.js.md new file mode 100644 index 0000000000..2bd2867e6f --- /dev/null +++ b/test/snapshots/prefer-import-meta-properties.js.md @@ -0,0 +1,481 @@ +# Snapshot report for `test/prefer-import-meta-properties.js` + +The actual snapshot is saved in `prefer-import-meta-properties.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## invalid(1): import path from "path"; import { fileURLToPath } from "url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); + +> Input + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + ` + +> Output + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + 3 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/1 + + `␊ + 1 | import path from "path";␊ + 2 | import { fileURLToPath } from "url";␊ + > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(2): import path from "path"; const dirname = path.dirname(import.meta.filename); + +> Input + + `␊ + 1 | import path from "path";␊ + 2 | const dirname = path.dirname(import.meta.filename);␊ + ` + +> Output + + `␊ + 1 | import path from "path";␊ + 2 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/1 + + `␊ + 1 | import path from "path";␊ + > 2 | const dirname = path.dirname(import.meta.filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(3): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); + +> Input + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const dirname = fileURLToPath(new URL(".", import.meta.url));␊ + ` + +> Output + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + > 2 | const dirname = fileURLToPath(new URL(".", import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(4): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL("./", import.meta.url)); + +> Input + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const dirname = fileURLToPath(new URL("./", import.meta.url));␊ + ` + +> Output + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + > 2 | const dirname = fileURLToPath(new URL("./", import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(5): import { fileURLToPath } from "url"; const filename = fileURLToPath(import.meta.url); + +> Input + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename = fileURLToPath(import.meta.url);␊ + ` + +> Output + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + > 2 | const filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(6): import { fileURLToPath } from "url"; const filename = fileURLToPath(new URL(import.meta.url)); + +> Input + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename = fileURLToPath(new URL(import.meta.url));␊ + ` + +> Output + + `␊ + 1 | import { fileURLToPath } from "url";␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath } from "url";␊ + > 2 | const filename = fileURLToPath(new URL(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(7): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); + +> Input + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + ` + +> Output + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/1 + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(8): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); + +> Input + + `␊ + 1 | import { fileURLToPath } from "node:url";␊ + 2 | const filename = fileURLToPath(import.meta.url);␊ + ` + +> Output + + `␊ + 1 | import { fileURLToPath } from "node:url";␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath } from "node:url";␊ + > 2 | const filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(9): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); + +> Input + + `␊ + 1 | import * as path from "node:path";␊ + 2 | import url from "node:url";␊ + 3 | const dirname = path.dirname(url.fileURLToPath(import.meta.url));␊ + ` + +> Output + + `␊ + 1 | import * as path from "node:path";␊ + 2 | import url from "node:url";␊ + 3 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/1 + + `␊ + 1 | import * as path from "node:path";␊ + 2 | import url from "node:url";␊ + > 3 | const dirname = path.dirname(url.fileURLToPath(import.meta.url));␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(10): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); + +> Input + + `␊ + 1 | import url from "node:url";␊ + 2 | const filename = url.fileURLToPath(import.meta.url);␊ + ` + +> Output + + `␊ + 1 | import url from "node:url";␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | import url from "node:url";␊ + > 2 | const filename = url.fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(11): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); + +> Input + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = fileURLToPath(import.meta.url);␊ + 4 | const __dirname = path.dirname(__filename);␊ + ` + +> Output + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = import.meta.filename;␊ + 4 | const __dirname = import.meta.dirname;␊ + ` + +> Error 1/2 + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + > 3 | const __filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 4 | const __dirname = path.dirname(__filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | import path from "node:path";␊ + 2 | import { fileURLToPath } from "node:url";␊ + 3 | const __filename = fileURLToPath(import.meta.url);␊ + > 4 | const __dirname = path.dirname(__filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(12): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); + +> Input + + `␊ + 1 | import path from "node:path";␊ + 2 | const __filename = import.meta.filename;␊ + 3 | const __dirname = path.dirname(__filename);␊ + ` + +> Output + + `␊ + 1 | import path from "node:path";␊ + 2 | const __filename = import.meta.filename;␊ + 3 | const __dirname = import.meta.dirname;␊ + ` + +> Error 1/1 + + `␊ + 1 | import path from "node:path";␊ + 2 | const __filename = import.meta.filename;␊ + > 3 | const __dirname = path.dirname(__filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(13): const path = process.getBuiltinModule("node:path"); const { fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); + +> Input + + `␊ + 1 | const path = process.getBuiltinModule("node:path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + 4 | const dirname = path.dirname(filename);␊ + ` + +> Output + + `␊ + 1 | const path = process.getBuiltinModule("node:path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ + 3 | const filename = import.meta.filename;␊ + 4 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/2 + + `␊ + 1 | const path = process.getBuiltinModule("node:path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ + > 3 | const filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 4 | const dirname = path.dirname(filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | const path = process.getBuiltinModule("node:path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + > 4 | const dirname = path.dirname(filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(14): const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); + +> Input + + `␊ + 1 | const { fileURLToPath: renamed } = process.getBuiltinModule("node:url");␊ + 2 | const filename = renamed(import.meta.url);␊ + ` + +> Output + + `␊ + 1 | const { fileURLToPath: renamed } = process.getBuiltinModule("node:url");␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | const { fileURLToPath: renamed } = process.getBuiltinModule("node:url");␊ + > 2 | const filename = renamed(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(15): import { fileURLToPath as renamed } from "node:url"; const filename = renamed(import.meta.url); + +> Input + + `␊ + 1 | import { fileURLToPath as renamed } from "node:url";␊ + 2 | const filename = renamed(import.meta.url);␊ + ` + +> Output + + `␊ + 1 | import { fileURLToPath as renamed } from "node:url";␊ + 2 | const filename = import.meta.filename;␊ + ` + +> Error 1/1 + + `␊ + 1 | import { fileURLToPath as renamed } from "node:url";␊ + > 2 | const filename = renamed(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + ` + +## invalid(16): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); + +> Input + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + 4 | const dirname = path.dirname(filename);␊ + ` + +> Output + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + 3 | const filename = import.meta.filename;␊ + 4 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/2 + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + > 3 | const filename = fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 4 | const dirname = path.dirname(filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | const path = process.getBuiltinModule("path");␊ + 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ + 3 | const filename = fileURLToPath(import.meta.url);␊ + > 4 | const dirname = path.dirname(filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` + +## invalid(17): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); + +> Input + + `␊ + 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ + 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ + ` + +> Output + + `␊ + 1 | const filename = import.meta.filename;␊ + 2 | const dirname = import.meta.dirname;␊ + ` + +> Error 1/2 + + `␊ + > 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ + 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ + ` + +> Error 2/2 + + `␊ + 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ + > 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ + ` diff --git a/test/snapshots/prefer-import-meta-properties.js.snap b/test/snapshots/prefer-import-meta-properties.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..aa627faad6527eb919376b36e5917e2493deb93f GIT binary patch literal 1417 zcmV;41$O#DRzV7l<7h!6;Yz>>Hy zwA0`@J`_U$joyZsP<0#vL=T0^9uX6U&)5Y^zxsFV~3G?zmn+ zIz})@TAte`#qN*ADf)+Vq-ELWkwg0qy9c|UIp6zK=-I_7(r_I=AWh42jJ8R3uUw|m z`?UnVSX#YarELaACG_ladCKw~qvOxHfq(fUT7GBleuv1E+It6WOp zq-p}kkO*D?1wW$?LAIdv#o%MW;F3lLIoZe#p$vrvrSJ_g3aM)k#JM&y26tybksGo_ z#!Fz4HVZ^dD-gk2)Yz>33RwF=nl*t8u<1&{YmldC#L%~#S#lB%TRzDL?KA~#ry|hk zgu*!8Sx{_SIdOa~>kYlX0D6zrqnD5hDF(H`c!R>Yi@8s5+@@K>?UGkMs%5ME6{ys0 ze%l>Wi`(S&HS5|mUjy1N4pTdJ!Jp1=1|py95xHTv(k(hg-c0xFfk}|1JD3OVIEOPR zfQ70S!3IiZR4Kum^>2XCpOIz_=-Zgh!e7vsnn(JY>?0-hK2tHyiriy))RN;8VEU{ppGY|!Ma`2FZOe@A~hB(NTv z>FI$n@J{qSPWhQWgBYE~=?obEp#1oFr~L)+_k9jACdXSbF-teXDn0hQh${A7qAX4D zi4*wMCi)6zZuYMgXZ1?2a7&vM#OFu_`se3y}%3?-<5S z5IZ^K42>?nw?Gj;7Mbk=vv(r9EnNpfFAY^F`cyx82c<@2T{xS%z>cl%4#dRTgh%AH4UsO`4lAL;kr#kdQTzKQGjj3rUUtrM_-r4U`VGgGQ16T9dCoQ zZy$ZyC1+ntV&0TO-5#mK%VBl}*Hks9$<#5A*ba_WrR zT>x?{4RY|5J^_^elyci4S6ZQ+@_2`$(`s%)U&IxIgAR4(zp!wiOs*`}b3_8tJ? zE_52jVetO9Kr$Ho6KiM(%kp6Ebbc?$Wi4N*Yt3brXVlcYl7`9-+SXQ(;aBonY32NT Xh-^$EHY8Cau2207!~(}nbvFP2uv4aS literal 0 HcmV?d00001 diff --git a/test/snapshots/prefer-module.js.md b/test/snapshots/prefer-module.js.md index 1758729ffc..56457b3304 100644 --- a/test/snapshots/prefer-module.js.md +++ b/test/snapshots/prefer-module.js.md @@ -1914,479 +1914,3 @@ Generated by [AVA](https://avajs.dev). Suggestion 1/1: Switch to \`import\`.␊ 1 | import "lodash"␊ ` - -## invalid(1): import path from "path"; import { fileURLToPath } from "url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); - -> Input - - `␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ - ` - -> Output - - `␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - 3 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import path from "path";␊ - 2 | import { fileURLToPath } from "url";␊ - > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(2): import path from "path"; const dirname = path.dirname(import.meta.filename); - -> Input - - `␊ - 1 | import path from "path";␊ - 2 | const dirname = path.dirname(import.meta.filename);␊ - ` - -> Output - - `␊ - 1 | import path from "path";␊ - 2 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import path from "path";␊ - > 2 | const dirname = path.dirname(import.meta.filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(3): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL(".", import.meta.url)); - -> Input - - `␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const dirname = fileURLToPath(new URL(".", import.meta.url));␊ - ` - -> Output - - `␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import { fileURLToPath } from "url";␊ - > 2 | const dirname = fileURLToPath(new URL(".", import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(4): import { fileURLToPath } from "url"; const dirname = fileURLToPath(new URL("./", import.meta.url)); - -> Input - - `␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const dirname = fileURLToPath(new URL("./", import.meta.url));␊ - ` - -> Output - - `␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import { fileURLToPath } from "url";␊ - > 2 | const dirname = fileURLToPath(new URL("./", import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(5): import { fileURLToPath } from "url"; const filename = fileURLToPath(import.meta.url); - -> Input - - `␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const filename = fileURLToPath(import.meta.url);␊ - ` - -> Output - - `␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const filename = import.meta.filename;␊ - ` - -> Error 1/1 - - `␊ - 1 | import { fileURLToPath } from "url";␊ - > 2 | const filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ` - -## invalid(6): import { fileURLToPath } from "url"; const filename = fileURLToPath(new URL(import.meta.url)); - -> Input - - `␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const filename = fileURLToPath(new URL(import.meta.url));␊ - ` - -> Output - - `␊ - 1 | import { fileURLToPath } from "url";␊ - 2 | const filename = import.meta.filename;␊ - ` - -> Error 1/1 - - `␊ - 1 | import { fileURLToPath } from "url";␊ - > 2 | const filename = fileURLToPath(new URL(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ` - -## invalid(7): import path from "node:path"; import { fileURLToPath } from "node:url"; const dirname = path.dirname(fileURLToPath(import.meta.url)); - -> Input - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ - ` - -> Output - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - > 3 | const dirname = path.dirname(fileURLToPath(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(8): import { fileURLToPath } from "node:url"; const filename = fileURLToPath(import.meta.url); - -> Input - - `␊ - 1 | import { fileURLToPath } from "node:url";␊ - 2 | const filename = fileURLToPath(import.meta.url);␊ - ` - -> Output - - `␊ - 1 | import { fileURLToPath } from "node:url";␊ - 2 | const filename = import.meta.filename;␊ - ` - -> Error 1/1 - - `␊ - 1 | import { fileURLToPath } from "node:url";␊ - > 2 | const filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ` - -## invalid(9): import * as path from "node:path"; import url from "node:url"; const dirname = path.dirname(url.fileURLToPath(import.meta.url)); - -> Input - - `␊ - 1 | import * as path from "node:path";␊ - 2 | import url from "node:url";␊ - 3 | const dirname = path.dirname(url.fileURLToPath(import.meta.url));␊ - ` - -> Output - - `␊ - 1 | import * as path from "node:path";␊ - 2 | import url from "node:url";␊ - 3 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import * as path from "node:path";␊ - 2 | import url from "node:url";␊ - > 3 | const dirname = path.dirname(url.fileURLToPath(import.meta.url));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(10): import url from "node:url"; const filename = url.fileURLToPath(import.meta.url); - -> Input - - `␊ - 1 | import url from "node:url";␊ - 2 | const filename = url.fileURLToPath(import.meta.url);␊ - ` - -> Output - - `␊ - 1 | import url from "node:url";␊ - 2 | const filename = import.meta.filename;␊ - ` - -> Error 1/1 - - `␊ - 1 | import url from "node:url";␊ - > 2 | const filename = url.fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ` - -## invalid(11): import path from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); - -> Input - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const __filename = fileURLToPath(import.meta.url);␊ - 4 | const __dirname = path.dirname(__filename);␊ - ` - -> Output - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const __filename = import.meta.filename;␊ - 4 | const __dirname = import.meta.dirname;␊ - ` - -> Error 1/2 - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - > 3 | const __filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - 4 | const __dirname = path.dirname(__filename);␊ - ` - -> Error 2/2 - - `␊ - 1 | import path from "node:path";␊ - 2 | import { fileURLToPath } from "node:url";␊ - 3 | const __filename = fileURLToPath(import.meta.url);␊ - > 4 | const __dirname = path.dirname(__filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(12): import path from "node:path"; const __filename = import.meta.filename; const __dirname = path.dirname(__filename); - -> Input - - `␊ - 1 | import path from "node:path";␊ - 2 | const __filename = import.meta.filename;␊ - 3 | const __dirname = path.dirname(__filename);␊ - ` - -> Output - - `␊ - 1 | import path from "node:path";␊ - 2 | const __filename = import.meta.filename;␊ - 3 | const __dirname = import.meta.dirname;␊ - ` - -> Error 1/1 - - `␊ - 1 | import path from "node:path";␊ - 2 | const __filename = import.meta.filename;␊ - > 3 | const __dirname = path.dirname(__filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(13): const path = process.getBuiltinModule("node:path"); const { fileURLToPath } = process.getBuiltinModule("node:url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); - -> Input - - `␊ - 1 | const path = process.getBuiltinModule("node:path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ - 3 | const filename = fileURLToPath(import.meta.url);␊ - 4 | const dirname = path.dirname(filename);␊ - ` - -> Output - - `␊ - 1 | const path = process.getBuiltinModule("node:path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ - 3 | const filename = import.meta.filename;␊ - 4 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/2 - - `␊ - 1 | const path = process.getBuiltinModule("node:path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ - > 3 | const filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - 4 | const dirname = path.dirname(filename);␊ - ` - -> Error 2/2 - - `␊ - 1 | const path = process.getBuiltinModule("node:path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("node:url");␊ - 3 | const filename = fileURLToPath(import.meta.url);␊ - > 4 | const dirname = path.dirname(filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(14): const { fileURLToPath: renamed } = process.getBuiltinModule("node:url"); const filename = renamed(import.meta.url); - -> Input - - `␊ - 1 | const { fileURLToPath: renamed } = process.getBuiltinModule("node:url");␊ - 2 | const filename = renamed(import.meta.url);␊ - ` - -> Output - - `␊ - 1 | const { fileURLToPath: renamed } = process.getBuiltinModule("node:url");␊ - 2 | const filename = import.meta.filename;␊ - ` - -> Error 1/1 - - `␊ - 1 | const { fileURLToPath: renamed } = process.getBuiltinModule("node:url");␊ - > 2 | const filename = renamed(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ` - -## invalid(15): import { fileURLToPath as renamed } from "node:url"; const filename = renamed(import.meta.url); - -> Input - - `␊ - 1 | import { fileURLToPath as renamed } from "node:url";␊ - 2 | const filename = renamed(import.meta.url);␊ - ` - -> Output - - `␊ - 1 | import { fileURLToPath as renamed } from "node:url";␊ - 2 | const filename = import.meta.filename;␊ - ` - -> Error 1/1 - - `␊ - 1 | import { fileURLToPath as renamed } from "node:url";␊ - > 2 | const filename = renamed(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - ` - -## invalid(16): const path = process.getBuiltinModule("path"); const { fileURLToPath } = process.getBuiltinModule("url"); const filename = fileURLToPath(import.meta.url); const dirname = path.dirname(filename); - -> Input - - `␊ - 1 | const path = process.getBuiltinModule("path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ - 3 | const filename = fileURLToPath(import.meta.url);␊ - 4 | const dirname = path.dirname(filename);␊ - ` - -> Output - - `␊ - 1 | const path = process.getBuiltinModule("path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ - 3 | const filename = import.meta.filename;␊ - 4 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/2 - - `␊ - 1 | const path = process.getBuiltinModule("path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ - > 3 | const filename = fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - 4 | const dirname = path.dirname(filename);␊ - ` - -> Error 2/2 - - `␊ - 1 | const path = process.getBuiltinModule("path");␊ - 2 | const { fileURLToPath } = process.getBuiltinModule("url");␊ - 3 | const filename = fileURLToPath(import.meta.url);␊ - > 4 | const dirname = path.dirname(filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` - -## invalid(17): const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url); const dirname = process.getBuiltinModule("node:path").dirname(filename); - -> Input - - `␊ - 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ - 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ - ` - -> Output - - `␊ - 1 | const filename = import.meta.filename;␊ - 2 | const dirname = import.meta.dirname;␊ - ` - -> Error 1/2 - - `␊ - > 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct filename using \`fileURLToPath()\`.␊ - 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ - ` - -> Error 2/2 - - `␊ - 1 | const filename = process.getBuiltinModule("node:url").fileURLToPath(import.meta.url);␊ - > 2 | const dirname = process.getBuiltinModule("node:path").dirname(filename);␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not construct dirname.␊ - ` diff --git a/test/snapshots/prefer-module.js.snap b/test/snapshots/prefer-module.js.snap index 1c74d78c18ad657f73bb68bdc86561b4278807df..062d9ab1a22e04b56f667d486a538169ff6eedfa 100644 GIT binary patch literal 4060 zcmV<24m)r$D&xH5VrfmSv?$ zSK4+rb03Qc00000000B+U0ZV;M-|rEmBdmJ2𝔰>2moG1|4|k#?okWsL+5zTnu2 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 OH}?PAhV(ylng9T6Y0ZfM literal 5199 zcmV-V6tL?-RzV^ZVU%&$;iuGv6&8t~#@KHon<>#C9ug)jpoB z)Q(!!%3LO&ogy2W4VyIFdS%w#u$9a@wT4r*b5-X^CZF9}Y1FL6M%i&2pL=9(&T_4N zA3Lk>oIdX-b#~u}QuzTw^5i5GGC)XyoE#uzn4Dw<4%k)euwAups4X_#C6W76ABf8A z|6kug5fw_vNpdLqL#}g3&2fqMxpes9G?}Z^?OC^S)XqtD8Q9$6pMhJOM~>JHx8l@D zekeahcH0ZiQJHdip^GZp>UF2?iQ!-?WT$}0*suX1oq~-OdZxoR9l$o6og$@XZMHQ} z$#F;~OHRmvB&T>N4*)1{_O;;zFS(GcVd3yRx`x%AkP&i{oI+vV0brg^2`4P#6MFcs zi9rCVqCLU^q1So6ha(P_tnCr~ko;iRLh`<~K;(G?_Hk=rv1;cQ<{SRU%iAkeyJjue z{)qKp#KqDzQrg*c!?})vk>%wI{vsqk65SlVL9Qp!vy@DeJMQrRjfB`Oz>ajp1Gofi zvGu3GVtYO1dqW~+$u;Z`?j|}co$K}rDtIesv1-lQWQI;VLylG4GMT9?EIM^Jw_v+g zF8EVU;4tK~UETr;a^+vV@6k+Dsb;;J6>7g|x#d9ZOtW6il`2(x&+Z+!IlC;k%*m1P zazk|Y=lM|bmm@;VJRs&eAu*{4bQ}0LVCE}gW`<%E)MU9C3|ww<2J>RkdI&{qQPVWS5uT@$0Z&J>Q>0QN8M+*D4cDr>jlC7OoJkKY)}48K)*WipXNS_+ zEIEM`iJt(>9rZOg5{hy;2e^D?z-2SRA-j_sfIW+mzbkF;*+}deWEyleDa2Df7f^kS zQaxBkIlDIJOU%tTMEsrr{N4!oEt7@W`p9g2D>_~790*K~+vimH{Pmx=X zRovM!ah-rwAposkNlRVvMz=Ov$_6HGC^^msbD#RdV)!%|nGm10)D`>ms%R}1m`E}{ zbFu{U>?YvZ%Nfst!I*!a1O9!I^)DQs5HBxLmx%p*Wwe;cWPIhbS#eCr0xz%i=R<~K zK7JPX_=&*B*yvy{>Uke4qQh0uG&qxCVj#)tGZ`I>dHDt4<)=e0W8>+b-@A?mo|ce# zeKZZDWzDp5n^PR%umUibzXn|XVjo)+b28YHxOctpJKrl1OLb>K#rL5AgmLD0!nY<@ zw;N9Ns05Bl0LLbzOcjX2fT;js2av-Gkud(yLXMI0yk-J-h}aSMlQ1eGcsMs5JYCe_ z>Dz#(f9(^?EaEcZ1JLBtm7+6gijMj;O#_cN0Uj@LaRZTJ%F6_SLF?%J76BTH6mT41 zl9gbhOb6cu$oyS~43-)u6CdRkJ4g}AGYDxVkD~ye4G2D(iR3!~oxfq|$dbxrqNBZf z3LG|CX{UPi=%%3iQ+)uS*KmNO`DijRQm&v3MJasDc%tMur__0>Y{x-GU@PY>0L;q} z7+gvMBU;N4tyQy;;xPj8(8&R=0f-Fqh{Va!{sRztwNEBB;aOT7m`2TE8U`?}=N+n- ztVuT=k(@+sIr_M4p}33*aZw~~vU*P{3f*{^ryp{VRGC|{pi=HVVTLfyfu)td$ub0q zAQUL(ZXgbnZW5O)ptRT21Ok&*DyOri^pm;w0;t{+L8YC}B?~R(vI_B=lr%$3(9X6FvN9j9Lz&BCRh1n=BB#@L;c)8sTgXn#8DA~TFIsM zO4QFVF9s-{D@D;D%}gqg%EcH$IkpOAvZ17pzzXmXW$Lh1*C-xjkHCat;#GOLC>*cE zAm!O)_BgCC!Q-TpdTs+qjpIngsvFJ$$i0o!4N&w7DH~!yHyIB))j6d=5DL}+0P7vW zGBc^tSF6DPD?-VH%(|q(n_!FsPGFsmK+CpmJL)Pz>`ZhFaCaR)FAUA%eQa z!ubHdlo&s=S|Ne>X|KS706nerQg;RFXO|ZN1m7z|&@j17Ac)FE7{WNb3S)9%yq3Zk zIeM|kRLOA$$>Awa)F7F&OIEY$67Sc$H42AY0jS#`s1_licmgLNWa+>7Nl>V72TcR=(ObGRiik8YK2{w{BfiKhj*VYc66T z{%V(02xjbFAm#?FUlk{YX!HOQ*-WU-;dzS{iNA=Yc;g*psJ?yJU^5zv?7M>6Hy*(> zm&=Kmx&bJ734ZR1w$%v_*Y{a^CK(mV&>so^_gRTd|CK-d4hP7h@jg+Ha)^2f$jc%mm zN9spPWNf>UlHQ9M%}2j{!^-e;;e96YdofBun9=h<)MtF7)uPZcA)Y(vcN>g)Ib7A& zZry@6d=d)4%s&W3?DWkSi|9;PEmDiw9_4VpL9a%M{_kO{4m|OIU?HlS*a!q;9y$g@ zSCpM?M51}Z82PT?tMg@`&b=K}Cr(uhlq?Jt0)X=r;K-BX10}~fsQ=2$6tHvo@d&4wkTT$;pH@#s%qX&8+>Cq2-b&cHv?R~i)3Oo^_PC#6$7FVWI=G-yX$a-6K% zFQ6HAibR^wV&gGSu;*Dtxdg`cb~gb*!?~G~vb+^G7ts#~Z#CnfHb^kfTMU2+`Mzjp$|59;|>-UDtp;u~*T$#zTKO~q9Ao>httNmgA_1h;w}-EN z+&fEckm=Tn;pu%fFzLfScyJVk%rhV${3r0q%crxlfvxrllv%OTW?wF%e@W zU6{Q}aiJCKaw_lQU6|3qn3JCePJSwIGCn@)YvAgok0;2}w7=c(Qorj=#y2&aZ9O{l zGC{%P&;oGy)nVIfp$yFL{{VjfbENyVSWIM1_b%UA7^npr{TD_8Fd+TZnBa|RG(>52 zA1-Q3;}Gh-RT2Xq`Y!1xvzzC)`i{sg{fsr5?R=8*t<&zGY7l_tkF(k zjDreNSBjYI%?zbD6u9#MaR0@D6N?n%*Lw@B4fN>#KOUx4{?Ux#{*MmEg56Fq{2G{J zF~fCIE#-zg!KF4T3-JwCCPV+}lvIj3-BCU`W&5@J6CqY^1o~ZukSQ38SqEN+N$o(E z7agrvsHhR82Y6f?^vD9%KEM-=$BYHH=u^AI#^waUqfH8PUBw}bVs+tXM8rGCV}*z; zHzRY{O`Yx7%?IpQ-P92=nEkUr&>p4za`er75R!eE#;*gEGve5VlU+1k|FNx5Lj0Ju z4z!r|C-CL-1_mcHgFwA2pn=S2%)DE`_>V*L*zv~31*a$Ner4eUL)38fGALHtIiI*==e(FM^b%yN&oC^$4;)0CieG}{2I^meE&rcR#VL^`#CvTL?nsm|5y zS{vnWAfm1EmkQ}j=@)i~4v)VVt-4)vmu@436EFR*S$AleB+LsAkYxccNM&IOP#a#^ z0a}I9OByA|X1fcp@P((zg0MU`PIQ(4qx8TAQ*=;XYty!DQg!9gj zV->d?yvmkauw5%h{{~-dgMaLW(zAd zR_k1)?)j5Ux5VW9Uo-M`i(TXU4uIm}K4=)HqrY|OXzFjKZRv|K?m@t~qg_`xs+Ir0 zfnKGZO;_?Qf1T5;*a27K+2$dGpI`yD^r$yysV?H2bYFBw5E5T%7`A<4OfCan+^*;S z7&Bv>#M=ZJ&aF+fp8=x%P)W36Y*XWMCI(Y#(LF0xB!nx#d*6J|?j4zQE%0 zD2OZ6TO8!BL3fRV0&lcW!Z<9nqBlDYSQtcY&Q8`cgm-rVkZ0q9tgiybv?D-?{T)yO z+thHb{Q+?8*Ri=~-~qwmpDCZ{jLk-+c7)8pX}zjmM6~(nz0^(+Em%-Gk?w8)cD3V- z6YJ7z)O!_B@A=MCPvVML9PA1izZSh_%O|omXU?9|tCCwE?MkWq7(nV<;fEiOS#W;79J=dn`1@05111029VHW6N|&P7wM`d6JK4ce5FN{U0SeHfQz=3fXmY4i zn&=1XKLUpSMl)Cg_9Zh}cqn>%-ZyunclSviq?`4sVOUl_eZVOCJ%G#C8C)ca!tjBq zs}qrRl*ah{dBEpm-Pc+_7QY90^v#ZXR3ijyd9(usTD(wv5WHuh=6YnMs|`cwEsc8u z_|Z6{F}u#&9kJ)vkF?JM{yovBF{dE5>ew7R5$e!1724QZil*MPp`T&Yd0FXBer{O zvr=^{HNUA=#0hj;<|BeqfEOpS<|hH_LlRLA@FoEHCHOVfMn(hZW19|W8#7x_x&d2~ zF9SzB)3c6H=M-@=3ht}bPPg^NxHMR%)0a4W34g~)mJp~hRI<-jJ)JN z@G3Uy5$~#{CuFXjnCy$tITaA>_np#BRKp83!~)=#z{$a>Wl~Z9n1Sp0)nNq%XA)u` z8pfJVoSvhFqdsY*?D#JS^5HC>C=kG4svCZ z#K@Xa#3f%d0>2tR<4ro(24-Ytk}jQ))^?FiP+ z#oYZV@M3%a6w~{q { From f9b359f8d2aa5ad1c4fb5fc7ac7c2cde503fd8a1 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Mon, 31 Mar 2025 17:30:16 +0900 Subject: [PATCH 35/38] docs: fix docs --- docs/rules/prefer-import-meta-properties.md | 2 -- docs/rules/prefer-module.md | 8 -------- 2 files changed, 10 deletions(-) diff --git a/docs/rules/prefer-import-meta-properties.md b/docs/rules/prefer-import-meta-properties.md index 632ef96cca..bd55aea7b0 100644 --- a/docs/rules/prefer-import-meta-properties.md +++ b/docs/rules/prefer-import-meta-properties.md @@ -14,8 +14,6 @@ Starting with Node.js 20.11, [`import.meta.dirname`](https://nodejs.org/api/esm. This rule replaces those codes written in the legacy way with `import.meta.{dirname,filename}`. - - ## Examples ```js diff --git a/docs/rules/prefer-module.md b/docs/rules/prefer-module.md index 11409b0412..a90f2b9886 100644 --- a/docs/rules/prefer-module.md +++ b/docs/rules/prefer-module.md @@ -62,14 +62,6 @@ Prefer using the [JavaScript module](https://developer.mozilla.org/en-US/docs/We `export …` should be used in JavaScript modules. -1. Disallows `fileURLToPath(import.meta.url)` and similar operations. - - Starting with Node.js 20.11, [`import.meta.dirname`](https://nodejs.org/api/esm.html#importmetadirname) and [`import.meta.filename`](https://nodejs.org/api/esm.html#importmetafilename) have been introduced in ES modules. - - `fileURLToPath(import.meta.url)` can be replaced by `import.meta.filename`. - - `path.dirname(import.meta.filename)` can be replaced by `import.meta.dirname`. - *`.cjs` files are ignored.* ## Fail From f790666a950f68b218e6109682a52b754f1bc47a Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Mon, 31 Mar 2025 17:36:32 +0900 Subject: [PATCH 36/38] update eslint.dogfooding.config.js --- eslint.dogfooding.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/eslint.dogfooding.config.js b/eslint.dogfooding.config.js index 82caa4c5a0..d25356b52a 100644 --- a/eslint.dogfooding.config.js +++ b/eslint.dogfooding.config.js @@ -45,6 +45,7 @@ const config = [ ], rules: { 'unicorn/prefer-module': 'off', + 'unicorn/prefer-import-meta-properties': 'off', // We can enable this rule when we drop support for Node.js v18. }, }, ]; From 50f05e8d4f897ab95c9a4a5bb41f51d951657def Mon Sep 17 00:00:00 2001 From: fisker Date: Mon, 31 Mar 2025 16:55:47 +0800 Subject: [PATCH 37/38] Minor tweak --- rules/prefer-import-meta-properties.js | 16 +++++++++------- test/prefer-import-meta-properties.js | 9 ++++++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/rules/prefer-import-meta-properties.js b/rules/prefer-import-meta-properties.js index 7d4f91e67e..87ab4bcc1c 100644 --- a/rules/prefer-import-meta-properties.js +++ b/rules/prefer-import-meta-properties.js @@ -6,11 +6,11 @@ import { isMethodCall, } from './ast/index.js'; -const ERROR_CALCULATE_DIRNAME = 'error/calculate-dirname'; -const ERROR_CALCULATE_FILENAME = 'error/calculate-filename'; +const ERROR_DIRNAME = 'error/calculate-dirname'; +const ERROR_FILENAME = 'error/calculate-filename'; const messages = { - [ERROR_CALCULATE_DIRNAME]: 'Do not construct dirname.', - [ERROR_CALCULATE_FILENAME]: 'Do not construct filename using `fileURLToPath()`.', + [ERROR_DIRNAME]: 'Do not construct dirname.', + [ERROR_FILENAME]: 'Do not construct filename using `fileURLToPath()`.', }; const isParentLiteral = node => { @@ -201,8 +201,10 @@ function create(context) { const urlParent = newUrl.parent; // `new URL(import.meta.url)` - if (newUrl.arguments.length === 1 && newUrl.arguments[0] === memberExpression // `url.fileURLToPath(new URL(import.meta.url))` - + if ( + newUrl.arguments.length === 1 + && newUrl.arguments[0] === memberExpression + // `url.fileURLToPath(new URL(import.meta.url))` && isUrlFileURLToPathCall(urlParent, sourceCode) && urlParent.arguments[0] === newUrl ) { @@ -294,7 +296,7 @@ function create(context) { function getProblem(node, name) { return { node, - messageId: name === 'dirname' ? ERROR_CALCULATE_DIRNAME : ERROR_CALCULATE_FILENAME, + messageId: name === 'dirname' ? ERROR_DIRNAME : ERROR_FILENAME, fix: fixer => fixer.replaceText(node, `import.meta.${name}`), }; } diff --git a/test/prefer-import-meta-properties.js b/test/prefer-import-meta-properties.js index 4fe2977401..82311b9348 100644 --- a/test/prefer-import-meta-properties.js +++ b/test/prefer-import-meta-properties.js @@ -14,11 +14,14 @@ test.snapshot({ 'const url = import.meta.url;', 'const dirname = new URL(".", import.meta.url).pathname;', 'const filename = new URL(import.meta.url).pathname;', - 'const filename = fileURLToPath(import.meta.url);', // `fileURLToPath` is not imported - 'const dirname = path.dirname(import.meta.filename);', // `path` is not imported + // `fileURLToPath` is not imported + 'const filename = fileURLToPath(import.meta.url);', + // `path` is not imported + 'const dirname = path.dirname(import.meta.filename);', outdent` import path from "path"; - const not_dirname = path.dirname(new URL(import.meta.url).pathname); // It is the same as dirname on macOS but returns different results on Windows. + // It is the same as dirname on macOS but returns different results on Windows. + const notDirname = path.dirname(new URL(import.meta.url).pathname); `, outdent` // path is not initialized From 701d27d1e31b31c13e0ac6fa9df6b781ef3c1e7c Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 31 Mar 2025 17:08:24 +0700 Subject: [PATCH 38/38] Update prefer-import-meta-properties.md --- docs/rules/prefer-import-meta-properties.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/rules/prefer-import-meta-properties.md b/docs/rules/prefer-import-meta-properties.md index bd55aea7b0..01f6e44647 100644 --- a/docs/rules/prefer-import-meta-properties.md +++ b/docs/rules/prefer-import-meta-properties.md @@ -12,13 +12,13 @@ Starting with Node.js 20.11, [`import.meta.dirname`](https://nodejs.org/api/esm. > `import.meta.filename` is the same as the `url.fileURLToPath()` of the `import.meta.url`.\ > `import.meta.dirname` is the same as the `path.dirname()` of the `import.meta.filename`. -This rule replaces those codes written in the legacy way with `import.meta.{dirname,filename}`. +This rule replaces legacy patterns with `import.meta.{dirname,filename}`. ## Examples ```js -import path from "node:path"; -import { fileURLToPath } from "node:url"; +import path from 'node:path'; +import {fileURLToPath} from "node:url"; // ❌ const filename = fileURLToPath(import.meta.url); @@ -28,13 +28,13 @@ const filename = import.meta.filename; ``` ```js -import path from "node:path"; -import { fileURLToPath } from "node:url"; +import path from 'node:path'; +import {fileURLToPath} from 'node:url'; // ❌ const dirname = path.dirname(fileURLToPath(import.meta.url)); const dirname = path.dirname(import.meta.filename); -const dirname = fileURLToPath(new URL(".", import.meta.url)); +const dirname = fileURLToPath(new URL('.', import.meta.url)); // ✅ const dirname = import.meta.dirname;