Skip to content

Commit

Permalink
Report React context exports (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
IgorAufricht authored Oct 21, 2024
1 parent 268df3b commit 97bdd56
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
17 changes: 17 additions & 0 deletions src/only-export-components.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,18 @@ const valid = [
name: "Allow connect from react-redux",
code: "const MyComponent = () => {}; export default connect(() => ({}))(MyComponent);",
},
{
name: "Two components, one of them with 'Context' in its name",
code: "export const MyComponent = () => {}; export const ChatContext = () => {};",
},
{
name: "Component & local React context",
code: "export const MyComponent = () => {}; const MyContext = createContext('test');",
},
{
name: "Only React context",
code: "export const MyContext = createContext('test');",
},
];

const invalid = [
Expand Down Expand Up @@ -273,6 +285,11 @@ const invalid = [
code: 'const Foo = () => {}; export { Foo as "🍌"}',
errorId: "localComponents",
},
{
name: "Component and React Context",
code: "export const MyComponent = () => {}; export const MyContext = createContext('test');",
errorId: "reactContext",
},
];

const it = (name: string, cases: Parameters<typeof ruleTester.run>[2]) => {
Expand Down
20 changes: 18 additions & 2 deletions src/only-export-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export const onlyExportComponents: TSESLint.RuleModule<
| "namedExport"
| "anonymousExport"
| "noExport"
| "localComponents",
| "localComponents"
| "reactContext",
| []
| [
{
Expand All @@ -35,6 +36,8 @@ export const onlyExportComponents: TSESLint.RuleModule<
"Fast refresh only works when a file only exports components. Move your component(s) to a separate file.",
noExport:
"Fast refresh only works when a file has exports. Move your component(s) to a separate file.",
reactContext:
"Fast refresh only works when a file only exports components. Move your React context(s) to a separate file.",
},
type: "problem",
schema: [
Expand All @@ -56,7 +59,7 @@ export const onlyExportComponents: TSESLint.RuleModule<
checkJS = false,
allowExportNames,
} = context.options[0] ?? {};
const filename = context.getFilename();
const filename = context.filename;
// Skip tests & stories files
if (
filename.includes(".test.") ||
Expand Down Expand Up @@ -86,6 +89,7 @@ export const onlyExportComponents: TSESLint.RuleModule<
| TSESTree.BindingName
| TSESTree.StringLiteral
)[] = [];
const reactContextExports: TSESTree.Identifier[] = [];

const handleLocalIdentifier = (
identifierNode: TSESTree.BindingName,
Expand Down Expand Up @@ -124,6 +128,15 @@ export const onlyExportComponents: TSESLint.RuleModule<
nonComponentExports.push(identifierNode);
}
} else {
if (
init &&
init.type === "CallExpression" &&
init.callee.type === "Identifier" &&
init.callee.name === "createContext"
) {
reactContextExports.push(identifierNode);
return;
}
if (
init &&
// Switch to allowList?
Expand Down Expand Up @@ -263,6 +276,9 @@ export const onlyExportComponents: TSESLint.RuleModule<
for (const node of nonComponentExports) {
context.report({ messageId: "namedExport", node });
}
for (const node of reactContextExports) {
context.report({ messageId: "reactContext", node });
}
} else if (localComponents.length) {
for (const node of localComponents) {
context.report({ messageId: "localComponents", node });
Expand Down

0 comments on commit 97bdd56

Please sign in to comment.