Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable absolute path aliases with eslint import plugin in a typescript react project?

I have installed the eslint-plugin-import to my project and my goal is to use the 'import/no-relative-parent-imports': 'error' setting to forbid relative imports in my project to enhance readibility.

However this setting produces errors across my project because it does not pick up my tsconfig alias to the root folder.
My tsconfig.json has the following setting.

 "paths": {
      "src/": ["./src/*"]
    }

I try importing components in my project the following way.
import { Component } from 'src/components/ComponentA' but then eslint complains about using relative imports when in fact I import my component absolutely with the help of the tsconfig path alias. I have installed the eslint-import-resolver-typescript and enabled it in my .eslintrc.js file.

settings: {
    'import/resolver': {
      typescript: {},
    },
  },

My error message is the following.

Relative imports from parent directories are not allowed. Please either pass what you're importing through at runtime (dependency injection), move `example.ts` to same directory as `src/components/ComponentA` or consider making `src/components/ComponentA` a package. (eslintimport/no-relative-parent-imports)
like image 657
Paralyz3d Avatar asked Oct 09 '20 08:10

Paralyz3d


Video Answer


2 Answers

This behaviour is correct. As per the codebase of no-relative-parent-imports, this lint only verifies whether you are using any component/class from another parent directory or not. This rule does not care whether your import path is relative or absolute.

Let's say you have following directory path:

src
+---utils
|   +---time
|   |   +---- TimeWrapper.ts
|   +---Logger.ts
+---index.ts

Now in case you are trying to use TimeWrapper inside the Logger, this rule will allow this import, since the TimeWrapper is present inside Logger's parent folder (src/util). Whereas, in case you are trying to access Logger inside TimeWrapper, this rule will throw and error, since Logger is not present inside TimeWrapper's parent folder (src/util/time).

So, in reality, this rule does not care whether you are importing the classes using relative path or absolute path. It only cares, whether the resolved path dependency is present in same parent folder or not.

This rule should be only used in some places of your code. Like, you don't want to have classes of Database folder to have dependency on any other folders like Services. So you should not use it for your whole project, since that would make development too much dificult.

In case you want to avoid relative import, you can use following :

module.exports = {
  rules: {
    'no-restricted-imports': [
      'error',
      {
        patterns: [
          {
            group: ['../*'],
            message: 'Usage of relative parent imports is not allowed.',
          },
        ],
      },
    ],
  },
};
like image 171
Ashok Avatar answered Oct 18 '22 00:10

Ashok


It is working as expected. According to the rule documentation:

Use this rule to prevent imports to folders in relative parent paths.

Contrary to what you expect, this does not imply to prevent relative imports to folders in parent paths. In consequence, if an imported modules path after full resolution is in a parent path relative to the current file, this rule will give you an error.

The documentation further explains:

This rule is useful for enforcing tree-like folder structures instead of complex graph-like folder structures.

Therefore, modules are forced to depend only on adjacent and child dependencies and not at all on parent dependencies. This is an effective way of preventing circular dependencies, e.g. having a child to depend on a parent, which in turn depends on the child again (directly or transitively).

Overwriting relative paths with paths absolute to the project will not change the relative relation of the files to each other. Instead, it will obfuscate your dependencies and make it hard to find import issues.

With this understanding and the intention of the rule in mind, it is working as expected by throwing the error mentioned above.

Keeping this rule in place will cause some effort to restructure your project accordingly and fix the imports to parent files. In return, you get a more stable and less error-prone dependency management, which I highly encourage to make use of. If you only want to prevent any relative import paths, you should switch to another rule instead.

like image 26
Janik Avatar answered Oct 18 '22 02:10

Janik