2

I'd like to set up project with Node.js & Typescript & ts-node & compiling to ESM modules.

Some of libraries from NPM requires ESM in theirs latest versions. That is why I need to compile my Typescript code to Javascript code that uses ESM instead of CommonJS.

But still I am getting error when I run index.js:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for SomeClass.ts

Here goes code:

index.js

import TsNode           from "ts-node";

//

const tsNodeService = TsNode.register({
    transpileOnly: false
});

TsNode.createEsmHooks(tsNodeService); //tried with & without that line

//

(async () => {    
    const SomeClass = await import("./SomeClass.ts");

    console.log(new SomeClass().method("abc", 123));
})();

// alternatively tried also:
/*
import SomeClass from "./SomeClass.ts";

console.log(new SomeClass().method("abc", 123));
*/

SomeClass.ts

export default class SomeClass {
    method(a: string, b: number) {
        return `${a} and ${b}`;
    }
}

tsconfig.json

{
    "$schema": "https://json.schemastore.org/tsconfig",

    "compilerOptions": {
        "baseUrl":  "./",
        "outDir":   "./output/",

        "module":   "Node16",
        "target":   "ES2022",

        "strict":                       true,
        "strictPropertyInitialization": false,
        "esModuleInterop":              true,
        "noImplicitAny":                true,
        "removeComments":               true,
        "preserveConstEnums":           true,
        "sourceMap":                    true,
        "pretty":                       true,
        "experimentalDecorators":       true,
        "allowJs":                      true,
        "resolveJsonModule":            true
    },

    "exclude": [
        "node_modules/**/*"
    ]
}

package.json

{
  "name": "testesmts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "author": "",
  "type": "module",
  "license": "ISC",
  "dependencies": {
    "ts-node": "^10.9.1",
    "typescript": "^4.9.3"
  }
}

Sonaht
  • 85
  • 6
  • 1
    Do you *need* ts-node? – kelsny Nov 28 '22 at 14:58
  • I recommend trying to setup running `tsx index.ts` ( https://github.com/esbuild-kit/tsx ) (instead of `node index.js`)without any compilation instead – Dimava Nov 28 '22 at 15:05
  • @caTS yes I need ts-node, because I need to decide about config programatically, for example `transpileOnly` or not. – Sonaht Nov 28 '22 at 15:09
  • @Dimava tsx doesn't do type-checking – Sonaht Nov 28 '22 at 15:20
  • Same problem here :/ – NathanVss Jan 02 '23 at 15:38
  • Does this answer your question? [Appending .js extension on relative import statements during Typescript compilation (ES6 modules)](https://stackoverflow.com/questions/62619058/appending-js-extension-on-relative-import-statements-during-typescript-compilat) – jsejcksn Jan 26 '23 at 05:09

1 Answers1

1

I had a similar problem. But I solved by using ts-import.

https://www.npmjs.com/package/ts-import

Another solution is below codes. This codes is more simpler. TsNode.register() makes importing ts files possible.

#!/usr/bin/env node

const TsNode = require('ts-node')
const path = require('path')

const tsNodeService = TsNode.register({
    transpileOnly: false
});

TsNode.createEsmHooks(tsNodeService);

(async () => {
  require(path.resolve(__dirname, 'src/index.ts'));
  
})();
ymdd1
  • 36
  • 5