Reputation: 348
Every time when I try to extend the abtract class Command
and I try to compile I get the error: Error: Cannot find module 'src/classes/commandBase'
My project has the following structure:
├────tsconfig.json
└────src
├───classes
│ └───commandBase.ts
├───commands
│ └───ping.ts
├───handlers
├───listeners
└───models
commandBase.ts
abstract class Command {
name: string;
abstract execute(client: Client, message: Message, args: string[]): void;
constructor(name: string) {
this.name = name;
}
}
export default Command;
ping.ts
import Command from "src/classes/commandBase";
class Ping extends Command {
constructor() {
super("ping");
}
async execute(
client: Client,
message: Message,
args: string[]
): Promise<void> {
// ...
}
}
export default Ping;
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "CommonJS",
"rootDir": "./src/",
"outDir": "./dist/",
"strict": true,
"moduleResolution": "node",
"importHelpers": true,
"experimentalDecorators": true,
"esModuleInterop": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"forceConsistentCasingInFileNames": true,
"removeComments": true,
"typeRoots": ["node_modules/@types"],
"sourceMap": true,
"baseUrl": ".",
"paths": {}
},
"include": ["./**/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
If I change import Command from "src/classes/commandBase";
to import Command from "../classes/commandBase";
everything is working fine, no errors appear. The thing is I use autocompletion (VS Code) and everytime I import "Command" it automatically writes "src/classes/commandBase";
Another thing is if I create a new file which doesnt extend Command but imports it everything is also working as intended. So I am very confused about this behavior.
File foo.ts
import Command from "src/classes/commandBase";
const foo: Command = {
name: "",
execute: function (client: Client, message: Message, args: string[]): void {
throw new Error("Function not implemented.");
}
}
Upvotes: 3
Views: 353
Reputation: 660
That is because your Classes and Commands folders are in the src directory, you don't need to leave that directory. Your path should be something like ./classes/ or ./commands/Ping if you're running from the main folder.
Here is not specified "./" before source folder
../ indicates that you're leaving the current directory to go up one ./ is in the current directory
Add in your settings JSON "typescript.preferences.importModuleSpecifier": "relative",
This configuration run to me, check structure and configuration are you using about module in tsconfig.json, and choice 'absolute paths' instead to avoid relative path cases as "../../../"
import Command from "@classes/commandBase";
tsconfig.json
/* Modules */
"module": "commonjs",
"rootDir": "./src",
"baseUrl": ".",
"paths": { /* Set absolute paths with '@path' */
"@config/*": ["./src/config/*"],
"@controllers/*": ["./src/controllers/*"],
"@services/*": ["./src/services/*"],
"@classes/*": ["./src/classes/*"],
"@commands/*": ["./src/commands/*"],
"@routes/*": ["./src/routes/*"],
"@pages/*": ["./src/pages/*"],
"@utils/*": ["./src/utils/*"],
"@middlewares/*": ["./src/middlewares/*"]
}
// Allow multiple folders to be treated when resolving modules
"typeRoots": [
"./node_modules/@types",
"./src/@types"
package.json
"plugins": [
[
"module-resolver",
{
"alias": {
"@config": "./src/config",
"@controllers": "./src/controllers",
"@services": "./src/services",
"@classes": "./src/classes",
"@commands": "./src/commands",
"@routes": "./src/routes",
"@pages": "./src/pages",
"@utils": "./src/utils",
"@middlewares": "./src/middlewares"
}
}
]
]
}
}
Upvotes: 1
Reputation: 26344
Set typescript.preferences.importModuleSpecifier
to relative
in your settings (JSON):
"typescript.preferences.importModuleSpecifier": "relative"
It doesn't error in foo.ts
because Command
is being used as a type and not as a class to extend from. Types are erased at runtime, so there is no error because the import has been erased.
Upvotes: 1