github copilot
github copilot

Reputation: 103

typescript 4.4.4: tsconfig paths not resolving as expected

my tsconfig.json

{
  "compilerOptions": {
    "target": "ES2018",
    "module": "CommonJS",
    "lib": ["ESNext", "ESNext.AsyncIterable"],
    "skipLibCheck": true,
    "sourceMap": true,
    "outDir": "./dist",
    "moduleResolution": "node",
    "removeComments": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"],
      "@config": ["src/config"],
    }
  },
  "exclude": ["node_modules"],
  "include": ["./src/**/*.ts"]
}

I am pretty sure there is nothing wrong in tsconfig paths because I even get path autocompletion from my IDE. however when my code is compiled (tsc --project tsconfig.json)

import { PRODUCTION } from '@config';

// or

import { PRODUCTION } from '@/config';

I get following javascript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _config_1 = require("@config");
console.log(_config_1.PRODUCTION);
//# sourceMappingURL=index.js.map

but javascript doesn't understand what "@" is therefore I get "module not found" error. How can I solve this problem?

Upvotes: 10

Views: 18766

Answers (2)

Victor
Victor

Reputation: 708

I've been stuck with this issue for 2 whole days trying to find something that works. @Wing's answer is correct, if you're using plain tsc with no other tools, then Node won't know what you mean by @/ (or whatever your alias is) in your imports.

I've tried a few different approaches and I've found one that required no configuration.

What worked:

At the end of my journey I came across a package that is still actively being maintained: tsc-alias. The only thing I needed to do was add && tsc-alias -p tsconfig.json to my tsc command in my build script and voilà, it works. So your full command would be something like tsc -p tsconfig.json && tsc-alias -p tsconfig.json.

What I tried that didn't work:

  • I tried "module-alias" and I couldn't get it to work.
  • I tried "tsconfig-paths" as suggested by @AlexMorley-Finch with no luck as well. The package seems to be finding the modules but there seems to be a bug that causes the path of the modules not to be mapped correctly (there's an issue open for it).
  • I then came across tscpaths. This package requires you to explicitly specify your project, src dir and out dir. I got it to work after figuring out my outdir needed to be ./build/src instead of ./build. The caveat here: this package hasn't been touched since May 2019 as of writing this.

Upvotes: 16

Wing
Wing

Reputation: 9691

See this issue on TypeScript's GitHub project: Module path maps are not resolved in emitted code (#10866)

tl;dr

  • TypeScript won't rewrite your module paths
  • paths was designed to help TypeScript understand path aliases used by bundlers
  • You'll either need to:
    • use a bundler, such as webpack, and configure its own path maps
    • use a build time tool, such as tspath, to rewrite the paths
    • modify the runtime module resolver, with something like module-alias

Upvotes: 20

Related Questions