Eslint-plugin-import: import/no-extraneous-dependencies globs doesn't work on deeper folder tree (monorepo)

Created on 18 Mar 2019  ยท  11Comments  ยท  Source: benmosher/eslint-plugin-import

Globs doesn't work on nested folders within monorepo. I'm getting lint errors within foo.test.tsx or foo.story.tsx

image

Here is my project structure:

โ”œโ”€โ”€ packages
โ”‚   โ”œโ”€โ”€ common
โ”‚   โ”‚   โ”œโ”€โ”€ README.md
โ”‚   โ”‚   โ”œโ”€โ”€ __tests__
โ”‚   โ”‚   โ”œโ”€โ”€ dist
โ”‚   โ”‚   โ”œโ”€โ”€ package.json
โ”‚   โ”‚   โ”œโ”€โ”€ src // ๐Ÿ‘‰ *.test.tsx and *.story.tsx reside here
โ”‚   โ”‚   โ”œโ”€โ”€ tsconfig.build.json
โ”‚   โ”‚   โ””โ”€โ”€ tsconfig.json
โ”‚   โ”œโ”€โ”€ components
โ”‚   โ”‚   โ”œโ”€โ”€ README.md
โ”‚   โ”‚   โ”œโ”€โ”€ dist
โ”‚   โ”‚   โ”œโ”€โ”€ package.json
โ”‚   โ”‚   โ”œโ”€โ”€ src // ๐Ÿ‘‰ *.test.tsx and *.story.tsx reside here
โ”‚   โ”‚   โ”œโ”€โ”€ tsconfig.build.json
โ”‚   โ”‚   โ””โ”€โ”€ tsconfig.json

config:

.eslintrc.js:

module.exports = {
  root: true,
  extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint', 'import'],
  rules: {
    'import/no-extraneous-dependencies': [
      'error',
      {
        devDependencies: [
          '**/*.test.{ts,tsx}',
          '**/*.spec.{ts,tsx}',
          '**/*.story.tsx',
          '**/__tests__/**',
          '**/__mocks__/**',
          './config/**/*.js',
        ],
      },
    ],
  },
};
help wanted

Most helpful comment

yup, same output

'import/no-extraneous-dependencies': [
      'error',
      {
        packageDir: [
          './packages/common/',
          './packages/components/',
          './packages/customer-registration/',
          './',
        ],
        devDependencies: [
          '**/*.test.{ts,tsx}',
          '**/*.spec.{ts,tsx}',
          '**/*.story.tsx',
          '**/__tests__/**',
          '**/__mocks__/**',
          './config/**/*.js',
        ],
      },
    ],

All 11 comments

Have you set the packageDir option?

yup, same output

'import/no-extraneous-dependencies': [
      'error',
      {
        packageDir: [
          './packages/common/',
          './packages/components/',
          './packages/customer-registration/',
          './',
        ],
        devDependencies: [
          '**/*.test.{ts,tsx}',
          '**/*.spec.{ts,tsx}',
          '**/*.story.tsx',
          '**/__tests__/**',
          '**/__mocks__/**',
          './config/**/*.js',
        ],
      },
    ],

@Hotell your setup (with packageDir) messes up things big time from me. I think it says to eslint:

When you work out imports in any package test against all these package files.

So imports in common will be tested against the package.json file of components - you don't want that.


Instead, remove packageDir property in the root .eslintrc.js and in each package drop this eslintrc.js:

const { join } = require('path');

module.exports = {
  rules: {
    'import/no-extraneous-dependencies': [
      'error',
      // Use package.json from both this package folder and root.
      { packageDir: [__dirname, join(__dirname, '../../')] }
    ]
  }
};

This one says:

When you work out the imports in this folder, also account for the root package.json

@Hotell can you try again with v2.20.0 and confirm if the problem still exists?

yup, same output

'import/no-extraneous-dependencies': [
      'error',
      {
        packageDir: [
          './packages/common/',
          './packages/components/',
          './packages/customer-registration/',
          './',
        ],
        devDependencies: [
          '**/*.test.{ts,tsx}',
          '**/*.spec.{ts,tsx}',
          '**/*.story.tsx',
          '**/__tests__/**',
          '**/__mocks__/**',
          './config/**/*.js',
        ],
      },
    ],

Trouble with that is if packages/components/' has a dependency on something, that dependency needs to be either in packages/components/package.json or in ./package.json. It doesn't work if the dependency is in some other package (e.g. packages/customer-registration/package.json).

In this setup it is satisfied by a dependency in any package in the monorepo, not the package where the dependency is used.

if packages/components/' has a dependency on something, that dependency needs to be either in packages/components/package.json or in ./package.json. It doesn't work if the dependency is in some other package (e.g. packages/customer-registration/package.json).

This is correct - both how it should work, and how it works with node's resolution algorithm.

Are you saying it's not working that way? Or that you want it to be "satisfied by a dependency in any package in the monorepo"?

I realised aht I'm saying is just what ws said in https://github.com/benmosher/eslint-plugin-import/issues/1302#issuecomment-572546519

Except I tried using packageDir separately in each subpackage (specifying only that package and the root package) but this resulted in the rule not generating any warnings at all.

I found good alternative using eslint overrides: https://github.com/benmosher/eslint-plugin-import/issues/1214#issuecomment-587934594

Hi all
I've create a PR (#1696) to correctly Work with monorepo.
It does the internal / external detection on the resolved moduelpath instead of the of the hypothetic name.
This means it also correctly work with animy resolver, because it only consider the resolved path. It resolves a lot of problematic cases.

But I've no news about the merge of it...

You can try it from my branch if you want.

@ljharb would this one be closed as well as https://github.com/benmosher/eslint-plugin-import/issues/1174 ?

Seems reasonable. Please file a new issue if the _next release_ does not address any of these issues.

Was this page helpful?
0 / 5 - 0 ratings