Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom module resolution in TypeScript + VSCode

I have the following project structure:

<PROJECT_FOLDER>
├── node_modules
├── src
│   ├── components
│   │   └── MyAwesomeComponent.tsx
│   ├── views
│   │   └── MyAwesomeView
│   │       └── index.tsx
│   ├── Application.tsx
│   └── index.tsx
├── webpack.config.js
└── tsconfig.json

and the following tsconfig.json

{
    "compilerOptions": {
        "outDir": "./dist/",
        "noImplicitAny": true,
        "moduleResolution": "classic",
        "module": "es6",
        "target": "es5",
        "jsx": "react",
        "allowJs": true,
        "sourceMap": true,
        "noImplicitReturns": true,
        "experimentalDecorators": true,

        "baseUrl": ".",
        "paths": {
            "*": [
                "src/*",
                "node_modules/*"
            ]
        },
    }
}

Assume I have react in node_modules (and even @types/react installed). When I'm tryin to import somewhat, for example import * as React from "react" or import MyComponent from "components/MyAwesomeComponent, both imports are errorneous with message "Cannot find module..." and so on.

As I'm writing the import string, VSCode suggests me modules from node_modules, but doesn't suggest me folders from src/*.

Relative import still works, but this is the hell, you know.

I'm definitely new to TypeScript, but I'm doing things according to the "Module Resolution" TypeScript docs, and it doesn't work.

Highly appreciate any help here!


Update

I have changed my moduleResolution to node and set the config shared by @Alserda (thank you for answer, but looks like I'm doing something wrong, because you config doesn't solve the problem). Then I run suggested tsc --traceResolution. It resolved all my imports as well, VSCode now resolving the node_modules, but still doesn't resolve my components/MyAwesomeComponent:enter image description here


Update 2

Well, my webpack.config.js does already have corresponding modules enter image description here

But I don't think that the problem is here, I even did not run webpack-dev-server, and I believe that VSCode doesn't use the webpack.config.js information to configure the project :)


Update 3

Here is the output for the components/MyAwesomeComponent import:

======== Resolving module 'components/MyAwesomeComponent' from '/home/username/path/to/project/src/Application.tsx'. ========
Explicitly specified module resolution kind: 'NodeJs'.
'baseUrl' option is set to '/home/username/path/to/project/src', using this value to resolve non-relative module name 'components/MyAwesomeComponent'.
Resolving module name 'components/MyAwesomeComponent' relative to base url '/home/username/path/to/project/src' - '/home/username/path/to/project/src/components/MyAwesomeComponent'.
Loading module as file / folder, candidate module location '/home/username/path/to/project/src/components/MyAwesomeComponent', target file type 'TypeScript'.
File '/home/username/path/to/project/src/components/MyAwesomeComponent.ts' does not exist.
File '/home/username/path/to/project/src/components/MyAwesomeComponent.tsx' exist - use it as a name resolution result.
======== Module name 'components/MyAwesomeComponent' was successfully resolved to '/home/username/path/to/project/src/components/MyAwesomeComponent.tsx'. ========

Final update

VSCode did not enforce update project settings from my tsconfig.json even after Reload TypeScript project. I just restarted it, and everything works fine now! :)

Thanks everybody for your help!

like image 295
Limbo Avatar asked Aug 23 '18 11:08

Limbo


Video Answer


1 Answers

You probably have to add this key:

...
"include": [
    "src/**/*"
],
...

The pathkey that you are using is mainly for making TypeScript understand that your imports 'will work' for your Webpack configuration. Say you have an alias key in your Webpack configuration like:

alias: {
  core: resolve(__dirname, '../src/services/core'),

(and you have your context key on your src folder).

Then you should add a path key in your tsconfig like

    "paths": {
        "core/*": ["./services/core/*"],

(with your src folder as baseURL

I'm always using the following configuration for TypeScript & React.js. This has been working great for me for multiple projects.

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es3",
        "moduleResolution": "node",
        "baseUrl": "src",
        "allowSyntheticDefaultImports": true,
        "noImplicitAny": true,
        "strict": false,
        "sourceMap": true,
        "outDir": "dist/",
        "jsx": "react",

        "allowJs": true,
        "declaration": false,
        "removeComments": true,
        "noLib": false,
        "preserveConstEnums": true,
        "suppressImplicitAnyIndexErrors": true,
        "types": [ "node" ],
        "lib": ["es6", "dom"]
    },
    "include": [
        "src/**/*"
    ]
}

And if you're using awesome-typescript-loader, I also include this:

    "awesomeTypescriptLoaderOptions": {
        "useCache": true,
        "forceIsolatedModules": true
    }

Edit:

I think the import error is related to Webpack. Try setting the following in your Webpack config:

const path = require('path');
...
context: path.resolve(__dirname, './src'),
resolve: {
  modules: ['src', 'node_modules']
...
like image 76
Alserda Avatar answered Sep 21 '22 01:09

Alserda