Webpack là gì?
Webpack là một công cụ đóng gói module (module bundler) không thể thiếu trong quy trình phát triển web hiện đại. Nhiệm vụ chính của nó là thực hiện phân tích tĩnh các mối quan hệ phụ thuộc giữa các module khác nhau—bao gồm JavaScript, CSS, hình ảnh và nhiều loại tài nguyên khác—sau đó biên dịch chúng thành các tài nguyên tĩnh đã được tối ưu hóa. Quá trình này giúp hợp nhất nhiều tệp riêng lẻ thành một hoặc một vài tệp đầu ra, từ đó giảm đáng kể số lượng yêu cầu HTTP mà trình duyệt phải thực hiện và cải thiện hiệu suất tải ứng dụng.
Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách cài đặt Webpack và sử dụng nó để đóng gói cả tệp JavaScript và CSS.
Cài đặt Webpack
Để bắt đầu sử dụng Webpack, bạn cần cài đặt nó cùng với công cụ dòng lệnh (CLI) của nó trên hệ thống của mình.
1. Cài đặt toàn cầu (Global Installation)
Mở terminal hoặc command prompt với quyền quản trị viên và chạy các lệnh sau:
npm install webpack -g
npm install webpack-cli -g
Nếu bạn gặp lỗi trong quá trình cài đặt, hãy thử xóa các thư mục liên quan đến webpack trong thư mục cài đặt global của npm và chạy lại các lệnh trên.
2. Kiểm tra phiên bản (Check Version)
Sau khi cài đặt, bạn có thể kiểm tra phiên bản của Webpack để đảm bảo rằng nó đã được cài đặt thành công:
webpack -v
Đóng gói JavaScript với Webpack
Mục tiêu của phần này là minh họa cách Webpack có thể kết hợp nhiều tệp JavaScript thành một tệp đầu ra duy nhất, thường được đặt tên là bundle.js, và lưu trữ nó trong một thư mục dist. Tệp đã được đóng gói này sau đó sẽ được sử dụng trong một trang HTML.
Các bước thực hiện:
- Tạo các tệp JavaScript nguồn.
- Tạo tệp đầu vào chính (entry file), ví dụ:
app.js. - Cấu hình Webpack thông qua tệp
webpack.config.js. - Chạy lệnh Webpack để đóng gói.
- Tạo một tệp
index.htmlđể kiểm tra kết quả.
Ví dụ minh họa:
Đầu tiên, hãy tạo một cấu trúc thư mục đơn giản cho dự án của bạn:
my-webpack-app/
├── src/
│ ├── math.js
│ ├── display.js
│ └── app.js
├── webpack.config.js
└── index.html
(1) Tạo tệp src/math.js:
Tệp này chứa một hàm thực hiện phép cộng.
// src/math.js
exports.sum = (a, b) => {
return a + b;
};
(2) Tạo tệp src/display.js:
Tệp này chứa một hàm để hiển thị kết quả lên trang web.
// src/display.js
exports.showResult = (message) => {
const paragraph = document.createElement('p');
paragraph.textContent = message;
document.body.appendChild(paragraph);
};
(3) Tạo tệp đầu vào src/app.js:
Đây là điểm bắt đầu của ứng dụng, nơi chúng ta nhập các module khác và sử dụng chúng.
// src/app.js
const calculations = require("./math");
const uiElements = require("./display");
const val1 = 150;
const val2 = 250;
const finalResult = calculations.sum(val1, val2);
uiElements.showResult(`Kết quả của ${val1} + ${val2} là: ${finalResult}`);
(4) Tạo tệp cấu hình webpack.config.js:
Tệp này được đặt ở cùng cấp với thư mục src.
const path = require("path");
module.exports = {
// Điểm khởi đầu của ứng dụng
entry: "./src/app.js",
output: {
// Đường dẫn thư mục đầu ra (phải là đường dẫn tuyệt đối)
path: path.resolve(__dirname, "dist"),
// Tên tệp đầu ra đã được đóng gói
filename: "bundle.js"
}
};
Cấu hình này chỉ dẫn Webpack lấy ./src/app.js làm điểm bắt đầu, phân tích tất cả các phụ thuộc được yêu cầu trong đó, và sau đó đóng gói tất cả vào một tệp có tên bundle.js nằm trong thư mục dist.
(5) Thực thi lệnh biên dịch
Mở terminal trong thư mục gốc của dự án (my-webpack-app/) và chạy lệnh sau:
webpack
Sau khi lệnh chạy thành công, bạn sẽ thấy một thư mục dist mới được tạo, chứa tệp bundle.js. Tệp này chứa toàn bộ mã JavaScript từ math.js, display.js và app.js đã được kết hợp và tối ưu hóa.
(6) Kiểm tra kết quả với index.html
Tạo một tệp index.html ở thư mục gốc của dự án:
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kiểm tra Webpack JS</title>
</head>
<body>
<h1>Ứng dụng Webpack với JavaScript</h1>
<!-- Liên kết tệp JavaScript đã được đóng gói -->
<script src="dist/bundle.js"></script>
</body>
</html>
Mở tệp index.html trong trình duyệt của bạn. Bạn sẽ thấy dòng chữ "Kết quả của 150 + 250 là: 400" hiển thị trên trang, chứng tỏ Webpack đã đóng gói và thực thi JavaScript thành công.
Đóng gói CSS với Webpack
Mặc định, Webpack chỉ hiểu và xử lý các tệp JavaScript. Để mở rộng khả năng của nó sang các loại tệp khác như CSS, hình ảnh hoặc font chữ, chúng ta cần sử dụng "loaders". Loaders là các module giúp Webpack "dịch" các tệp không phải JavaScript thành các module mà nó có thể xử lý và đóng gói.
Mục tiêu của phần này là đóng gói một tệp CSS vào bundle cuối cùng bằng cách sử dụng style-loader và css-loader.
Các bước thực hiện:
- Cài đặt các loaders cần thiết (
style-loader,css-loader). - Cập nhật tệp cấu hình
webpack.config.jsđể xử lý CSS. - Tạo một tệp CSS.
- Cập nhật tệp đầu vào
app.jsđể import tệp CSS. - Chạy lệnh Webpack và kiểm tra kết quả.
Cài đặt style-loader và css-loader:
css-loader chịu trách nhiệm đọc và giải thích các quy tắc @import và url() trong tệp CSS, biến chúng thành các module JavaScript. style-loader sau đó sẽ lấy chuỗi CSS này và chèn vào thẻ <style> trong HTML khi ứng dụng chạy.
Trong thư mục gốc của dự án, chạy lệnh sau:
npm install style-loader css-loader --save-dev
Cờ --save-dev được dùng để lưu dependency này vào phần devDependencies trong tệp package.json, biểu thị rằng chúng chỉ cần thiết cho quá trình phát triển và build, không phải cho môi trường sản phẩm cuối cùng.
Cập nhật webpack.config.js:
Chúng ta cần thêm một quy tắc (rule) vào phần module.exports để chỉ định Webpack cách xử lý các tệp .css.
const path = require("path");
module.exports = {
entry: "./src/app.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.css$/, // Áp dụng quy tắc này cho các tệp có đuôi .css
use: ["style-loader", "css-loader"] // Sử dụng loaders theo thứ tự ngược (từ phải sang trái)
}
]
}
};
Trong cấu hình trên, test: /\.css$/ là một biểu thức chính quy (regular expression) khớp với tất cả các tệp có phần mở rộng là .css. Mảng use chỉ định loaders nào sẽ được sử dụng, và chúng được áp dụng từ phải sang trái (hoặc từ cuối lên đầu): css-loader sẽ xử lý tệp CSS trước, sau đó style-loader sẽ lấy CSS đã xử lý và chèn nó vào DOM của trang web.
Tạo tệp CSS:
Tạo một thư mục css trong src và thêm tệp main-styles.css vào đó:
/* src/css/main-styles.css */
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #e6f7ff; /* Light blue background */
color: #1a1a1a;
padding: 25px;
margin: 0;
}
h1 {
color: #0056b3; /* Darker blue heading */
text-align: center;
border-bottom: 2px solid #0056b3;
padding-bottom: 10px;
}
p {
font-size: 1.1em;
line-height: 1.6;
margin-left: 20px;
}
Cập nhật tệp đầu vào src/app.js:
Để Webpack biết về tệp CSS này, chúng ta cần require nó trong tệp JavaScript đầu vào của mình:
// src/app.js
require("./css/main-styles.css"); // Nhập tệp CSS
const calculations = require("./math");
const uiElements = require("./display");
const val1 = 150;
const val2 = 250;
const finalResult = calculations.sum(val1, val2);
uiElements.showResult(`Kết quả của ${val1} + ${val2} là: ${finalResult}`);
Đóng gói và kiểm tra:
Chạy lại lệnh Webpack từ terminal trong thư mục gốc của dự án:
webpack
Sau đó, mở lại tệp index.html trong trình duyệt của bạn. Bạn sẽ thấy giao diện trang web đã thay đổi theo các quy tắc CSS đã định nghĩa (ví dụ: nền màu xanh nhạt, kiểu chữ khác). Điều này chứng tỏ Webpack đã thành công trong việc đóng gói cả JavaScript và CSS vào một tệp bundle.js duy nhất.