Psibean
Psibean

Reputation: 173

TypeScript 4.5: Module not found importing local file

I have a node express based application with the following tsconfig:

{
  "compilerOptions": {
    "lib": [ "es6", "es2021", "esnext" ],
    "target": "esnext",
    "module": "es2022",
    "composite": true,
    "declaration": true,
    "declarationMap": true,
    "forceConsistentCasingInFileNames": true,
    "importHelpers": true,
    "newLine": "LF",
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noUncheckedIndexedAccess": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "preserveConstEnums": true,
    "removeComments": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "noImplicitAny": true,
    "moduleResolution": "Node",
    "sourceMap": false,
    "rootDir": "./src",
    "outDir": "./dist",
    "baseUrl": "./src",
    "paths": {
      "*": [
        "node_modules/*"
    ]
}

}, }

Note: switching my module to commonjs is NOT a soultion, I want it to be built as a module.

I get an error on the very first local file import in my index file, but the file it says it can't find (module not found) does exist, it has a default export and the build output does have a .d.ts file beside it with a type export for it as well.

I can't figure out why it just isn't working.

Error:

Cannot find module 'workspace\dist\config\csrf' imported from workspace\dist\index.js

Note: I replaced the absolute path with a workspace placeholder. In this case, I have a file: src/config/csrf.ts which is being built / transpiled to dist/config/csrf.js, and it all seems to be in check, and yet it doesn't import.

Given this is the very first local file import in the entry file, I'd assume all the others will have the same problem.

What's going on, just how am I supposed to be resolving my local files when building a module?

My exports are like this:

const csrf = () => {
    // Code ommitted
}
export default csrf;

Using Node ^16.13.2 and TypeScript 4.5.6

Edit : I have the following scripts set up

  "scripts": {
    "clean": "rm -rf dist/",
    "lint": "tslint -c tslint.json -p tsconfig.json --fix",
    "tsc": "tsc",
    "build": "npm run clean && npm run lint && npm run tsc",
    "build:light": "npm run tsc",
    "migrate:dev": "npx prisma migrate dev",
    "migrate:prod": "npm run migrate:prod && npm run prisma:generate",
    "dev:start": "npm run build && npm run start",
    "dev:light": "npm run build:light && npm run start",
    "dev": "nodemon --watch src -e ts,ejs --exec npm run dev:start",
    "light": "nodemon --watch src -e ts,ejs --exec npm run dev:light",
    "start": "node -r dotenv/config .",
    "test": "echo \"Error: no test specified\" && exit 1"

},

And the error occurs when using npm run dev or npm run light.

So do note, TypeScript compiles fine, this error is occurring when the actual built JavaScript is run via node.

Edit: I've found out that, if I manually update the built JavaScript import it works

E.g.:

import csrf from "./config/csrf";

updates to:

import csrf from "./config/csrf.js"

it suddenly works,

What the hell? I shouldn't have vto manually update all of my transpiled files, right? What's the proper approach to having your TypeScript imports transpile to compatible JavaScript imports?

This just seems extremely convoluted and unnecessary. What am I missing? It makes zero sense to have ".js" on the imports in the TypeScript just so the built output will actually run

Upvotes: 3

Views: 3953

Answers (1)

Psibean
Psibean

Reputation: 173

The got package on github has a pretty handy / nifty guide on converting from commonjs to ESM, for both js and TypeScript:

According to this, you do indeed need to add the .js extension to imports on the TypeScript files, so I've done this. it's working and I have encountered a different problem which will raise a new question.

Upvotes: 4

Related Questions