网站首页 > 技术文章 正文
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
随着 Node.js v23.6.0 的发布,开发者现在可以在 Node.js 中原生使用 TypeScript,无需额外的转译工具(例如: ts-node)或新增手动编译步骤。该功能显著简化了开发和构建流程,并通过降低复杂性提升了整体开发体验。
1. 新功能速览
以下是一个简单的 TypeScript 示例,演示了 Node.js 对 TypeScript 的原生支持:
// demo.mts
function main(message: string): void {
console.log('Message:' + message);
}
main('Hello!');
而以前,在 Node.js 中运行 TypeScript 需要使用 TypeScript 编译器 (tsc) 或 ts-node 之类的工具进行转译。而从 Node v23.6.0 开始,开发者可以直接运行该文件:
node demo.mts
// 注意:需要 Node.js v23.6.0 以上版本
而且,运行此命令将产生以下警告:
ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
由于类型剥离 (Type Stripping) 仍处于实验阶段,因此尚不建议在生产环境使用且未来可能随时变更。如果要在开发设置中隐藏警告,可以通过下面的命令:
node --disable-warning=ExperimentalWarning demo.mts
// 临时取消警告
export NODE_OPTIONS="--disable-warning=ExperimentalWarning"
// 永久取消警告
对于长期配置,开发者可以将其存储在 .bashrc、.zshrc 或 .env 文件中,或在 IDE 设置中对其进行配置。
2. 在 Node.js 实际项目中使用 TypeScript
在 Node.js 中启用运行时 TypeScript 支持有两种方法:
- 全面支持 TypeScript 的所有语法和功能,包括:使用任意版本的 TypeScript,可以使用第三方软件包
- 为了获得轻量级支持,开发者可以使用内置的类型剥离支持
2.1 全面支持 TypeScript
要在 Node.js 中使用 TypeScript 并完全支持所有 TypeScript 功能,包括: tsconfig.json,开发者可以使用第三方软件包。下面以 tsx 为例,但还有许多其他类似的库可用。
npm install --save-dev tsx
然后可以通过以下方式运行 TypeScript 代码:
npx tsx your-file.ts
// 或者使用 node 命名运行
node --import=tsx your-file.ts
2.2 使用类型剥离 (Type Stripping) 方式
默认情况下,Node.js 会执行仅包含可擦除 TypeScript 语法 (Erasable TypeScript Syntax) 的 TypeScript 文件。
Node.js 会将 TypeScript 语法替换为空格,并且不执行类型检查 。要启用不可擦除 TypeScript 语法的转换,例如:Enum、namespace、参数属性、导入别名、module 等,开发者可以使用
--experimental-transform-types 标志,而要禁用此功能,可以使用
--no-experimental-strip-types 标志。
// This namespace is exporting a value
namespace A {
export let x = 1
}
同时,Node.js 会忽略 tsconfig.json 文件,因此依赖于 tsconfig.json 中设置的功能,例如:路径或将较新的 JavaScript 语法转换为较旧的标准将不受支持。
类型剥离旨在保证轻量级且有意不支持需要转化为 JavaScript 的语法,并将内联类型替换为空格,无需 Source Map 即可运行 TypeScript 代码。
类型剥离与大多数版本的 TypeScript 兼容,但建议使用 5.8 或更新版本,并使用以下 tsconfig.json 设置:
{
"compilerOptions": {
"noEmit": true,
// 如果只想执行 *.ts 文件可使用 noEmit 选项
// 如果打算分发 *.js 文件,则无需使用此标志
"target": "esnext",
"module": "nodenext",
"rewriteRelativeImportExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}
一个常见的场景是在 TypeScript 中导入流行的 Node.js 库,例如:
import {writeFileSync} from 'fs';
function saveMessage(message: string): void {
writeFileSync('message.txt', message);
}
saveMessage('Hello, Node.js!');
上面示例表明原生 TypeScript 可以与标准 Node.js 模块无缝协作。需要注意的是,Node.js 通过扩展名区分文件类型:
- .ts:ESM 或 CommonJS,取决于 package.json 的 “type” 字段
- .mts:始终视为 ESM
- .cts:始终视为 CommonJS
- .tsx:目前不支持
开发者必须谨慎选择文件名,以保持与 Node.js 模块的兼容性。
3.Node.js TypeScript 与传统 TypeScript 的不同
Node.js 通过类型剥离(无需转译即可移除类型注释)实现了原生 TypeScript 支持。主要限制和解决方法包括:
3.1 不支持的 TypeScript 特定功能及替代方案
3.2 本地导入需要 .ts 扩展名
// 传统方式
import {myFunction} from './my-module.js';
// Node.js 原生 TS 支持
import {myFunction} from './my-module.ts';
3.3 需要显式导入类型
import type {Cat, Dog} from './animal.ts';
3.4 --input-type CLI 选项
从标准输入 stdin 或使用 --eval 运行 TypeScript 代码时,开发者需要使用 --input-type 明确指定解释:
echo 'console.log("Hello"as const)' | node --input-type module-typescript
3.5 类型剥离(Type stripping)和 Source Map
类型剥离可保留空格以实现精确调试,并消除 Source Map 依赖性:
function describeColor(color: Color): string {
return `Color named "${color.colorName}"`;
}
type Color = {colorName: string};
describeColor({colorName: 'green'});
Post-type-stripping JavaScript:
function describeColor(color) {
return `Color named "${color.colorName}"`;
}
describeColor({colorName: 'green'});
4. 结论
Node.js v23.6.0 版本新增了原生 TypeScript 支持,无疑是一个重大进步,其简化了 TypeScript 工作流程,并减少了对打包工具的依赖。虽然仍然存在一些限制,但未来的增强功能(
--experimental-transform-types)可能会进一步扩展 Node.js 的 TypeScript 功能。
参考资料
https://nodejs.org/api/typescript.html
https://nodesource.com/blog/Node.js-Supports-TypeScript-Natively
https://dev.to/kevin-uehara/node-will-finally-suport-typescript-18k6
猜你喜欢
- 2025-05-15 宇宙厂:深入聊聊 CJS 和 ESM 模块化三点核心差异?
- 2025-05-15 #前端高手进阶#一起薅羊毛~
- 2025-05-15 前端基础进阶(十):深入详解函数的柯里化
- 2025-05-15 2025 年 Object 和 Map 如何选择?
- 2025-05-15 为何说 postMessage 才是真正的 setTimeout(0)?
- 2025-05-15 为什么高手写 JS 总是又快又好?这10个技巧你要知道
- 2025-05-15 2025 年 Deno 终于官宣 pnpm 和 Yarn 可使用 JSR?
- 2025-05-15 宇宙厂:为什么前端要了解 Interaction to Next Paint (INP)
- 2025-05-15 请务必用 postTask/isInputPending 释放JS主线程!
- 2025-05-15 未来 JS 标准中的 Map.getOrInsert:彻底告别 if-else 判断?
你 发表评论:
欢迎- 最近发表
-
- 宇宙厂:深入聊聊 CJS 和 ESM 模块化三点核心差异?
- #前端高手进阶#一起薅羊毛~
- 前端基础进阶(十):深入详解函数的柯里化
- 2025 年 Object 和 Map 如何选择?
- 为何说 postMessage 才是真正的 setTimeout(0)?
- 为什么高手写 JS 总是又快又好?这10个技巧你要知道
- 2025 年 Deno 终于官宣 pnpm 和 Yarn 可使用 JSR?
- 宇宙厂:为什么前端要了解 Interaction to Next Paint (INP)
- Node.js 原生支持 TypeScript?开发者需要了解的一切
- 请务必用 postTask/isInputPending 释放JS主线程!
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端md5加密 (49)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- 前端接口 (46)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle约束 (46)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)