Webpack — nó là gì, kiến trúc và nguyên lý hoạt động

Tác giả: IT Sectr Đã đăng: 2026-05-19 Thời gian đọc: 8 phút

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 JavaScript xây dựng đồ thị phụ thuộc và tạo ra các tệp đầu ra được tối ưu hóa.
  • Entry là điểm vào mà từ đó Webpack bắt đầu xây dựng đồ thị phụ thuộc của ứng dụng.
  • Loaders là các phép biến đổi xử lý các tệp thuộc nhiều loại khác nhau (TypeScript, SCSS, hình ảnh) trước khi thêm vào đồ thị.
  • Plugins là các tiện ích mở rộng thực hiện các tác vụ bổ sung: nén (minification), chèn HTML, quản lý biến môi trường.
  • Code Splitting là việc chia bundle thành các chunk được tải theo yêu cầu để tăng tốc tải ban đầu.

Webpack là gì?

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.

Tại sao Webpack trở thành tiêu chuẩn ngành

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.

Cách Webpack hoạt động

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.

Quy trình build Webpack

js
// 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.

Các khái niệm chính của Webpack

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, Output và các chế độ

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. Modedevelopment, 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 và Plugins

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.

Các loader phổ biến và mục đích của chúng

LoaderMục đíchTrường hợp sử dụng
babel-loaderBiên dịch ES6+/JSX sang ES5Component React với JSX
ts-loaderBiên dịch TypeScript sang JavaScriptAngular, dự án TypeScript
css-loaderXử lý @importurl() trong CSSCSS module, PostCSS
sass-loaderBiên dịch SCSS/SASS sang CSSBootstrap, giao diện tùy chỉnh
file-loaderSao chép tệp vào đầu raHình ảnh, phông chữ
svg-inline-loaderNhúng SVG vào JavaScriptBiể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.

Tối ưu hóa build Webpack

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. MinimizerTerserPlugin cho JS và CssMinimizerPlugin cho CSS.

Các kỹ thuật tối ưu hóa nâng cao

js
// 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 cho React Native và các dự án web

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 IonicCordova.

Webpack cho build đa nền tảng

Đố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-nativereact-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.

Webpack 5 Module Federation: Micro-frontend

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.

Các vấn đề thường gặp và giải pháp

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 requiredVersionsingleton: 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 khác Webpack 4 như thế nào?

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%.

Làm thế nào để giảm kích thước cấu hình Webpack?

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à gì?

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 xử lý hình ảnh như thế nào?

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.

Tôi có nên di chuyển từ Webpack sang Vite không?

Đố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

  • Webpack là một bundler JavaScript phổ quát với hệ sinh thái loader và plugin lớn nhất.
  • Entry, Output, LoadersPlugins là bốn khái niệm cơ bản xác định bất kỳ cấu hình build nào.
  • Loaders biến đổi các tệp (TypeScript, SCSS, JSX) trước khi thêm vào đồ thị phụ thuộc.
  • Plugins mở rộng chức năng của Webpack ở tất cả các giai đoạn của vòng đời build.
  • Code SplittingTree Shaking giảm kích thước bundle bằng cách loại bỏ mã không sử dụng và tải chậm.
  • Module Federation là công nghệ micro-frontend cho phép tải các module từ các bản dựng khác nhau trong thời gian chạy.
  • Đối với dự án mới hãy cân nhắc Vite, đối với các giải pháp doanh nghiệp hiện có, Webpack vẫn là lựa chọn ổn định.

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.

Thảo luận dự án

Đọc thêm