LỗiCó thể bạn vừa thêm "type": "module" vào tệp package.json của mình để tận hưởng ES Modules hiện đại. Tuy nhiên, ngay khi bạn cố gắng chạy một tệp TypeScript, Node.js sẽ gặp sự cố. Thay vì thực thi mã của bạn, runtime sẽ đưa ra một lỗi mở rộng gây khó chịu:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /path/to/file.ts
at new NodeError (node:internal/errors:399:5)
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:79:11)
Tại sao lỗi này xảy raNode.js không hỗ trợ TypeScript một cách nguyên bản. Khi bạn kích hoạt ES Modules (ESM), Node.js sử dụng một loader nghiêm ngặt chỉ nhận diện các tệp .js, .mjs, và .json. Không giống như hệ thống CommonJS cũ, ESM loader sẽ không cho phép ts-node can thiệp vào runtime một cách dễ dàng nếu không có các flag cụ thể.
Nếu bạn chạy node script.ts, Node sẽ nhìn vào phần mở rộng và dừng lại ngay lập tức. Nó đơn giản là không biết phải làm gì với tệp .ts trong ngữ cảnh ESM.
Giải pháp 1: Sử dụng 'tsx' (Tiêu chuẩn hiện đại)Trong quá trình phát triển, tsx hiện là công cụ đáng tin cậy nhất. Đây là giải pháp thay thế cho Node.js được xây dựng trên esbuild, giúp nó nhanh hơn tới 10 lần so với ts-node truyền thống. Nó xử lý ESM và TypeScript mà không cần cấu hình thêm.
1. Cài đặt tsx```
npm install --save-dev tsx
### 2. Chạy tệp của bạnChỉ cần thay thế `node` hoặc `ts-node` bằng `tsx`:
npx tsx ./src/index.ts
Cách này hoạt động vì `tsx` tự động đăng ký các loader cần thiết ở chế độ chạy ngầm. Bạn sẽ không phải quản lý các flag phức tạp hay các cảnh báo thử nghiệm (experimental warnings).
## Giải pháp 2: Sử dụng 'ts-node' với ESM LoaderNếu quy trình làm việc của bạn phụ thuộc vào `ts-node`, bạn phải chỉ định rõ cho Node.js cách xử lý ESM loader. Lệnh bạn sử dụng tùy thuộc vào phiên bản Node.js cụ thể của bạn.
### Dành cho Node.js v20.6.0+ hoặc v18.19.0+Các bản cập nhật gần đây đã giới thiệu flag `--import`. Đây là cách ổn định và hiện đại để đăng ký hỗ trợ TypeScript:
node --import ts-node/register ./src/index.ts
### Dành cho các phiên bản Node.js cũ hơn (v16.x hoặc v18 đời đầu)Bạn phải sử dụng flag loader thử nghiệm. Lưu ý rằng Node.js sẽ hiển thị cảnh báo rằng đây là một tính năng đang thử nghiệm:
node --loader ts-node/esm ./src/index.ts
### Cập nhật tệp tsconfig.jsonĐể `ts-node` hoạt động với ESM, tệp `tsconfig.json` của bạn cần một khối cấu hình `ts-node` cụ thể:
{ "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" }, "ts-node": { "esm": true } }
## Giải pháp 3: Khắc phục cho môi trường Production (Biên dịch)Chạy trực tiếp các tệp `.ts` rất tốt khi lập trình, nhưng sẽ rủi ro cho môi trường production. Cách tiếp cận mạnh mẽ nhất là biên dịch mã của bạn sang JavaScript tiêu chuẩn trước khi triển khai.
### 1. Build dự án```
npx tsc
2. Chạy kết quả đầu raSau khi biên dịch, hãy chạy tệp JavaScript kết quả từ thư mục build của bạn (thường là dist hoặc out):
node dist/index.js
Vì đầu ra là .js tiêu chuẩn, ESM loader của Node sẽ xử lý nó mà không gặp vấn đề gì. Lưu ý: Trong chế độ ESM, các câu lệnh import trong TypeScript của bạn phải bao gồm phần mở rộng .js, ngay cả khi tệp nguồn là .ts.
Kiểm tra nhanhBạn không chắc chắn lỗi đã được sửa chưa? Hãy tạo một tệp tên là check.ts và thêm đoạn mã này:
const message: string = "Loader đang hoạt động!";
console.log(message);
Chạy npx tsx check.ts. Nếu bạn thấy thông báo mà không có stack trace, môi trường của bạn đã sẵn sàng.
Các lưu ý quan trọng
- Sử dụng .js khi import: ESM yêu cầu phần mở rộng tệp đầy đủ. Luôn viết
import { tool } from './tool.js';. - Thử dùng .mts: Sử dụng phần mở rộng
.mtsbuộc Node phải coi tệp đó là ES Module bất kể cài đặt trongpackage.jsoncủa bạn như thế nào. - Luôn cập nhật: Nếu bạn đang sử dụng phiên bản cũ hơn Node 18, hãy cân nhắc nâng cấp lên v20+ để sử dụng flag
--importổn định hơn.

