Skip to content

@onerepo/plugin-eslint

Install via npm
npm install --save-dev @onerepo/plugin-eslint

Eslint 9 moved from a multi-RC/cascading config system to flat configs. As welcome of a change this was, it broke one of the fundamental tenets of monorepos: Workspace-specific configurations should be contained within the Workspace’s root and should not pollute outside itself in the global scope.

With the flat configuration format, either all rules need to be hard coded into the root configuration file or developers need to know to manually export their workspace configurations and import them directly into the flat config.

This plugin solves some of the flat config short-comings by automatically spreading eslint configs from workspaces into the root config.

  1. Create a root config

    This will be your monorepo-wide configuration. All global plugins and rules should be set here.

    eslint.config.js
    import eslint from '@eslint/js';
    export default [{ ignores: ['**/dist'] }, eslint.configs.recommended];
  2. Wrap your root config

    eslint.config.js
    import eslint from '@eslint/js';
    import onerepoEslint from '@onerepo/plugin-eslint/config';
    export default onerepoEslint({ ignores: ['**/dist'] }, eslint.configs.recommended);

    This wrapper is optional in general, but required if you would like to have make Workspace-specific configurations that will not bleed across their own boundaries and affect other Workspaces.

  3. Add Workspace configs

    You can now create ESLint flat configs in each workspace as if they were the root of your workspace and each workspace will be merged into the repository’s root config with the appropriate file selectors and ignores set — resulting in a single “flat config” as read by ESLint that will prevent individual Workspace rules from conflicting with each other.

    my-workspace/eslint-config.js
    import pluginAstro from 'eslint-plugin-astro';
    export default [
    { ignores: '.astro/**' },
    ...pluginAstro.configs.recommended,
    {
    rules: {
    'import/no-unresolved': ['error', { ignore: ['astro:*'] }],
    },
    },
    ];

    Notice that file paths and ignores are relative to the Workspace. When the onerepoEslint wrapper is applied to the repository’s root eslint.config, all file paths will be appropriately resolved to only affect files within the given Workspace. This prevents any rules and configurations from unintentionally bleeding across to other Workspaces.

function eslint(opts): Plugin;

Include the eslint plugin in your oneRepo plugin setup:

onerepo.config.ts
import { eslint } from '@onerepo/plugin-eslint';
export default {
plugins: [eslint()],
};
ParameterType
optsOptions
type Options = {
githubAnnotate?: boolean;
name?: string | string[];
warnings?: boolean;
};

Options for configuring the ESLint plugin for oneRepo.

onerepo.config.js
export default {
plugins: [
eslint({
name: ['lint', 'eslint'],
}),
],
};
optional githubAnnotate: boolean;

When true or unset and run in GitHub Actions, any files failing format checks will be annotated with an error in the GitHub user interface.

optional name: string | string[];

The name of the eslint command. You might change this to 'lint' or ['lint', 'eslint'] to keep things more familiar for most developers.

optional warnings: boolean;

Control the ESLint setting default to suppress warnings and only report errors.

./onerepo.config.ts
import type { Config } from 'onerepo';
export default {
tasks: {
'pre-commit': {
serial: ['$0 eslint --add'],
},
'pre-merge': {
serial: ['$0 eslint --all --no-fix'],
},
},
} satisfies Config;

If you’re also running Prettier, it is important to run ESLint _before__ Prettier. Do this by creating sequential tasks: an array of tasks within the serial tasks array:

./onerepo.config.ts
import type { Config } from 'onerepo';
export default {
tasks: {
'pre-commit': {
serial: [['$0 eslint --add', '$0 prettier --add']],
},
'pre-merge': {
serial: [['$0 eslint --all --no-fix', '$0 prettier --check']],
},
},
} satisfies Config;

Aliases: one lint

Run eslint across files and Workspaces.

Terminal window
one eslint [options...]
OptionTypeDescription
--addbooleanAdd modified files after write to the git stage.
--affectedbooleanSelect all affected Workspaces. If no other inputs are chosen, this will default to true.
--all, -abooleanRun across all Workspaces
--cacheboolean, default: trueUse cache if available
--files, -farrayDetermine Workspaces from specific files
--fixboolean, default: trueApply auto-fixes if possible
--prettyboolean, default: trueControl ESLint’s --color flag.
--stagedbooleanUse files on the git stage to calculate affected files or Workspaces. When unset or --no-staged, changes will be calculated from the entire branch, since its fork point.
--warnings, --warnbooleanReport warnings from ESLint.
--workspaces, -warrayList of Workspace names to run against
Advanced options
OptionTypeDescription
--from-refstringGit ref to start looking for affected files or Workspaces
--github-annotateboolean, default: trueAnnotate files in GitHub with errors when failing lint checks in GitHub Actions
--show-advancedbooleanPair with --help to show advanced options.
--through-refstringGit ref to start looking for affected files or Workspaces