Webpack: Các khái niệm cốt lõi

23 tháng 07, 2021 - 1496 lượt xem

Sở hữu một cộng đồng support khổng lồ và ngày càng phổ biến, Webpack là một công cụ đắc lực cho các web developer thời hiện đại. Chúng ta có thể thấy mặt Webpack ở khắp nơi: từ React cho đến VueJS hay rất nhiều framework, thư viện khác.

Nếu đây là lần đầu bạn tìm hiểu Webpack, trước đây TechMaster đã có 1 bài viết giới thiệu tổng quan về Webpack và sử dụng demo rất chi tiết, các bạn có thể tham khảo tại đây nhé: Tối ưu static website với Webpack

Còn trong bài viết này, chúng ta sẽ đi vào các các chủ đề: tại sao Webpack lại ra đời và những khái niệm cốt lõi của nó

webpack

Tại sao chúng ta cần Webpack?

Để trả lời cho câu hỏi này, hãy cùng nhìn lại cách mà Javascript được sử dụng trước khi khái niệm về các "công cụ đóng gói" được ra đời.
Trước đây, có 2 cách dùng Javascript trên trình duyệt:

  • Đầu tiên là sử dụng các đoạn script khác nhau cho mỗi tính năng cụ thể. Vấn đề của cách này là sẽ gặp khó khăn khi mở rộng dự án, vì tải quá nhiều đoạn script sẽ dẫn đến nghẽn mạng.
  • Cách thứ hai là dùng 1 "cục" script.js cực bự, chứa toàn bộ code Javascript cần thiết. Lúc này chúng ta sẽ gặp phải các vấn đề về scope, kích thước file lớn, khó đọc và bảo trì vì quá dài

IIFEs - Immediately invoked function expressions (biểu thức hàm được gọi ngay lập tức) đã giải quyết được vấn đề về scope của cách thứ 2. Đi kèm với nó là sự ra đời của nhiều công cụ như Make, Gulp, Grunt, Broccoli, Brunch, v.v... giúp chúng ta "nối" các file lại với nhau 1 cách an toàn. Thế nhưng vẫn còn các vấn đề khác với cách tiếp cận này: sửa một file lại phải build lại tất, code thừa quá nhiều ví dụ khi cần dùng mỗi 1 hàm vẫn cứ phải bê nguyên cả 1 cái thư viện chục nghìn dòng...
Javascript vẫn tiếp tục phát triển. Khái niệm module ra đời sau đó nhờ NodeJS, dần dần được trở thành một tính năng chính thức cho Javascript.
Và rồi người ta tự hỏi giá mà có một công cụ không chỉ giúp chúng ta viết modules mà còn hỗ trợ bất kỳ kiểu định dạng module và mọi kiểu tài nguyên, tất-cả-trong-một thì tuyệt vời ông mặt trời nhỉ.
Và Webpack là câu trả lời cho yêu cầu trên.

Dependency Graph

Dependency Graph

  • Đầu tiên, chúng ta nên biết là Webpack sẽ coi mọi thứ đều là các module, và các module này có thể liên quan, phụ thuộc lẫn nhau để tạo ra thành phẩm cuối cùng. Nếu một module nào đó có liên quan đến module khác, ví dụ như file index.html dùng css từ file style.css, ảnh picture.png, font myfont.woff... Webpack sẽ đánh dấu đây là một dependency (sự phụ thuộc).
  • Khi khởi động, Webpack sẽ đi từ các entry points được liệt kê trong file config và ngầm vẽ ra một dependency graph (biểu đồ thể hiện sự phụ thuộc lẫn nhau của các module). Trong quá trình đóng gói, mỗi khi gặp một dependency Webpack sẽ liệt kê nó vào dependency graph.
  • Vậy là dựa vào dependency graph, Webpack sẽ nắm rõ được toàn bộ các module được sử dụng trong dự án, cũng như cái nào phụ thuộc cái nào, để từ đó đóng gói ra 1 file thành phẩm cuối cùng.
  • Ngoài ra, chúng ta sẽ có 5 khái niệm cốt lõi trong Webpack:

1. Entry point

2. Output

3. Loaders

4. Plugins

5. Mode

1. Entry points

  • Entry point chính là module "khởi điểm". Từ module này Webpack sẽ bắt đầu tạo ra dependency graph mô tả chi tiết mối quan hệ giữa các module
  • Mặc định thì entry point sẽ là file ./src/index.js, nhưng chúng ta có thể chọn file khác thông qua file config của Webpack.
    module.exports = {
      entry: {
          index: {
              import: "./src/index.js",
              filename: "js/index.[contenthash].js",
          },
          about: {
              import: "./src/about.js",
              filename: "js/about.[contenthash].js",
          },
      },
    };
  • Đoạn config trên tạo ra 2 entry points "index" và "about" và sử dụng 2 option importfilename trong 2 entry points này.
  • Một số options thường dùng:
    • dependOn: entry point A này đang phụ thuộc vào entry point B nào khác. Entry point B sẽ phải được load trước entry point A.
    • filename: Chỉ định tên file output.
    • import: entry point này sẽ cần load những module nào khi khởi động.

2. Output

  • Đã có bắt đầu thì phải có kết thúc. Output chính là nơi Webpack trả về các bundles.
  • Mặc định thì output bao gồm file bundle chính tại ./dist/main.js, và những file bundle khác cũng sẽ nằm tại folder ./dist. Tất nhiên cũng giống như Entry point, chúng ta tùy chỉnh lại Output thông qua file config của Webpack:
    module.exports = {
    entry: {
      index: './src/index.js',
      about: './src/about.js',
    },
    output: {
      filename: '[name].js',
      path: __dirname + '/dist',
    },
    };
    //sẽ trả về 2 file tại folder dist: index.js và about.js
  • Webpack sẽ trả về 2 file tại folder dist: index.js và about.js

3. Loaders

  • Về bản chất thì Webpack chỉ hiểu được các file Javascript và JSON. Các Loaders sẽ giúp Webpack có thể xử lý được các kiểu file khác bằng cách biến chúng thành các module hợp lệ và đưa vào dependency graph.
  • Chúng ta vẫn sẽ tùy chỉnh Loaders trong file config
    module.exports = {
    module: {
      rules: [{ test: /\.txt$/, use: 'raw-loader' }],
    },
    };
    Đoạn config trên có thể hiểu như sau: "Mỗi khi xử lý đến file nào có định dạng .txt, Webpack sẽ sử dụng Loader raw-loader để biến đổi file trên trước khi tiếp tục đóng gói"

4. Plugins

  • Nếu như các Loaders dùng để biến đổi một số loại modules cụ thể, các Plugins sẽ xử lý nhiều tác vụ khác, ví dụ như tối ưu quá trình đóng gói, quản lý tài nguyên... Nói cách khác, Plugins sẽ làm được mọi thứ mà Loader chưa làm được
  • Để sử dụng Plugins, chúng ta cần sử dụng require() để import Plugins và đăng ký trong array plugins. Hầu hết các Plugins đều cho phép tùy chỉnh cụ thể.
const HtmlWebpackPlugin = require('html-webpack-plugin'); //sử dụng plugin html-webpack

module.exports = {
  plugins: [
        new HtmlWebpackPlugin({ 
            template: './src/index.html' 
        })
    ],
};
  • Đoạn config trên sẽ báo Webpack sử dụng plugin ' html-webpack-plugin' để tạo ra 1 file HTML, file này sẽ có nội dung dựa trên './src/index.html'. Sau đó Webpack sẽ "nhét" (injection) các bundles khác vào trong file HTML này.
  • Tham khảo danh sách các plugins của Webpack tại đây.

5. Mode

  • Để phân biệt rõ code đang viết và code thành phẩm, Webpack hỗ trợ 3 chế độ làm việc: development nếu như bạn đang trong quá trình phát triển, production nếu như đang làm việc với sản phẩm hoàn thiện và none cho các trường hợp còn lại. Mặc định nếu không tùy chỉnh thì Webpack sẽ coi như chúng ta đang ở production
  • Chúng ta sẽ chia nhỏ webpack config ra 3 file tương ứng 3 chế độ và dùng thư viện webpack-merge để kết hợp lại. Về phần này, Bài viết Tối ưu static website với Webpack cũng đã có đề cập và demo cụ thể.

Lời kết

Thế giới công nghệ luôn luôn phát triển không ngừng. Những vấn đề mới sẽ được giải quyết bằng các giải pháp mới và Webpack là một ví dụ rõ ràng khi nó giải quyết được rất nhiều vấn đề. Webpack là Một công cụ xuất sắc được dùng cho hàng loạt tên tuổi lớn, rất đáng để bạn tìm hiểu và ứng dụng theo nhu cầu riêng của mình

webpack

Bình luận

avatar
Phạm Thị Mẫn 2021-07-23 10:27:56.778632 +0000 UTC

Bài viết hơi bị hay!!

Avatar
avatar
Trịnh Minh Cường 2021-07-23 14:01:35.554415 +0000 UTC

Cần cho thêm ví dụ mẫu và link để chạy. Không có ví dụ mẫu đọc hụt hẫng

Avatar
* Vui lòng trước khi bình luận.
Ảnh đại diện
  +3 Thích
+3