Configuring Webpack for React Development

React-Webpack

Introduction

React là một thư viện front-end khá phổ biến và được sử dụng khá nhiều trong các ứng dụng web hiện đại. Nếu tìm kiếm trên Viblo, chắc hẳn bạn sẽ thấy khá nhiều bài viết hay về React. Tương tự như React, Webpack là một công cụ module bundler đang phát triển khá nhanh trong thời gian gần đây và dần thay thế Gulp - một công cụ task runner truyền thống, hay Browserify một công cụ có chức năng tương tự như Webpack.

Trong bài viết này, mình sẽ giới thiệu về cách sử dụng Webpack để xây dựng một build process cho các ứng dụng React sử dụng npm, Webpack, và Babel. Ngoài ra mình cũng sẽ giới thiệu cách cài đặt Webpack Dev Server cũng như Hot Module Reloading khi làm việc với React.

Cách cài đặt này mình thường sử dụng cho các project cá nhân hoặc khi muốn experiment với một thứ gì mới ở React. Mình cũng sẽ không đi sâu vào việc giải thích các programming jargons (như trong những bài viết trước 😄 ), bài viết này sẽ giống như một tutorial nho nhỏ hơn.

Installing Dependencies

Công việc đầu tiên sẽ là cài đặt các dependencies cần thiết cho môi trường phát triển của chúng ta. Trước khi bắt đầu, bạn cần chắc chắn ràng máy tính bạn đang dùng đã cài đặt NodeJS và NPM. Dưới đây là một số hướng dẫn cho các môi trường khác nhau:

Giả sử, project của chúng ta được chứa trong thư mục app, hãy bắt đầu bằng việc khởi tạo NPM cho project đó:

$ cd code/app
$ npm init -y

Sau khi chạy lệnh trên chúng ta sẽ có một file package.json file trong thư mục gốc của project với một số template được khởi tạo sẵn:

{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {},
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Công việc tiếp theo sẽ là cài đặt các packages: ReactReact DOM sử dụng câu lệnh bên dưới. Hai package này là bắt buộc trong quá trình phát triển ứng dụng với React.

npm install --save react react-dom

Tiếp theo chúng ta cần cài đặt Webpack, tuy nhiên nó sẽ là một development-only dependency:

npm install --save-dev webpack

Khi xây dựng ứng dụng React, chúng ta thường dùng JSX thay vì các native API mà React cung cấp để tạo nội dung cho render function. Tương tự như VueJS, chúng ta thường sử dụng Single File Component thay vì API mà Vue cung cấp (bạn có thể tìm hiểu thêm tại bài viết này). Tuy nhiên browser không hiểu được cú pháp JSX, do đó chúng ta cần một bước trung gian để chuyển đổi JSX sang JavaScript. Ở đây chúng ta sẽ sử dụng Babel (Babel Transpiler) để thực hiện việc đó. Chúng ta sẽ bắt đầu bằng việc cài đặt các package cần thiết:

  • babel-core: hiểu đơn giản nó chính là babel transpiler.
  • babel-loader: custom loader cho Webpack sử dụng để transform JavaScript file.
npm install --save-dev babel-core babel-loader

Tiếp theo chúng ta cần cài đặt Babel preset cho React cũng như preset cho ES6 (nếu bạn sử dụng ES2015 khi xây dựng project):

  • babel-preset-react: chuyển đổi JSX thành JavaScript
  • babel-preset-es2015: chuyển đổi ES6 thành ES5
npm install --save-dev babel-preset-react babel-preset-es2015

Sau khi cài đặt các preset cần thiết chúng ta cần configure Babel sử dụng các preset vừa cài đặt. Chúng ta sẽ thực hiện việc đó sử dụng Babel Configuration File - .babelrc với nội dung như sau:

{
  "presets": ["react", "es2015"]
}

Đến thời điểm này, các dependency cần thiết đã được cài đặt, trong phần tiếp theo chúng ta sẽ đi sâu vào việc configure Webpack cho project của chúng ta.

Configuring Webpack

Chúng ta sẽ bắt đầu bằng việc tạo file webpack.config.js trong thư mục gốc của project. File này sẽ chứa các thông tin liên quan đến build process của bạn (một JavaScript object):

// webpack.config.js
module.exports = {
  // configurations here
};

Để đơn giản hóa, chúng ta sẽ chỉ quan tâm đến 3 configuration cơ bản trong Webpack: entry, output, và module. Chúng ta có thể tìm hiểu thêm qua documentation của Webpack:

Trong tutorial này chúng ta sẽ chỉ sử dụng một entry point duy nhất - app.js (nơi các React component được tập trung và render). Tương tự cho phần output, chúng ta sẽ sử dụng filename option với tên file là bundle.js. Tất nhiên tùy từng project mà entryoutput sẽ có thay đổi và có thể phức tạp hơn so với ví dụ ở đây. Phần quan trong nhất trong file configuration này là module, nơi chúng ta sẽ định nghĩa các transformations sẽ được thực hiện trên source code của chúng ta. Ở đây chúng ta sẽ sử dụng babel-loader để chuyển đổi JSX và ES6 thành ES5. Việc này sẽ được thực hiện bằng việc định nghĩa các loader bên trong loader option (more about Webpack loaders).

Nội dung file webpack.config.js sẽ như bên dưới:

module.exports = {
  entry: './app.js',

  output: {
    filename: 'bundle.js'
  },

  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  }
};

Sau khi đã có được configuration cơ bản cho Webpack, chúng ta sẽ thực hiện build process sử dụng file configuration nói trên. Có hai cách cơ bản như sau:

  • Sử dụng webpack binary: nếu bạn đã cài đặt webpack global thì chỉ cần chạy webpack command trong thư mục gốc của project. Lưu ý webpack binary cũng có thể được tìm thấy bên trong thư mục node_modules/.bin, và thông thường chúng ta sẽ sử dụng webpack binary cài đặt theo project thay vì webpack cài đặt chung trên hệ thống.
  • Sử dụng NPM script: tương tự như alias trên Linux, chúng ta có thể sử dụng NPM script để map các build command phức tạp đến một alias đơn giản hơn. Ở đây chúng ta sẽ tạo một build command đơn giản:
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "build": "webpack"
},

Configuring Webpack Dev Server

Webpack cung cấp một công cụ khá hữu ích - webpack dev server giúp cho việc phát triển ứng dụng trở nên dễ dàng và thuận tiện hơn. Trong phần này của bài viết, chúng ta sẽ cài đặt webpack dev server cho ứng dụng của chúng ta:

Bước đầu tiên là cài đặt package cần thiết - webpack-dev-server

npm install --save-dev webpack-dev-server

Sau khi cài đặt webpack-dev-server, cách đơn giản nhất để sử dụng công cụ này là tạo một NPM script với tên là start bên trong file package.json, và sử dụng npm run start command để khởi chạy dev server. Để access đến project trên trình duyệt chúng ta sẽ truy cập đến địa chỉ http://localhost:8080. Mặc định dev server của chúng sẽ có cổng là 8080, tuy nhiên chúng ta có thể sử dụng --port option để thay đổi cổng mặc định. Một option khá hữu ích khá là --progress cho phép chúng ta quan sát rõ hơn trạng thái của build process.

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "build": "webpack",
  "start": "webpack-dev-server --port 8000 --progress"
},

Adding CSS Loader

Một điểm khá hay của Webpack đó là ngoài JavaScript, tất cả các loại file khác đều có thể được coi như module và sẽ được thêm vào JavaScript bundle nếu cần thiết. Điều này giúp cải thiện performance của ứng dụng khá nhiều. Trong phần này của bài viết, chúng ta sẽ cùng tìm hiểu cách embed CSS bên trong Webpack JavaScript bundle sử dụng style-loadercss-loader.

Đầu tiên chúng ta cần cài đặt hai loader cho webpack:

npm install --save-dev style-loader css-loader

Tiếp theo chúng ta cần thêm một loader configuration mới bên trong webpack.config.js file:

loaders: [
  {
    test: /\.js$/,
    exclude: /node_modules/,
    loader: 'babel-loader'
  },
  {
    test: /\.css$/,
    loader: 'style-loader!css-loader'
  }
]

Tất nhiên trong thực tế, chúng ta có thể sử dụng các loader khác nhau cho các tool khác nhau mà project cần dùng. Ví dụ chúng ta sẽ sử dụng sass-loader cho SASS file hoặc vue-loader cho .vue file,...

Hot Module Reloading

Việc reload lại toàn bộ ứng dụng khi có một thay đổi nhỏ (thêm một đấu phẩy chẳng hạn) bên trong một component là khá mất thời gian trong các ứng dụng lớn. Sẽ tốt hơn nếu chúng ta chỉ reload lại component có thay đổi và giữ nguyên trang thái của các component khác. Trong phần này của bài viết, chúng ta sẽ tìm hiểu và cài đặt hot module reload cho project của chúng ta sử dụng react-hot-loader.

Đầu tiên chúng ta cần cài đặt package cần thiết:

npm install --save-dev react-hot-loader

Tiếp theo chúng ta sẽ thay đổi nội dụng file configuration của webpack sử dụng loader vừa cài đặt. Chúng ta sẽ thay loader option bằng loaders và sử dụng một array để lưu các loader cần thiết. Lưu ý các loader sẽ được thực hiện từ phải qua trái theo thứ tự định nghĩa trong loaders option. Cuối cùng chúng ta cần thêm --hot option cho webpack dev server command.

loaders: [
  {
    test: /\.js$/,
    exclude: /node_modules/,
    loaders: ['react-hot-loader', 'babel-loader']
  },
  {
    test: /\.css$/,
    loader: 'style-loader!css-loader'
  }
]
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "start": "webpack-dev-server --progress --inline --hot"
  }

Conclusion

Trong bài viết này, mình có giới thiệu ở mức khá cơ bản cách cài đặt build process cho ứng dụng React. Tất nhiên, trong project thực tế, build process của bạn sẽ không đơn giản như trong ví dụ phía trên. Các công cụ dành cho việc phát triển front-end thay đổi từng ngày và có khá nhiều công cụ mới đã ra đời. Tuy nhiên việc lựa chọn công cụ phù hợp và cần thiết để nghiên cứu và sử dụng là khá quan trọng, tùy thuộc phần lớn vào những gì mà bạn đang phát triển.

Souce code trong bài viết: https://github.com/vinhnguyen-fly/webpack-react-demo

Resources