Skip to content

Commit 14e01d9

Browse files
committed
Add allowExportNames option (fixes #29) [publish]
1 parent 05379a0 commit 14e01d9

File tree

5 files changed

+56
-5
lines changed

5 files changed

+56
-5
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Changelog
22

3-
## Unreleased
3+
## 0.4.4
44

5+
- Add `allowExportNames` option (fixes #29)
56
- Support memo default export function components (fixes #27)
67
- Warn on export expressions that are not React component (array, object, logical expression, ...) (fixes #26)
78

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,21 @@ createRoot(document.getElementById("root")).render(<App />);
8383

8484
## Options
8585

86+
### allowExportNames <small>(v0.4.4)</small>
87+
88+
If you use a framework that handles HMR of some specific exports, you can use this option to avoid warning for them.
89+
90+
Example for [Remix](https://remix.run/docs/en/main/other-api/dev#:~:text=React%20Fast%20Refresh,-can%20only%20handle):
91+
92+
```json
93+
{
94+
"react-refresh/only-export-components": [
95+
"warn",
96+
{ "allowExportNames": ["meta", "links", "headers", "loader", "action"] }
97+
]
98+
}
99+
```
100+
86101
### allowConstantExport <small>(v0.4.0)</small>
87102

88103
Don't warn when a constant (string, number, boolean, templateLiteral) is exported aside one or more components.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "eslint-plugin-react-refresh",
3-
"version": "0.4.3",
3+
"version": "0.4.4",
44
"license": "MIT",
55
"scripts": {
66
"build": "scripts/bundle.ts",

src/only-export-components.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,21 @@ const valid = [
116116
code: "const foo = 'world'; export const CONSTANT = `Hello ${foo}`; export const Foo = () => {};",
117117
options: [{ allowConstantExport: true }],
118118
},
119+
{
120+
name: "Component and allowed export",
121+
code: "export const loader = () => {}; export const Bar = () => {};",
122+
options: [{ allowExportNames: ["loader", "meta"] }],
123+
},
124+
{
125+
name: "Component and allowed function export",
126+
code: "export function loader() {}; export const Bar = () => {};",
127+
options: [{ allowExportNames: ["loader", "meta"] }],
128+
},
129+
{
130+
name: "Only allowed exports without component",
131+
code: "export const loader = () => {}; export const meta = { title: 'Home' };",
132+
options: [{ allowExportNames: ["loader", "meta"] }],
133+
},
119134
];
120135

121136
const invalid = [
@@ -201,6 +216,12 @@ const invalid = [
201216
filename: "Test.jsx",
202217
errorId: "anonymousExport",
203218
},
219+
{
220+
name: "Component and export non in allowExportNames",
221+
code: "export const loader = () => {}; export const Bar = () => {}; export const foo = () => {};",
222+
options: [{ allowExportNames: ["loader", "meta"] }],
223+
errorId: "namedExport",
224+
},
204225
];
205226

206227
const it = (name: string, cases: Parameters<typeof ruleTester.run>[2]) => {

src/only-export-components.ts

+17-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@ export const onlyExportComponents: TSESLint.RuleModule<
1414
| "anonymousExport"
1515
| "noExport"
1616
| "localComponents",
17-
[] | [{ allowConstantExport?: boolean; checkJS?: boolean }]
17+
| []
18+
| [
19+
{
20+
allowConstantExport?: boolean;
21+
checkJS?: boolean;
22+
allowExportNames?: string[];
23+
},
24+
]
1825
> = {
1926
meta: {
2027
messages: {
@@ -36,15 +43,19 @@ export const onlyExportComponents: TSESLint.RuleModule<
3643
properties: {
3744
allowConstantExport: { type: "boolean" },
3845
checkJS: { type: "boolean" },
46+
allowExportNames: { type: "array", items: { type: "string" } },
3947
},
4048
additionalProperties: false,
4149
},
4250
],
4351
},
4452
defaultOptions: [],
4553
create: (context) => {
46-
const { allowConstantExport = false, checkJS = false } =
47-
context.options[0] || {};
54+
const {
55+
allowConstantExport = false,
56+
checkJS = false,
57+
allowExportNames,
58+
} = context.options[0] || {};
4859
const filename = context.getFilename();
4960
// Skip tests & stories files
5061
if (
@@ -86,6 +97,9 @@ export const onlyExportComponents: TSESLint.RuleModule<
8697
nonComponentExports.push(identifierNode);
8798
return;
8899
}
100+
if (allowExportNames?.includes(identifierNode.name)) {
101+
return;
102+
}
89103
if (
90104
allowConstantExport &&
91105
init &&

0 commit comments

Comments
 (0)