如何将 ts-node ESM 与节点模块一起使用?

Posted

技术标签:

【中文标题】如何将 ts-node ESM 与节点模块一起使用?【英文标题】:How to use ts-node ESM with node modules? 【发布时间】:2021-08-08 12:12:09 【问题描述】:

注意:我知道以下问题是关于实验性功能的。我创建了一个clone on the ts-node discussion forum。不过,我相信 *** 的曝光范围更广,并且会在更短的时间内找到解决方案。

我正在尝试制作一个简单的脚本,从一个位置读取文件并对其进行处理。这是我到目前为止所拥有的,关注#1007:

节点:v12.22.1

my-app
├── .eslintrc.cjs
├── .gitignore
├── in
│   └── given.txt
├── node_modules
├── out
├── package-lock.json
├── package.json
├── src
│   ├── helper.ts
│   └── main.ts
└── tsconfig.json

package.json


  "name": "my-app",
  "version": "1.0.0",
  "type": "module",
  "scripts": 
    "lint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings=0",
    "start": "node --experimental-specifier-resolution=node --experimental-modules --no-warnings --loader ts-node/esm ./src/main.ts"
  ,
  "author": "Kaustubh Badrike",
  "devDependencies": 
    "@types/node": "^15.3.0",
    "@typescript-eslint/eslint-plugin": "^4.24.0",
    "@typescript-eslint/parser": "^4.24.0",
    "eslint": "^7.26.0",
    "ts-node": "^9.1.1",
    "typescript": "^4.2.4"
  

tsconfig.json


  "compilerOptions": 
    "target": "es5",                                /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "ESNext",                           /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    
    /* Strict Type-Checking Options */
    "strict": true,                                 /* Enable all strict type-checking options. */
    
    /* Module Resolution Options */
    "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "esModuleInterop": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    
    /* Advanced Options */
    "skipLibCheck": true,                           /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true        /* Disallow inconsistently-cased references to the same file. */
  

main.ts

import  readFileSync  from "fs";

const contents = readFileSync('../in/given.txt');

但是,当我尝试 npm run start 时,我得到以下信息

TypeError [ERR_INVALID_RETURN_PROPERTY_VALUE]: Expected string to be returned for the "format" from the "loader getFormat" function but got type 
object.
    at Loader.getFormat (internal/modules/esm/loader.js:125:13)
    at Loader.getModuleJob (internal/modules/esm/loader.js:247:20)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:49:17)
    at async Promise.all (index 0)
    at link (internal/modules/esm/module_job.js:53:9)

如果我从 fs 中删除导入,则不会发生该错误。从 helper.ts 导入项目也可以。

我需要做什么才能让它工作?

【问题讨论】:

【参考方案1】:

试试这个:

import fs from 'fs'
const contents = fs.readFileSync(/*more*/);

这可能会对您有所帮助: https://www.geeksforgeeks.org/node-js-fs-readfilesync-method/

【讨论】:

当您添加答案时,还要添加正在以不同方式完成的内容以及您认为它会起作用的原因。我相信您甚至没有尝试重现该问题,只是更改了导入语法,希望它能起作用并为您赢得一些声誉。【参考方案2】:

2021 年 5 月 23 日更新

ts-node v10.0.0 已发布,它修复了与 NodeJS上ESM加载器中节点内置模块的分辨率> = 12.20.0,

原答案

我可以在 NodeJS 12.22.1 上重现您的问题。我还可以确认它在 NodeJS 14.16 上正常工作。

是否有可能更新您的 NodeJS 版本?

请记住,NodeJS 对 ESM 的支持在很长一段时间内都是实验性的,并且通常会在此阶段进行更改。

此外,与您使用的 NodeJS (12.X) 版本接近 end of it's maintenance life 的事实相关,我的建议是您将 NodeJS 更新到至少版本 14.x 以解决此问题和让您受益于最新发展并保证长期支持。

您可以在此处找到有关要求和配置的更完整答案:Unable to import ESM .ts module in node

【讨论】:

以上是关于如何将 ts-node ESM 与节点模块一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

节点 Lambda:ts-node 的导入导致 TypeError

ts-node 将选项传递给节点

如何在打字稿项目中导入节点模块。 ERR_REQUIRE_ESM

尝试将 vue 与 ts-node 一起使用

无法再获取节点或 ts-node/register 以使用 es2020(flatMap 不是函数)

如何在 Azure 应用服务上运行使用 ts-node 开发的节点应用程序