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.
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ụngcommonjs
target
: Chỉ định cấp độ ngôn ngữ đầu ramoduleResolution
: Hỗ trợ trình biên dịch xác định ý nghĩa của một câu lệnhimport
. Giá trịnode
mô phỏng cơ chế phân giải module của NodeoutDir
: 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 start
và lint
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.