Lỗi gặp phải
Error: Cannot find module 'express'
Require stack:
- /home/user/myapp/app.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
Node.js báo lỗi này khi require() hoặc import không tìm thấy thứ bạn yêu cầu. Có ba nguyên nhân chính: package chưa được cài, đường dẫn file nội bộ bị sai, hoặc node_modules bị hỏng vì lý do nào đó.
Nguyên nhân gốc rễ
- Package chưa được cài —
npm installchưa được chạy, hoặc chạy ở sai thư mục - Đường dẫn tương đối trong
require('./someFile')bị sai — lệch một cấp thư mục node_modulesbị hỏng hoặc cài không đầy đủ (cài dở, đầy đĩa, v.v.)- Package có trong
package.jsonnhưng chưa thực sự được cài ở máy - Phiên bản Node.js không tương thích — package yêu cầu Node 18+ nhưng bạn đang dùng 16
- Dùng package global trong project local (hoặc ngược lại)
Cách sửa 1: Cài package còn thiếu
Chín trong mười trường hợp, đây là cách sửa đơn giản nhất. Package đơn giản là chưa có:
# npm
npm install express
# yarn
yarn add express
# pnpm
pnpm add express
Cài công cụ chỉ dùng khi phát triển như Jest hay TypeScript? Dùng --save-dev để tránh làm phình to bản build production:
npm install --save-dev jest
Kiểm tra nhanh:
node -e "require('express'); console.log('OK')"
Cách sửa 2: Xóa sạch và cài lại node_modules
Đôi khi node_modules bị lệch so với package-lock.json — cài dở, chuyển nhánh, hoặc nâng cấp thất bại đều có thể gây ra điều này. Cách khắc phục triệt để:
rm -rf node_modules package-lock.json
npm install
Trên Windows (PowerShell):
Remove-Item -Recurse -Force node_modules
Remove-Item package-lock.json
npm install
Lệnh này xóa toàn bộ và cài lại từ đầu. Thông thường npm install mất khoảng 30–90 giây với hầu hết các project.
Cách sửa 3: Kiểm tra lại thư mục đang đứng
Một cái bẫy kinh điển. Bạn chạy ứng dụng từ thư mục cha — nhưng node_modules lại nằm trong thư mục con của project, không phải nơi bạn đang đứng:
# Sai — node_modules không ở đây
cd /home/user
node myapp/app.js
# Đúng
cd /home/user/myapp
node app.js
Xác nhận node_modules và package.json cùng nằm trong một thư mục:
ls node_modules | grep express
Cách sửa 4: Sửa đường dẫn file nội bộ bị sai
Khi lỗi hiển thị Cannot find module './utils', Node.js đang tìm file tương đối so với module hiện tại — và nó không ở nơi bạn nghĩ.
// Sai: file không tồn tại ở đường dẫn này
const utils = require('./utils');
// Thử lên một cấp
const utils = require('../utils');
// Hoặc trong thư mục con
const utils = require('./helpers/utils');
Không chắc Node.js đang nhận thư mục nào làm gốc? In ra kiểm tra:
console.log(__dirname); // đường dẫn tuyệt đối của file hiện tại
Cách sửa 5: Vấn đề đường dẫn TypeScript / ESM
TypeScript với "moduleResolution": "NodeNext" có một điểm đặc biệt: bạn phải import với phần mở rộng .js dù file nguồn là .ts. Trông có vẻ lạ nhưng đúng — trình biên dịch tự xử lý lúc build.
// Dòng này import foo.ts — phần mở rộng .js là cố ý
import { foo } from './foo.js';
Đang dùng ts-node và gặp lỗi module? Thử thêm cờ ESM:
npx ts-node --esm app.ts
Hoặc chuyển sang trình phân giải dễ chịu hơn trong tsconfig.json:
{
"compilerOptions": {
"moduleResolution": "node"
}
}
Cách sửa 6: Xung đột package global và local
Các công cụ như nodemon hay ts-node thường được cài global, nhưng các script trong package.json lại kỳ vọng có bản local. Cài chúng làm dev dependency để đảm bảo nhất quán trên mọi máy:
npm install --save-dev nodemon ts-node
Để xem một package được cài ở đâu:
npm list express # cài local
npm list -g express # cài global
Cách sửa 7: NODE_PATH cho Monorepo
Các cấu hình tùy chỉnh và monorepo đôi khi cần chỉ định rõ đường dẫn phân giải module. Nếu Node.js không tìm thấy package dùng chung giữa các workspace:
# Chạy một lần
NODE_PATH=./src node app.js
# Gắn vào script trong package.json
"scripts": {
"start": "NODE_PATH=./src node app.js"
}
Các bước kiểm tra
- Xác nhận package có trong danh sách:
cat package.json | grep express - Xác nhận package đã được cài thực tế:
ls node_modules/express - Kiểm tra require trực tiếp:
node -e "require('express'); console.log('loaded')" - Chạy lại ứng dụng:
node app.js— lỗi sẽ không còn xuất hiện
Phòng tránh
- Commit
package.jsonvàpackage-lock.json— không bao giờ commitnode_modules - Sau khi clone repo hoặc pull code có thêm dependency mới, chạy
npm installngay - Thêm
node_modules/vào.gitignore— nếu không, repo sẽ phình to hàng trăm MB - Dùng
npm citrong pipeline CI/CD; khác vớinpm install, lệnh này tuân thủ chính xác lockfile - Khai báo phiên bản Node.js tối thiểu trong
package.jsonđể phát hiện sớm xung đột engine:"engines": { "node": ">=18" }

