diff --git a/CHANGELOG.md b/CHANGELOG.md index e6081ff69f..5a91bfbe79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - [`no-named-as-default-member`] to `warnings` canned config - add [`no-extraneous-dependencies`] rule ([#241], thanks [@jfmengels]) - add [`extensions`] rule ([#250], thanks [@lo1tuma]) +- add [`no-nodejs-modules`] rule ([#158], thanks [@jfmengels]) - consider `resolve.fallback` config option in the webpack resolver ([#254]) ### Changed @@ -152,6 +153,7 @@ for info on changes for earlier releases. [`no-extraneous-dependencies`]: ./docs/rules/no-extraneous-dependencies.md [`extensions`]: ./docs/rules/extensions.md [`imports-first`]: ./docs/rules/imports-first.md +[`no-nodejs-modules`]: ./docs/rules/no-nodejs-modules.md [#256]: https://github.com/benmosher/eslint-plugin-import/pull/256 [#254]: https://github.com/benmosher/eslint-plugin-import/pull/254 diff --git a/README.md b/README.md index 8a654dbf00..d7deb38fed 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,11 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a * Report CommonJS `require` calls and `module.exports` or `exports.*`. ([`no-commonjs`]) * Report AMD `require` and `define` calls. ([`no-amd`]) +* No Node.js builtin modules. ([`no-nodejs-modules`]) [`no-commonjs`]: ./docs/rules/no-commonjs.md [`no-amd`]: ./docs/rules/no-amd.md +[`no-nodejs-modules`]: ./docs/rules/no-nodejs-modules.md **Style guide:** diff --git a/docs/rules/no-nodejs-modules.md b/docs/rules/no-nodejs-modules.md new file mode 100644 index 0000000000..df3c27e4e5 --- /dev/null +++ b/docs/rules/no-nodejs-modules.md @@ -0,0 +1,31 @@ +# No Node.js builtin modules + +Forbid the use of Node.js builtin modules. Can be useful for client-side web projects that do not have access to those modules. + +## Rule Details + +### Fail + +```js +import fs from 'fs'; +import path from 'path'; + +var fs = require('fs'); +var path = require('path'); +``` + +### Pass + +```js +import _ from 'lodash'; +import foo from 'foo'; +import foo from './foo'; + +var _ = require('lodash'); +var foo = require('foo'); +var foo = require('./foo'); +``` + +## When Not To Use It + +If you have a project that is run mainly or partially using Node.js. diff --git a/src/index.js b/src/index.js index f968fa2f5a..733363811d 100644 --- a/src/index.js +++ b/src/index.js @@ -15,6 +15,7 @@ export const rules = { 'no-duplicates': require('./rules/no-duplicates'), 'imports-first': require('./rules/imports-first'), 'no-extraneous-dependencies': require('./rules/no-extraneous-dependencies'), + 'no-nodejs-modules': require('./rules/no-nodejs-modules'), // metadata-based 'no-deprecated': require('./rules/no-deprecated'), diff --git a/src/rules/no-nodejs-modules.js b/src/rules/no-nodejs-modules.js new file mode 100644 index 0000000000..4474182381 --- /dev/null +++ b/src/rules/no-nodejs-modules.js @@ -0,0 +1,21 @@ +import importType from '../core/importType' +import isStaticRequire from '../core/staticRequire' + +function reportIfMissing(context, node, name) { + if (importType(name, context) === 'builtin') { + context.report(node, 'Do not import Node.js builtin modules') + } +} + +module.exports = function (context) { + return { + ImportDeclaration: function handleImports(node) { + reportIfMissing(context, node, node.source.value) + }, + CallExpression: function handleRequires(node) { + if (isStaticRequire(node)) { + reportIfMissing(context, node, node.arguments[0].value) + } + }, + } +} diff --git a/tests/src/rules/no-nodejs-modules.js b/tests/src/rules/no-nodejs-modules.js new file mode 100644 index 0000000000..51ae9b99db --- /dev/null +++ b/tests/src/rules/no-nodejs-modules.js @@ -0,0 +1,48 @@ +import { test } from '../utils' + +import { RuleTester } from 'eslint' + +const ruleTester = new RuleTester() + , rule = require('rules/no-nodejs-modules') + +const errors = [{ + ruleId: 'no-nodejs-modules', + message: 'Do not import Node.js builtin modules', +}] + +ruleTester.run('no-nodejs-modules', rule, { + valid: [ + test({ code: 'import _ from "lodash"'}), + test({ code: 'import find from "lodash.find"'}), + test({ code: 'import foo from "./foo"'}), + test({ code: 'import foo from "../foo"'}), + test({ code: 'import foo from "foo"'}), + test({ code: 'import foo from "./"'}), + test({ code: 'import foo from "@scope/foo"'}), + test({ code: 'var _ = require("lodash")'}), + test({ code: 'var find = require("lodash.find")'}), + test({ code: 'var foo = require("./foo")'}), + test({ code: 'var foo = require("../foo")'}), + test({ code: 'var foo = require("foo")'}), + test({ code: 'var foo = require("./")'}), + test({ code: 'var foo = require("@scope/foo")'}), + ], + invalid: [ + test({ + code: 'import path from "path"', + errors, + }), + test({ + code: 'import fs from "fs"', + errors, + }), + test({ + code: 'var path = require("path")', + errors, + }), + test({ + code: 'var fs = require("fs")', + errors, + }), + ], +})