-
Notifications
You must be signed in to change notification settings - Fork 24.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[lint] Add a lint rule to disallow Haste imports
This is an ESLint plugin that infers whether an import looks like a Haste module name. To keep the linter fast and simple, it does not look in the Haste map. Instead, it looks for uppercase characters in single-name import paths, since npm has disallowed uppercase letters in package names for a long time. There are some false negatives (e.g. "merge" is a Haste module and this linter rule would not pick it up) but those are about 1.1% of the module names in the RN repo, and unit tests and integration tests will fail anyway once Haste is turned off. Test Plan: Run `yarn lint` as a sanity check. Modify an import statement to use a Haste module name and verify the linter reports an error. Do the same with a require call.
- Loading branch information
Showing
8 changed files
with
108 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# eslint-plugin-react-native-community | ||
|
||
This plugin is intended to be used in `@react-native-community/eslint-plugin`. You probably want to install that package instead. | ||
|
||
## Installation | ||
|
||
``` | ||
yarn add --dev eslint @react-native-community/eslint-plugin | ||
``` | ||
|
||
*Note: We're using `yarn` to install deps. Feel free to change commands to use `npm` 3+ and `npx` if you like* | ||
|
||
## Usage | ||
|
||
Add to your eslint config (`.eslintrc`, or `eslintConfig` field in `package.json`): | ||
|
||
```json | ||
{ | ||
"plugins": ["@react-native-community"] | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
exports.rules = { | ||
'no-haste-imports': require('./no-haste-imports'), | ||
}; |
64 changes: 64 additions & 0 deletions
64
packages/eslint-plugin-react-native-community/no-haste-imports.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
module.exports = { | ||
meta: { | ||
type: 'problem', | ||
docs: { | ||
description: | ||
'disallow Haste module names in import statements and require calls', | ||
}, | ||
schema: [], | ||
}, | ||
|
||
create(context) { | ||
return { | ||
ImportDeclaration(node) { | ||
checkImportForHaste(context, node.source.value, node.source); | ||
}, | ||
CallExpression(node) { | ||
if (isStaticRequireCall(node)) { | ||
const [firstArgument] = node.arguments; | ||
checkImportForHaste(context, firstArgument.value, firstArgument); | ||
} | ||
}, | ||
}; | ||
}, | ||
}; | ||
|
||
function checkImportForHaste(context, importPath, node) { | ||
if (isLikelyHasteModuleName(importPath)) { | ||
context.report({ | ||
node, | ||
message: `"${importPath}" appears to be a Haste module name. Use path-based imports instead.`, | ||
}); | ||
} | ||
} | ||
|
||
function isLikelyHasteModuleName(importPath) { | ||
// Our heuristic assumes an import path is a Haste module name if it is not a | ||
// path and doesn't appear to be an npm package. For several years, npm has | ||
// disallowed uppercase characters in package names. | ||
// | ||
// This heuristic has a ~1% false negative rate for the filenames in React | ||
// Native, which is acceptable since the linter will not complain wrongly and | ||
// the rate is so low. False negatives that slip through will be caught by | ||
// tests with Haste disabled. | ||
return ( | ||
// Exclude relative paths | ||
!importPath.startsWith('.') && | ||
// Exclude package-internal paths and scoped packages | ||
!importPath.includes('/') && | ||
// Include camelCase and UpperCamelCase | ||
/[A-Z]/.test(importPath) | ||
); | ||
} | ||
|
||
function isStaticRequireCall(node) { | ||
return ( | ||
node && | ||
node.callee && | ||
node.callee.type === 'Identifier' && | ||
node.callee.name === 'require' && | ||
node.arguments.length === 1 && | ||
node.arguments[0].type === 'Literal' && | ||
typeof node.arguments[0].value === 'string' | ||
); | ||
} |
11 changes: 11 additions & 0 deletions
11
packages/eslint-plugin-react-native-community/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "@react-native-community/eslint-plugin", | ||
"version": "1.0.0", | ||
"description": "ESLint rules for @react-native-community/eslint-config", | ||
"main": "index.js", | ||
"repository": { | ||
"type": "git", | ||
"url": "git@github.com:facebook/react-native.git" | ||
}, | ||
"license": "MIT" | ||
} |