Problem
For a cleaner approach I am trying to not use relative path in my Typescript project like this.
import { MyModel } from '../../../../../models';
However, when trying to use paths for local file resolution, cdktf throws the Error: Cannot find module '@models'.
Here is my tfconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"alwaysStrict": true,
"charset": "utf8",
"declaration": true,
"experimentalDecorators": true,
"inlineSourceMap": true,
"inlineSources": true,
"lib": [
"es2018"
],
"module": "CommonJS",
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"strict": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"stripInternal": true,
"target": "ES2018",
"incremental": true,
"paths": {
"@models": [
"./lib/models/index.ts"
],
"@helpers": [
"./lib/helpers/index.ts"
],
},
},
"include": ["**/*.ts", "./src/**/*.ts"],
"exclude": [
"node_modules",
"cdktf.out"
]
}
inside my code:
import { MyModel } from "@models"
- The TS server doesn’t complain and compiles. But when running ‘cdktf synth’ I get that error.
I also tried this workaround from a github comment.
https://github.com/aws/jsii/issues/865#issuecomment-950261852
Please let me know how I can solve this issue.
Hi @sabinaya.kc 
What command do you have in your cdktf.json > app config?
edit: You might need to adjust that one similar to in the example you linked: cdk-ts-path-mapping/cdk.json at master · moltar/cdk-ts-path-mapping · GitHub
{
"language": "typescript",
"app": "npx ts-node -r tsconfig-paths/register --prefer-ts-exts src/main.ts",
"projectId": "XX",
"sendCrashReports": "true",
"terraformProviders": ["aws@~> 4.0"],
"terraformModules": [
{
"name": "vpc",
"source": "terraform-aws-modules/vpc/aws",
"version": "~> 3.0"
}
],
"context": {
"excludeStackIdFromLogicalIds": "true",
"allowSepCharsInLogicalIds": "true"
}
}
I tried this approach but then I get this error.
In my stack code tgw-stack.ts, I have
Do you get the same error when running the app command from your cdktf.json file directly?
Yes, I do get the same error. If my local imports are plain interfaces, it works fine such as @models, but as soon as I add a complex type or class (which has cdktf imports such as Construct or IAspect.ts) it throws the above error. I dont know what I am doing wrong. I am using the latest version of typescript, cdktf etc. Some kinda cyclic dependency might be causing this which I am struggling to find.
This is my folder structure,
libs
- helpers
- tag-aspect.ts
- models
- my-model.ts
- constructs
- my-vpc.ts
src
- environments
- core
- tgw-stack.ts --> imports { TagAddingAspect } from "@helpers" --> Throws above error.
main.ts --> calls the tgw-stack.ts
TagAspect code inside lib\helpers
import { IConstruct } from "constructs";
import { IAspect } from "cdktf";
// Not all constructs are taggable, so we need to filter it
type TaggableConstruct = IConstruct & {
tags?: { [key: string]: string };
tagsInput?: { [key: string]: string };
};
function isTaggableConstruct(x: IConstruct): x is TaggableConstruct {
return "tags" in x && "tagsInput" in x;
}
export class TagsAddingAspect implements IAspect {
constructor(private tagsToAdd: Record<string, string>) {}
// This method is called on every Construct within the specified scope (resources, data sources, etc.).
visit(node: IConstruct) {
if (isTaggableConstruct(node)) {
// We need to take the input value to not create a circular reference
const currentTags = node.tagsInput || {};
this.tagsToAdd["Name"] = node.node.id;
node.tags = { ...this.tagsToAdd, ...currentTags };
}
}
}
I got this to work by removing baseUrl from my tsconfig, and instead adding only paths, ex:
{
"compilerOptions": {
"paths": {
"src/*": ["./src/*"],
"gen/*": ["./.gen/*"]
},
"alwaysStrict": true,
"charset": "utf8",
"declaration": true,
"experimentalDecorators": true,
"inlineSourceMap": true,
"inlineSources": true,
"lib": ["es2018"],
"module": "CommonJS",
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"strict": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"stripInternal": true,
"target": "ES2018",
"incremental": true,
"skipLibCheck": true
},
"ts-node": {
"require": ["tsconfig-paths/register"]
},
"include": ["**/*.ts"],
"exclude": ["node_modules", "cdktf.out"]
}
This still requires the fix from this commit.
Basically, I think the circular dependency is coming from having the base URL at the project root, which includes the node_modules folder. By not having this set, and instead only using paths, you can avoid the circular dependency.
I get this error.
Missing baseUrl in compilerOptions. tsconfig-paths will be skipped
Error: Cannot find module ‘gen/modules/eks-blueprints-addons’
Require stack:
Is this is a generated module? Normally the path is ./.gen/modules/... (with a . before the gen) and you need to run cdktf get to generate these bindings?
No its not a generated module. Its more like a lib folder in the root. that can be used accross the other stacks in a mono repo.
Also, its the same problem with the .gen folder.
If I need to access the .gen folder from a deeply nested stack or class, i have to use ../../../../gen instead of doing .gen/ or @gen.
Hey @sabinaya.kc did you ever resolve your issue?
I need tsconfig-paths/register in my ts-node to make the tsconfig’s paths work.
"ts-node": {
"require": ["tsconfig-paths/register"],
}
But I’m getting the exact same error as you.
class MyStack extends TerraformStack {
^
TypeError: Class extends value undefined is not a constructor or null