npm package: @onehoax/eslint_prettier
Description: ESLint and Prettier base configs
Author: Andres Osorio
Latest version: 0.0.6

# Prerequisites

The `@onehoax/eslint_prettier` relies on recent versions of `eslint` and its `ts, andgular` extensions,
which in turn rely on recent versions of `Angular` and `Nodejs`.
Installing and using this package may work in projects with `Angular < 18.x` and `Nodejs < 20.x`, 
but it might break under certain situations and/or when using newer linting features/rules.
It is recommended that your project comply with the following requirements to go ahead with the installation:

- `Nodejs >= 20.*` -> [reference](https://eslint.org/docs/latest/use/migrate-to-9.0.0)
- `Angular >= 18.*` -> [reference](https://github.com/angular-eslint/angular-eslint?tab=readme-ov-file#supported-angular-cli-versions)

# Installation

1. Uninstall any `eslint`, `tslint`, and `prettier` related packages (TSLint has been deprecated in favor of ESLint):  
    ```bash
    # list `eslint` packages
    > npm ls eslint tslint prettier
    # remove all `eslint` packages 
    > npm uninstall eslint tslint prettier ...
    ```

2. Install the following as dev dependencies:
    ```bash
    npm install -D @onehoax/eslint_prettier
    ```

**Note:** there is a command that automates some of the installation/configuration process
(`ng add @angular-eslint/schematics` - see references) and integrates linting with Angular's CLI, but we 
require more control over the process for our use case, therefore we do it manually.

# Configuration

1. Remove existing `eslint`, `tslint`, and `prettier` config files (TSLint has been deprecated in favor of ESLint)

2. Create files `eslint.config.mjs`, `prettier.config.mjs` on the project's root directory and place the following contents inside:
    ```js
    // eslint.config.mjs
    import angularConfigs from "@onehoax/eslint_prettier/eslint/angular";

    export default [
      ...angularConfigs.ts,
      ...angularConfigs.template,
    ];

    // prettier.config.mjs
    import baseConfig from "@onehoax/eslint_prettier/prettier/base";

    export default baseConfig;
    ```

## Overriding configs

`@onehoax/eslint_prettier/eslint/[base | angular]` contains an array of [ESLint flat configuration objets](https://eslint.org/docs/latest/use/configure/configuration-files#configuration-objects);  
`@onehoax/eslint_prettier/prettier/base` exports a `JSON` object with `prettier` options;  
you can extend/override both types of configs returned by the package by doing the following:  
```js
// eslint.config.mjs
import angularConfigs from "@onehoax/eslint_prettier/eslint/angular";

export default [
  ...angularConfigs.ts.map((config) => {
    return {
      ...config,
      rules: {
        ...config.rules,
        "unused-imports/no-unused-imports": "warn",
        "@angular-eslint/component-selector": [
          "error",
          {
            type: "element",
            prefix: "myprefix",
            style: "kebab-case",
          },
        ],
      },
    };
  }),
  ...angularConfigs.template,
];

// prettier.config.mjs
import baseConfig from "@onehoax/eslint_prettier/prettier/base";

export default {
  ...baseConfig,
  tabWidth: 4,
  ...
};
```

# Run

Add the following script to your `package.json`:
```json
{
  ...,
  "scripts": {
    ...,
    "lint": "eslint .",
    "format:check": "prettier -c './src/**/*.(ts|js|json|html|css|scss)' './test/**/*.(ts|js|json|html|css|scss)'",
    "format:write": "prettier -w './src/**/*.(ts|js|json|html|css|scss)' './test/**/*.(ts|js|json|html|css|scss)'"
  },
  ...
}
```

You can now run `npm run lint` to lint the whole project (see below for files included) or 
`npx eslint ./src/...` to lint a specific folder/file.  
Running `eslint` will only report problems to the console, it will not write anything.

Both `format` commands above run prettier against the folders/files specified:
- `npm run format:check` -> reports if the files comply with the formatting rules or not; it will not wirte any changes
- `npm run format:write` -> writes formatting changes to files according to the rules
- `npx prettier -c ./src/...` -> runs prettier check against a specific folder/file
- `npx prettier -w ./src/...` -> runs prettier write against a specific folder/file

## Files

`@onehoax/eslint_prettier/eslint/[base | angular]`'s files settings are the following for the respective rules:
- ["src/\*\*/\*.ts", "test/\*\*/\*.ts"]
- ["src/\*\*/\*.html"]  

Therefore you don't need to specify the files to run `eslint` against unless you want to check other files.

## Gradual Integration

### Starting Point

- It is the developer's responsibility to keep their code clean according to the linting/formatting rules  
- Focus on checking whatever files you're working on at the moment and fix those problems;
  fixing the whole project at once is unrealistic
- If you integrate `eslint` with your editor, it will likely show you the linting problems inline as
  you code (this is the case for `vscode` - see references below); otherwise you'll have to run `npx
  eslint <relative path to your file>` periodically  
- If you integrate `prettier` with your editor, it will format your files on-save or when you call
  the editor's format function (see references below); otherwise, run run `npx prettier <relative path to your file>` periodically  
- If the rules are too restrictive when integrating into existing projects, the developer can always
  extend/override the rules for a gradual integration

[`Prettier`](https://prettier.io/docs/en/options#require-pragma) provides a way to restrict itself to only format files that contain a special comment, called a pragma, at the top of the file.  
This is very useful when gradually transitioning large, unformatted codebases to Prettier.

### Future Goals

The goal is to integrate the linting/formatting into commit workflow and the `CI/CD` pipelines.

# References

- [ESLint Base Config](./eslint/base/README.md)
- [ESLint Angular Config](./eslint/angular/README.md)
- [Prettier Base Config](./prettier/README.md)
- [Linting with the VSCode extension for ESLint](https://github.com/angular-eslint/angular-eslint?tab=readme-ov-file#linting-with-the-vscode-extension-for-eslint)
- [Prettier Editor Integration](https://prettier.io/docs/en/editors)
- [Prettier Pre-commit Hook](https://prettier.io/docs/en/precommit)
- [Prettier Gradual Transition](https://prettier.io/docs/en/options#require-pragma)

# TODO 

- [ ] Integrate as part commit workflow ([`Husky`](https://typicode.github.io/husky/) and `pre-commit hooks`)
- [ ] Integrate as part of CI/CD