Skip to main content
Glama
no-reexports.js5.29 kB
/** * ESLint rule to prevent re-exporting of imported identifiers */ module.exports = { meta: { type: 'problem', docs: { description: 'Disallow re-exporting of imported identifiers', category: 'Best Practices', recommended: false, }, schema: [ { type: 'object', properties: { allowList: { type: 'array', items: { type: 'string' }, }, allowModules: { type: 'array', items: { type: 'string' }, }, allowRenamed: { type: 'boolean', }, }, additionalProperties: false, }, ], }, create: function (context) { const options = context.options[0] || {} const allowList = new Set(options.allowList || []) const allowModules = new Set(options.allowModules || []) const allowRenamed = options.allowRenamed || false // Maps to track imported identifiers and their source modules const importedIdentifiers = new Map() // name -> source // Track variables to handle complex re-exports const variableSources = new Map() // variable name -> imported source return { // Track imports ImportDeclaration(node) { const source = node.source.value const isAllowedModule = allowModules.has(source) node.specifiers.forEach((specifier) => { const name = specifier.local.name if (!allowList.has(name) && !isAllowedModule) { importedIdentifiers.set(name, source) } }) }, // Track variable declarations that reference imports VariableDeclarator(node) { if (node.init && node.init.type === 'Identifier') { const source = importedIdentifiers.get(node.init.name) if (source) { variableSources.set(node.id.name, source) } } }, // Check named exports ExportNamedDeclaration(node) { // Direct re-export with source if (node.source) { const source = node.source.value if (!allowModules.has(source)) { node.specifiers.forEach((specifier) => { context.report({ node: specifier, message: `Passthrough export from '${source}' is not allowed. Passthrough files add complexity without value. Remove this re-export and import directly from '${source}' where needed.`, }) }) } return } // Standard named exports node.specifiers.forEach((specifier) => { const name = specifier.local.name const exported = specifier.exported.name const isRenamed = name !== exported if (importedIdentifiers.has(name)) { if (!(allowRenamed && isRenamed)) { const source = importedIdentifiers.get(name) context.report({ node: specifier, message: `Passthrough export of '${name}' from '${source}' is not allowed. Modules should add value, not just re-export. Remove this re-export and update affected imports to use '${source}' directly.`, }) } } else if (variableSources.has(name)) { if (!(allowRenamed && isRenamed)) { const source = variableSources.get(name) context.report({ node: specifier, message: `Passthrough export of '${name}' which wraps an import from '${source}' is not allowed. Remove this variable and re-export pattern and update imports to reference '${source}' directly.`, }) } } }) // Check variable declaration exports if (node.declaration && node.declaration.type === 'VariableDeclaration') { node.declaration.declarations.forEach((declarator) => { if (declarator.init && declarator.init.type === 'Identifier') { const initName = declarator.init.name if (importedIdentifiers.has(initName)) { const source = importedIdentifiers.get(initName) context.report({ node: declarator, message: `Passthrough export of '${initName}' from '${source}' via variable declaration is not allowed. Add meaningful transformation or remove this pattern entirely. Update affected imports to use '${source}' directly.`, }) } } }) } }, // Check export all declarations ExportAllDeclaration(node) { const source = node.source.value if (!allowModules.has(source)) { context.report({ node, message: `Exporting all from '${source}' is not allowed. This creates hard-to-track dependencies. Import and export specific items with added value, or update affected imports to use '${source}' directly.`, }) } }, // Check default exports ExportDefaultDeclaration(node) { if (node.declaration && node.declaration.type === 'Identifier') { const name = node.declaration.name if (importedIdentifiers.has(name)) { const source = importedIdentifiers.get(name) context.report({ node, message: `Passthrough default export of '${name}' from '${source}' is not allowed. Default exports should provide value, not just re-export. Remove this file or add functionality before exporting.`, }) } else if (variableSources.has(name)) { const source = variableSources.get(name) context.report({ node, message: `Passthrough default export of '${name}' which wraps an import from '${source}' is not allowed. Remove this pattern and update imports to reference '${source}' directly.`, }) } } }, } }, }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tbreeding/jira-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server