Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

ordered-imports does not support path aliases defined in tsconfig #3654

Closed
Arnaud73 opened this issue Jan 15, 2018 · 15 comments
Closed

ordered-imports does not support path aliases defined in tsconfig #3654

Arnaud73 opened this issue Jan 15, 2018 · 15 comments

Comments

@Arnaud73
Copy link

Bug Report

  • TSLint version: 5.9.1
  • TypeScript version: 2.5.3
  • Running TSLint via: CLI (through Angular CLI)

TypeScript code being linted

import { CrudEntity } from '@app/shared/model/crud-entity.model';
import { EntityType } from '@app/structure/model/entity-type.enum';

with tslint.json configuration:

        "ordered-imports": [
            true,
            {
                "grouped-imports": true,
                "import-sources-order": "lowercase-last",
                "named-imports-order": "lowercase-first",
                "module-source-path": "full"
            }
        ],

Actual behavior

imports starting with @app are considered as imports from libraries.

Expected behavior

However, tsconfig file specifies @app as:

        "baseUrl": "./src",
        "paths": {
            "@app/*": [
                "app/*"
            ],
            "@env/*": [
                "environments/*"
            ]
        }

So those import shall be considered as parent imports.

@adidahiya
Copy link
Contributor

Isn't that pretty confusing though? There are many libraries that do use NPM scopes and therefore start with @. Not sure if it's worth adding the extra complexity to this rule to support usage like this.

@Arnaud73
Copy link
Author

It is a usage that is somehow popular in the Angular World, one can even find people promoting it (https://medium.com/@tomastrajan/6-best-practices-pro-tips-for-angular-cli-better-developer-experience-7b328bc9db81). But I do agree it may be confusing since NPM scopes start with @.

As a result I renamed my aliases as #app and #env. It compiles and runs fine, however, since those imports still do not start with .., they are still considered as library imports. I also tested app and envwhich run fine but also fail linting.

I agree not all developers are going to uses tsconfig aliases, but at least many Angular CLI developers are going to set baseUrl to ./src in their tsconfig.json file. As a result they can import files like 'app/my-module/my-module.module' which makes it very convenient not to use relative file paths for importing elements from other modules. In this case also, tslint will wrongly consider those imports as library imports.

@timc13
Copy link

timc13 commented Feb 12, 2018

I agree this is a huge use case. I do this for React as well to avoid long paths with many parent dir references (../). If tslint is aware of tsconfig.json, maybe it should parse paths and baseUrl and resolve them to ../ paths

@lautarodragan
Copy link

Facing same issue here. Would really love to use grouped-imports, both in our ReactJS and NodeJS apps, but ordered-imports isn't able to tell library from non-library imports.

@IanEdington
Copy link

I would agree with this. Aliases are becoming more popular and this would be super useful.

@ppowstanski
Copy link

ppowstanski commented Apr 18, 2018

I had the same issue and managed to fix it.

In tsconfig.json I have
"paths": { "@app/api": [ "./app/api/index" ] },

then in tslint.conf (still we check dependencies except optional):
"no-implicit-dependencies": [ true, "optional" ]

then finally in package.json (we have to have it in optional dependencies):
"optionalDependencies": { "@app/api": "app-hack" }

With such configuration I can use imports like below without any exception from TSLint:
import {DictionaryType} from '@app/api';

Hopefully that'll work for you :-)

@karol-majewski
Copy link
Contributor

What if we could tell TSLint which paths are in fact relative, even though they can look as absolute ones.

{
  "ordered-imports": [
    true,
    {
      "grouped-imports": true,
      ...
      "path-alias-roots": ["$@src/", "$@typings/"]
    }
  ]
}

@julienmarantes
Copy link

I use the same trick (add alias to tsconfig.json) but on karma test I get

HeadlessChrome 67.0.3396 (Windows 10.0.0) ERROR
  Uncaught Error: Missing: SyncTestZoneSpec
  at http://localhost:9876/_karma_webpack_/vendor.bundle.js:270128

Did I miss something ?

@JoshuaKGoldberg
Copy link
Contributor

What if we could tell TSLint which paths are in fact relative

Typed rules are able to access program.getCompilerOptions() so we shouldn't have to manually provide this in the rule's configuration.

Since the requested behavior is apparently popular in the Angular community, it seems reasonable that this could be made into an OptionallyTypedRule to enable an opt-in configuration setting to read path aliases from the compiler settings.

@sebelga
Copy link

sebelga commented Dec 23, 2018

@ppowstanski Late on the conversation, but we can simply define it like this:

"no-implicit-dependencies": [true, ["dev", "@src"]], // add any alias in the array

And avoid having to add fake optional dependencies in the package.json.

@adidahiya
Copy link
Contributor

I'd prefer looking at program.getCompilerOptions() (as @JoshuaKGoldberg suggested) rather than adding additional rule configuration. That way, there's only one source of truth for custom path mappings.

@abierbaum
Copy link
Contributor

Using #4134, you could do something like:

"rules": {
    "ordered-imports": [
        true,
        {
            "import-sources-order": "case-insensitive",
            "named-imports-order": "case-insensitive",
            "grouped-imports": true,
            "groups": [
                { "match": "^@app", "order": 20 },
                { "match": "^@env", "order": 30 },
                { "name": "parent_dir", "match": "^[.][.]", "order": 40 },
                { "name": "current dir", "match": "^[.]", "order": 50 },
                { "match": null, "order": 10 }
            ]
        }
    ]
}

Or whatever other way you may want to group the imports. We use something like this for our project with quite a few aliases for internal libraries and modules.

@sebelga
Copy link

sebelga commented Jan 20, 2019

Thanks @abierbaum !! Great job on that PR!

@JoshuaKGoldberg
Copy link
Contributor

☠️ TSLint's time has come! ☠️

TSLint is no longer accepting most feature requests per #4534. See typescript-eslint.io for the new, shiny way to lint your TypeScript code with ESLint. ✨

It was a pleasure open sourcing with you all!

@JoshuaKGoldberg
Copy link
Contributor

🤖 Beep boop! 👉 TSLint is deprecated 👈 (#4534) and you should switch to typescript-eslint! 🤖

🔒 This issue is being locked to prevent further unnecessary discussions. Thank you! 👋

@palantir palantir locked and limited conversation to collaborators Mar 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests