From 2c914d47651e5d13b925eaf1f35799fa510c9fcf Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 26 May 2022 12:43:07 +0800 Subject: [PATCH] `prefer-node-protocol`: Always check `require()` (#1827) --- docs/rules/prefer-node-protocol.md | 20 ++---- package.json | 2 +- rules/filename-case.js | 2 +- rules/prefer-node-protocol.js | 65 ++++++------------ rules/prevent-abbreviations.js | 2 +- rules/utils/get-documentation-url.js | 2 +- rules/utils/rule.js | 4 +- .../prefer-disallow-over-forbid.js | 2 +- .../prefer-negative-boolean-attribute.js | 2 +- test/prefer-node-protocol.mjs | 8 +-- test/snapshots/prefer-node-protocol.mjs.md | 20 ------ test/snapshots/prefer-node-protocol.mjs.snap | Bin 1061 -> 1026 bytes 12 files changed, 38 insertions(+), 91 deletions(-) diff --git a/docs/rules/prefer-node-protocol.md b/docs/rules/prefer-node-protocol.md index 6cfd07107a..ab4a507d77 100644 --- a/docs/rules/prefer-node-protocol.md +++ b/docs/rules/prefer-node-protocol.md @@ -25,6 +25,10 @@ export {strict as default} from 'assert'; import fs from 'fs/promises'; ``` +```js +const fs = require('fs/promises'); +``` + ## Pass ```js @@ -51,20 +55,6 @@ import _ from 'lodash'; import fs from './fs.js'; ``` -## Options - -Type: `object` - -### `checkRequire` - -Type: `boolean`\ -Default: `false` - -Currently, `require(…)` with the `node:` protocol is only available on Node.js 16. If you don't care about old versions, you can set this to `true`. - -We'll remove this option and check `require(…)` by default once this feature get backported to v12. - ```js -// eslint unicorn/prefer-node-protocol: ["error", {"checkRequire": true}] -const fs = require('fs'); // Fails +const fs = require('node:fs/promises'); ``` diff --git a/package.json b/package.json index a97a1ca8bc..30004828cd 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "url": "https://sindresorhus.com" }, "engines": { - "node": ">=14" + "node": ">=14.18" }, "scripts": { "create-rule": "node ./scripts/create-rule.mjs && npm run generate-rule-notices && npm run generate-rules-table", diff --git a/rules/filename-case.js b/rules/filename-case.js index cb921d36a0..5a00467807 100644 --- a/rules/filename-case.js +++ b/rules/filename-case.js @@ -1,5 +1,5 @@ 'use strict'; -const path = require('path'); +const path = require('node:path'); const {camelCase, kebabCase, snakeCase, upperFirst} = require('lodash'); const cartesianProductSamples = require('./utils/cartesian-product-samples.js'); diff --git a/rules/prefer-node-protocol.js b/rules/prefer-node-protocol.js index 5533c41bee..55a44a35cd 100644 --- a/rules/prefer-node-protocol.js +++ b/rules/prefer-node-protocol.js @@ -14,51 +14,31 @@ const importExportSourceSelector = [ 'Literal.source', ].join(''); -/** @param {import('eslint').Rule.RuleContext} context */ -const create = context => { - const {checkRequire} = { - checkRequire: false, - ...context.options[0], - }; - const selectors = [importExportSourceSelector]; - if (checkRequire) { - selectors.push(STATIC_REQUIRE_SOURCE_SELECTOR); - } +const selector = matches([ + importExportSourceSelector, + STATIC_REQUIRE_SOURCE_SELECTOR, +]); - return { - [matches(selectors)](node) { - const {value} = node; - if ( - typeof value !== 'string' - || value.startsWith('node:') - || !isBuiltinModule(value) - ) { - return; - } +const create = () => ({ + [selector](node) { + const {value} = node; + if ( + typeof value !== 'string' + || value.startsWith('node:') + || !isBuiltinModule(value) + ) { + return; + } - return { - node, - messageId: MESSAGE_ID, - data: {moduleName: value}, - /** @param {import('eslint').Rule.RuleFixer} fixer */ - fix: fixer => replaceStringLiteral(fixer, node, 'node:', 0, 0), - }; - }, - }; -}; - -const schema = [ - { - type: 'object', - additionalProperties: false, - properties: { - checkRequire: { - type: 'boolean', - default: false, - }, - }, + return { + node, + messageId: MESSAGE_ID, + data: {moduleName: value}, + /** @param {import('eslint').Rule.RuleFixer} fixer */ + fix: fixer => replaceStringLiteral(fixer, node, 'node:', 0, 0), + }; }, -]; +}); /** @type {import('eslint').Rule.RuleModule} */ module.exports = { @@ -69,7 +49,6 @@ module.exports = { description: 'Prefer using the `node:` protocol when importing Node.js builtin modules.', }, fixable: 'code', - schema, messages, }, }; diff --git a/rules/prevent-abbreviations.js b/rules/prevent-abbreviations.js index f51c5741a7..e4bf84315d 100644 --- a/rules/prevent-abbreviations.js +++ b/rules/prevent-abbreviations.js @@ -1,5 +1,5 @@ 'use strict'; -const path = require('path'); +const path = require('node:path'); const {defaultsDeep, upperFirst, lowerFirst} = require('lodash'); const avoidCapture = require('./utils/avoid-capture.js'); diff --git a/rules/utils/get-documentation-url.js b/rules/utils/get-documentation-url.js index 92d8d73787..3128369df3 100644 --- a/rules/utils/get-documentation-url.js +++ b/rules/utils/get-documentation-url.js @@ -1,5 +1,5 @@ 'use strict'; -const path = require('path'); +const path = require('node:path'); const packageJson = require('../../package.json'); const repoUrl = 'https://github.com/sindresorhus/eslint-plugin-unicorn'; diff --git a/rules/utils/rule.js b/rules/utils/rule.js index d4dcab1624..d23e010178 100644 --- a/rules/utils/rule.js +++ b/rules/utils/rule.js @@ -1,6 +1,6 @@ 'use strict'; -const path = require('path'); -const fs = require('fs'); +const path = require('node:path'); +const fs = require('node:fs'); const getDocumentationUrl = require('./get-documentation-url.js'); const isIterable = object => typeof object[Symbol.iterator] === 'function'; diff --git a/scripts/internal-rules/prefer-disallow-over-forbid.js b/scripts/internal-rules/prefer-disallow-over-forbid.js index 1c20abec73..605ba047cc 100644 --- a/scripts/internal-rules/prefer-disallow-over-forbid.js +++ b/scripts/internal-rules/prefer-disallow-over-forbid.js @@ -1,5 +1,5 @@ 'use strict'; -const path = require('path'); +const path = require('node:path'); const {matches} = require('../../rules/selectors/index.js'); const toLocation = require('../../rules/utils/to-location.js'); diff --git a/scripts/internal-rules/prefer-negative-boolean-attribute.js b/scripts/internal-rules/prefer-negative-boolean-attribute.js index a448a3d648..59e77629ec 100644 --- a/scripts/internal-rules/prefer-negative-boolean-attribute.js +++ b/scripts/internal-rules/prefer-negative-boolean-attribute.js @@ -1,5 +1,5 @@ 'use strict'; -const path = require('path'); +const path = require('node:path'); const messageId = path.basename(__filename, '.js'); diff --git a/test/prefer-node-protocol.mjs b/test/prefer-node-protocol.mjs index 5db6d91c88..23ade4b65f 100644 --- a/test/prefer-node-protocol.mjs +++ b/test/prefer-node-protocol.mjs @@ -8,7 +8,6 @@ test.snapshot({ 'import unicorn from "unicorn";', 'import fs from "./fs";', 'import fs from "unknown-builtin-module";', - 'const fs = require("fs");', 'import fs from "node:fs";', outdent` async function foo() { @@ -60,8 +59,7 @@ test.snapshot({ ], }); -// `options` -const checkRequireOptions = [{checkRequire: true}]; +// `require` test.snapshot({ valid: [ 'const fs = require("node:fs");', @@ -76,11 +74,11 @@ test.snapshot({ 'const fs = require();', 'const fs = require(...["fs"]);', 'const fs = require("unicorn");', - ].map(code => ({code, options: checkRequireOptions})), + ], invalid: [ 'const {promises} = require("fs")', 'const fs = require(\'fs/promises\')', - ].map(code => ({code, options: checkRequireOptions})), + ], }); test.babel({ diff --git a/test/snapshots/prefer-node-protocol.mjs.md b/test/snapshots/prefer-node-protocol.mjs.md index 02e7970087..fba55b82e2 100644 --- a/test/snapshots/prefer-node-protocol.mjs.md +++ b/test/snapshots/prefer-node-protocol.mjs.md @@ -255,16 +255,6 @@ Generated by [AVA](https://avajs.dev). ## Invalid #1 1 | const {promises} = require("fs") -> Options - - `␊ - [␊ - {␊ - "checkRequire": true␊ - }␊ - ]␊ - ` - > Output `␊ @@ -281,16 +271,6 @@ Generated by [AVA](https://avajs.dev). ## Invalid #2 1 | const fs = require('fs/promises') -> Options - - `␊ - [␊ - {␊ - "checkRequire": true␊ - }␊ - ]␊ - ` - > Output `␊ diff --git a/test/snapshots/prefer-node-protocol.mjs.snap b/test/snapshots/prefer-node-protocol.mjs.snap index e1b10a97b6e210c93d39129d432f4ad4f762c410..e69b401f8093a8e8c90777da281b83247127ae39 100644 GIT binary patch delta 763 zcmV+UAd#JIHFESgqaB}YQPM^!Ym97wGrtDB42oD zYbH#Tahm1X#sn6vhGHvL28M3`zg{{{2E~s+D*jyzxpJ}F^GvV9np>tje{L~>MOD}#coh)OdJ>epl}#Zl z=i>Y&t!V|^OkmN6P#nm?z_9DtiYwJSGd|gK?fAj-@r@!AShN+2IXM{^F4)|e-WoW^ zF}+!Is0yA*+zS$eMr=00*gL@;uszVhCi)rvHz8( zR&P7qJy}}i*ajxBXg3tU24ZFgc5sSdliLB8e?6!(lk@Y6!I5UGP?TC&npu>pp^hE_ z>YAu}>!5DMrWaKkP6tyh=5wI_NGz_*OIAoL%}XxH%+FIu%g@))RHz0@8UZCakzATs zo|stz4Q35}ErrzLT4`Q&9!c$_f*xYf~#AWo$}nT4HHV2{2q0h%BWmpspvv1i}S2DWOkF z6$4LDq*XEMU>$f}Oqw&*uqBR?%-qx>q8k%Rn9A`b5Omj}>4rHKT^P;XhS-xyEphE$ zA*L1v?1`k7_;wK$3Mwj=<5=1Qv?<5cG3=mkIj)Ho@gz3gaA~7<(@htp>4sz-q8SEv tDq71e3#H|TT`O1@UgwhTWJUaa3j%F)q%H-%o&;X!005QvJV!m?nZTkc%nUU3fkkIQu^2m0#lMRoS1xvYp6PX1e{;)p$1NtXXap4B1L9dvf|9qg zDP-kboWG>eEGo(Y!L2~N>)DDc)jKmj*>mmq!SnHrA`@72CluRqGB8}Qxih^r zaE`~D88Y|OQ?e78z@jx!%+JNZaOcA<6_($I=VGqxKD2*!LMRhhv>b}fxEUBeSUmRV z*O%T^P3CLAulDBac}!r@TqwQ^#2=Fm-&&iq?`D>5v`5;9L|taEs2~pn`#|v#ApXib_*~617~hsCx9EUQ5o;D+WijtwIq*lZHBaq^WD7>aBzN51U?8Z8$wi zwbYUW^+#fHWnQvET4`Q#NoIbYLRx;lh9)>jjDV7yNG?q*Ps}WVMvaEPmO^TAa$-Sh zih`CtBsw%>N~_JxYLU{rCMd3qfu_`=*vxc=0l(FDq*#sJR#4z^;z}d9!;_pq#pXrE zD2f6Xv$VmJ0Rto%9IQT9!B$o$XJqE2!~+8@Ikgz0Y|KL|vXedo7k}k)N@`kSX-)|+ zTos5c*(;!~C&C26g*+*tPfE1}Pf(;)OX^@9cwJ0twS*;clw{_n77^V5QNmP?FM*)D z4ox@Asp!IJ?l#1pOlpa1Lou~5U{55q#J8oWP*72^9LLfgpiMchj$sFV%W+M#h$peR zhfCXFXzuBvH2094h%IQk!M%sp+RH*|?P1pn)`i!Lqjxx>4*&p2%5U!g