[web] Add ESLint to enforce HMR how vite likes it (#1433)

Configuration changes taken from the vite starter (react-ts).

From the [vite
docs](https://github.com/vitejs/vite-plugin-react-swc?tab=readme-ov-file#consistent-components-exports)

> For React refresh to work correctly, your file should only export
React components.
>
> If an incompatible change in exports is found, the module will be
invalidated. To make it easier to export simple constants alongside your
component the module is only invalidated when their value changes.

While we're not currently using vite for our main apps, it would be
worthwhile to write code in a way that a future migration to it is
painless if needed.

About the what and the why, the Gatsby docs are illuminating:

https://www.gatsbyjs.com/docs/reference/local-development/fast-refresh/#how-it-works

Some other refs:
- https://github.com/ArnaudBarre/eslint-plugin-react-refresh
-
https://github.com/vitejs/vite/discussions/4577#discussioncomment-1161007
- https://github.com/vitejs/vite-plugin-react/issues/34
This commit is contained in:
Manav Rathi 2024-04-13 18:57:24 +05:30 committed by GitHub
commit a6887e3037
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 18 additions and 8 deletions

View file

@ -1385,7 +1385,6 @@ export async function moveToHiddenCollection(files: EnteFile[]) {
hiddenCollection = await createHiddenCollection();
}
const groupiedFiles = groupFilesBasedOnCollectionID(files);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const [collectionID, files] of groupiedFiles.entries()) {
if (collectionID === hiddenCollection.id) {
continue;
@ -1404,7 +1403,6 @@ export async function unhideToCollection(
) {
try {
const groupiedFiles = groupFilesBasedOnCollectionID(files);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const [collectionID, files] of groupiedFiles.entries()) {
if (collectionID === collection.id) {
continue;

View file

@ -17,6 +17,8 @@ package:
- "eslint-plugin-react-hooks", "eslint-plugin-react-namespace-import" - Some
React specific ESLint rules and configurations that are used by the
workspaces that have React code.
- "eslint-plugin-react-refresh" - A plugin to ensure that React components are
exported in a way that they can be HMR-ed.
- "prettier-plugin-organize-imports" - A Prettier plugin to sort imports.
- "prettier-plugin-packagejson" - A Prettier plugin to also prettify
`package.json`.

View file

@ -27,7 +27,7 @@
"dev:payments": "yarn workspace payments dev",
"dev:photos": "yarn workspace photos next dev",
"dev:staff": "yarn workspace staff dev",
"lint": "yarn prettier --check . && yarn workspaces run eslint --report-unused-disable-directives",
"lint": "yarn prettier --check . && yarn workspaces run eslint --report-unused-disable-directives .",
"lint-fix": "yarn prettier --write . && yarn workspaces run eslint --fix .",
"preview": "yarn preview:photos",
"preview:accounts": "yarn build:accounts && python3 -m http.server -d apps/accounts/out 3001",

View file

@ -5,5 +5,12 @@ module.exports = {
"plugin:react/recommended",
"plugin:react-hooks/recommended",
],
plugins: ["react-refresh"],
settings: { react: { version: "18.2" } },
rules: {
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
};

View file

@ -7,6 +7,7 @@
"@typescript-eslint/parser": "^7",
"eslint-plugin-react": "^7.34",
"eslint-plugin-react-hooks": "^4.6",
"eslint-plugin-react-refresh": "^0.4.6",
"prettier-plugin-organize-imports": "^3.2",
"prettier-plugin-packagejson": "^2.4"
}

View file

@ -24,6 +24,7 @@ module.exports = {
"max-len": "off",
"new-cap": "off",
"no-invalid-this": "off",
"no-throw-literal": "error",
// TODO(MR): We want this off anyway, for now forcing it here
eqeqeq: "off",
"object-curly-spacing": ["error", "always"],

View file

@ -148,7 +148,6 @@ const openOPFSCacheWeb = async (name: BlobCacheNamespace) => {
const root = await navigator.storage.getDirectory();
const caches = await root.getDirectoryHandle("cache", { create: true });
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const cache = await caches.getDirectoryHandle(name, { create: true });
return {

View file

@ -125,7 +125,6 @@ class HTTPService {
/**
* Returns axios interceptors.
*/
// eslint-disable-next-line class-methods-use-this
public getInterceptors() {
return axios.interceptors;
}
@ -137,7 +136,6 @@ class HTTPService {
* over what was sent in config.
*/
public async request(config: AxiosRequestConfig, customConfig?: any) {
// eslint-disable-next-line no-param-reassign
config.headers = {
...this.headers,
...config.headers,

View file

@ -2,7 +2,6 @@ import { Shadow, ThemeColorsOptions } from "@mui/material";
import { Components } from "@mui/material/styles/components";
import { TypographyOptions } from "@mui/material/styles/createTypography";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const getComponents = (
colors: ThemeColorsOptions,
typography: TypographyOptions,

View file

@ -2290,6 +2290,11 @@ eslint-plugin-jsx-a11y@^6.7.1:
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3"
integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==
eslint-plugin-react-refresh@^0.4.6:
version "0.4.6"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.6.tgz#e8e8accab681861baed00c5c12da70267db0936f"
integrity sha512-NjGXdm7zgcKRkKMua34qVO9doI7VOxZ6ancSvBELJSSoX97jyndXcSoa8XBh69JoB31dNz3EEzlMcizZl7LaMA==
eslint-plugin-react@^7.33.2:
version "7.33.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608"
@ -3311,7 +3316,7 @@ libsodium-wrappers@0.7.9:
dependencies:
libsodium "^0.7.0"
libsodium@0.7.9, libsodium@^0.7.0:
libsodium@^0.7.0:
version "0.7.9"
resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.9.tgz#4bb7bcbf662ddd920d8795c227ae25bbbfa3821b"
integrity sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A==