nyphur
nyphur

Reputation: 2866

Typescript cannot find module defined in paths

I have a typescript application that has paths for absolute imports. My tsconfig looks like this:

{
    "compilerOptions": {
      "baseUrl": ".",
      "paths": {
        "utils*": ["src/utils*"],
        "operations*": ["src/operations*"],
        "actions*": ["src/actions*"],
        "components*": ["src/components*"],
        "constants*": ["src/constants*"],
      },
      "outDir": "dist",
      "module": "esnext",
      "target": "esnext",
      "moduleResolution": "node",
      "noEmit": true,
      "lib": ["es2017", "dom"],
      "noUnusedLocals": true,
      "sourceMap": true,
      "skipLibCheck": true,
      "allowJs": true,
      "jsx": "preserve",
      "noUnusedParameters": true,
      "preserveConstEnums": true,
      "strict": true,
      "allowSyntheticDefaultImports": true,
      "noImplicitAny": true,
    },
    "exclude": [
      "node_modules",
      "dist",
    ],
    "include": [
      "./src/**/*"
    ],
    "files": [
      "./typings/index.d.ts"
    ]
  }

and I'm trying to use imports like so:

import { AppStateType } from 'actions/app';

however I get cannot find module 'actions/app'

I followed this answer but it didn't seem to work.

What am I doing wrong here?

Upvotes: 5

Views: 2620

Answers (1)

jered
jered

Reputation: 11571

The pattern for paths is kind of picky.

Try this:

"paths": {
    "utils/*": ["src/utils/*"],
    "operations/*": ["src/operations/*"],
    "actions/*": ["src/actions/*"],
    "components/*": ["src/components/*"],
    "constants/*": ["src/constants/*"],
},

Note the addition of a slash.

Since you have baseUrl set I think that should work, but if not the next step might be to specify the full relative path (relative to the tsconfig file):

"paths": {
    "utils/*": ["./src/utils/*"],
    "operations/*": ["./src/operations/*"],
    "actions/*": ["./src/actions/*"],
    "components/*": ["./src/components/*"],
    "constants/*": ["./src/constants/*"],
},

That will satisfy the TypeScript compiler, but if you're using Webpack or Parcel you may get complaints about them not being able to find the files even though TypeScript compiles it fine. In that case you need to set aliases for your bundler. It would look a bit like this:

Webpack

// webpack.config.js or similar
// ...
  resolve: {
    extensions: [".js", ".jsx"], // import without .js, .jsx, .json extensions
    alias: {
      "utils": path.resolve(__dirname, "src/utils/*"),
      "operations": path.resolve(__dirname, "src/operations/*"),
      "actions": path.resolve(__dirname, "src/actions/*"),
      "components": path.resolve(__dirname, "src/components/*"),
      "constants": path.resolve(__dirname, "src/constants/*")
    }
  },

Parcel

// package.json
// ...
  "alias": {
    "utils": "./src/utils/*",
    "operations": "./src/operations/*",
    "actions": "./src/actions/*",
    "components": "./src/components/*",
    "constants": "./src/constants/*"
  }

Upvotes: 1

Related Questions