为什么在不能在TypeScript项目ts-node执行.ts文件?

为什么在不能在TypeScript项目执行.ts文件?

我想要封装一个类,并且使用ts-node执行:
image.png

src/index.ts

class Animal {
  readonly age: number = 0
  readonly name: string | undefined = undefined

  constructor(age: number, name: string) {
    this.age = age 
    this.name = name
  }
}

export class Person extends Animal {

  readonly height: number 
  constructor(age: number, name: string, height: number) {
    super(age, name)
    this.height = height
  }
}

test/testPerson.ts

import { Person } from '../src/index';


const p = new Person(25, 'John', 177)

console.log(p)

export default {}

我运行ts-node 执行 测试文件报错:不识别.ts后缀的文件:

$ ts-node test/personTest.ts 
TypeError: Unknown file extension ".ts" for /Users/user/Desktop/Test/Test-demos/nodejs-test-demos/nodejs-demo-04-npmpackage/test/personTest.ts
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
    at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
    at defaultLoad (node:internal/modules/esm/load:143:22)
    at async ModuleLoader.load (node:internal/modules/esm/loader:403:7)
    at async ModuleLoader.moduleProvider (node:internal/modules/esm/loader:285:45)
    at async link (node:internal/modules/esm/module_job:78:21) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'
}

我按照网上说的,找到package.json 删除:
"type": "module",

但是又会报其他错误:

import { Person } from '../src/index';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:128:18)
    at wrapSafe (node:internal/modules/cjs/loader:1280:20)
    at Module._compile (node:internal/modules/cjs/loader:1332:27)
    at Module.m._compile (/Users/user/Library/pnpm/global/5/.pnpm/ts-node@10.9.2_@types+node@20.12.13_typescript@5.4.5/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/markleo/Library/pnpm/global/5/.pnpm/ts-node@10.9.2_@types+node@20.12.13_typescript@5.4.5/node_modules/ts-node/src/index.ts:1621:12)
    at Module.load (node:internal/modules/cjs/loader:1206:32)
    at Function.Module._load (node:internal/modules/cjs/loader:1022:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
    at phase4 (/Users/user/Library/pnpm/global/5/.pnpm/ts-node@10.9.2_@types+node@20.12.13_typescript@5.4.5/node_modules/ts-node/src/bin.ts:649:14)

请问:

1、package.json内"type": "module",的作用是什么呢?
2、我想要到时候打包上传npmjs.org,这个配置"type": "module",会不会有影响呢?
3、SyntaxError: Cannot use import statement outside a module 这个错误如何解决呢?

阅读 910
avatarAI BotBETA

1. package.json"type": "module", 的作用是什么?

package.json 文件中设置 "type": "module", 会使得 Node.js 将该包中的所有 .js 文件作为 ECMAScript 模块(ESM)来处理,而不是 CommonJS 模块。这意味着你可以使用 importexport 语句来导入和导出模块,而不需要像 CommonJS 那样使用 require()module.exports。这对于 TypeScript 项目特别有用,因为 TypeScript 默认支持 ES 模块语法。

2. 我想要到时候打包上传 npmjs.org,这个配置 "type": "module", 会不会有影响?

"type": "module", 添加到 package.json 中对你的包在 npmjs.org 上的兼容性有一定影响。它确保了其他开发者在使用你的包时,Node.js 会以 ES 模块的方式处理你的代码。这要求他们也必须了解如何正确处理 ES 模块。如果你的包主要是为支持 ES 模块的环境设计的,那么这通常不是问题。然而,如果你的包需要被更广泛的用户群体使用,包括那些可能还在使用 CommonJS 环境的用户,你可能需要提供一些兼容性措施,比如使用 Babel 之类的工具将你的 ES 模块代码转换为 CommonJS 格式,或者在你的包中同时提供两种格式的模块。

3. SyntaxError: Cannot use import statement outside a module 这个错误如何解决?

这个错误通常发生在 Node.js 没有将文件识别为 ES 模块时,但你尝试使用了 importexport 语句。解决这个问题的方法取决于你的具体设置:

  • 如果你正在使用 ts-node 并且想要使用 ES 模块
    确保你的 tsconfig.json 文件正确配置了 "module": "ESNext""module": "ES2020"(或其他支持 ES 模块语法的选项),并且你的 Node.js 版本支持 ES 模块。此外,如果你的 package.json 中包含了 "type": "module",,确保你的文件扩展名是 .mjs(尽管对于 TypeScript 文件来说,这通常不是必需的,因为 ts-node 会处理 .ts 文件),或者确保你的 Node.js 环境正确配置为识别 .ts 文件为 ES 模块(这通常通过 ts-node 的配置来实现)。
  • 如果你不想使用 ES 模块
    你可以将 importexport 语句替换为 CommonJS 的 require()module.exports。但是,请注意,这可能会影响你在 TypeScript 项目中的类型安全和模块化功能。
  • 检查你的 Node.js 版本
    确保你使用的 Node.js 版本支持 ES 模块。从 Node.js v12 开始,实验性地支持了 ES 模块,但从 v14 开始,支持变得更加稳定。
  • 使用 Babel
    如果你需要更广泛的兼容性,你可以考虑使用 Babel 来将你的 ES 模块代码转换为 CommonJS 格式。这可以在构建过程中自动完成,以确保你的包可以在不同的环境中运行。
1 个回答
✓ 已被采纳

在 tsconfig.json 中添加:

{
  "compilerOptions": {
    "esModuleInterop": true,
  }
}

运行:ts-node-esm script.ts

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏