Skip to content

Commit 42d81ae

Browse files
committed
Rename require-extension to jsx-require-extension
This rule is JSX-specific, not React-specific. Changing its name makes this clearer. I've kept the old one around as deprecated. We can remove it at the next major version bump. Addresses jsx-eslint#668 and jsx-eslint#686.
1 parent 2ed6995 commit 42d81ae

File tree

6 files changed

+110
-66
lines changed

6 files changed

+110
-66
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ Finally, enable all of the rules that you would like to use. Use [our preset](#
9696
* [react/prefer-stateless-function](docs/rules/prefer-stateless-function.md): Enforce stateless React Components to be written as a pure function
9797
* [react/prop-types](docs/rules/prop-types.md): Prevent missing props validation in a React component definition
9898
* [react/react-in-jsx-scope](docs/rules/react-in-jsx-scope.md): Prevent missing `React` when using JSX
99-
* [react/require-extension](docs/rules/require-extension.md): Restrict file extensions that may be required
10099
* [react/require-optimization](docs/rules/require-optimization.md): Enforce React components to have a shouldComponentUpdate method
101100
* [react/require-render-return](docs/rules/require-render-return.md): Enforce ES5 or ES6 class for returning value in render function
102101
* [react/self-closing-comp](docs/rules/self-closing-comp.md): Prevent extra closing tags for components without children
@@ -124,6 +123,7 @@ Finally, enable all of the rules that you would like to use. Use [our preset](#
124123
* [react/jsx-no-target-blank](docs/rules/jsx-no-target-blank.md): Prevent usage of unsafe `target='_blank'`
125124
* [react/jsx-no-undef](docs/rules/jsx-no-undef.md): Disallow undeclared variables in JSX
126125
* [react/jsx-pascal-case](docs/rules/jsx-pascal-case.md): Enforce PascalCase for user-defined JSX components
126+
* [react/jsx-require-extension](docs/rules/jsx-require-extension.md): Restrict file extensions that may be required
127127
* [react/jsx-sort-props](docs/rules/jsx-sort-props.md): Enforce props alphabetical sorting
128128
* [react/jsx-space-before-closing](docs/rules/jsx-space-before-closing.md): Validate spacing before closing bracket in JSX (fixable)
129129
* [react/jsx-uses-react](docs/rules/jsx-uses-react.md): Prevent React to be incorrectly marked as unused

docs/rules/require-extension.md renamed to docs/rules/jsx-require-extension.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Restrict file extensions that may be required (require-extension)
1+
# Restrict file extensions that may be required (jsx-require-extension)
22

33
`require()` statements should generally not include a file extension as there is a well defined mechanism for resolving a module ID to a specific file. This rule inspects the module ID being required and creates a warning if the ID contains a '.jsx' file extension.
44

@@ -29,7 +29,7 @@ The set of forbidden extensions is configurable. By default '.jsx' is blocked. I
2929

3030
```js
3131
"rules": {
32-
"react/require-extension": [1, { "extensions": [".js", ".jsx"] }],
32+
"react/jsx-require-extension": [1, { "extensions": [".js", ".jsx"] }],
3333
}
3434
```
3535

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ module.exports = {
3232
'jsx-boolean-value': require('./lib/rules/jsx-boolean-value'),
3333
'sort-comp': require('./lib/rules/sort-comp'),
3434
'require-extension': require('./lib/rules/require-extension'),
35+
'jsx-require-extension': require('./lib/rules/jsx-require-extension'),
3536
'jsx-no-duplicate-props': require('./lib/rules/jsx-no-duplicate-props'),
3637
'jsx-max-props-per-line': require('./lib/rules/jsx-max-props-per-line'),
3738
'jsx-no-literals': require('./lib/rules/jsx-no-literals'),

lib/rules/jsx-require-extension.js

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* @fileoverview Restrict file extensions that may be required
3+
* @author Scott Andrews
4+
*/
5+
'use strict';
6+
7+
var path = require('path');
8+
9+
// ------------------------------------------------------------------------------
10+
// Constants
11+
// ------------------------------------------------------------------------------
12+
13+
var DEFAULTS = {
14+
extensions: ['.jsx']
15+
};
16+
17+
var PKG_REGEX = /^[^\.]((?!\/).)*$/;
18+
19+
// ------------------------------------------------------------------------------
20+
// Rule Definition
21+
// ------------------------------------------------------------------------------
22+
23+
module.exports = function(context) {
24+
25+
function isPackage(id) {
26+
return PKG_REGEX.test(id);
27+
}
28+
29+
function isRequire(expression) {
30+
return expression.callee.name === 'require';
31+
}
32+
33+
function getId(expression) {
34+
return expression.arguments[0] && expression.arguments[0].value;
35+
}
36+
37+
function getExtension(id) {
38+
return path.extname(id || '');
39+
}
40+
41+
function getExtensionsConfig() {
42+
return context.options[0] && context.options[0].extensions || DEFAULTS.extensions;
43+
}
44+
45+
var forbiddenExtensions = getExtensionsConfig().reduce(function (extensions, extension) {
46+
extensions[extension] = true;
47+
return extensions;
48+
}, Object.create(null));
49+
50+
function isForbiddenExtension(ext) {
51+
return ext in forbiddenExtensions;
52+
}
53+
54+
// --------------------------------------------------------------------------
55+
// Public
56+
// --------------------------------------------------------------------------
57+
58+
return {
59+
60+
CallExpression: function(node) {
61+
if (isRequire(node)) {
62+
var id = getId(node);
63+
var ext = getExtension(id);
64+
if (!isPackage(id) && isForbiddenExtension(ext)) {
65+
context.report({
66+
node: node,
67+
message: 'Unable to require module with extension \'' + ext + '\''
68+
});
69+
}
70+
}
71+
}
72+
73+
};
74+
75+
};
76+
77+
module.exports.schema = [{
78+
type: 'object',
79+
properties: {
80+
extensions: {
81+
type: 'array',
82+
items: {
83+
type: 'string'
84+
}
85+
}
86+
},
87+
additionalProperties: false
88+
}];

lib/rules/require-extension.js

+16-61
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,32 @@
11
/**
22
* @fileoverview Restrict file extensions that may be required
33
* @author Scott Andrews
4+
* @deprecated
45
*/
56
'use strict';
67

7-
var path = require('path');
8-
9-
// ------------------------------------------------------------------------------
10-
// Constants
11-
// ------------------------------------------------------------------------------
12-
13-
var DEFAULTS = {
14-
extensions: ['.jsx']
15-
};
16-
17-
var PKG_REGEX = /^[^\.]((?!\/).)*$/;
18-
198
// ------------------------------------------------------------------------------
209
// Rule Definition
2110
// ------------------------------------------------------------------------------
2211

23-
module.exports = function(context) {
24-
25-
function isPackage(id) {
26-
return PKG_REGEX.test(id);
27-
}
28-
29-
function isRequire(expression) {
30-
return expression.callee.name === 'require';
31-
}
32-
33-
function getId(expression) {
34-
return expression.arguments[0] && expression.arguments[0].value;
35-
}
12+
var util = require('util');
13+
var jsxRequireExtension = require('./jsx-require-extension');
14+
var isWarnedForDeprecation = false;
3615

37-
function getExtension(id) {
38-
return path.extname(id || '');
39-
}
40-
41-
function getExtensionsConfig() {
42-
return context.options[0] && context.options[0].extensions || DEFAULTS.extensions;
43-
}
44-
45-
var forbiddenExtensions = getExtensionsConfig().reduce(function (extensions, extension) {
46-
extensions[extension] = true;
47-
return extensions;
48-
}, Object.create(null));
49-
50-
function isForbiddenExtension(ext) {
51-
return ext in forbiddenExtensions;
52-
}
53-
54-
// --------------------------------------------------------------------------
55-
// Public
56-
// --------------------------------------------------------------------------
57-
58-
return {
59-
60-
CallExpression: function(node) {
61-
if (isRequire(node)) {
62-
var id = getId(node);
63-
var ext = getExtension(id);
64-
if (!isPackage(id) && isForbiddenExtension(ext)) {
65-
context.report({
66-
node: node,
67-
message: 'Unable to require module with extension \'' + ext + '\''
68-
});
69-
}
16+
module.exports = function(context) {
17+
return util._extend(jsxRequireExtension(context), {
18+
Program: function() {
19+
if (isWarnedForDeprecation || /\=-(f|-format)=/.test(process.argv.join('='))) {
20+
return;
7021
}
71-
}
72-
73-
};
7422

23+
/* eslint-disable no-console */
24+
console.log('The react/require-extension rule is deprecated. Please ' +
25+
'use the react/jsx-require-extension rule instead.');
26+
/* eslint-enable no-console */
27+
isWarnedForDeprecation = true;
28+
}
29+
});
7530
};
7631

7732
module.exports.schema = [{

tests/lib/rules/require-extension.js renamed to tests/lib/rules/jsx-require-extension.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// Requirements
99
// ------------------------------------------------------------------------------
1010

11-
var rule = require('../../../lib/rules/require-extension');
11+
var rule = require('../../../lib/rules/jsx-require-extension');
1212
var RuleTester = require('eslint').RuleTester;
1313

1414
// ------------------------------------------------------------------------------
@@ -34,7 +34,7 @@ var REQUIRE_OBJECT = 'require({})';
3434
// ------------------------------------------------------------------------------
3535

3636
var ruleTester = new RuleTester();
37-
ruleTester.run('require-extension', rule, {
37+
ruleTester.run('jsx-require-extension', rule, {
3838

3939
valid: [
4040
{

0 commit comments

Comments
 (0)