eslint-plugin-boundaries icon indicating copy to clipboard operation
eslint-plugin-boundaries copied to clipboard

Eslint 9 support

Open budarin opened this issue 1 year ago • 4 comments

Compatibility with ESLint 9 is required

budarin avatar May 15 '24 20:05 budarin

Given the amount of breaking changes in eslint v9, there are many packages that haven't implemented official support for it yet. This includes some packages being dependency or devDependency of this one.

For example, @typescript/eslint-plugin don't support v9 officially yet

I'm thinking about trying to publish a new major beta version with support for v9 to ensure that it works before declaring a major formal release. After some time, after checking its stability and updating dependencies while they also adapt to this change, then we will give official support and publish a stable major version.

javierbrea avatar May 16 '24 17:05 javierbrea

Meanwhile, I'll leave the issue open for tracking the publication of the beta version @budarin . Thanks for opening it, by the way!

javierbrea avatar May 16 '24 17:05 javierbrea

I have just released the v5.0.0-beta.0, which already supports eslint v9.

Even when it seems that everything works in tests, I will keep it in beta version until some dependencies also support it officially, just to ensure that everything works as expected in all the examples in the documentation, specially those related to the presets exported by this plugin, and to the TypeScript usage.

Specifically, it is required to stay up to date about the progress of next issues in other projects:

  • https://github.com/typescript-eslint/typescript-eslint/issues/8211
  • https://github.com/import-js/eslint-plugin-import/issues/2948

Meanwhile, the code of the beta version supporting eslint v9 will be maintained in the release-eslint-v9 branch. The pending tasks, such as modify all examples to adapt them to the new eslint format will be progressively added to that branch until it is definitively merged and a stable release is published. So, I will keep this issue open until then.

javierbrea avatar Jun 17 '24 17:06 javierbrea

typescript-eslint and eslint-plugin-import now support V9! 🚀

Are there any other projects with concerns?

brianrodri avatar Oct 20 '24 07:10 brianrodri

Hello! I install 5.0.0-beta.1 and configure it, by plugin is not working:

// Config generated by vite starter (`pnpm create vite`)

import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import eslintPluginBoundaries from 'eslint-plugin-boundaries'
import tseslint from 'typescript-eslint'

export default tseslint.config(
  { ignores: ['dist'] },
  {
    extends: [js.configs.recommended, ...tseslint.configs.recommended],
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
    plugins: {
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      'react-refresh/only-export-components': [
        'warn',
        { allowConstantExport: true },
      ],
    },
  },

 // Add follow lines
  {
    plugins: {
      boundaries: eslintPluginBoundaries,
    },
  },
  eslintPluginBoundaries.configs.recommended,
  {
    settings: {
      'boundaries/elements': [
        {
          type: 'shared',
          pattern: 'shared/*',
        },
        {
          type: 'modules',
          pattern: 'modules/*',
        },
      ],
    },
    rules: {
      'boundaries/element-types': ['error', {
        default: 'disallow',
        rules: [
          {
            from: 'modules',
            allow: ['shared'],
          },
        ],
      }],
    },
  },
)
.
├── src
│   ├── modules
│   │   └── product
│   │       └── index.ts
│   ├── shared
│   │   └── test.ts
│   └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
// src/shared/test.ts
import { ProductService } from '../modules/product';

console.log(ProductService);

If i remove eslintPluginBoundaries.configs.recommended and settings, i got warning from plugin [boundaries]: Please provide element types using the 'boundaries/elements' setting, so plugin is included and rule boundaries/element-types executed. But there are not any validation.

So do I have mistake in config or plugin is not working with eslint 9 flat config now?

noveogroup-amorgunov avatar Oct 28 '24 16:10 noveogroup-amorgunov

@noveogroup-amorgunov,

It works with this syntax:

export default tsEslint.config({
  files: ["**/*.ts"],
  plugins: {
    boundaries: eslintPluginBoundaries,
  },
  settings: {
    "boundaries/elements": [],
  },
  rules: {
    ...eslintPluginBoundaries.configs.recommended.rules,
  },
});

5im0n avatar Oct 31 '24 16:10 5im0n

Hello! I install 5.0.0-beta.1 and configure it, by plugin is not working:

// Config generated by vite starter (`pnpm create vite`)

import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import eslintPluginBoundaries from 'eslint-plugin-boundaries'
import tseslint from 'typescript-eslint'

export default tseslint.config(
  { ignores: ['dist'] },
  {
    extends: [js.configs.recommended, ...tseslint.configs.recommended],
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
    plugins: {
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      'react-refresh/only-export-components': [
        'warn',
        { allowConstantExport: true },
      ],
    },
  },

 // Add follow lines
  {
    plugins: {
      boundaries: eslintPluginBoundaries,
    },
  },
  eslintPluginBoundaries.configs.recommended,
  {
    settings: {
      'boundaries/elements': [
        {
          type: 'shared',
          pattern: 'shared/*',
        },
        {
          type: 'modules',
          pattern: 'modules/*',
        },
      ],
    },
    rules: {
      'boundaries/element-types': ['error', {
        default: 'disallow',
        rules: [
          {
            from: 'modules',
            allow: ['shared'],
          },
        ],
      }],
    },
  },
)
.
├── src
│   ├── modules
│   │   └── product
│   │       └── index.ts
│   ├── shared
│   │   └── test.ts
│   └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
// src/shared/test.ts
import { ProductService } from '../modules/product';

console.log(ProductService);

If i remove eslintPluginBoundaries.configs.recommended and settings, i got warning from plugin [boundaries]: Please provide element types using the 'boundaries/elements' setting, so plugin is included and rule boundaries/element-types executed. But there are not any validation.

So do I have mistake in config or plugin is not working with eslint 9 flat config now?

I managed to make it work by using this configuration

// @ts-check
import globals from "globals";
import pluginJs from "@eslint/js";
import ts from "typescript-eslint";
import pluginReact from "eslint-plugin-react";
import pluginReactHooks from "eslint-plugin-react-hooks";
import pluginReactRefresh from "eslint-plugin-react-refresh";
import pluginBoundaries from "eslint-plugin-boundaries";
import configPrettier from "eslint-config-prettier";

export default ts.config(
  { ignores: ["node_modules", "dist", "public"] },
  {
    languageOptions: {
      ecmaVersion: 2023,
      globals: { ...globals.browser, ...globals.node },
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
      },
    },
  },
  {
    plugins: {
      boundaries: pluginBoundaries,
    },
    settings: {
      "boundaries/dependency-nodes": ["import"],
      "boundaries/elements": [
        {
          type: "shared",
          mode: "full",
          pattern: "src/shared/**/*",
        },
        {
          type: "features",
          mode: "full",
          pattern: "src/features/**/*",
        },
        {
          type: "core",
          mode: "full",
          pattern: "src/core/**/*",
        },
        {
          type: "content",
          mode: "full",
          pattern: "src/content/**/*",
        },
      ],
      "boundaries/include": ["src/**/*"],
      "import/resolver": {
        typescript: {
          alwaysTryTypes: true,
        },
      },
    },
    rules: {
      ...pluginBoundaries.configs.recommended.rules,
      "boundaries/no-unknown": ["error"],
      "boundaries/no-unknown-files": ["error"],
      "boundaries/element-types": [
        "error",
        {
          default: "disallow",
          message: "${file.type} is not allowed to import ${dependency.type}",
          rules: [
            {
              from: ["core"],
              allow: ["core"],
            },
            {
              from: ["shared"],
              allow: ["shared", "core"],
            },
            {
              from: ["features"],
              allow: ["shared"],
            },
            {
              from: ["content"],
              allow: ["shared"],
            },
          ],
        },
      ],
    },
  },
  {
    files: ["**/*.{tsx}"],
    settings: {
      react: {
        version: "detect",
      },
    },
    plugins: {
      react: pluginReact,
      "react-refresh": pluginReactRefresh,
      "react-hooks": pluginReactHooks,
    },
    rules: {
      ...pluginReact.configs.recommended.rules,
      ...pluginReactHooks.configs.recommended.rules,
      "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
    },
  },
  pluginJs.configs.recommended,
  ...ts.configs.recommended,
  {
    rules: {
      "no-console": "error",
    },
  },
  configPrettier,
);

I also needed to install eslint-import-resolver-typescript to my devDependencies. Then restart the Eslint server.

Sortweste avatar Nov 06 '24 03:11 Sortweste

@5im0n @Sortweste thank you for examples, I fixed linting with eslint-import-resolver-typescript and add path to tsconfigs files:

      "import/resolver": {
        typescript: {
          alwaysTryTypes: true,
          "project": [
            "tsconfig.app.json",
            "tsconfig.node.json",
          ]
        },

Vite generate base tsconfig.json with references, but it's not working with paths/baseUrl aliases in tsconfig.app.json.

noveogroup-amorgunov avatar Nov 08 '24 20:11 noveogroup-amorgunov

Adding "import/resolver" solved the problem. Version: eslint-plugin-boundaries: 5.0.1

 "import/resolver": {
      "typescript": {
        "alwaysTryTypes": true
      }
    },

Fixed config

{
  "parser": "@typescript-eslint/parser",
  "ignorePatterns": ["**/node_modules", "**/dist"],
  "plugins": ["@typescript-eslint", "boundaries"],
  "settings": {
    "import/resolver": {
      "typescript": {
        "alwaysTryTypes": true
      }
    },
    "boundaries/elements": [
      { "type": "core", "pattern": "src/core/*", "mode": "file" },
      { "type": "shared", "pattern": "src/shared/*", "mode": "file" }
    ]
  },
  "rules": {
    "boundaries/element-types": [
      "error",
      {
        "default": "disallow",
        "rules": [
          {
            "from": "core",
            "allow": ["core"]
          }
        ]
      }
    ]
  }
}

Why import/resolver setting is so important for plugin work?

alxpsr avatar Jul 31 '25 10:07 alxpsr