diff --git a/src/rule-must-colocate-fragment-spreads.js b/src/rule-must-colocate-fragment-spreads.js index 3bd21c3..14675cd 100644 --- a/src/rule-must-colocate-fragment-spreads.js +++ b/src/rule-must-colocate-fragment-spreads.js @@ -108,6 +108,7 @@ function getGraphQLFragmentDefinitionName(graphQLAst) { function rule(context) { const foundImportedModules = []; const graphqlLiterals = []; + const contextFilename = context.getFilename(); return { 'Program:exit'(_node) { @@ -145,7 +146,11 @@ function rule(context) { ImportDeclaration(node) { if (node.importKind === 'value') { - foundImportedModules.push(utils.getModuleName(node.source.value)); + const moduleName = utils.getModuleName( + node.source.value, + contextFilename + ); + foundImportedModules.push(moduleName); } }, @@ -153,7 +158,11 @@ function rule(context) { if (node.source.type === 'Literal') { // Allow dynamic imports like import(`test/${fileName}`); and (path) => import(path); // These would have node.source.value undefined - foundImportedModules.push(utils.getModuleName(node.source.value)); + const moduleName = utils.getModuleName( + node.source.value, + contextFilename + ); + foundImportedModules.push(moduleName); } }, @@ -163,7 +172,8 @@ function rule(context) { } const [source] = node.arguments; if (source && source.type === 'Literal') { - foundImportedModules.push(utils.getModuleName(source.value)); + const moduleName = utils.getModuleName(source.value, contextFilename); + foundImportedModules.push(moduleName); } }, diff --git a/src/utils.js b/src/utils.js index 20d7977..8237359 100644 --- a/src/utils.js +++ b/src/utils.js @@ -67,7 +67,7 @@ function getLocFromIndex(sourceCode, index) { } // Copied directly from Relay -function getModuleName(filePath) { +function getModuleName(filePath, contextFilename) { // index.js -> index // index.js.flow -> index.js let filename = path.basename(filePath, path.extname(filePath)); @@ -80,6 +80,14 @@ function getModuleName(filePath) { let moduleName = filename === 'index' ? path.basename(path.dirname(filePath)) : filename; + // Special case to handle relative sibling index imports such as: + // import MyComponent from './' + if (moduleName === '.' && contextFilename) { + moduleName = path.basename( + path.dirname(path.join(moduleName, contextFilename)) + ); + } + // foo-bar -> fooBar // Relay compatibility mode splits on _, so we can't use that here. moduleName = moduleName.replace(/[^a-zA-Z0-9]+(\w?)/g, (match, next) => diff --git a/test/must-colocate-fragment-spreads.js b/test/must-colocate-fragment-spreads.js index 096a7a1..691869e 100644 --- a/test/must-colocate-fragment-spreads.js +++ b/test/must-colocate-fragment-spreads.js @@ -100,7 +100,16 @@ ruleTester.run( const getOperation = (reference) => {\ return import(reference);\ };\ - ' + ', + { + filename: '/Container/MyComponent/AnotherComponent.js', + code: ` + import MyComponent from './'; + graphql\`fragment foo on Page { + ...MyComponent_foo + }\`; + ` + } ], invalid: [ { @@ -152,6 +161,16 @@ ruleTester.run( }\`; `, errors: [unusedFieldsWarning('component_fragment')] + }, + { + filename: '/Container/NotMyComponent/AnotherComponent.js', + code: ` + import MyComponent from './'; + graphql\`fragment foo on Page { + ...MyComponent_foo + }\`; + `, + errors: [unusedFieldsWarning('MyComponent_foo')] } ] }