Skip to content

Commit ec747c2

Browse files
authored
Add configs and simple types (#67)
1 parent 359ae21 commit ec747c2

File tree

9 files changed

+198
-14
lines changed

9 files changed

+198
-14
lines changed

CHANGELOG.md

+17
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,23 @@ export default observer(Foo);
2222

2323
Thanks @HorusGoul!
2424

25+
### Add recommended config and simple types (#67)
26+
27+
You can now add the recommended config to your ESLint config like this:
28+
29+
```js
30+
import reactRefresh from "eslint-plugin-react-refresh";
31+
32+
export default [
33+
/* Main config */
34+
reactRefresh.configs.recommended, // Or reactRefresh.configs.vite for Vite users
35+
];
36+
```
37+
38+
To follow ESLint recommandations, the rule is added with the `error` severity.
39+
40+
Some simple types ensure that people typecheking their config won't need `@ts-expect-error` anymore.
41+
2542
### Bump ESLint peer dependency to 8.40
2643

2744
This was actually done by mistake in the previous release when moving from a deprecated API to a new one.

README.md

+30-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# eslint-plugin-react-refresh [![npm](https://img.shields.io/npm/v/eslint-plugin-react-refresh)](https://www.npmjs.com/package/eslint-plugin-react-refresh)
22

3-
Validate that your components can safely be updated with fast refresh.
3+
Validate that your components can safely be updated with Fast Refresh.
44

55
## Explainer
66

7-
"Fast refresh", also known as "hot reloading", is a feature in many modern bundlers.
7+
"Fast Refresh", also known as "hot reloading", is a feature in many modern bundlers.
88
If you update some React component(s) on disk, then the bundler will know to update only the impacted parts of your page -- without a full page reload.
99

1010
`eslint-plugin-react-refresh` enforces that your components are structured in a way that integrations such as [react-refresh](https://www.npmjs.com/package/react-refresh) expect.
@@ -28,7 +28,33 @@ npm i -D eslint-plugin-react-refresh
2828

2929
## Usage
3030

31-
This plugin provides a single rule, `react-refresh/only-export-components`.
31+
This plugin provides a single rule, `react-refresh/only-export-components`. There are multiple ways to enable it.
32+
33+
### Recommended config
34+
35+
```js
36+
import reactRefresh from "eslint-plugin-react-refresh";
37+
38+
export default [
39+
/* Main config */
40+
reactRefresh.configs.recommended,
41+
];
42+
```
43+
44+
### Vite config
45+
46+
This enables the `allowConstantExport` option which is supported by Vite React plugins.
47+
48+
```js
49+
import reactRefresh from "eslint-plugin-react-refresh";
50+
51+
export default [
52+
/* Main config */
53+
reactRefresh.configs.vite,
54+
];
55+
```
56+
57+
### Without config
3258

3359
```js
3460
import reactRefresh from "eslint-plugin-react-refresh";
@@ -111,7 +137,6 @@ These options are all present on `react-refresh/only-exports-components`.
111137

112138
```ts
113139
interface Options {
114-
allowExportNames?: string[];
115140
allowExportNames?: string[];
116141
allowConstantExport?: boolean;
117142
customHOCs?: string[];
@@ -145,7 +170,7 @@ Example for [Remix](https://remix.run/docs/en/main/discussion/hot-module-replace
145170

146171
### allowConstantExport <small>(v0.4.0)</small>
147172

148-
> Default: `false`
173+
> Default: `false` (`true` in `vite` config)
149174
150175
Don't warn when a constant (string, number, boolean, templateLiteral) is exported aside one or more components.
151176

bun.lockb

5.07 KB
Binary file not shown.

eslint.config.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
import baseConfig from "@arnaud-barre/eslint-config";
22

3-
export default baseConfig;
3+
export default [
4+
...baseConfig,
5+
{
6+
rules: {
7+
"@arnaud-barre/no-default-export": "off",
8+
},
9+
},
10+
];

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"lint": "bun eslint . --max-warnings 0",
1010
"prettier": "bun prettier-ci --write",
1111
"prettier-ci": "prettier --ignore-path=.gitignore --check '**/*.{js,ts,json,md,yml}'",
12-
"ci": "tsc && bun lint && bun prettier-ci && bun test && bun run build"
12+
"ci": "tsc && bun lint && bun prettier-ci && bun test && bun run build && cd dist && publint"
1313
},
1414
"prettier": {},
1515
"peerDependencies": {
@@ -25,6 +25,7 @@
2525
"bun-types": "^1.1.31",
2626
"eslint": "^9.13.0",
2727
"prettier": "3.0.3",
28+
"publint": "^0.2.12",
2829
"typescript": "~5.6"
2930
}
3031
}

scripts/bundle.ts

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ await build({
1717
});
1818

1919
execSync("cp LICENSE README.md dist/");
20+
execSync("cp src/types.ts dist/index.d.ts");
2021

2122
writeFileSync(
2223
"dist/package.json",
@@ -26,10 +27,12 @@ writeFileSync(
2627
description:
2728
"Validate that your components can safely be updated with Fast Refresh",
2829
version: packageJSON.version,
30+
type: "commonjs",
2931
author: "Arnaud Barré (https://github.com/ArnaudBarre)",
3032
license: packageJSON.license,
3133
repository: "github:ArnaudBarre/eslint-plugin-react-refresh",
3234
main: "index.js",
35+
types: "index.d.ts",
3336
keywords: [
3437
"eslint",
3538
"eslint-plugin",

src/index.ts

+23-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
11
import { onlyExportComponents } from "./only-export-components.ts";
22

3-
export const rules = {
4-
"only-export-components": onlyExportComponents,
3+
const plugin = {
4+
rules: {
5+
"only-export-components": onlyExportComponents,
6+
},
7+
};
8+
9+
export default {
10+
rules: plugin.rules,
11+
configs: {
12+
recommended: {
13+
plugins: { "react-refresh": plugin },
14+
rules: { "react-refresh/only-export-components": "error" },
15+
},
16+
vite: {
17+
plugins: { "react-refresh": plugin },
18+
rules: {
19+
"react-refresh/only-export-components": [
20+
"error",
21+
{ allowConstantExport: true },
22+
],
23+
},
24+
},
25+
},
526
};
6-
// eslint-disable-next-line @arnaud-barre/no-default-export
7-
export default { rules };

src/types.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
type Config = {
2+
plugins: { "react-refresh": { rules: Record<string, any> } };
3+
rules: Record<string, any>;
4+
};
5+
6+
declare const _default: {
7+
rules: Record<string, any>;
8+
configs: {
9+
recommended: Config;
10+
vite: Config;
11+
};
12+
};
13+
14+
export default _default;

yarn.lock

+101-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
22
# yarn lockfile v1
3-
# bun ./bun.lockb --hash: 0E2E8C648B832E19-f03f14fd57c82352-DE4F31B62A420BFD-c372ca07548ab99e
3+
# bun ./bun.lockb --hash: 200298EB1539E3D4-a461114ade976598-38DCF0097CD18ABB-5c9d03f73b5bf09b
44

55

66
"@arnaud-barre/eslint-config@^5.1.0":
@@ -633,7 +633,7 @@ escape-string-regexp@^4.0.0:
633633
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
634634
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
635635

636-
eslint@>=7, eslint@>=8.56.0, "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", eslint@^9.13.0:
636+
eslint@>=7, eslint@>=8.40, eslint@>=8.56.0, "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", eslint@^9.13.0:
637637
version "9.13.0"
638638
resolved "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz"
639639
integrity sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==
@@ -833,11 +833,27 @@ flatted@^3.2.9:
833833
resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz"
834834
integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
835835

836+
fs.realpath@^1.0.0:
837+
version "1.0.0"
838+
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
839+
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
840+
836841
function-bind@^1.1.2:
837842
version "1.1.2"
838843
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
839844
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
840845

846+
glob@^8.0.1:
847+
version "8.1.0"
848+
resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz"
849+
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
850+
dependencies:
851+
once "^1.3.0"
852+
inflight "^1.0.4"
853+
inherits "2"
854+
minimatch "^5.0.1"
855+
fs.realpath "^1.0.0"
856+
841857
glob-parent@^5.1.2:
842858
version "5.1.2"
843859
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
@@ -894,6 +910,13 @@ ignore@^5.2.0, ignore@^5.3.1:
894910
resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz"
895911
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
896912

913+
ignore-walk@^5.0.1:
914+
version "5.0.1"
915+
resolved "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz"
916+
integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==
917+
dependencies:
918+
minimatch "^5.0.1"
919+
897920
import-fresh@^3.2.1:
898921
version "3.3.0"
899922
resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
@@ -912,6 +935,19 @@ indent-string@^4.0.0:
912935
resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz"
913936
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
914937

938+
inflight@^1.0.4:
939+
version "1.0.6"
940+
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
941+
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
942+
dependencies:
943+
once "^1.3.0"
944+
wrappy "1"
945+
946+
inherits@2:
947+
version "2.0.4"
948+
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
949+
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
950+
915951
is-arrayish@^0.2.1:
916952
version "0.2.1"
917953
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
@@ -1059,13 +1095,25 @@ minimatch@^3.1.2:
10591095
dependencies:
10601096
brace-expansion "^1.1.7"
10611097

1098+
minimatch@^5.0.1:
1099+
version "5.1.6"
1100+
resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz"
1101+
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
1102+
dependencies:
1103+
brace-expansion "^2.0.1"
1104+
10621105
minimatch@^9.0.4:
10631106
version "9.0.5"
10641107
resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz"
10651108
integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
10661109
dependencies:
10671110
brace-expansion "^2.0.1"
10681111

1112+
mri@^1.1.0:
1113+
version "1.2.0"
1114+
resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz"
1115+
integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
1116+
10691117
ms@^2.1.3:
10701118
version "2.1.3"
10711119
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
@@ -1091,6 +1139,35 @@ normalize-package-data@^2.5.0:
10911139
hosted-git-info "^2.1.4"
10921140
validate-npm-package-license "^3.0.1"
10931141

1142+
npm-bundled@^2.0.0:
1143+
version "2.0.1"
1144+
resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-2.0.1.tgz"
1145+
integrity sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==
1146+
dependencies:
1147+
npm-normalize-package-bin "^2.0.0"
1148+
1149+
npm-normalize-package-bin@^2.0.0:
1150+
version "2.0.0"
1151+
resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz"
1152+
integrity sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==
1153+
1154+
npm-packlist@^5.1.3:
1155+
version "5.1.3"
1156+
resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.1.3.tgz"
1157+
integrity sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==
1158+
dependencies:
1159+
glob "^8.0.1"
1160+
ignore-walk "^5.0.1"
1161+
npm-bundled "^2.0.0"
1162+
npm-normalize-package-bin "^2.0.0"
1163+
1164+
once@^1.3.0:
1165+
version "1.4.0"
1166+
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
1167+
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
1168+
dependencies:
1169+
wrappy "1"
1170+
10941171
optionator@^0.9.3:
10951172
version "0.9.4"
10961173
resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz"
@@ -1168,7 +1245,7 @@ path-parse@^1.0.7:
11681245
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
11691246
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
11701247

1171-
picocolors@^1.0.0, picocolors@^1.1.0:
1248+
picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1:
11721249
version "1.1.1"
11731250
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"
11741251
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
@@ -1193,6 +1270,15 @@ [email protected]:
11931270
resolved "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz"
11941271
integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==
11951272

1273+
publint@^0.2.12:
1274+
version "0.2.12"
1275+
resolved "https://registry.npmjs.org/publint/-/publint-0.2.12.tgz"
1276+
integrity sha512-YNeUtCVeM4j9nDiTT2OPczmlyzOkIXNtdDZnSuajAxS/nZ6j3t7Vs9SUB4euQNddiltIwu7Tdd3s+hr08fAsMw==
1277+
dependencies:
1278+
npm-packlist "^5.1.3"
1279+
picocolors "^1.1.1"
1280+
sade "^1.8.1"
1281+
11961282
punycode@^2.1.0:
11971283
version "2.3.1"
11981284
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz"
@@ -1260,6 +1346,13 @@ run-parallel@^1.1.9:
12601346
dependencies:
12611347
queue-microtask "^1.2.2"
12621348

1349+
sade@^1.8.1:
1350+
version "1.8.1"
1351+
resolved "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz"
1352+
integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
1353+
dependencies:
1354+
mri "^1.1.0"
1355+
12631356
"semver@2 || 3 || 4 || 5":
12641357
version "5.7.2"
12651358
resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz"
@@ -1432,6 +1525,11 @@ word-wrap@^1.2.5:
14321525
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz"
14331526
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
14341527

1528+
wrappy@1:
1529+
version "1.0.2"
1530+
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
1531+
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
1532+
14351533
yocto-queue@^0.1.0:
14361534
version "0.1.0"
14371535
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"

0 commit comments

Comments
 (0)