Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(config): adopt projectService and remove old pathsOverrides.tsconfigLocation #205

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 0 additions & 62 deletions apps/docs-website/docs/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -348,72 +348,10 @@ As outlined in the [criteria](./core-philosophy/criteria.md) page, Sheriff comes

```ts
pathsOverrides: {
tsconfigLocation: string | string[];
tests: string[];
}
```

#### `pathsOverrides.tsconfigLocation`

By default, Sheriff will use the `project: true` option to locate the `tsconfig.json` of your project.

But, if you have multiple `tsconfig.json` files in your project (like `tsconfig.json`, `tsconfig.eslint.json`, `tsconfig.node.json`, etc...), you can use this parameter to specify which config Sheriff will pickup.

You can pass it a path as a string (or a list of paths as a array of strings, see: [one-tsconfigjson-per-package](https://typescript-eslint.io/linting/typed-linting/monorepos/#one-tsconfigjson-per-package-and-an-optional-one-in-the-root)).

Example:

<Tabs groupId="esmorcjs">
<TabItem value="ESM" label="ESM">

```js title="eslint.config.js"
import sheriff from "eslint-config-sheriff";
import { defineFlatConfig } from "eslint-define-config";

const sheriffOptions = {
react: false,
next: false,
astro: false,
lodash: false,
playwright: false,
jest: false,
vitest: false,
pathsOverrides: {
// highlight-next-line
tsconfigLocation: "./tsconfig.eslint.json",
},
};

export default defineFlatConfig([...sheriff(sheriffOptions)]);
```

</TabItem>
<TabItem value="CommonJS" label="CommonJS">

```js title="eslint.config.js"
const { sheriff } = require("eslint-config-sheriff");
const { defineFlatConfig } = require("eslint-define-config");

const sheriffOptions = {
react: false,
next: false,
astro: false,
lodash: false,
playwright: false,
jest: false,
vitest: false,
pathsOverrides: {
// highlight-next-line
tsconfigLocation: "./tsconfig.eslint.json",
},
};

module.exports = defineFlatConfig([...sheriff(sheriffOptions)]);
```

</TabItem>
</Tabs>

#### `pathsOverrides.tests`

By default, Sheriff will apply Jest or Vitest rules only on specific files.
Expand Down
8 changes: 6 additions & 2 deletions packages/eslint-config-sheriff/src/getAstroConfig.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import astro from 'eslint-plugin-astro';
import { getLegacyCompatDirname } from './utils/getLegacyCompatDirname';

export const getAstroConfig = (
hasReact: boolean,
customTSConfigPath: string | string[] | undefined,
disableProjectService: boolean,
) => {
return [
...astro.configs.recommended,
Expand All @@ -11,7 +12,10 @@ export const getAstroConfig = (
files: ['**/*.astro'],
languageOptions: {
parserOptions: {
project: customTSConfigPath || true,
...(disableProjectService ? {} : { projectService: true }),
tsconfigRootDir: disableProjectService
? undefined
: getLegacyCompatDirname(),
},
},
settings: {
Expand Down
6 changes: 3 additions & 3 deletions packages/eslint-config-sheriff/src/getBaseConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ import globals from 'globals';
export const getBaseConfig = (
userConfigChoices: SheriffSettings,
): TSESLint.FlatConfig.ConfigArray => {
const customTSConfigPath = userConfigChoices.pathsOverrides?.tsconfigLocation;

return tseslint.config(
{
files: [supportedFileTypes],
Expand All @@ -46,7 +44,9 @@ export const getBaseConfig = (
},
{
files: [`**/*{${allJsExtensions}}`],
languageOptions: getLanguageOptionsTypescript(customTSConfigPath),
languageOptions: getLanguageOptionsTypescript(
userConfigChoices.disableProjectService ?? false,
),
},
{
files: [supportedFileTypes],
Expand Down
11 changes: 7 additions & 4 deletions packages/eslint-config-sheriff/src/getExportableConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const getExportableConfig = (
if (userConfigChoices.react || userConfigChoices.next) {
// we insert reactConfig this way because it's an array. It's an array because it contains multiple configs, currently: react, react-hooks, react-a11y and react-refresh.
exportableConfig.push(
...getReactConfig(userConfigChoices.pathsOverrides?.tsconfigLocation),
...getReactConfig(userConfigChoices.disableProjectService ?? false),
);
}

Expand Down Expand Up @@ -60,11 +60,14 @@ export const getExportableConfig = (
}

if (userConfigChoices.astro) {
const customTSConfigPath =
userConfigChoices.pathsOverrides?.tsconfigLocation;
const hasReact = Boolean(userConfigChoices.react);

exportableConfig.push(...getAstroConfig(hasReact, customTSConfigPath));
exportableConfig.push(
...getAstroConfig(
hasReact,
userConfigChoices.disableProjectService ?? false,
),
);
}

if (userConfigChoices.playwright) {
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-config-sheriff/src/getReactConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ import { getLanguageOptionsTypescriptReact } from './utils/getLanguageOptionsTyp
import { type TSESLint } from '@typescript-eslint/utils';

export const getReactConfig = (
customTSConfigPath?: string | string[],
disableProjectService: boolean,
): TSESLint.FlatConfig.ConfigArray => {
return tseslint.config(
{
// we are specifically not including .astro files here, to not overwrite astro-eslint-parser.
files: [`**/*{${allJsExtensions},${allJsxExtensions}}`],
languageOptions: getLanguageOptionsTypescriptReact(customTSConfigPath),
languageOptions: getLanguageOptionsTypescriptReact(disableProjectService),
},
{
files: [supportedFileTypes],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import tseslint from 'typescript-eslint';
import { getLegacyCompatDirname } from './getLegacyCompatDirname';

export const getLanguageOptionsTypescript = (
userChosenTSConfig?: string | string[],
disableProjectService: boolean,
) => {
return {
parser: tseslint.parser,
parserOptions: {
ecmaFeatures: { modules: true },
project: userChosenTSConfig || true,
...(disableProjectService ? {} : { projectService: true }),
tsconfigRootDir: disableProjectService
? undefined
: getLegacyCompatDirname(),
},
};
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import globals from 'globals';
import tseslint from 'typescript-eslint';
import { getLegacyCompatDirname } from './getLegacyCompatDirname';

export const getLanguageOptionsTypescriptReact = (
userChosenTSConfig?: string | string[],
disableProjectService: boolean,
) => {
return {
parser: tseslint.parser,
parserOptions: {
ecmaFeatures: { modules: true, jsx: true },
project: userChosenTSConfig || true,
...(disableProjectService ? {} : { projectService: true }),
tsconfigRootDir: disableProjectService
? undefined
: getLegacyCompatDirname(),
jsxPragma: null, // useful for typescript x react@17 https://github.com/jsx-eslint/eslint-plugin-react/blob/8cf47a8ac2242ee00ea36eac4b6ae51956ba4411/index.js#L165-L179
},
globals: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

export const getLegacyCompatDirname = () => {
const isESM = typeof import.meta !== 'undefined';
return isESM ? dirname(fileURLToPath(import.meta.url)) : __dirname;
// return url.fileURLToPath(new URL('.', isESM ? import.meta.url : __filename)); // alternative code
};
13 changes: 9 additions & 4 deletions packages/sheriff-types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,6 @@ export interface SheriffSettings extends Partial<SheriffConfigurablePlugins> {
* This parameter allows you to override the paths for some Sheriff settings.
*/
pathsOverrides?: {
/**
* With this setting, if you have multiple tsconfig.json files in your project (like tsconfig.json, tsconfig.eslint.json, tsconfig.node.json, etc...) you can specify which config Sheriff will pickup. You can also specify a list of paths, see: https://typescript-eslint.io/linting/typed-linting/monorepos/#one-tsconfigjson-per-package-and-an-optional-one-in-the-root.
*/
tsconfigLocation?: string | string[];
/**
* This setting overrides the default Sheriff filepaths for test files. It accepts an array of filepaths, dictaced by minimatch syntax. Sheriff will apply Jest or Vitest rules only on these files.
*/
Expand All @@ -115,6 +111,15 @@ export interface SheriffSettings extends Partial<SheriffConfigurablePlugins> {
* This setting accepts an array of filepaths, dictaced by minimatch syntax. Only the matching files found in this array will be linted. All other files will be ignored. This is useful if you want to lint only a subset of your project.
*/
files?: string[];
/**
* `projectService` is enabled by default. If for whatever reason `projectService` is causing you issues, you can disable it.
* For example, if you want to just use the legacy `project` option.
* See https://typescript-eslint.io/packages/parser/#projectservice.
*
* WARNING: disabling `projectService` is extremely discouraged, as the entire linting will probably break.
* At the very least, you should enable the `project` option as an alternative.
*/
disableProjectService?: boolean;
}

export interface ServerResponse {
Expand Down