Webpack là một bundler mã nguồn mở mạnh mẽ đã trở thành tiêu chuẩn thực tế để xây dựng các ứng dụng JavaScript. Nó nhận các module có phụ thuộc và tạo ra các tài nguyên tĩnh được tối ưu hóa cho trình duyệt hoặc môi trường chạy khác. Theo Webpack Documentation (2026), hệ sinh thái có hơn 15 nghìn loader và plugin cho mọi tác vụ xây dựng.
Những điểm chính
Webpack là một bundler module phân tích các phụ thuộc của ứng dụng và đóng gói chúng thành các tệp tĩnh cho trình duyệt hoặc máy chủ. Được tạo bởi Tobias Koppers vào năm 2012, Webpack nhanh chóng trở thành tiêu chuẩn xây dựng nhờ khái niệm tất cả tệp đều là module: JavaScript, CSS, hình ảnh, phông chữ và thậm chí cả HTML đều được xử lý thông qua một hệ thống loader duy nhất.
Webpack đã giới thiệu một ý tưởng mang tính cách mạng cho thời đại của nó: loader cho phép bạn bao gồm bất kỳ tài nguyên nào thông qua import hoặc require. Điều này giải phóng các nhà phát triển khỏi nhu cầu sử dụng các công cụ riêng biệt cho bộ tiền xử lý CSS (SCSS), trình biên dịch TypeScript và trình tối ưu hóa hình ảnh. Đến năm 2020, Webpack được sử dụng trong hơn 80% dự án JavaScript (dữ liệu npm stat: 2019–2024).
Đối thủ cạnh tranh — Vite, Parcel và Turbopack — cung cấp tốc độ phát triển nhanh hơn, nhưng Webpack duy trì vị trí dẫn đầu trong phân khúc doanh nghiệp nhờ tính ổn định, hệ sinh thái trưởng thành và khả năng tương thích ngược. Việc di chuyển từ Webpack sang Vite trong các dự án lớn mất hàng tuần và thường bị chặn do không tương thích plugin.
Webpack xây dựng đồ thị phụ thuộc bắt đầu từ điểm vào. Mỗi import hoặc require được tìm thấy sẽ được thêm vào đồ thị, đi qua một chuỗi loader và được đặt vào một chunk. Đầu ra cuối cùng phụ thuộc vào cấu hình: một bundle duy nhất, nhiều chunk hoặc đầu ra thư viện ở định dạng UMD, CommonJS hoặc ES Module.
// Cấu hình tối thiểu Webpack 5
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash:8].js',
clean: true,
},
module: {
rules: [
{ test: /\.ts$/, use: 'ts-loader', exclude: /node_modules/ },
],
},
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, filename: 'vendor.[contenthash:8].js' } },
},
},
};
Webpack 5 đã giới thiệu bộ nhớ đệm tích hợp dựa trên hệ thống tệp, giúp tăng tốc độ xây dựng lại từ 2 đến 5 lần. Bộ nhớ đệm liên tục lưu kết quả biến đổi module giữa các lần chạy, điều này đặc biệt quan trọng trong CI/CD. Để kích hoạt, chỉ cần thêm cache: { type: 'filesystem' } vào cấu hình.
Webpack hoạt động với bốn khái niệm cơ bản: Entry (điểm vào), Output (đầu ra), Loaders (biến đổi) và Plugins (tiện ích mở rộng). Hiểu các khái niệm này là cần thiết để cấu hình bất kỳ bản dựng nào từ một trang web đơn giản đến ứng dụng doanh nghiệp phức tạp.
Entry là một mảng hoặc đối tượng xác định một hoặc nhiều điểm vào. Multi-entry được sử dụng cho các ứng dụng đa thành phần. Output cấu hình các tệp đầu ra: đường dẫn, mẫu tên, URL công khai. Mode — development, production hoặc none — tự động kích hoạt các plugin tối ưu và giá trị mặc định cho mỗi chế độ.
Content Hash — bao gồm hash nội dung trong tên tệp ([contenthash]) đảm bảo lưu trữ đệm dài hạn. Trình duyệt chỉ tải tệp mới khi nội dung của nó thay đổi. SplitChunksPlugin tự động trích xuất các phụ thuộc chung từ các entry khác nhau vào các chunk riêng biệt, ngăn chặn trùng lặp mã.
Loaders biến đổi các tệp nguồn trước khi thêm chúng vào đồ thị phụ thuộc. Mỗi loader là một hàm nhận nội dung tệp và trả về một module JavaScript. Plugins là các tiện ích mở rộng mạnh mẽ hơn có quyền truy cập vào toàn bộ vòng đời xây dựng: từ khởi động đến tạo tệp đầu ra.
| Loader | Mục đích | Trường hợp sử dụng |
|---|---|---|
| babel-loader | Biên dịch ES6+/JSX sang ES5 | Component React với JSX |
| ts-loader | Biên dịch TypeScript sang JavaScript | Angular, dự án TypeScript |
| css-loader | Xử lý @import và url() trong CSS | CSS module, PostCSS |
| sass-loader | Biên dịch SCSS/SASS sang CSS | Bootstrap, giao diện tùy chỉnh |
| file-loader | Sao chép tệp vào đầu ra | Hình ảnh, phông chữ |
| svg-inline-loader | Nhúng SVG vào JavaScript | Biểu tượng, logo |
Plugins, không giống như loader, có thể thực hiện các hành động ở bất kỳ giai đoạn nào của bản dựng. HtmlWebpackPlugin tự động tạo tệp HTML với các tập lệnh được liên kết. MiniCssExtractPlugin trích xuất CSS vào các tệp riêng biệt để tải song song. DefinePlugin cho phép truyền biến môi trường vào mã ứng dụng trong quá trình xây dựng.
Webpack cung cấp các cơ chế tối ưu hóa tích hợp: tree shaking, code splitting và nén. Tree shaking loại bỏ các xuất không sử dụng khỏi module ES. Code splitting thông qua import() chia bundle thành các chunk động. Minimizer — TerserPlugin cho JS và CssMinimizerPlugin cho CSS.
// webpack.config.js — tối ưu hóa build production
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: { compress: { drop_console: true }, mangle: true },
}),
new CssMinimizerPlugin(),
],
runtimeChunk: 'single',
splitChunks: {
chunks: 'async',
minSize: 20000,
maxAsyncRequests: 30,
},
},
};
Module Federation là tính năng mạnh nhất của Webpack 5 cho micro-frontend. Nó cho phép tải các module từ các bản dựng độc lập khác trong thời gian chạy. Mỗi vi ứng dụng được phát triển và triển khai độc lập, nhưng được tập hợp thành một giao diện duy nhất cho người dùng. Segment Analytics đã sử dụng Module Federation trong sản xuất từ năm 2021, giảm thời gian triển khai xuống 80%.
Webpack hiếm khi được sử dụng trực tiếp trong React Native — Metro tồn tại cho mục đích này. Tuy nhiên, Webpack được sử dụng trong các dự án React Native Web, khi một cơ sở mã duy nhất được xây dựng cho cả nền tảng di động (qua Metro) và web (qua Webpack). Webpack cũng phổ biến trong các ứng dụng lai với Ionic và Cordova.
Đối với các dự án sử dụng React Native Web để hiển thị web, Webpack được cấu hình với các bí danh thay thế các module gốc bằng các triển khai web. Alias react-native → react-native-web cho phép sử dụng các component dùng chung mà không thay đổi import. DefinePlugin truyền cờ nền tảng để biên dịch có điều kiện mã dành riêng cho nền tảng.
Tối ưu hóa Webpack cho web di động khác với máy tính để bàn. Bản dựng Mobile-first bao gồm nén mạnh mẽ, lazy loading hình ảnh và tải ưu tiên CSS quan trọng. CompressionPlugin với nén brotli giảm kích thước bundle 20–25% cho mạng di động 3G/4G. Sử dụng webpack-merge để chia cấu hình cho các nền tảng khác nhau: bản dựng mobile-first và tối ưu hóa cho máy tính để bàn.
Module Federation là một tính năng mang tính cách mạng của Webpack 5 cho phép tải các module JavaScript từ các bản dựng độc lập khác mà không cần xuất bản lên npm. Mỗi vi ứng dụng được phát triển độc lập, có cấu hình Webpack riêng và được triển khai riêng biệt. Ứng dụng Host kết nối các module từ bản dựng từ xa thông qua cấu hình đặc biệt của ModuleFederationPlugin.
Nhà cung cấp hiển thị (expose) các module đã chọn và máy chủ sử dụng remotes để kết nối chúng. Module Federation hỗ trợ các thư viện dùng chung: nếu React được sử dụng trong hai vi ứng dụng, Webpack sẽ tải nó chỉ một lần. Điều này tiết kiệm tới 60% lưu lượng truy cập cho người dùng. Các công ty lớn, bao gồm Segment và Best Buy, sử dụng Module Federation trong sản xuất, giảm thời gian triển khai từ hàng giờ xuống còn vài phút.
Khi làm việc với Module Federation, các nhà phát triển thường gặp phải xung đột về các phụ thuộc dùng chung của các phiên bản khác nhau. Giải pháp là chỉ định rõ ràng requiredVersion và singleton: true cho các thư viện quan trọng. Một vấn đề khác là mất ngữ cảnh khi import component từ bản dựng từ xa, đặc biệt là với React Context và Redux. Để giải quyết, hãy sử dụng shared: { react: { singleton: true } } để đảm bảo tất cả các vi ứng dụng sử dụng một phiên bản React duy nhất. Đối với các kiến trúc micro-frontend lớn, nên sử dụng Module Federation cùng với hệ thống monorepo (Nx, Turborepo) để đồng bộ hóa phiên bản của các phụ thuộc dùng chung và đảm bảo tính nhất quán của bản dựng.
Câu hỏi thường gặp
Webpack 5 đã giới thiệu bộ nhớ đệm liên tục (tăng tốc độ xây dựng lại lên tới 5 lần), hỗ trợ tích hợp Module Federation cho micro-frontend và đầu ra clean tự động. Các loader cũ (raw-loader, url-loader) và nhiều polyfill Node.js đã bị loại bỏ, giảm kích thước cấu hình trung bình 30%.
Sử dụng webpack-cli init để tạo cấu hình cơ bản. Đối với các dự án điển hình, hãy sử dụng create-react-app (CRA) hoặc Next.js, chúng ẩn cấu hình Webpack. Nếu cần thiết lập tùy chỉnh — webpack-merge cho phép bạn chia cấu hình thành các module có thể tái sử dụng cho các môi trường khác nhau.
Webpack Dev Server là máy chủ phát triển tích hợp với hỗ trợ HMR (Hot Module Replacement). Nó theo dõi các thay đổi tệp và cập nhật các module trong trình duyệt mà không cần tải lại toàn bộ trang. Đối với phát triển di động, máy chủ phát triển có thể được cấu hình để truy cập qua mạng cục bộ bằng cách chỉ định host: '0.0.0.0' và chứng chỉ HTTPS.
Webpack 5 sử dụng Asset Modules tích hợp để xử lý hình ảnh: asset/resource sao chép tệp nguyên trạng, asset/inline nhúng dưới dạng base64 (cho tệp dưới 8KB), asset tự động chọn dựa trên kích thước. Để tối ưu hóa hình ảnh, hãy thêm image-webpack-loader với nén WebP và tối ưu hóa không mất dữ liệu.
Đối với các dự án mới — có, Vite mang lại sự gia tăng tốc độ đáng kể. Đối với các dự án doanh nghiệp hiện có với hàng trăm plugin Webpack — việc di chuyển có thể mất 2–4 tuần. Hãy đánh giá tốc độ build phát triển quan trọng như thế nào: nếu thời gian build hoàn chỉnh vượt quá 5 phút, việc di chuyển là hợp lý.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm