Trang chủHướng dẫnHướng dẫn tạo dự án Node.js với TypeScript chi tiết từ A-Z
Chuyên gia

Hướng dẫn tạo dự án Node.js với TypeScript chi tiết từ A-Z

CyStack blog 6 phút để đọc
CyStack blog27/08/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 6 minutes

Trong hướng dẫn này, chúng ta sẽ tạo dự án Node.js Với TypeScript. Chúng ta sẽ xây dựng một ứng dụng Express bằng TypeScript và biên dịch nó thành mã JavaScript.

tạo dự án Node.js với TypeScript

Node.js là một môi trường runtime cho phép chạy JavaScript ở phía máy chủ và đã được sử dụng rộng rãi kể từ khi ra mắt vào năm 2011. Tuy nhiên, khi dự án mở rộng, việc phát triển JavaScript phía server có thể trở nên khó khăn do đặc tính động và hệ thống kiểu dữ liệu yếu của ngôn ngữ này.

Không ít lập trình viên chuyển từ các ngôn ngữ khác sang JavaScript phàn nàn về việc thiếu khả năng kiểm tra kiểu tĩnh mạnh mẽ, và đây chính là lúc TypeScript xuất hiện để lấp đầy khoảng trống này.

TypeScript là một siêu tập hợp (super-set) của JavaScript giúp xây dựng và quản lý các dự án JavaScript quy mô lớn. Có thể coi TypeScript như JavaScript nhưng bổ sung thêm các tính năng như kiểu tĩnh mạnh mẽ, biên dịch và lập trình hướng đối tượng.

Lưu ý, về mặt kỹ thuật, TypeScript là một siêu tập hợp của JavaScript, nghĩa là mọi mã JavaScript hợp lệ đều hợp lệ trong TypeScript.

Dưới đây là một số lợi ích khi sử dụng TypeScript:

  • Tùy chọn kiểm tra kiểu tĩnh
  • Suy luận kiểu
  • Có thể sử dụng Interface

Yêu cầu

Trước khi bắt đầu, bạn cần cài đặt Node.js trên hệ thống. Có thể thực hiện việc này bằng cách làm theo hướng dẫn “Cách cài đặt Node.js và tạo môi trường phát triển cục bộ” phù hợp với hệ điều hành của bạn.

Các bước trong hướng dẫn này áp dụng cho các phiên bản Ubuntu mới nhất: Ubuntu 24.04, Ubuntu 22.04 và Ubuntu 20.04. Nếu đang sử dụng Ubuntu phiên bản ≤ 18.04, bạn nên nâng cấp lên phiên bản mới hơn vì các phiên bản cũ không còn được Ubuntu hỗ trợ. Bộ hướng dẫn đi kèm sẽ hỗ trợ bạn nâng cấp phiên bản Ubuntu.

Bước 1: Khởi tạo dự án

Đầu tiên, tạo một thư mục mới có tên là node_project và chuyển vào thư mục đó:

mkdir node_project
cd node_project

Tiếp theo, khởi tạo dự án dưới dạng một dự án npm:

npm init -y

Tham số -y cho phép npm tự động chấp nhận tất cả giá trị mặc định. Bạn có thể cập nhật các thông tin này sau trong tập tin package.json.

Bước 2: Cấu hình trình biên dịch TypeScript

Sau khi đã khởi tạo dự án npm, chúng ta đã có thể cài đặt và cấu hình TypeScript.

Chạy lệnh sau trong thư mục dự án để cài đặt TypeScript:

npm install --save-dev typescript

Kết quả

added 1 package, and audited 2 packages in 1s
found 0 vulnerabilities

TypeScript sử dụng một tập tin có tên tsconfig.json để cấu hình các tùy chọn của trình biên dịch cho dự án. Tạo tập tin tsconfig.json tại thư mục gốc của dự án:

nano tsconfig.json

Sau đó dán vào nội dung JSON sau:

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "es6",
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist"
  },
  "lib": ["es2015"]
}

Cùng điểm qua một số khóa quan trọng trong đoạn JSON trên:

  • module: Xác định phương pháp sinh mã module. Node sử dụng commonjs
  • target: Chỉ định cấp độ ngôn ngữ đầu ra
  • moduleResolution: Hỗ trợ trình biên dịch xác định ý nghĩa của một câu lệnh import. Giá trị node mô phỏng cơ chế phân giải module của Node
  • outDir: Thư mục đầu ra chứa các tập tin .js sau khi biên dịch. Trong hướng dẫn này, thư mục đầu ra được đặt tên là dist

Để tìm hiểu thêm về các tùy chọn cấu hình, bạn có thể tham khảo tài liệu chính thức của TypeScript. Tài liệu này sẽ giải thích chi tiết hơn cho từng tùy chọn.

Bước 3: Tạo Server Express tối thiểu bằng TypeScript

Bây giờ, chúng ta sẽ cài đặt framework Express và tạo một server tối thiểu:

npm install --save express@4.17.1
npm install --save-dev @types/express@4.17.1

Lệnh thứ hai sẽ cài đặt các kiểu dữ liệu cho Express để TypeScript có thể hỗ trợ tốt hơn. Trong TypeScript, các kiểu dữ liệu này thường nằm trong các tệp có phần mở rộng .d.ts và dùng để cung cấp thông tin về kiểu của API, trong trường hợp này là framework Express.

Gói này là bắt buộc vì TypeScript và Express là hai gói độc lập. Nếu không có gói @types/express, TypeScript sẽ không thể biết các lớp trong Express có những kiểu dữ liệu gì.

Tiếp theo, tạo thư mục src trong thư mục gốc của dự án:

mkdir src

Sau đó tạo một tệp TypeScript có tên app.ts bên trong:

nano src/app.ts

Mở tệp app.ts bằng trình soạn thảo và dán đoạn mã sau:

import express from 'express';
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(port, () => {
  return console.log(`Express is listening at <http://localhost>:${port}`);
});

Đoạn mã trên tạo một server Node lắng nghe các yêu cầu tại cổng 3000. Để chạy ứng dụng, trước tiên cần biên dịch mã TypeScript thành mã JavaScript bằng lệnh sau:

npx tsc

Lệnh này sử dụng tệp cấu hình mà chúng ta đã tạo ở bước trước để xác định cách biên dịch mã và nơi lưu kết quả đầu ra. Trong trường hợp này, mã JavaScript sẽ được lưu tại thư mục dist.

Chạy tệp JavaScript đầu ra bằng Node:

node dist/app.js

Nếu thành công, bạn sẽ thấy thông báo hiển thị trên terminal như sau:

Kết quả

Express is listening at <http://localhost:3000>

Bây giờ bạn có thể truy cập địa chỉ http://localhost:3000 bằng trình duyệt và sẽ thấy thông điệp:

Kết quả

Hello World!

Mở tệp dist/app.js, bạn sẽ thấy phiên bản đã được biên dịch từ mã TypeScript:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const app = (0, express_1.default)();
const port = 3000;
app.get('/', (req, res) => {
    res.send('Hello World!');
});
app.listen(port, () => {
    return console.log(`Express is listening at <http://localhost>:${port}`);
});
//# sourceMappingURL=app.js.map

Đến đây, bạn đã thiết lập thành công một dự án Node sử dụng TypeScript. Tiếp theo, chúng ta sẽ cấu hình eslint để kiểm tra lỗi trong mã TypeScript.

Bước 4: Cấu hình kiểm tra TypeScript với eslint

Bây giờ bạn có thể cấu hình TypeScript linting cho dự án. Trước hết, hãy cài đặt eslint bằng npm:

npm install --save-dev eslint

Sau đó, chạy lệnh khởi tạo ESLint để thiết lập dự án thông qua giao diện tương tác.

npm init @eslint/config@latest

Lệnh này sẽ đặt ra một loạt câu hỏi. Trong dự án này, chúng ta sẽ chọn như sau:

  • Bạn muốn sử dụng ESLint để làm gì?: Để kiểm tra cú pháp và phát hiện lỗi
  • Dự án của bạn sử dụng loại module nào?: Module JavaScript (import/export)
  • Dự án của bạn sử dụng framework nào?: Không sử dụng framework
  • Dự án của bạn có sử dụng TypeScript không?: Có
  • Mã nguồn của bạn chạy ở đâu?: Node
  • Bạn muốn định dạng tệp cấu hình như thế nào?: JavaScript

Sau cùng, hệ thống sẽ hỏi bạn có muốn cài thêm các thư viện phụ trợ cho eslint hay không. Chọn Yes. Quá trình sẽ hoàn tất và tạo ra tệp cấu hình sau:

// .eslintrc.js
module.exports = {
  env: {
    es2021: true,
    node: true,
  },
  extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 13,
    sourceType: 'module',
  },
  plugins: ['@typescript-eslint'],
  rules: {},
}

Chạy eslint để kiểm tra tất cả tệp có phần mở rộng TypeScript .ts:

npx eslint . --ext .ts

Sau khi thiết lập xong ESLint để kiểm tra cú pháp TypeScript, bước tiếp theo là cập nhật cấu hình npm, bổ sung một số script tiện lợi cho việc lint và chạy dự án.

Bước 5: Cập nhật tệp package.json

Định nghĩa các lệnh thường dùng dưới dạng npm scripts sẽ giúp bạn chạy các tác vụ bằng câu lệnh ngắn gọn hơn. Các script này được định nghĩa trong tệp package.json và có thể chạy bằng câu lệnh npm run your_script_name.

Trong bước này, chúng ta sẽ thêm một script start để biên dịch mã TypeScript rồi chạy ứng dụng .js đầu ra.

Đồng thời, thêm một script lint để chạy eslint kiểm tra các tệp TypeScript.

Mở tệp package.json và cập nhật như sau:

{
  "name": "node_project",
  "version": "1.0.0",
  "description": "",
  "main": "dist/app.js",
  "scripts": {
    "start": "tsc && node dist/app.js",
    "lint": "eslint . --ext .ts",
    "test": "echo \\"Error: no test specified\\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/express": "^4.17.1",
    "@typescript-eslint/eslint-plugin": "^5.4.0",
    "@typescript-eslint/parser": "^5.4.0",
    "eslint": "^8.3.0",
    "typescript": "^4.5.2"
  },
  "dependencies": {
    "express": "^4.17.1"
  }
}

Trong đoạn cấu hình trên, bạn đã cập nhật đường dẫn chính (main) để trỏ đến tệp .js đã được biên dịch, đồng thời thêm hai lệnh startlint trong phần scripts.

Lệnh start đầu tiên sẽ chạy tsc để biên dịch, sau đó dùng node để thực thi đầu ra.

Lệnh lint giống với lệnh bạn đã chạy ở bước trước, chỉ khác là bỏ tiền tố npx vì trong ngữ cảnh này không cần dùng đến.

Kết luận

Trong hướng dẫn này, bạn đã tìm hiểu lý do TypeScript giúp viết mã JavaScript an toàn và nhất quán, cùng với một số lợi ích nổi bật khi sử dụng TypeScript.

Cuối cùng, bạn đã thiết lập một dự án Node.js với framework Express, đồng thời biên dịch và chạy dự án bằng TypeScript.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất