• ใช้ การจัดโค้ดเมื่อบันทึก ของ VSCode โดยใส่ config ตามด้านล่างนี้ ที่ .vscode/settings.json และจำเป็นต้องมี extension ESLint

    {
      "eslint.enable": true,
      "eslint.format.enable": true,
      "editor.defaultFormatter": "dbaeumer.vscode-eslint",
      "editor.formatOnSave": true,
      "editor.formatOnPaste": true,
      "emmet.showExpandedAbbreviation": "never",
      "editor.codeActionsOnSave": {
        "source.fixAll.eslint": "explicit"
      },
      "[typescriptreact]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
      },
      "[typescript]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
      },
      "[javascript]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
      },
      "[javascriptreact]": {
        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
      }
    }
  • ใช้ ESLint ในการจัด code โดยใส่ config ตามด้านล่างนี้ ที่ eslint.config.js

    import js from '@eslint/js';
    import importPlugin from 'eslint-plugin-import';
    import reactHooks from 'eslint-plugin-react-hooks';
    import reactRefresh from 'eslint-plugin-react-refresh';
    import globals from 'globals';
    import tseslint from 'typescript-eslint';
     
    export default tseslint.config(
      { ignores: ['dist'] },
      {
        extends: [
          js.configs.recommended,
          ...tseslint.configs.recommended,
          ...tseslint.configs.stylistic,
          importPlugin.flatConfigs.recommended
        ],
        files: ['**/*.{ts,tsx}'],
        languageOptions: {
          ecmaVersion: 2020,
          sourceType: 'module',
          parser: tseslint.parser,
          parserOptions: {
            ecmaFeatures: { jsx: true },
          },
          globals: {
            ...globals.browser,
            React: 'readonly',
          },
        },
        settings: {
          'import/parsers': {
            '@typescript-eslint/parser': ['.ts', '.tsx']
          },
          'import/resolver': {
            typescript: true,
            node: true,
          },
        },
        plugins: {
          'react-hooks': reactHooks,
          'react-refresh': reactRefresh,
          '@typescript-eslint': tseslint.plugin
        },
        rules: {
          ...reactHooks.configs.recommended.rules,
          '@typescript-eslint/no-namespace': 'off',
          '@typescript-eslint/no-unused-vars': 'error',
          'no-console': ['error', { allow: ['warn', 'error'] }],
          'indent': ['error', 2],
          'linebreak-style': ['error', 'unix'],
          'quotes': ['error', 'single'],
          'semi': ['error', 'always'],
          'no-multiple-empty-lines': ['error', { 'max': 1 }],
          'object-curly-spacing': ['error', 'always'],
          'array-bracket-spacing': ['error', 'never'],
          'react-refresh/only-export-components': [ 'warn', { allowConstantExport: true }, ],
          
          'import/order': [
            'error', {
              pathGroups: [
                {
                  // Minimatch pattern used to match against specifiers
                  "pattern": "@/**",
                  // The predefined group this PathGroup is defined in relation to
                  "group": "parent",
                  // How matching imports will be positioned relative to "group"
                  "position": "after"
                }
              ],
              groups: [
                'builtin',
                'external',
                'internal',
                'parent',
                'sibling',
                'index'
              ],
              'newlines-between': 'always',
              alphabetize: { order: 'asc', caseInsensitive: true },
            }
          ]
        }
      },
    )