npm package: @lunit/eslint-config
Description: Lunit ESLint Config
Author: Larry Kim
Latest version: 2.0.0

# @lunit/eslint-config

A TypeScript ESLint ruleset designed for Lunit projects based on [@rushstack/eslint-config](https://github.com/microsoft/rushstack/tree/main/eslint/eslint-config).

This ESLint configuration is only available for TypeScript projects.

## Installation

```shell
npm install --save-dev @lunit/eslint-config
```

## Usage

### Getting Started

`@lunit/eslint-config v2.x` is configured using the ESLint Flat Config approach.

For information regarding ESLint Flat Config, please refer to the relevant ESLint Blog post.
- https://eslint.org/blog/2022/08/new-config-system-part-2/


To use it, add @lunit/eslint-config to your eslint.config.js file as follows.
If you are using TypeScript ESLint rules, please remove them.
This is already being used in Rushstack ESLint, causing conflict issues.


#### ESM

```javascript
// eslint.config.js
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import { defineConfig, globalIgnores } from "eslint/config";
import eslintConfig from '@lunit/eslint-config';

export default defineConfig([
  globalIgnores(["dist"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      js.configs.recommended,
      reactHooks.configs.flat["recommended-latest"],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
  },
  lunitEslintConfig,
]);
```

#### CommonJS

```javascript
// eslint.config.cjs
const js = require("@eslint/js");
const  globals = require("globals");
const reactHooks = require("eslint-plugin-react-hooks");
const reactRefresh = require("eslint-plugin-react-refresh");
const { defineConfig, globalIgnores } = require("eslint/config");
const lunitEslintConfig = require('@lunit/eslint-config');

module.exports = defineConfig([
  globalIgnores(["dist"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      js.configs.recommended,
      reactHooks.configs.flat["recommended-latest"],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
  },
  // You can add the ESLint Config rules as follows.
  lunitEslintConfig,
]);
```

> If you created the app using vite,
> please refer to the information below.

If the tsconfig.json file is separate and the actual rules are applied in `tsconfig.app.json`,
please configure it as follows.

rushstack eslint config internally follows the rules set in tsconfig,
so you must link the corresponding JSON file.

#### ESM
```js
// eslint.config.js
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import { defineConfig, globalIgnores } from "eslint/config";
import eslintConfig from '@lunit/eslint-config';

export default defineConfig([
  globalIgnores(["dist"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      js.configs.recommended,
      reactHooks.configs.flat["recommended-latest"],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
  },
  {
    ...eslintConfig,
    // You must integrate the tsconfig.app.json file applied to the actual ts and tsx files as shown below.
    languageOptions: {
      parserOptions: {
        project: ["./tsconfig.app.json"],
        tsconfigRootDir: import.meta.dirname,
      },
    },
  }
]);
```

#### CommonJS

```js
// eslint.config.cjs
const js = require("@eslint/js");
const  globals = require("globals");
const reactHooks = require("eslint-plugin-react-hooks");
const reactRefresh = require("eslint-plugin-react-refresh");
const { defineConfig, globalIgnores } = require("eslint/config");
const lunitEslintConfig = require('@lunit/eslint-config');

module.exports = defineConfig([
  globalIgnores(["dist"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      js.configs.recommended,
      reactHooks.configs.flat["recommended-latest"],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
  },
  {
    ...lunitEslintConfig,
    // You must integrate the tsconfig.app.json file applied to the actual ts and tsx files as shown below.
    languageOptions: {
      parserOptions: {
        project: ["./tsconfig.app.json"],
        tsconfigRootDir: __dirname,
      },
    },
  }
]);
```

### Advanced

#### Override rushstack eslint rule

If you wish to modify the Rushstack ESLint rule, please refer to the code below.

#### ESM
```js
// eslint.config.js
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import { defineConfig, globalIgnores } from "eslint/config";
import eslintConfig from '@lunit/eslint-config';

export default defineConfig([
  globalIgnores(["dist"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      js.configs.recommended,
      reactHooks.configs.flat["recommended-latest"],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
  },
  {
    // Using Spread Operator lunit Eslint Config
    ...lunitEslintConfig,
    rules: {
      // Using Spread Operator lunit Eslint Config Rules
      ...lunitEslintConfig.rules,
      // And apply the target rule
      '@rushstack/no-new-null': 'error',
    },
  }
]);
```

#### CommonJS

```js
// eslint.config.cjs
const js = require("@eslint/js");
const  globals = require("globals");
const reactHooks = require("eslint-plugin-react-hooks");
const reactRefresh = require("eslint-plugin-react-refresh");
const { defineConfig, globalIgnores } = require("eslint/config");
const lunitEslintConfig = require('@lunit/eslint-config');

module.exports = defineConfig([
  globalIgnores(["dist"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [
      js.configs.recommended,
      reactHooks.configs.flat["recommended-latest"],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
  },
  {
    // Using Spread Operator lunit Eslint Config
    ...lunitEslintConfig,
    rules: {
      // Using Spread Operator lunit Eslint Config Rules
      ...lunitEslintConfig.rules,
      // And apply the target rule
      '@rushstack/no-new-null': 'error',
    },
  }
]);
```

#### Migrate 1.x to 2.x

Since migration to the ESLint flat config is required,
please refer to the official ESLint documentation guide below.

- https://eslint.org/docs/latest/use/configure/migration-guide