Setup dự án Node.js với TypeScript ESLint Prettier
Châm ngôn của mình là học để kiếm tiền.
Vì thế mình build các khóa học của mình để giúp anh em tiến bộ nhanh hơn x10 lần , để kiếm được nhiều tiền hơn
- 🏆 React.js Super: Trở thành React.js Developer trong 7 ngày với mức thu nhập 20 triệu/tháng
- 🏆 Node.js Super: Giúp bạn học cách phân tích, thiết kế, deploy 1 API Backend bằng Node.js
- 🏆 Next.js Super: Mình sẽ chia sẻ từ A-Z kiến thức về Next.js, thứ giúp mình kiếm hơn 1 tỉ/năm
- 🏆 Deploy Super: CI/CD Deploy tự động React, Node, Next lên VPS qua Github Actions kết hợp Telegram Bot
Đây là năm 2024 rồi, bây giờ mà code Node.js với Javascript thì có vẻ hơi "lạc hậu" 🥲. Typescript gần như là bắt buộc khi code những project liên quan đến Javascript trong những năm gần đây.
Code TypeScript một thời gian bạn sẽ không muốn quay về code Javascript nữa. Trust me 😎.
Có thể bạn sẽ thắc mắc, "thế ESLint với Prettier dùng để làm gì? "
ESLint thì chuẩn hóa tiêu chuẩn code, còn Prettier thì format code cho đẹp. Khi code một dự án chỉ có một mình bạn thì sao cũng được, nhưng khi code một dự án nhiều người thì đòi hỏi tất cả mọi người trong team phải code theo cùng một tiêu chuẩn, nếu không thì sẽ rất khó khăn trong việc đọc code của những người khác. Và ESLint và Prettier sẽ giúp bạn giải quyết vấn đề này.
Vì vậy, trong bài viết này, mình sẽ hướng dẫn các bạn cách setup dự án Node.js với TypeScript, cũng như cách sử dụng ESLint Prettier để check code.
🥇Cấu trúc thư mục dự án
Cấu trúc thư mục dự án mình sẽ sử dụng như sau:
📦nodejs-typescript
┣ 📂dist
┣ 📂src
┃ ┣ 📂constants
┃ ┃ ┣ 📜enum.ts
┃ ┃ ┣ 📜httpStatus.ts
┃ ┃ ┗ 📜message.ts
┃ ┣ 📂controllers
┃ ┃ ┗ 📜users.controllers.ts
┃ ┣ 📂middlewares
┃ ┃ ┣ 📜error.middlewares.ts
┃ ┃ ┣ 📜file.middlewares.ts
┃ ┃ ┣ 📜users.middlewares.ts
┃ ┃ ┗ 📜validation.middlewares.ts
┃ ┣ 📂models
┃ ┃ ┣ 📂database
┃ ┃ ┃ ┣ 📜Blacklist.ts
┃ ┃ ┃ ┣ 📜Bookmark.ts
┃ ┃ ┃ ┣ 📜Follower.ts
┃ ┃ ┃ ┣ 📜Hashtag.ts
┃ ┃ ┃ ┣ 📜Like.ts
┃ ┃ ┃ ┣ 📜Media.ts
┃ ┃ ┃ ┣ 📜Tweet.ts
┃ ┃ ┃ ┗ 📜User.ts
┃ ┃ ┣ 📜Error.ts
┃ ┃ ┗ 📜Success.ts
┃ ┣ 📂routes
┃ ┃ ┗ 📜users.routes.ts
┃ ┣ 📂services
┃ ┃ ┣ 📜bookmarks.services.ts
┃ ┃ ┣ 📜database.services.ts
┃ ┃ ┣ 📜followers.services.ts
┃ ┃ ┣ 📜hashtags.services.ts
┃ ┃ ┣ 📜likes.services.ts
┃ ┃ ┣ 📜medias.services.ts
┃ ┃ ┣ 📜tweets.services.ts
┃ ┃ ┗ 📜users.services.ts
┃ ┣ 📂utils
┃ ┃ ┣ 📜crypto.ts
┃ ┃ ┣ 📜email.ts
┃ ┃ ┣ 📜file.ts
┃ ┃ ┣ 📜helpers.ts
┃ ┃ ┗ 📜jwt.ts
┃ ┣ 📜index.ts
┃ ┗ 📜type.d.ts
┣ 📜.editorconfig
┣ 📜.env
┣ 📜.eslintignore
┣ 📜.eslintrc
┣ 📜.gitignore
┣ 📜.prettierignore
┣ 📜.prettierrc
┣ 📜nodemon.json
┣ 📜package.json
┣ 📜tsconfig.json
┗ 📜yarn.lockGiải thích các thư mục:
dist: Thư mục chứa các file buildsrc: Thư mục chứa mã nguồnsrc/constants: Chứa các file chứa các hằng sốsrc/middlewares: Chứa các file chứa các hàm xử lý middleware, như validate, check token, ...src/controllers: Chứa các file nhận request, gọi đến service để xử lý logic nghiệp vụ, trả về responsesrc/services: Chứa các file chứa method gọi đến database để xử lý logic nghiệp vụsrc/models: Chứa các file chứa các modelsrc/routes: Chứa các file chứa các routesrc/utils: Chứa các file chứa các hàm tiện ích, như mã hóa, gửi email, ...- Còn lại là những file config cho project như
.eslintrc,.prettierrc, ... mình sẽ giới thiệu ở bên dưới
🥇Khởi tạo dự án
Đầu tiên chúng ta cần tạo folder để làm việc.
mkdir nodejs-typescript
cd nodejs-typescriptTiếp theo, chúng ta sẽ setup dự án với package.json và thêm các dependencies cần thiết.
🥈Tạo dự án Node.js
Sử dụng -y khi chạy lệnh npm init khi tạo file package.json để không cần nhập các thông tin về project. Chúng ta có thể vào file package.json để chỉnh sửa sau.
npm init -y🥈Thêm TypeScript như một dev dependency
Bước này chắc sẽ không bất ngờ lắm nhỉ, để sử dụng Typescript, chúng ta cần phải cài đặt nó trước.
npm install typescript --save-devSau khi cài typescript, chúng ta có thể dùng TypeScript để biên dịch code bằng câu lệnh tsc (lưu ý là mình cài local (không phải global) nên muốn dùng tsc thì phải gián tiếp qua script trong package.json hoặc dùng trực tiếp thì npx tsc).
🥈Cài đặt kiểu dữ liệu TypeScript cho Node.js
Vì dùng TypeScript để code Node.js nên chúng ta cần cài thêm kiểu dữ liệu cho Node.js.
npm install @types/node --save-dev🥈Cài đặt ESLint
Cứ theo doc ESLint mà "vả" thôi
npm init @eslint/config@latestKhi chạy câu lệnh này nó sẽ cho bạn chọn một số option phù hợp, các bạn chọn theo mình dưới đây là được nhé:
Để ý cho mình cái bước Where does your code run, các bạn dùng phím cách trên bàn phím để bỏ đi Browser và chọn Node rồi enter nhé.
? How would you like to use ESLint? …
To check syntax only
❯ To check syntax and find problems
? What type of modules does your project use? …
❯ JavaScript modules (import/export)
CommonJS (require/exports)
None of these
? Which framework does your project use? …
React
Vue.js
❯ None of these
? Does your project use TypeScript? …
No
❯ Yes
? Where does your code run? … (Press <space> to select, <a> to toggle all, <i> to invert selection)
Browser
✔ Node
The config that you've selected requires the following dependencies:
eslint, globals, @eslint/js, typescript-eslint
? Would you like to install them now? › No / Yes
? Which package manager do you want to use? …
❯ npm
yarn
pnpm
bun
Kết quả chọn là như thế này nhé anh em
✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · none
✔ Does your project use TypeScript? · typescript
✔ Where does your code run? · node
The config that you've selected requires the following dependencies:
eslint, globals, @eslint/js, typescript-eslint
✔ Would you like to install them now? · Yes
✔ Which package manager do you want to use? · npm
Sau khi chạy xong, nó sẽ tạo ra 1 file eslint.config.mjs trong thư mục gốc của dự án.
eslint.config.mjs
import globals from 'globals'
import pluginJs from '@eslint/js'
import tseslint from 'typescript-eslint'
export default [
{ files: ['**/*.{js,mjs,cjs,ts}'] },
{ languageOptions: { globals: globals.node } },
pluginJs.configs.recommended,
...tseslint.configs.recommended
]và tự động cài một số package liên quan đến ESLint vào devDependencies trong package.json.
🥈Cài đặt các package config cần thiết còn lại
Chúng ta cần cài đặt các package config cần thiết để làm việc với TypeScript như ESLint, Prettier, ...
npm install prettier eslint-config-prettier eslint-plugin-prettier tsx tsc-alias rimraf nodemon --save-devprettier: Code formatter chínheslint-config-prettier: Cấu hình ESLint để không bị xung đột với Prettiereslint-plugin-prettier: Dùng thêm một số rule prettier cho eslinttsx: Dùng để chạy TypeScript code trực tiếp mà không cần buildtsc-alias: Xử lý alias khi buildrimraf: Dùng để xóa folderdistkhi trước khi buildnodemon: Dùng để tự động restart server khi có sự thay đổi trong code
🥈Cấu hình tsconfig.json
Tạo file tsconfig.json tại thư mục root, có thể tạo bằng lệnh touch tsconfig.json hoặc cứ tạo bằng tay, quen cái nào thì dùng cái đấy
Tiếp theo copy và paste cấu hình dưới đây vào file tsconfig.json của bạn
{
"compilerOptions": {
"module": "NodeNext", // Quy định output module được sử dụng
"moduleResolution": "NodeNext",
"target": "ES2023", // Target output cho code
"outDir": "dist", // Đường dẫn output cho thư mục build
"esModuleInterop": true,
"strict": true /* Enable all strict type-checking options. */,
"skipLibCheck": true /* Skip type checking all .d.ts files. */,
"baseUrl": ".", // Đường dẫn base cho các import
"paths": {
"~/*": ["src/*"] // Đường dẫn tương đối cho các import (alias)
}
},
"files": ["src/type.d.ts"], // Các file dùng để defined global type cho dự án
"include": ["src/**/*"] // Đường dẫn include cho các file cần build
}💡 Mẹo:
Nếu muốn bỏ qua check lỗi khi build thì các bạn có thể thêm
"noEmit": truevào filetsconfig.jsonnhé. Mà mình nghĩ không ai muốn làm vậy đâu, thế thì thà dùng JavaScript cho rồi 😂
🥈Cấu hình file config cho ESLint
Mở file eslint.config.mjs lên và thêm nội dung dưới đây
Các bạn import cái này vào đầu file eslint.config.mjs
import eslintPluginPrettier from 'eslint-plugin-prettier'Thêm đoạn này vào cuối cùng phần array export default
{
plugins: {
prettier: eslintPluginPrettier
},
rules: {
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': 'warn',
'prettier/prettier': [
'warn',
{
arrowParens: 'always',
semi: false,
trailingComma: 'none',
tabWidth: 2,
endOfLine: 'auto',
useTabs: false,
singleQuote: true,
printWidth: 120,
jsxSingleQuote: true
}
]
},
ignores: ['**/node_modules/', '**/dist/']
}Cuối cùng chúng ta sẽ có file eslint.config.mjs như sau
import globals from 'globals'
import pluginJs from '@eslint/js'
import tseslint from 'typescript-eslint'
import eslintPluginPrettier from 'eslint-plugin-prettier'
export default [
{ files: ['**/*.{js,mjs,cjs,ts}'] },
{ languageOptions: { globals: globals.node } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
{
plugins: {
prettier: eslintPluginPrettier
},
rules: {
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': 'warn',
'prettier/prettier': [
'warn',
{
arrowParens: 'always',
semi: false,
trailingComma: 'none',
tabWidth: 2,
endOfLine: 'auto',
useTabs: false,
singleQuote: true,
printWidth: 120,
jsxSingleQuote: true
}
]
},
ignores: ['**/node_modules/', '**/dist/']
}
]💡 Mẹo:
Anh em nhớ cài extension
ESLintcho VS Code để nó hiểu được file này nhé
🥈Cấu hình file config cho Prettier
Tạo file .prettierrc trong thư trong thư mục root với nội dung dưới đây
{
"arrowParens": "always",
"semi": false,
"trailingComma": "none",
"tabWidth": 2,
"endOfLine": "auto",
"useTabs": false,
"singleQuote": true,
"printWidth": 120,
"jsxSingleQuote": true
}Mục đích là cấu hình prettier.
💡 Mẹo:
Anh em nên cài Extension
Prettier - Code formattercho VS Code để nó hiểu nhé.
Tiếp theo Tạo file .prettierignore ở thư mục root
Mục đích là Prettier bỏ qua các file không cần thiết
node_modules/
dist/🥈Config editor để chuẩn hóa cấu hình editor
Tạo file .editorconfig ở thư mục root
Mục đích là cấu hình các config đồng bộ các editor với nhau nếu dự án có nhiều người tham gia.
Để VS Code hiểu được file này thì anh em cài Extension là EditorConfig for VS Code nhé
[*]
indent_size = 2
indent_style = space🥈Cấu hình file gitignore
Tạo file .gitignore ở thư mục root
Mục đích là cấu hình các file không cần đẩy lên git
node_modules/
dist/🥈Cấu hình file nodemon.json
Tạo file nodemon.json ở thư mục root
Mục đích là cấu hình nodemon để tự động restart server khi có sự thay đổi trong code
{
"watch": ["src", ".env"],
"ext": ".ts,.js",
"ignore": [],
"exec": "tsx ./src/index.ts"
}🥈Cấu hình file package.json
Mở file package.json lên, thêm đoạn script này vào
"scripts": {
"dev": "npx nodemon",
"build": "rimraf ./dist && tsc && tsc-alias",
"start": "node dist/index.js",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"prettier": "prettier --check .",
"prettier:fix": "prettier --write ."
}🥇Tạo file type.d.ts
Tạo file type.d.ts trong thư mục src, tạm thời bây giờ các bạn để trống cũng được. Mục đích là để defined các global type cho dự án.
Các bạn mở file tsconfig.json lên sẽ thấy dòng mình add file này vào để cho typescript nó nhận diện
🥇Tạo file index.ts
Tạo file index.ts trong thư mục src
const name: string = 'Dư Thanh Được'
console.log(name)Bây giờ dùng các câu lệnh dưới để test thử nhé
🥇Câu lệnh để chạy dự án
Đến đây là xong rồi đó. Các bạn có thể chạy dự án bằng các câu lệnh sau
🥈Chạy dự án trong môi trường dev
npm run dev🥈Build dự án TypeScript sang JavaScript cho production
Có thể các bạn sẽ hỏi rằng tại sao phải build, để nguyên TypeScript thì luôn vẫn được mà. Đúng vậy nhưng khi build thì chúng ta sẽ có những lợi ích sau
- Code chạy được mà không cần cài đặt TypeScript
- Chạy nhanh hơn vì đã được biên dịch rồi
- Có thể minify code để giảm dung lượng
- Code chạy được trên những mội trường không hỗ trợ TypeScript
Để build thì chạy câu lệnh sau
npm run buildTiếp theo chạy câu lệnh sau để chạy dự án, lưu ý câu lệnh này đòi hỏi bạn phải build trước để có code trong thư mục dist
npm run start🥈Kiểm tra lỗi ESLint / Prettier bằng Terminal
Câu lệnh này sẽ giúp bạn kiểm tra lỗi ESLint trong dự án
npm run lintNếu bạn muốn ESLint tự động fix lỗi thì chạy câu lệnh sau
npm run lint:fixTương tự với Prettier, ta có câu lệnh
npm run prettiervà
npm run prettier:fix🥇Một số lưu ý
🥈Skip kiểm tra lỗi TypeScript khi build
Chỉ cần vào package.json sửa lại script build như sau
"build": "rimraf ./dist && tsc --noCheck && tsc-alias",🥈Lưu ý cài thêm gói @types/ten-thu-vien nếu cần
Vì đây là dự án chạy với Typescript nên khi cài đặt bất cứ một thư viện này chúng ta nên xem thư viện đó có hỗ trợ TypeScript không nhé. Có một số thư viện ở npm hỗ trợ TypeScript sẵn, có một số thì chúng ta phải cài thêm bộ TypeScript của chúng qua @types/ten-thu-vien
Ví dụ như express thì chúng ta cài như sau
npm i express
npm i @types/express -D🥈Cách import thư viện ES Module?
Mặc dù chúng ta dùng import và export khi code TypeScript, trông có vẻ là ES Module nhưng ẩn sâu bên trong đó là CommonJS.
Chỉ là TypeScript làm thế cho chúng ta tiện lợi hơn thôi.
Vậy nên dự án của chúng ta vẫn là CommonJS, nên khi dùng thư viện ES Module thì chúng ta cần phải dùng import('ten-thu-vien').default để lấy ra thư viện đó.
Ví dụ thư viện formidable là một thư viện ES Module, nên khi dùng nó chúng ta phải dùng như sau
export const handleUploadImage = async (req: Request) => {
const formidable = (await import('formidable')).default
}Chúc các bạn thành công nhé.
Thank me later 🤪
👉 Kiến thức trong khóa học Next.js này đã giúp mình kiếm hơn 1 tỉ đồng/năm
Phew! Cuối cùng bạn cũng đã đọc xong. Bài viết này có hơi dài một tí vì mình muốn nó đầy đủ nhất có thể 😅
Website bạn đang đọc được viết bằng Next.js TypeScript và tối ưu từng chi tiết nhỏ như SEO, hiệu suất, nội dung để đảm bảo bạn có trải nghiệm tốt nhất.
Với lượt view trung bình là 30k/tháng (dù website rất ít bài viết). Website này đem lại doanh thu 1 năm vừa qua là hơn 1 tỉ đồng
Đó chính là sức mạnh của SEO, sức mạnh của Next.js.
Mình luôn tin rằng kiến thức là chìa khóa giúp chúng ta đi nhanh nhất.
Mình đã dành hơn 6 tháng để phát triển khóa học Next.js Super | Dự án quản lý quán ăn & gọi món bằng QR Code. Trong khóa này các bạn sẽ được học mọi thứ về framework Next.js, các kiến thức từ cơ bản cho đến nâng cao nhất, mục đích của mình là giúp bạn chinh phục mức lương 25 - 30 triêu/tháng
Nếu bạn cảm thấy bài viết này của mình hữu ích, mình nghĩ bạn sẽ thích hợp với phong cách dạy của mình. Không như bài viết này, khóa học là sự kết hợp giữa các bài viết, video, bài tập nhỏ và dự án lớn có thể xin việc được ngay. Học xong mình đảm bảo bạn sẽ lên tay ngay. 💪🏻








