From a11166c39f2de103eb1e97bccb46bc1d1d04ff23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C4=8Curda?= Date: Fri, 16 Aug 2024 15:20:02 +0200 Subject: [PATCH] fixup! Feat: Example NextJS app with app router #DS-1393 --- .eslintrc.js | 1 + examples/next-with-app-router/.eslintrc.json | 107 +++++++++++++++++- examples/next-with-app-router/package.json | 1 + .../next-with-app-router/src/app/layout.tsx | 2 +- .../next-with-app-router/src/app/page.tsx | 4 +- .../next-with-app-router/tsconfig.eslint.json | 4 + yarn.lock | 3 +- 7 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 examples/next-with-app-router/tsconfig.eslint.json diff --git a/.eslintrc.js b/.eslintrc.js index ca59332c4b..da83a39496 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -23,6 +23,7 @@ module.exports = { 'packages/codemods', 'exporters/scss', 'exporters/js', + 'examples/*' ], extends: ['@lmc-eu/eslint-config-react/base', '@lmc-eu/eslint-config-react/optional', 'prettier', 'plugin:prettier/recommended', 'plugin:storybook/recommended'], diff --git a/examples/next-with-app-router/.eslintrc.json b/examples/next-with-app-router/.eslintrc.json index bffb357a71..fd84c51da3 100644 --- a/examples/next-with-app-router/.eslintrc.json +++ b/examples/next-with-app-router/.eslintrc.json @@ -1,3 +1,108 @@ { - "extends": "next/core-web-vitals" + "extends": [ + "../../.eslintrc", + "@lmc-eu/eslint-config-react", + "@lmc-eu/eslint-config-typescript", + "@lmc-eu/eslint-config-typescript/react", + "prettier", + "plugin:prettier/recommended", + "@lmc-eu/eslint-config-jest", + "plugin:@next/next/recommended" + ], + "env": { + "jest": true + }, + "plugins": ["promise", "react", "@typescript-eslint", "prettier", "react-refresh"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "project": "./tsconfig.eslint.json" + }, + "rules": { + // @see: https://github.com/ArnaudBarre/eslint-plugin-react-refresh + "react-refresh/only-export-components": "warn", + // @TODO: add to typescript config + "react/jsx-filename-extension": ["error", { "extensions": [".js", ".jsx", ".ts", ".tsx"] }], + // we like to use props spreading for additional props in this case + "react/jsx-props-no-spreading": "off", // Used inside HOC, that is fine. + // prefer arrow function over function expression + "react/function-component-definition": [ + "warn", + { "namedComponents": "arrow-function", "unnamedComponents": "arrow-function" } + ], + // we have missing displayName attribute in our components + // it is good for debugging + // @see: https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/display-name.md + "react/display-name": "off", + // ignore UNSTABLE_ prefix in component names + "react/jsx-pascal-case": [ + "error", + { + "allowAllCaps": true, + "ignore": ["UNSTABLE_*"] + } + ], + // ignore UNSAFE and UNSTABLE_ prefixes + "camelcase": [ + "error", + { + "properties": "never", + "ignoreDestructuring": false, + "allow": ["^UNSAFE_", "^UNSTABLE_"] + } + ], + // allow ++ in for loops + "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }], + // allow reassign in properties + "no-param-reassign": ["warn", { "props": false }], + // support monorepos + "import/no-extraneous-dependencies": [ + "error", + { + "packageDir": ["./", "../../"], + "peerDependencies": true + } + ], + "import/order": [ + "error", + { + "groups": ["builtin", "external", "internal", "parent", "sibling", "index"], + "pathGroups": [ + { + "pattern": "**", + "group": "internal" + }, + { + "pattern": "..", + "group": "parent", + "position": "after" + } + ], + "pathGroupsExcludedImportTypes": ["builtin"], + "alphabetize": { + "order": "asc", + "caseInsensitive": true + }, + "newlines-between": "never" + } + ], + // disable double quotes + "quotes": ["warn", "single"], + // use useIsomorphicLayoutEffect instead of useLayoutEffect + // @see: https://medium.com/@alexandereardon/uselayouteffect-and-ssr-192986cdcf7a + "no-restricted-imports": [ + "error", + // Disabling using of useLayoutEffect from react + { + "name": "react", + "importNames": ["useLayoutEffect"], + "message": "`useLayoutEffect` causes a warning in SSR. Use `useIsomorphicLayoutEffect`" + } + ], + // allow empty interfaces with single extends (e.g. interface Foo extends SpiritBar {}) + // interface which extends some other interface is not considered as meaningful interface + // we need this for meeting our component API conventions + // @see: https://typescript-eslint.io/rules/no-empty-interface/ + "@typescript-eslint/no-empty-interface": ["error", { "allowSingleExtends": true }] + } } diff --git a/examples/next-with-app-router/package.json b/examples/next-with-app-router/package.json index 257c683a08..0ad498b24e 100644 --- a/examples/next-with-app-router/package.json +++ b/examples/next-with-app-router/package.json @@ -17,6 +17,7 @@ "react-dom": "^18" }, "devDependencies": { + "@next/eslint-plugin-next": "^14.2.5", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", diff --git a/examples/next-with-app-router/src/app/layout.tsx b/examples/next-with-app-router/src/app/layout.tsx index 9a2dafdebb..4df8ca8552 100644 --- a/examples/next-with-app-router/src/app/layout.tsx +++ b/examples/next-with-app-router/src/app/layout.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import React, { ReactNode } from 'react'; const RootLayout = ({ children }: Readonly<{ children: ReactNode }>) => { return ( diff --git a/examples/next-with-app-router/src/app/page.tsx b/examples/next-with-app-router/src/app/page.tsx index 2c93a2982a..ff573b3610 100644 --- a/examples/next-with-app-router/src/app/page.tsx +++ b/examples/next-with-app-router/src/app/page.tsx @@ -1,7 +1,9 @@ import { Heading } from '@lmc-eu/spirit-web-react'; +import { NextPage } from 'next'; +import React from 'react'; import './globals.scss'; -const Home = () => { +const Home: NextPage = () => { return Spirit App Router; }; diff --git a/examples/next-with-app-router/tsconfig.eslint.json b/examples/next-with-app-router/tsconfig.eslint.json new file mode 100644 index 0000000000..dc13a26063 --- /dev/null +++ b/examples/next-with-app-router/tsconfig.eslint.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["./", "./.eslintrc.js"] +} diff --git a/yarn.lock b/yarn.lock index 9d111a0fd7..861f51d582 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4643,7 +4643,7 @@ __metadata: languageName: node linkType: hard -"@next/eslint-plugin-next@npm:14.2.5": +"@next/eslint-plugin-next@npm:14.2.5, @next/eslint-plugin-next@npm:^14.2.5": version: 14.2.5 resolution: "@next/eslint-plugin-next@npm:14.2.5" dependencies: @@ -21286,6 +21286,7 @@ __metadata: "@lmc-eu/spirit-design-tokens": "workspace:^" "@lmc-eu/spirit-web": "workspace:^" "@lmc-eu/spirit-web-react": "workspace:^" + "@next/eslint-plugin-next": "npm:^14.2.5" "@types/node": "npm:^20" "@types/react": "npm:^18" "@types/react-dom": "npm:^18"