1/** 2 * @fileoverview Ensure modules are not required twice at top level of a module 3 * @author devsnek 4 */ 5'use strict'; 6 7const { isRequireCall, isString } = require('./rules-utils.js'); 8 9//------------------------------------------------------------------------------ 10// Rule Definition 11//------------------------------------------------------------------------------ 12 13 14function isTopLevel(node) { 15 do { 16 if (node.type === 'FunctionDeclaration' || 17 node.type === 'FunctionExpression' || 18 node.type === 'ArrowFunctionExpression' || 19 node.type === 'ClassBody' || 20 node.type === 'MethodDefinition') { 21 return false; 22 } 23 } while (node = node.parent); 24 return true; 25} 26 27module.exports = (context) => { 28 if (context.parserOptions.sourceType === 'module') { 29 return {}; 30 } 31 32 function getRequiredModuleNameFromCall(node) { 33 // Node has arguments and first argument is string 34 if (node.arguments.length && isString(node.arguments[0])) { 35 return node.arguments[0].value.trim(); 36 } 37 38 return undefined; 39 } 40 41 const required = new Set(); 42 43 const rules = { 44 CallExpression: (node) => { 45 if (isRequireCall(node) && isTopLevel(node)) { 46 const moduleName = getRequiredModuleNameFromCall(node); 47 if (moduleName === undefined) { 48 return; 49 } 50 if (required.has(moduleName)) { 51 context.report( 52 node, 53 '\'{{moduleName}}\' require is duplicated.', 54 { moduleName } 55 ); 56 } else { 57 required.add(moduleName); 58 } 59 } 60 }, 61 }; 62 63 return rules; 64}; 65