react-native-macos/packages/eslint-plugin-react-native-.../no-haste-imports.js

74 строки
2.0 KiB
JavaScript
Исходник Обычный вид История

/**
* 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
*/
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'
);
}