Series 6 – Next.js Advanced & Production
Bài 5: Next.js Build & Deployment – Từ mã nguồn đến môi trường Production
1. Mở đầu
Trong quá trình phát triển một ứng dụng web, việc chạy thành công trên máy tính cá nhân chưa có nghĩa là ứng dụng đã sẵn sàng để đưa đến người dùng.
Khi phát triển, chúng ta thường chạy ứng dụng bằng lệnh npm run dev. Chế độ này hỗ trợ việc lập trình và kiểm tra thay đổi nhanh chóng. Tuy nhiên, khi triển khai sản phẩm thực tế, ứng dụng cần được build, cấu hình môi trường và đưa lên một máy chủ hoặc nền tảng hosting phù hợp.
Ví dụ, một website được xây dựng bằng Next.js có thể chạy bình thường trên máy cá nhân nhưng gặp lỗi khi triển khai do thiếu biến môi trường, sai cấu hình build hoặc không tương thích với môi trường production.
Vì vậy, hiểu rõ Build và Deployment là bước quan trọng để một Frontend Developer có thể đưa ứng dụng từ mã nguồn đến môi trường sử dụng thực tế.
2. Build là gì?
Build là quá trình chuyển đổi mã nguồn thành đầu ra phù hợp để ứng dụng có thể được chạy hoặc triển khai.
Trong Next.js, quá trình build có thể bao gồm:
- Biên dịch TypeScript và JSX.
- Xử lý module và dependencies.
- Tối ưu JavaScript, CSS và tài nguyên.
- Tạo các trang HTML được render trước khi triển khai, tùy theo cấu hình và cách render.
- Chuẩn bị các thành phần cần thiết cho môi trường production.
Trong một dự án Next.js thông thường, chúng ta có thể chạy:
npm run build
Lệnh này thường thực thi script build được khai báo trong package.json, chẳng hạn:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint"
}
}
Ý nghĩa của các lệnh:
| Lệnh | Mục đích |
|---|---|
npm run dev |
Chạy môi trường phát triển |
npm run build |
Build ứng dụng cho production |
npm run start |
Khởi chạy server production sau khi build, với cách triển khai Next.js phù hợp |
npm run lint |
Chạy ESLint nếu script được cấu hình |
Lưu ý rằng npm run start không thay thế cho bước build. Với cách triển khai server Next.js thông thường, cần build thành công trước khi chạy ứng dụng ở chế độ production.
3. Phân biệt Development và Production
Development và Production là hai môi trường có mục đích khác nhau.
Development được sử dụng trong quá trình lập trình. Developer thường xuyên thay đổi mã nguồn, kiểm tra giao diện và phát hiện lỗi.
Production là môi trường phục vụ người dùng thực tế. Ứng dụng cần ổn định, có cấu hình phù hợp và được vận hành theo cách triển khai đã lựa chọn.
Một số khác biệt phổ biến:
| Tiêu chí | Development | Production |
|---|---|---|
| Mục tiêu | Phát triển và gỡ lỗi | Phục vụ người dùng |
| Cách chạy | npm run dev |
Build rồi triển khai theo cấu hình |
| Mã nguồn | Ưu tiên trải nghiệm phát triển | Được xử lý và tối ưu phù hợp |
| Lỗi | Có công cụ hỗ trợ debug | Cần theo dõi log và xử lý sự cố |
| Biến môi trường | Dùng cấu hình dành cho phát triển | Dùng cấu hình dành cho production |
Không nên dùng cấu hình production tùy tiện trên máy phát triển hoặc đưa thông tin nhạy cảm của môi trường production vào mã nguồn.
4. Kiểm tra ứng dụng trước khi build
Trước khi build, Developer nên kiểm tra những yếu tố có thể gây lỗi khi triển khai.
Kiểm tra mã nguồn
Nếu dự án sử dụng TypeScript, hãy bảo đảm kiểu dữ liệu được khai báo đúng và không còn lỗi cần xử lý. Với dự án sử dụng ESLint, nên chạy kiểm tra code theo script đã cấu hình.
Ví dụ:
npm run lint
npm run build
Tùy dự án, bạn cũng có thể có các script riêng cho kiểm thử:
npm run test
Lệnh test chỉ hoạt động nếu dự án đã cấu hình công cụ kiểm thử và khai báo script tương ứng.
Kiểm tra tài nguyên
Hãy kiểm tra các đường dẫn ảnh, font, CSS và những file được import trong ứng dụng. Một đường dẫn hoạt động trên máy cá nhân không đảm bảo sẽ hoạt động khi triển khai nếu file bị thiếu hoặc cấu hình đường dẫn không đúng.
Kiểm tra các route
Đối với ứng dụng sử dụng App Router, hãy kiểm tra các trang tĩnh, dynamic routes, trang lỗi và những route cần dữ liệu từ server.
Nếu sử dụng Static Export, cần kiểm tra thêm các giới hạn của chế độ này và bảo đảm những route cần thiết đã được xuất trong quá trình build.
5. Biến môi trường trong Next.js
Trong một ứng dụng web, có những giá trị thay đổi tùy theo môi trường, chẳng hạn URL của API, thông tin kết nối dịch vụ hoặc cấu hình tích hợp.
Thay vì ghi cứng các giá trị này vào mã nguồn, Developer có thể sử dụng biến môi trường.
Ví dụ file .env.local:
API_BASE_URL=http://localhost:4000
Trong mã nguồn server:
const apiBaseUrl = process.env.API_BASE_URL;
Khi triển khai production, giá trị API_BASE_URL có thể được cấu hình thành URL API của môi trường thực tế.
Phân biệt biến môi trường phía server và phía client
Đây là một lưu ý rất quan trọng trong Next.js.
Biến môi trường không có tiền tố NEXT_PUBLIC_ thường chỉ được truy cập phía server. Biến có tiền tố NEXT_PUBLIC_ có thể được đưa vào bundle phía client và bị người dùng xem được.
Ví dụ:
NEXT_PUBLIC_API_BASE_URL=https://api.example.com
DATABASE_PASSWORD=your-secret-value
NEXT_PUBLIC_API_BASE_URL có thể được sử dụng trong code phía client nếu cần. Ngược lại, DATABASE_PASSWORD phải được giữ trong môi trường server và tuyệt đối không đưa vào client bundle.
Không nên hiểu rằng chỉ cần đặt một giá trị trong file .env là giá trị đó tự động được bảo vệ trong mọi tình huống. Vị trí sử dụng và cách build ứng dụng cũng rất quan trọng.
Đối với những giá trị NEXT_PUBLIC_ được thay thế trong mã client lúc build, thay đổi biến môi trường sau khi build không nhất thiết làm thay đổi giá trị đã được đóng gói. Điều này cần được tính đến khi thiết kế quy trình triển khai.
6. Deployment là gì?
Deployment là quá trình đưa ứng dụng đã được chuẩn bị lên môi trường để người dùng có thể truy cập.
Một quy trình deployment đơn giản có thể bao gồm:
- Đưa mã nguồn lên Git repository.
- Cài đặt dependencies trong môi trường build.
- Chạy kiểm tra và build ứng dụng.
- Cấu hình biến môi trường cần thiết.
- Triển khai đầu ra lên nền tảng hosting phù hợp.
- Kiểm tra ứng dụng sau khi triển khai.
Có nhiều cách triển khai Next.js, tùy vào kiến trúc của ứng dụng.
Managed hosting: Nền tảng hosting quản lý phần lớn quy trình build và triển khai. Đây là lựa chọn thuận tiện cho nhiều dự án Next.js.
Node.js server: Chạy ứng dụng Next.js trên môi trường Node.js có hỗ trợ server runtime.
Docker hoặc hạ tầng riêng: Đóng gói và vận hành ứng dụng trong môi trường do đội ngũ quản lý.
Static hosting: Phù hợp khi ứng dụng được xuất thành các tài nguyên tĩnh và không cần những chức năng phụ thuộc server runtime.
Không có một hình thức triển khai phù hợp với tất cả dự án. Cần lựa chọn dựa trên yêu cầu về dữ liệu động, xử lý server, lưu lượng truy cập và cách vận hành.
7. Quy trình triển khai Next.js với server runtime
Với một ứng dụng Next.js thông thường cần server runtime, quy trình cơ bản có thể là:
npm ci
npm run build
npm run start
Trong đó:
npm cicài đặt dependencies dựa trên lockfile, phù hợp với môi trường build tự động.npm run buildtạo đầu ra production.npm run startkhởi chạy server production theo script của dự án.
Trong môi trường triển khai thực tế, các lệnh này thường được thực hiện bởi nền tảng hosting hoặc quy trình CI/CD thay vì chạy thủ công trên máy cá nhân.
Nếu ứng dụng sử dụng tính năng cần server runtime, chỉ tải các file HTML tĩnh lên hosting có thể không đáp ứng được yêu cầu.
8. Quy trình triển khai với Static Export
Đối với dự án đã cấu hình:
const nextConfig = {
output: "export",
};
export default nextConfig;
Sau khi chạy:
npm run build
Next.js sẽ tạo thư mục out chứa các tài nguyên tĩnh được xuất.
Khi đó, nội dung của thư mục out có thể được triển khai lên static hosting hoặc CDN phù hợp.
Cần phân biệt hai cách triển khai:
- Ứng dụng Next.js có server runtime: triển khai ứng dụng để server xử lý các tính năng cần thiết.
- Next.js Static Export: triển khai các file tĩnh đã được xuất.
Hai cách này có yêu cầu vận hành khác nhau. Không nên áp dụng cùng một quy trình mà không kiểm tra khả năng hỗ trợ của nền tảng đích.
9. CI/CD và tự động hóa deployment
Khi làm việc nhóm, việc build và triển khai thủ công sau mỗi thay đổi có thể mất thời gian và dễ phát sinh sai sót.
CI/CD là nhóm thực hành và quy trình giúp tự động hóa các bước như kiểm tra code, chạy test, build và triển khai ứng dụng.
Continuous Integration (CI) tập trung vào việc tích hợp thay đổi thường xuyên và kiểm tra chúng thông qua các quy trình tự động.
Continuous Delivery hoặc Continuous Deployment (CD) giúp tự động hóa việc chuẩn bị bản phát hành hoặc triển khai sản phẩm, tùy theo quy trình của đội ngũ.
Ví dụ, một quy trình có thể được thiết kế như sau:
Developer push code
↓
CI chạy lint và test
↓
Build ứng dụng
↓
Build thành công?
↙ ↘
Không Có
↓ ↓
Báo lỗi Deploy
↓
Kiểm tra ứng dụng
Khi triển khai CI/CD, cần bảo vệ secrets trong hệ thống quản lý biến môi trường của nền tảng tự động hóa, giới hạn quyền truy cập và không ghi các thông tin nhạy cảm vào log.
10. Kiểm tra sau khi deployment
Build thành công không có nghĩa là ứng dụng chắc chắn hoạt động đúng sau khi triển khai. Một số lỗi chỉ xuất hiện khi chạy trên môi trường production.
Sau deployment, nên kiểm tra:
- Trang chủ và các route quan trọng có truy cập được không.
- Hình ảnh, font và CSS có tải thành công không.
- Các yêu cầu API có sử dụng đúng URL không.
- Những chức năng cần xác thực có hoạt động đúng không.
- Các biến môi trường có được cấu hình đầy đủ không.
- Trang lỗi và trạng thái loading có hiển thị phù hợp không.
- Log và hệ thống theo dõi có phát hiện lỗi runtime hay không.
Nếu ứng dụng sử dụng domain riêng, hãy kiểm tra thêm HTTPS, DNS và cấu hình domain của nền tảng hosting.
Đối với dự án quan trọng, có thể sử dụng staging environment để kiểm tra bản phát hành trước khi đưa vào production.
11. Những lỗi thường gặp khi triển khai
Thiếu biến môi trường: Ứng dụng có thể build thất bại hoặc gọi sai API do thiếu cấu hình.
Đưa secrets vào frontend: Các khóa bí mật có thể bị lộ nếu được đưa vào client bundle.
Chọn sai hình thức hosting: Static hosting không thể thay thế server runtime cho các chức năng cần xử lý request động.
Chỉ kiểm tra trên development: Một số lỗi chỉ xuất hiện trong bản production hoặc trên môi trường thực tế.
Không kiểm tra sau deployment: Ứng dụng có thể triển khai thành công nhưng vẫn lỗi khi người dùng truy cập một route cụ thể.
Không có phương án rollback: Khi bản phát hành mới gặp sự cố, việc không thể quay về bản ổn định có thể làm tăng thời gian gián đoạn dịch vụ.
12. Bài tập thực hành
Hãy xây dựng một dự án Next.js đơn giản và chuẩn bị triển khai production.
- Kiểm tra các script trong
package.json. - Chạy lint và các bài test đã cấu hình.
- Tạo biến môi trường dành cho URL API.
- Chạy
npm run build. - Chạy thử ứng dụng production cục bộ nếu sử dụng server runtime.
- Triển khai lên nền tảng hosting phù hợp.
- Kiểm tra các route, tài nguyên và yêu cầu API.
- Ghi lại những lỗi phát sinh và cách khắc phục.
Nếu dự án sử dụng Static Export, hãy thực hiện thêm bước kiểm tra thư mục out và triển khai các tài nguyên tĩnh thay vì chạy server Next.js.
13. Kết luận
Build và Deployment là hai bước quan trọng trong quá trình đưa ứng dụng Next.js từ môi trường phát triển đến người dùng thực tế. Build chuẩn bị đầu ra production, còn deployment đưa đầu ra đó lên môi trường vận hành phù hợp.
Một quy trình tốt không chỉ dừng lại ở việc chạy thành công lệnh build. Developer còn cần quản lý biến môi trường, lựa chọn hình thức hosting, kiểm tra sau deployment và xây dựng quy trình tự động hóa khi dự án phát triển.
Khi hiểu rõ những bước này, Frontend Developer có thể chủ động hơn trong việc phát hành ứng dụng, phối hợp với Backend và DevOps, cũng như xử lý các vấn đề thường gặp trong môi trường production.
Bài viết này hoàn thành nhóm chủ đề Next.js Advanced & Production của Series 6, bao gồm Metadata & SEO, Internationalization & Localization, Internationalized Routing, Static Export và Build & Deployment.





Khoá học lập trình game con rắn cho trẻ em




