diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 90da943b887c..5030ca291751 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -135,6 +135,7 @@ Then you should add `airbnb` (or `airbnb-base`) to your `extends` section of `.e | [`@typescript-eslint/no-non-null-assertion`](./docs/rules/no-non-null-assertion.md) | Disallows non-null assertions using the `!` postfix operator (`no-non-null-assertion` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-object-literal-type-assertion`](./docs/rules/no-object-literal-type-assertion.md) | Forbids an object literal to appear in a type assertion expression (`no-object-literal-type-assertion` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-parameter-properties`](./docs/rules/no-parameter-properties.md) | Disallow the use of parameter properties in class constructors. (`no-parameter-properties` from TSLint) | :heavy_check_mark: | | +| [`@typescript-eslint/no-require-imports`](./docs/rules/no-require-imports.md) | Disallows invocation of `require()` (`no-require-imports` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-this-alias`](./docs/rules/no-this-alias.md) | Disallow aliasing `this` (`no-this-assignment` from TSLint) | | | | [`@typescript-eslint/no-triple-slash-reference`](./docs/rules/no-triple-slash-reference.md) | Disallow `/// ` comments (`no-reference` from TSLint) | :heavy_check_mark: | | | [`@typescript-eslint/no-type-alias`](./docs/rules/no-type-alias.md) | Disallow the use of type aliases (`interface-over-type-literal` from TSLint) | | | diff --git a/packages/eslint-plugin/ROADMAP.md b/packages/eslint-plugin/ROADMAP.md index 444700439669..86f0224f0af5 100644 --- a/packages/eslint-plugin/ROADMAP.md +++ b/packages/eslint-plugin/ROADMAP.md @@ -114,7 +114,7 @@ | [`no-default-export`] | 🔌 | [`import/no-default-export`] | | [`no-duplicate-imports`] | 🔌 | [`import/no-duplicates`] | | [`no-mergeable-namespace`] | 🛑 | N/A | -| [`no-require-imports`] | 🛑 | N/A | +| [`no-require-imports`] | ✅ | [`@typescript-eslint/no-require-imports`] | | [`object-literal-sort-keys`] | 🌓 | [`sort-keys`][sort-keys] [2] | | [`prefer-const`] | 🌟 | [`prefer-const`][prefer-const] | | [`prefer-readonly`] | 🛑 | N/A | @@ -578,6 +578,7 @@ Relevant plugins: [`chai-expect-keywords`](https://github.com/gavinaiken/eslint- [`@typescript-eslint/no-use-before-define`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md [`@typescript-eslint/restrict-plus-operands`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/restrict-plus-operands.md [`@typescript-eslint/indent`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/indent.md +[`@typescript-eslint/no-require-imports`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-require-imports.md [`@typescript-eslint/array-type`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/array-type.md [`@typescript-eslint/class-name-casing`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/class-name-casing.md [`@typescript-eslint/interface-name-prefix`]: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/interface-name-prefix.md diff --git a/packages/eslint-plugin/docs/rules/no-require-imports.md b/packages/eslint-plugin/docs/rules/no-require-imports.md new file mode 100644 index 000000000000..0d2b831a1acd --- /dev/null +++ b/packages/eslint-plugin/docs/rules/no-require-imports.md @@ -0,0 +1,34 @@ +# Disallows invocation of `require()` (no-require-imports) + +Prefer the newer ES6-style imports over `require()`. + +## Rule Details + +Examples of **incorrect** code for this rule: + +```ts +var lib = require('lib'); +let lib2 = require('lib2'); +var lib5 = require('lib5'), + lib6 = require('lib6'); +import lib8 = require('lib8'); +``` + +Examples of **correct** code for this rule: + +```ts +import { l } from 'lib'; +var lib3 = load('not_an_import'); +var lib4 = lib2.subImport; +var lib7 = 700; +import lib9 = lib2.anotherSubImport; +import lib10 from 'lib10'; +``` + +## When Not To Use It + +If you don't care about TypeScript module syntax, then you will not need this rule. + +## Compatibility + +- TSLint: [no-require-imports](https://palantir.github.io/tslint/rules/no-require-imports/) diff --git a/packages/eslint-plugin/lib/rules/no-require-imports.js b/packages/eslint-plugin/lib/rules/no-require-imports.js new file mode 100644 index 000000000000..82537a4dcdaa --- /dev/null +++ b/packages/eslint-plugin/lib/rules/no-require-imports.js @@ -0,0 +1,50 @@ +/** + * @fileoverview Disallows invocation of `require()`. + * @author Kanitkorn Sujautra + */ +'use strict'; + +const util = require('../util'); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'Disallows invocation of `require()`.', + extraDescription: [util.tslintRule('no-require-imports')], + category: 'TypeScript', + url: util.metaDocsUrl('no-require-imports'), + recommended: 'error' + }, + schema: [], + messages: { + noRequireImports: 'A `require()` style import is forbidden.' + } + }, + create(context) { + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + CallExpression(node) { + if (node.callee.name === 'require') { + context.report({ + node, + messageId: 'noRequireImports' + }); + } + }, + TSExternalModuleReference(node) { + context.report({ + node, + messageId: 'noRequireImports' + }); + } + }; + } +}; diff --git a/packages/eslint-plugin/tests/lib/rules/no-require-imports.js b/packages/eslint-plugin/tests/lib/rules/no-require-imports.js new file mode 100644 index 000000000000..1eb40a59c34e --- /dev/null +++ b/packages/eslint-plugin/tests/lib/rules/no-require-imports.js @@ -0,0 +1,81 @@ +/** + * @fileoverview Disallows invocation of `require()`. + * @author Kanitkorn Sujautra + */ +'use strict'; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const rule = require('../../../lib/rules/no-require-imports'), + RuleTester = require('eslint').RuleTester; + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ + parserOptions: { + sourceType: 'module' + }, + parser: '@typescript-eslint/parser' +}); + +ruleTester.run('no-require-imports', rule, { + valid: [ + "import {l} from 'lib'", + "var lib3 = load('not_an_import')", + 'var lib4 = lib2.subImport', + 'var lib7 = 700', + 'import lib9 = lib2.anotherSubImport', + "import lib10 from 'lib10'" + ], + invalid: [ + { + code: "var lib = require('lib')", + errors: [ + { + message: 'A `require()` style import is forbidden.', + line: 1, + column: 11 + } + ] + }, + { + code: "let lib2 = require('lib2')", + errors: [ + { + message: 'A `require()` style import is forbidden.', + line: 1, + column: 12 + } + ] + }, + { + code: "var lib5 = require('lib5'), lib6 = require('lib6')", + errors: [ + { + message: 'A `require()` style import is forbidden.', + line: 1, + column: 12 + }, + { + message: 'A `require()` style import is forbidden.', + line: 1, + column: 36 + } + ] + }, + { + code: "import lib8 = require('lib8')", + errors: [ + { + message: 'A `require()` style import is forbidden.', + line: 1, + column: 15 + } + ] + } + ] +});