10

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.

4
  • Where is reference of this component in your project Cannot find module 'core/nav-menu/nav-menu.component.. share the code. Commented Jul 24, 2018 at 16:45
  • Ok, I edited with an example of an import. It the same error for every root-relative import. Commented Jul 25, 2018 at 16:07
  • Did you try setting rootDirs setting? That might help Commented Jul 27, 2018 at 9:29
  • This isn't a tslint issue Commented Jul 29, 2018 at 17:25

1 Answer 1

8
+50

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.

Sign up to request clarification or add additional context in comments.

2 Comments

This is correct. If your base URL actually is app then you should set rootDir to the same
Yes. This absolutely works. Then I had to add src/app/ to all of my root-relative imports. So the solution I was using at stackoverflow.com/questions/34614818/… was actually not an ideal solution, although I did have it working without errors in another project. (I'm not sure what was different that made it work). This a better solution, because root-relative imports can be easily identifiable and easily found/searched for by querying src/app/. I will add this solution to the question from answer where I found my previous configuration.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.