Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom eslint plugin to check fbjs imports #13014

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"flowtype",
"prettier",
"react",
"jest"
"jest",
"custom"
],

// Map from global var to bool specifying if it can be redefined
Expand Down Expand Up @@ -262,5 +263,8 @@
"jest/no-focused-tests": 1,
"jest/no-identical-title": 1,
"jest/valid-expect": 1,

// Custom rules, the plugin is located in the eslint-plugin folder.
"custom/fbjs-import": 1
}
}
14 changes: 14 additions & 0 deletions eslint-plugin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

const fbjsImportRule = require('./rules/fbjs-import');

module.exports.rules = {
'fbjs-import': fbjsImportRule,
};
17 changes: 17 additions & 0 deletions eslint-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "eslint-plugin-custom",
"version": "1.0.0",
"license": "BSD-3-Clause",
"description": "Custom ESLint rules used in the React Native repo",
"main": "index.js",
"engines": {
"node": ">=6"
},
"repository": {
"type": "git",
"url": "https://github.com/facebook/react-native.git"
},
"dependencies": {
"eslint-module-utils": "^2.0.0"
}
}
57 changes: 57 additions & 0 deletions eslint-plugin/rules/fbjs-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

/**
* ESLint rule to avoid importing fbjs modules using haste, they should be imported
* using `fbjs/lib/<module>` otherwise it won't work in OSS.
*/
const fs = require('fs');
const moduleVisitor = require('eslint-module-utils/moduleVisitor').default;
const path = require('path');

// Note that this file will be in the `<root>/node_modules/eslint-plugin-custom/rules`
// folder when installed so file paths are relative to that.
// Find modules that could be imported from fbjs.
const fbjsFiles = fs
.readdirSync(path.resolve(__dirname, '../../fbjs/lib'))
.filter(file => file.match(/\.js$/g));

// Find RN dependencies to avoid false positive if there is a commonjs module with
// the same name as one of the fbjs modules.
const reactNativePackageJSON = JSON.parse(
fs.readFileSync(path.resolve(__dirname, '../../../package.json'))
);

const fbjsModules = new Set(
fbjsFiles
.map(file => file.replace('.js', ''))
.filter(module => !reactNativePackageJSON.dependencies[module])
);

module.exports = {
create: context => {
const visitor = source => {
const moduleName = source.value;
if (fbjsModules.has(moduleName)) {
context.report({
node: source,
message: `fbjs module \`${moduleName}\` should not be imported using haste`,
fix: fixer => {
return fixer.insertTextBeforeRange(
[source.start + 1, source.end],
'fbjs/lib/'
);
},
});
}
};

return moduleVisitor(visitor, { commonjs: true });
},
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
"eslint-config-fb-strict": "^20.0.3",
"eslint-config-fbjs": "^1.1.1",
"eslint-plugin-eslint-comments": "^2.0.1",
"eslint-plugin-custom": "file:eslint-plugin",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this will work with our internal Yarn offline cache that well, unfortunately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like nuclide uses this to register custom plugins, that would probably work instead or using a file dependency. https://github.com/facebook/nuclide/blob/693623fd6e2124b094ab4d4d5fad15a67496c6b7/.eslintrc.js#L513-L514

"eslint-plugin-flowtype": "^2.33.0",
"eslint-plugin-jest": "^21.5.0",
"eslint-plugin-prettier": "2.1.1",
Expand Down