diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89b6ff64..e59ccf5d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,7 +69,7 @@ jobs: run: yarn install - name: Css Lint - run: yarn css-lint + run: yarn lint:css typecheck: name: Typecheck runs-on: ubuntu-latest diff --git a/.unimportedrc.json b/.unimportedrc.json index 14a2d972..2baf1ef6 100644 --- a/.unimportedrc.json +++ b/.unimportedrc.json @@ -1,11 +1,17 @@ { - "entry": ["./src/main.tsx"], + "entry": ["./src/index.tsx"], "ignorePatterns": ["**/node_modules/**", "build/**"], - "ignoreUnimported": ["**/*.d.ts"], - "ignoreUnused": [], + "ignoreUnimported": ["**/*.d.ts", "**/*.test.*"], + "ignoreUnused": [ + "@apollo/client", + "@graphql-codegen/introspection", + "@graphql-codegen/typescript-operations", + "@togglecorp/re-map", + "@sentry/react" + ], "extensions": [".ts", ".js", ".tsx", ".jsx"], "aliases": { - "#views/*": ["./src/views/*"], - "#utils/*": ["./src/utils/*"] + "#utils/*": ["./src/utils/*"], + "#views/*": ["./src/views/*"] } } diff --git a/CHECKLIST.md b/CHECKLIST.md deleted file mode 100644 index 72042dc7..00000000 --- a/CHECKLIST.md +++ /dev/null @@ -1,76 +0,0 @@ -# Checklist - -## Build Requirements - -- [x] Vite - - [x] Compression - - [x] Sourcemaps - - [x] Environment variables (validation and typesafe) - - [x] Versioning -- [x] Babel or SWC (for transpiling) - - [ ] Polyfilling -> https://github.com/alloc/vite-plugin-legacy -- [ ] Bundle Visualizer -> https://github.com/btd/rollup-plugin-visualizer - -## DX-1 Requirements - -- [x] Absolute imports (configure eslint and vite) -- [x] React Hot Reloading -- [x] Postcss - - [x] CSS Modules - - [x] Nested CSS - - [x] Normalize CSS - - [x] Autoprefixer - - [ ] Setup lint for unused css modules -- [x] Typescript -- [x] Stylelint -- [x] Unimported -- [x] Eslint - - [ ] Multiple configurations -- [x] Testing - -## DX-2 Requirements - -- [x] Docker -- [x] Github Actions - - [x] Parallel execution - - [x] Eslint - - [x] Stylelint - - [x] Typescript - - [x] Build - - [x] Testing -- [x] PR templates -- [x] Documentations - -### Web App Requirements - -- [x] Fonts -- [ ] Sentry -- [ ] i18n -- [ ] Captcha -- [ ] Images -> https://github.com/ElMassimo/vite-plugin-image-presets -- [ ] Icons -> https://github.com/antfu/unplugin-icons -- [ ] PWA -> https://github.com/vite-pwa/vite-plugin-pwa -- [ ] Analytics -> https://github.com/stafyniaksacha/vite-plugin-radar - -#### Routing and Auth - -- [x] Routing - - [x] Typesafe - - [ ] Error boundaries - - [ ] Authenticate/Authorize -- [ ] Link with permissions -- [ ] Detect login on different tab -- [ ] Login as certain user - -#### Network - -- [ ] GraphQL -- [ ] GraphQL Code Generator - - [ ] Typescript Types - -### UI Library Requirements - -- [ ] Storybook -- [ ] NPM package - -### Static Site Generation diff --git a/docker-compose.yml b/docker-compose.yml index 3f19cad0..0ff5e2f8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,9 +2,7 @@ version: '3.8' services: react: build: . - command: sh -c 'yarn install && yarn dev --host' - environment: - APP_TITLE: ${APP_TITLE:-React Base App} + command: sh -c 'yarn install && yarn start --host' volumes: - .:/code ports: diff --git a/eslint.config.js b/eslint.config.js index 7c802424..67c54cda 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,10 +1,8 @@ import { FlatCompat } from '@eslint/eslintrc'; import js from '@eslint/js'; -import path from 'path'; -import { fileURLToPath } from 'url'; +import process from 'process'; -const filename = fileURLToPath(import.meta.url); -const dirname = path.dirname(filename); +const dirname = process.cwd(); const compat = new FlatCompat({ baseDirectory: dirname, @@ -13,9 +11,11 @@ const compat = new FlatCompat({ const appConfigs = compat.config({ env: { + node: true, browser: true, es2020: true, }, + root: true, extends: [ 'airbnb', 'airbnb/hooks', @@ -30,14 +30,18 @@ const appConfigs = compat.config({ plugins: [ '@typescript-eslint', 'react-refresh', + 'simple-import-sort', + 'import-newlines' ], settings: { 'import/parsers': { - '@typescript-eslint/parser': ['.ts', '.tsx'] + '@typescript-eslint/parser': ['.ts', '.tsx'] }, 'import/resolver': { - typescript: { - project: './tsconfig.json', + typescript: { + project: [ + './tsconfig.json', + ], }, }, }, @@ -72,6 +76,7 @@ const appConfigs = compat.config({ 'import/no-cycle': ['error', { allowUnsafeDynamicCyclicDependency: true }], 'react/react-in-jsx-scope': 'off', + 'camelcase': 'off', 'react/jsx-indent': ['error', 4], 'react/jsx-indent-props': ['error', 4], @@ -83,7 +88,35 @@ const appConfigs = compat.config({ 'react-hooks/exhaustive-deps': 'warn', 'react/require-default-props': ['warn', { ignoreFunctionalComponents: true }], + 'simple-import-sort/imports': 'warn', + 'simple-import-sort/exports': 'warn', + 'import-newlines/enforce': ['warn', 1] }, + overrides: [ + { + files: ['*.js', '*.jsx', '*.ts', '*.tsx'], + rules: { + 'simple-import-sort/imports': [ + 'error', + { + 'groups': [ + // side effect imports + ['^\\u0000'], + // packages `react` related packages come first + ['^react', '^@?\\w'], + // internal packages + ['^#.+$'], + // parent imports. Put `..` last + // other relative imports. Put same-folder imports and `.` last + ['^\\.\\.(?!/?$)', '^\\.\\./?$', '^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'], + // style imports + ['^.+\\.json$', '^.+\\.module.css$'], + ] + } + ] + } + } + ] }).map((conf) => ({ ...conf, files: ['src/**/*.tsx', 'src/**/*.jsx', 'src/**/*.ts', 'src/**/*.js'], diff --git a/index.html b/index.html index e0322f2c..ce1d6e84 100644 --- a/index.html +++ b/index.html @@ -8,7 +8,7 @@ %APP_TITLE% - + + + + + -
+
+
+ %APP_TITLE% loading... +
+