node.js - Typescript: ενεργοποίηση TS προγραμματιστικά με ESM


Θα ήθελα να στήσω ένα έργο με Node.js & Typescript & ts-node & μεταγλώττιση σε ESM modules.

Ορισμένες βιβλιοθήκες από το NPM απαιτούν ESM στις τελευταίες εκδόσεις τους. Γι' αυτό χρειάζεται να μεταγλωττίσω τον κώδικα Typescript μου σε κώδικα Javascript που χρησιμοποιεί ESM αντί για CommonJS.

Αλλά παρ' όλα αυτά παίρνω σφάλμα όταν τρέχω το index.js:

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

Ορίστε ο κώδικας:

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"
  }
}

Απάντηση #1

Είχα παρόμοιο πρόβλημα. Αλλά το έλυσα χρησιμοποιώντας ts-import.

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

Μια άλλη λύση είναι οι παρακάτω κώδικες. Αυτοί οι κώδικες είναι πιο απλοί. TsNode.register() καθιστά δυνατή την εισαγωγή αρχείων ts.

#!/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'));
  
})();