diff --git a/desktop/.eslintrc.js b/desktop/.eslintrc.js index 9178296aa..f4cebb4ed 100644 --- a/desktop/.eslintrc.js +++ b/desktop/.eslintrc.js @@ -68,6 +68,13 @@ module.exports = { 'no-unsafe-negation': 2, 'no-useless-computed-key': 2, 'no-useless-rename': 2, + 'no-restricted-properties': [ + 1, + { + object: 'electron', + property: 'remote', + }, + ], // additional rules for this project 'header/header': [2, 'block', {pattern}], @@ -76,6 +83,7 @@ module.exports = { 'node/no-extraneous-import': [2, {allowModules: builtInModules}], 'node/no-extraneous-require': [2, {allowModules: builtInModules}], 'flipper/no-relative-imports-across-packages': [2], + 'flipper/no-electron-remote-imports': [1], }, settings: { 'import/resolver': { diff --git a/desktop/eslint-plugin-flipper/src/index.ts b/desktop/eslint-plugin-flipper/src/index.ts index b9ded1b70..5b3bda50b 100644 --- a/desktop/eslint-plugin-flipper/src/index.ts +++ b/desktop/eslint-plugin-flipper/src/index.ts @@ -10,9 +10,13 @@ import noRelativeImportsAcrossPackages, { RULE_NAME as noRelativeImportsAcrossPackagesRuleName, } from './rules/noRelativeImportsAcrossPackages'; +import noElectronRemoteImports, { + RULE_NAME as noElectronRemoteImportsRuleName, +} from './rules/noElectronRemoteImports'; module.exports = { rules: { [noRelativeImportsAcrossPackagesRuleName]: noRelativeImportsAcrossPackages, + [noElectronRemoteImportsRuleName]: noElectronRemoteImports, }, }; diff --git a/desktop/eslint-plugin-flipper/src/rules/__tests__/noElectronRemoteImports.node.ts b/desktop/eslint-plugin-flipper/src/rules/__tests__/noElectronRemoteImports.node.ts new file mode 100644 index 000000000..713ff74f1 --- /dev/null +++ b/desktop/eslint-plugin-flipper/src/rules/__tests__/noElectronRemoteImports.node.ts @@ -0,0 +1,53 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +import {TSESLint} from '@typescript-eslint/experimental-utils'; +import rule, {RULE_NAME} from '../noElectronRemoteImports'; + +const tester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { + sourceType: 'module', + ecmaVersion: 2020, + }, +}); + +tester.run(RULE_NAME, rule, { + valid: [ + { + code: `import {something} from 'electron';`, + filename: __filename, + }, + { + code: `import remote from 'electron';`, + filename: __filename, + }, + { + code: `import remote from './electron';`, + filename: __filename, + }, + ], + invalid: [ + { + code: `import {remote} from 'electron';`, + filename: __filename, + errors: [{messageId: 'noElectronRemoteImports'}], + }, + { + code: `import {remote, somethingelse} from 'electron';`, + filename: __filename, + errors: [{messageId: 'noElectronRemoteImports'}], + }, + { + code: `import {remote as notRemote} from 'electron';`, + filename: __filename, + errors: [{messageId: 'noElectronRemoteImports'}], + }, + ], +}); diff --git a/desktop/eslint-plugin-flipper/src/rules/noElectronRemoteImports.ts b/desktop/eslint-plugin-flipper/src/rules/noElectronRemoteImports.ts new file mode 100644 index 000000000..e63dc9aa1 --- /dev/null +++ b/desktop/eslint-plugin-flipper/src/rules/noElectronRemoteImports.ts @@ -0,0 +1,53 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +import {TSESTree} from '@typescript-eslint/experimental-utils'; +import {createESLintRule} from '../utils/createEslintRule'; + +type Options = []; + +export type MessageIds = 'noElectronRemoteImports'; +export const RULE_NAME = 'no-electron-remote-imports'; + +export default createESLintRule({ + name: RULE_NAME, + meta: { + type: 'suggestion', + docs: { + description: '`remote` is slow. Please be careful when using it.', + category: 'Possible Errors', + recommended: 'warn', + }, + schema: [], + messages: { + noElectronRemoteImports: + 'Accessing properties on the `remote` object is blocking and 10,000x slower than a local one. Please consider alternatives or cache your access.', + }, + }, + defaultOptions: [], + create(context) { + return { + ImportDeclaration(node: TSESTree.ImportDeclaration) { + if (node.source.value === 'electron') { + const hasImport = + node.specifiers.filter( + (v) => + v.type === 'ImportSpecifier' && v.imported.name === 'remote', + ).length > 0; + if (hasImport) { + context.report({ + node, + messageId: 'noElectronRemoteImports', + }); + } + } + }, + }; + }, +});