Instead of relative module imports I would like to import my modules like this: import { IntHelper } from 'utils/IntHelper';
. Even though intellisense works fine in VSCode the transpiled javascript files throw an exception: Cannot find module
.
My project structure:
root
File: MyProject.ts
import { IntHelper } from 'utils/IntHelper';
File: IntHelper.ts
export module IntHelper {
export const xy: string = 'Test';
export function crossSum(int: number) {
return int; // Nonsense - ofcourse.
}
}
Tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"noImplicitAny": true,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"*": [
"*",
"src/*"
]
}
}
}
My question:
Why does it throw the cannot find module exception in the javascript files even though it appears to be fine in the typescript files? When I hover the 'utils/IntHelper'
part in my import line in the typescript file VSCode would also show the correct path to that module.
Module resolution is the process the compiler uses to figure out what an import refers to. Consider an import statement like import { a } from "moduleA" ; in order to check any use of a , the compiler needs to know exactly what it represents, and will need to check its definition moduleA .
To be able to use absolute paths in TypeScript we can set the baseUrl property in the tsconfig. json file. With this, we define src as our root directory (for module resolution).
The tsconfig. json file specifies the root files and the compiler options required to compile the project. JavaScript projects can use a jsconfig. json file instead, which acts almost the same but has some JavaScript-related compiler flags enabled by default.
The tsconfig. json is generally put in the root folder of the project.
You are having the same problem as many others, the belief that the TypeScript compiler will save the resolved paths to the JS files. That is not the case. You will need to resolve this on your own, or by using a tool, WebPack is often what people suggest (WebPack, however, is a monster), please see this answer:
Typescript2 path module resolution
This will most likely solve your problem as well!
Of course in your case node gets confused about the module, because it expects all non-relative paths to be present in node_modules. The good solution with typescript is to use paths
section of tsconfig like this:
{
"compilerOptions": {
"paths": {
"@utils": [
"src/utils/*"
]
}
}
}
now we can
import { IntHelper } from '@utils/IntHelper';
but we still have to notify webpack or node about out path configuration:
// for node:
--require tsconfig-paths/register
// for webpack
const TsConfigPathsPlugin = require('awesome-typescript-loader').TsConfigPathsPlugin;
resolve: {
plugins: [
new TsConfigPathsPlugin(),
]
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With