Skip to content

Commit

Permalink
Add configs and simple types (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudBarre authored Dec 2, 2024
1 parent 359ae21 commit ec747c2
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 14 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ export default observer(Foo);

Thanks @HorusGoul!

### Add recommended config and simple types (#67)

You can now add the recommended config to your ESLint config like this:

```js
import reactRefresh from "eslint-plugin-react-refresh";

export default [
/* Main config */
reactRefresh.configs.recommended, // Or reactRefresh.configs.vite for Vite users
];
```

To follow ESLint recommandations, the rule is added with the `error` severity.

Some simple types ensure that people typecheking their config won't need `@ts-expect-error` anymore.

### Bump ESLint peer dependency to 8.40

This was actually done by mistake in the previous release when moving from a deprecated API to a new one.
Expand Down
35 changes: 30 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# eslint-plugin-react-refresh [![npm](https://img.shields.io/npm/v/eslint-plugin-react-refresh)](https://www.npmjs.com/package/eslint-plugin-react-refresh)

Validate that your components can safely be updated with fast refresh.
Validate that your components can safely be updated with Fast Refresh.

## Explainer

"Fast refresh", also known as "hot reloading", is a feature in many modern bundlers.
"Fast Refresh", also known as "hot reloading", is a feature in many modern bundlers.
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.

`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.
Expand All @@ -28,7 +28,33 @@ npm i -D eslint-plugin-react-refresh

## Usage

This plugin provides a single rule, `react-refresh/only-export-components`.
This plugin provides a single rule, `react-refresh/only-export-components`. There are multiple ways to enable it.

### Recommended config

```js
import reactRefresh from "eslint-plugin-react-refresh";

export default [
/* Main config */
reactRefresh.configs.recommended,
];
```

### Vite config

This enables the `allowConstantExport` option which is supported by Vite React plugins.

```js
import reactRefresh from "eslint-plugin-react-refresh";

export default [
/* Main config */
reactRefresh.configs.vite,
];
```

### Without config

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

```ts
interface Options {
allowExportNames?: string[];
allowExportNames?: string[];
allowConstantExport?: boolean;
customHOCs?: string[];
Expand Down Expand Up @@ -145,7 +170,7 @@ Example for [Remix](https://remix.run/docs/en/main/discussion/hot-module-replace

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

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

Expand Down
Binary file modified bun.lockb
Binary file not shown.
9 changes: 8 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import baseConfig from "@arnaud-barre/eslint-config";

export default baseConfig;
export default [
...baseConfig,
{
rules: {
"@arnaud-barre/no-default-export": "off",
},
},
];
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"lint": "bun eslint . --max-warnings 0",
"prettier": "bun prettier-ci --write",
"prettier-ci": "prettier --ignore-path=.gitignore --check '**/*.{js,ts,json,md,yml}'",
"ci": "tsc && bun lint && bun prettier-ci && bun test && bun run build"
"ci": "tsc && bun lint && bun prettier-ci && bun test && bun run build && cd dist && publint"
},
"prettier": {},
"peerDependencies": {
Expand All @@ -25,6 +25,7 @@
"bun-types": "^1.1.31",
"eslint": "^9.13.0",
"prettier": "3.0.3",
"publint": "^0.2.12",
"typescript": "~5.6"
}
}
3 changes: 3 additions & 0 deletions scripts/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ await build({
});

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

writeFileSync(
"dist/package.json",
Expand All @@ -26,10 +27,12 @@ writeFileSync(
description:
"Validate that your components can safely be updated with Fast Refresh",
version: packageJSON.version,
type: "commonjs",
author: "Arnaud Barré (https://github.com/ArnaudBarre)",
license: packageJSON.license,
repository: "github:ArnaudBarre/eslint-plugin-react-refresh",
main: "index.js",
types: "index.d.ts",
keywords: [
"eslint",
"eslint-plugin",
Expand Down
27 changes: 23 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
import { onlyExportComponents } from "./only-export-components.ts";

export const rules = {
"only-export-components": onlyExportComponents,
const plugin = {
rules: {
"only-export-components": onlyExportComponents,
},
};

export default {
rules: plugin.rules,
configs: {
recommended: {
plugins: { "react-refresh": plugin },
rules: { "react-refresh/only-export-components": "error" },
},
vite: {
plugins: { "react-refresh": plugin },
rules: {
"react-refresh/only-export-components": [
"error",
{ allowConstantExport: true },
],
},
},
},
};
// eslint-disable-next-line @arnaud-barre/no-default-export
export default { rules };
14 changes: 14 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
type Config = {
plugins: { "react-refresh": { rules: Record<string, any> } };
rules: Record<string, any>;
};

declare const _default: {
rules: Record<string, any>;
configs: {
recommended: Config;
vite: Config;
};
};

export default _default;
104 changes: 101 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
# bun ./bun.lockb --hash: 0E2E8C648B832E19-f03f14fd57c82352-DE4F31B62A420BFD-c372ca07548ab99e
# bun ./bun.lockb --hash: 200298EB1539E3D4-a461114ade976598-38DCF0097CD18ABB-5c9d03f73b5bf09b


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

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:
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:
version "9.13.0"
resolved "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz"
integrity sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==
Expand Down Expand Up @@ -833,11 +833,27 @@ flatted@^3.2.9:
resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz"
integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==

fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==

function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==

glob@^8.0.1:
version "8.1.0"
resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz"
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
dependencies:
once "^1.3.0"
inflight "^1.0.4"
inherits "2"
minimatch "^5.0.1"
fs.realpath "^1.0.0"

glob-parent@^5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
Expand Down Expand Up @@ -894,6 +910,13 @@ ignore@^5.2.0, ignore@^5.3.1:
resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz"
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==

ignore-walk@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz"
integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==
dependencies:
minimatch "^5.0.1"

import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
Expand All @@ -912,6 +935,19 @@ indent-string@^4.0.0:
resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz"
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==

inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
dependencies:
once "^1.3.0"
wrappy "1"

inherits@2:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==

is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
Expand Down Expand Up @@ -1059,13 +1095,25 @@ minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"

minimatch@^5.0.1:
version "5.1.6"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"

minimatch@^9.0.4:
version "9.0.5"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz"
integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
dependencies:
brace-expansion "^2.0.1"

mri@^1.1.0:
version "1.2.0"
resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz"
integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==

ms@^2.1.3:
version "2.1.3"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
Expand All @@ -1091,6 +1139,35 @@ normalize-package-data@^2.5.0:
hosted-git-info "^2.1.4"
validate-npm-package-license "^3.0.1"

npm-bundled@^2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/npm-bundled/-/npm-bundled-2.0.1.tgz"
integrity sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==
dependencies:
npm-normalize-package-bin "^2.0.0"

npm-normalize-package-bin@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz"
integrity sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==

npm-packlist@^5.1.3:
version "5.1.3"
resolved "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.1.3.tgz"
integrity sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==
dependencies:
glob "^8.0.1"
ignore-walk "^5.0.1"
npm-bundled "^2.0.0"
npm-normalize-package-bin "^2.0.0"

once@^1.3.0:
version "1.4.0"
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"

optionator@^0.9.3:
version "0.9.4"
resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz"
Expand Down Expand Up @@ -1168,7 +1245,7 @@ path-parse@^1.0.7:
resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==

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

publint@^0.2.12:
version "0.2.12"
resolved "https://registry.npmjs.org/publint/-/publint-0.2.12.tgz"
integrity sha512-YNeUtCVeM4j9nDiTT2OPczmlyzOkIXNtdDZnSuajAxS/nZ6j3t7Vs9SUB4euQNddiltIwu7Tdd3s+hr08fAsMw==
dependencies:
npm-packlist "^5.1.3"
picocolors "^1.1.1"
sade "^1.8.1"

punycode@^2.1.0:
version "2.3.1"
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz"
Expand Down Expand Up @@ -1260,6 +1346,13 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"

sade@^1.8.1:
version "1.8.1"
resolved "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz"
integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
dependencies:
mri "^1.1.0"

"semver@2 || 3 || 4 || 5":
version "5.7.2"
resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz"
Expand Down Expand Up @@ -1432,6 +1525,11 @@ word-wrap@^1.2.5:
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==

wrappy@1:
version "1.0.2"
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==

yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
Expand Down

0 comments on commit ec747c2

Please sign in to comment.