Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript/TSLint: TSLint not recognizing root-relative imports via baseUrl

I'm using root-relative imports via the baseUrl compiler option in tsconfig.json, as per this solution, but I'm having a problem where Atom IDE is showing me linting errors that look like:

Cannot find module 'core/nav-menu/nav-menu.component'.

The imports look like (in src/app/core/nav-menu.module.ts):

import { NavMenuComponent } from 'core/nav-menu/nav-menu.component';

TSLint in Atom isn't finding the root-relative imported files, but the Angular compiler isn't having a problem with them.

I'm not sure if my tslint.json config is wrong... Everything with this is working as expected in another project I have here on the same machine, but I can't spot what is different with this project, causing this problem.

tslint.json:

{
  "rulesDirectory": [
    "node_modules/codelyzer"
  ],
  "rules": {
    "arrow-return-shorthand": true,
    "callable-types": true,
    "class-name": true,
    "comment-format": [
      true,
      "check-space"
    ],
    "curly": true,
    "deprecation": {
      "severity": "warn"
    },
    "eofline": true,
    "forin": true,
    "import-blacklist": [
      true,
      "rxjs/Rx"
    ],
    "import-spacing": true,
    "indent": [
      true,
      "spaces"
    ],
    "interface-over-type-literal": true,
    "label-position": true,
    "max-line-length": [
      true,
      140
    ],
    "member-access": false,
    "member-ordering": [
      true,
      {
        "order": [
          "static-field",
          "instance-field",
          "static-method",
          "instance-method"
        ]
      }
    ],
    "no-arg": true,
    "no-bitwise": true,
    "no-console": [
      true,
      "debug",
      "time",
      "timeEnd",
      "trace"
    ],
    "no-construct": true,
    "no-debugger": true,
    "no-duplicate-super": true,
    "no-empty": false,
    "no-empty-interface": true,
    "no-eval": true,
    "no-inferrable-types": [
      true,
      "ignore-params"
    ],
    "no-misused-new": true,
    "no-non-null-assertion": true,
    "no-shadowed-variable": true,
    "no-string-literal": false,
    "no-string-throw": true,
    "no-switch-case-fall-through": true,
    "no-trailing-whitespace": true,
    "no-unnecessary-initializer": true,
    "no-unused-expression": true,
    "no-use-before-declare": true,
    "no-var-keyword": true,
    "object-literal-sort-keys": false,
    "one-line": [
      true,
      "check-open-brace",
      "check-catch",
      "check-else",
      "check-whitespace"
    ],
    "prefer-const": true,
    "quotemark": [
      true,
      "single"
    ],
    "radix": true,
    "semicolon": [
      true,
      "always"
    ],
    "triple-equals": [
      true,
      "allow-null-check"
    ],
    "typedef-whitespace": [
      true,
      {
        "call-signature": "nospace",
        "index-signature": "nospace",
        "parameter": "nospace",
        "property-declaration": "nospace",
        "variable-declaration": "nospace"
      }
    ],
    "unified-signatures": true,
    "variable-name": false,
    "whitespace": [
      true,
      "check-branch",
      "check-decl",
      "check-operator",
      "check-separator",
      "check-type"
    ],
    "no-output-on-prefix": true,
    "use-input-property-decorator": true,
    "use-output-property-decorator": true,
    "use-host-property-decorator": true,
    "no-input-rename": true,
    "no-output-rename": true,
    "use-life-cycle-interface": true,
    "use-pipe-transform-interface": true,
    "component-class-suffix": true,
    "directive-class-suffix": true
  }
}

src/tslint.json:

{
  "extends": "../tslint.json",
  "rules": {
    "directive-selector": [
      true,
      "attribute",
      "s2es",
      "camelCase"
    ],
    "component-selector": [
      true,
      "element",
      "s2es",
      "kebab-case"
    ]
  }
}

tsconfig.json:

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "app",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  }
}

src/tsconfig.app.json:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "module": "es2015",
    "types": [],
    "baseUrl": "app",
    "types": ["node"]
  },
  "exclude": [
    "src/test.ts",
    "**/*.spec.ts"
  ]
}

On a side note, why is baseUrl: "app" not the default? Why do file-relative imports the seem like standard for Angular/TypeScript development. That's insane.

like image 685
BBaysinger Avatar asked Jul 11 '18 18:07

BBaysinger


1 Answers

Your base url is wrong:

Your tsconfig.json has to be set to: "baseurl": "./"

You dont need a baseurl in your tsconfig.app.ts, it should be removed.

As suggested in the comments the import paths should be updated as well. Add 'src/app' in front of the import path.

This applies if your structure is like following and you are running Angular 6:

 * project
 | - src
 | | - app (with app files like app.modules.ts)
 | | - tsconfig.app.json
 | - tsconfig.json

Maybe you tampered with the files, while trying to find out what's wrong. This is also the standard config of newly generated Angular projects.

like image 127
Daniel Habenicht Avatar answered Oct 12 '22 11:10

Daniel Habenicht