node 运行ts 脚本的那些些事儿

我们知道 nodejs 默认使用是 commonjs 模块导入导出方式

js 复制代码
// 创建并导出模块
exports.foo = function() {
    console.log('foo');
};

// 导入模块
var lib = require('./foo');
lib.foo(); // 调用

如果我们要使用 esm 模块导入方式

  1. 直接将文件后缀 .js 改成 .mjs (方式1)
  2. 在package.json 新增type字段 { type: 'module' } (方式2)

nodejs 使用 ts-node 执行 .ts 文件

如果我们使用ts-node运行 .ts 文件 , 可能会报 Unknown file extension ".ts" for xxx.ts

ts 复制代码
// package.json
{
  type: "module"
}


// foo.ts
export function foo(x: number): number {
  return x * 2;
}

// test.ts
import { foo } from "./foo";

console.log(foo(1));


// 命令终端执行 
npx ts-node ./test.ts //Unknown file extension ".ts" for xxx.ts

因为我们代码中使用的是esm 导入导出, 所以package.json 设置了 type: "module",这是很正常的事情,但原因在于ts-node 执行的时候, 先编译commonjs 模块的.js 文件, 然后用node 执行.js 文件, import 导入对 ts-node 来说没有实际功能作用, 只是一个标记符号。 所以这里设置的type:"module" 反而不对了, 要么删除type要么设置type:"commonjs"

js 复制代码
// package.json
{
  type: "commonjs"
}


// foo.ts
export function foo(x: number): number {
  return x * 2;
}

// test.ts
import { foo } from "./foo";

console.log(foo(1));


// 命令终端执行 
npx ts-node ./test.ts // Cannot use import statement outside a module

当我们把package.json 改成 type: "commonjs" 后又报 Cannot use import statement outside a module, 这是因为ts-node 编译.ts 文件的时候会走 tsconfig.json 文件, 这个文件中有个编译选项 module: "ESNext"

ts 复制代码
{
    "compilerOptions": {
        "module": "ESNext",
    },
    "include": ["src/"],
}

这就导致了 ts-node 编译成的 js 文件是 esm 模块化标准。但 ts-node 里面的 node 执行时依旧是以 commonjs 标准执行的

所以这里也要干掉 module: "ESNext" 或者改成module: "commonjs"

很多时候我们项目在用 tsconfig.json 文件, 但是我们要执行node ts脚本的时候配置项 module 会和 tsconfig.json 冲突了, 这个时候我们可以用ts-node 执行的ts 脚本的时候 手动指定一个自定义个 tsconfig.json 文件

bash 复制代码
npx ts-node --project ./tsconfig.custom.json ./test.ts

这样基本就大功告成了。

相关推荐
毕设源码-邱学长3 分钟前
【开题答辩全过程】以 基于VUE的藏品管理系统的设计与实现为例,包含答辩的问题和答案
前端·javascript·vue.js
San30.36 分钟前
深入理解 JavaScript:手写 `instanceof` 及其背后的原型链原理
开发语言·javascript·ecmascript
北冥有一鲲1 小时前
LangChain.js:RAG 深度解析与全栈实践
开发语言·javascript·langchain
用户28907942162711 小时前
Spec-Kit应用指南
前端
酸菜土狗1 小时前
🔥 手写 Vue 自定义指令:实现内容区拖拽调整大小(超实用)
前端
ohyeah1 小时前
深入理解 React Hooks:useState 与 useEffect 的核心原理与最佳实践
前端·react.js
Cache技术分享1 小时前
275. Java Stream API - flatMap 操作:展开一对多的关系,拉平你的流!
前端·后端
apollo_qwe2 小时前
前端缓存深度解析:从基础到进阶的实现方式与实践指南
前端
周星星日记2 小时前
vue中hash模式和history模式的区别
前端·面试
Light602 小时前
Vue 高阶优化术:v-bind 与 v-on 的实战妙用与思维跃迁
前端·低代码·vue3·v-bind·组件封装·v-on·ai辅助开发