简体   繁体   中英

Typescript can't find modules which are imported with webpack alias

I am currently setting up my project to be a bit cleaner, especially in the frontend part with references.

In hindsight I noticed that I was very generous with the folder structure for my frontend files and ended up with lots of layers. That's why I decided to look into what webpack can do for this case, and found out about the alias functionality.

This is how I set it up:

resolve: {
    alias: {
        components: path.resolve(__dirname, "Scripts/Views/Components"),
        data: path.resolve(__dirname, "Scripts/Data"),
        definitions: path.resolve(__dirname, "Scripts/Definitions"),
        helper: path.resolve(__dirname, "Scripts/Helper"),
        scripts: path.resolve(__dirname, "Scripts"),
        views: path.resolve(__dirname, "Scripts/Views"),
    },
    extensions: [".tsx", ".ts", ".js", ".jsx"],
    modules: ["node_modules"]
}

As you can see, I created alias' for various folders here.

This is my folder structure:

在此处输入图片说明

Now, let's hop into eg the LoginDialog.tsx. Here I am trying to import like this:

import { IErrorAttachedProperty } from "definitions/formHelper";

However, all I end up with here is an error that no module could be found this way.

What am I doing wrong here?

If it is of any significance - The webpack.config.js resides in the same directory as the Scripts folder.

you have to config tsconfig.json for typescript

"baseUrl": "./",
"paths": {
  "components/*": [
    "./src(or any other path)/Scripts/Views/Components"
  ]
},

here is nice example ts alias

Ok, so to avoid confusion for others I'm posting my solution/findings:

Yes, you can just use tsconfig.json without needing resolve/alias in Webpack. You should just do it once with Typescript setup.

EDIT: Nope, turns out you do need resolve/alias section in webpack.config.js . Typescript will be happy without it, but then you will get Webpack errors when it builds. Do both to make it work .

TIP: Make sure the paths you provide in the paths section of tsconfig.json are relative to the baseUrl entry point. Don't make them relative to the tsconfig.json file, baseUrl is like the project root for the non-relative module imports defined with paths .

From Typescript docs, absolute modules names (import * from package-a ) are relative to baseUrl ~ https://www.typescriptlang.org/docs/handbook/module-resolution.html#base-url

All module imports with non-relative names are assumed to be relative to the baseUrl.

Relative modules (import * from ./packages ) are just from current file as stated:

Note that relative module imports are not impacted by setting the baseUrl, as they are always resolved relative to their importing files.

So if you have:

./packages
  ./package-a
  ./package-b
./index.ts
./tsconfig.json

Your tsconfig.json would look like:

{
    "compilerOptions": {
        "baseUrl": "./packages",
        "paths": {
            "package-a/*": [ "./package-a/*" ],
        },
    },
    "include": [
        "./packages/**/*"
    ]
}

Then your webpack.config.json would look like:

{
    resolve: {
        alias: {
            'package-a': path.resolve(__dirname, 'packages/package-a/'),
        }
    },
}

Then you can import from index.ts like this:

import { pkgAThing } from 'package-a';
// or
import { otherPkgAThing } from 'package-a/dir/dir`;

Which is alternative to relative style:

import { pkgAThing } from './packages/package-a`;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM