Chào anh em, lại là mình đây . Hôm nay chúng ta lại tiếp tục đi đến 1 chủ đề tuy mới mà lại cũ , đó là Webpack
, hẳng ai đã làm việc với React, Vue
chắn chắn đều sẽ biết về module bundler
siêu mạnh mẽ và thông dụng này và bài viết này sẽ nói về Plugin webpack
một phần được ví như là backbone
của webpack
. Nào hãy cùng theo dõi nhé
1. Chuẩn bị
Yêu cầu:
- Đã có kiến thức cơ bản về
Webpack
. - Môi trường mình sẽ sử dụng:
- Window 10
- node v12.14.0
- yarn v1.22.4
- editor: VSCode
Mục đích:
- Điểm qua một số plugin siêu hữu ích để anh em có thể dùng cho các dự án sắp tới.
Những phần bỏ qua:
- Phần cấu hình mình sẽ không mô tả chi tiết trong bài viết, các bạn có thể theo dõi thông qua repo.
- Giải thích các thuật ngữ, khái niệm cơ bản mà các bạn hoàn toàn có thể đọc thông qua trang chính thức của thư viện đó.
2. Nội dung
Vậy webpack plugin là gì ?
Plugins are the backbone of webpack. webpack itself is built on the same plugin system that you use in your webpack configuration!
Có bao nhiêu loại webpack plugin ?
Cơ bản sẽ gồm 2 loại:
- Các plugin được tích hợp sẵn bên trong webpack. Ví dụ:
DefinePlugin, ProgressPlugin, EnvironmentPlugin, etc.
- Các plugin được xây dựng từ cộng đồng. Ví dụ:
html-webpack-plugin, webpack-bundle-analyzer, copy-webpack-plugin, etc.
Hôm nay, mình sẽ chia sẽ về một số plugin được xây dựng từ cộng đồng mà mình rất rất thường xuyên sử dụng.
Một số plugin
copy-webpack-plugin
Mục đích của plugin này để copy các file hay thư mục được chỉ định đến thư mục nào đó (thông thường là thư mục build)
Demo
// webpack.config.js
const path = require('path')
const CopyPlugin = require('copy-webpack-plugin')
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve('build'),
publicPath: '/',
},
plugins: [
new CopyPlugin({
patterns: [
{
from: path.resolve('src/assets'),
to: path.resolve('build/assets'),
toType: 'dir',
},
],
}),
],
}
Chúng ta sẽ chỉ định copy thư mục từ src/assets
sang build/assets
khi tiến hành build
Thư mục trước khi build
Chạy lệnh sau để build
yarn webpack
Thư mục sau khi build
Bạn sẽ thấy plugin đã copy 1 bản assets
sang thư mục build
do ta chỉ định ở cấu hình phía trên.
case-sensitive-paths-webpack-plugin
Mục đích của plugin này để bắt buộc phân biệt chữ hoa thường khi các bạn import file
Demo
Cấu trúc thư mục
Khi bạn không sử dụng case-sensitive-paths-webpack-plugin
// webpack.config.js
const path = require('path')
// const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve('build'),
publicPath: '/',
},
// plugins: [new CaseSensitivePathsPlugin()],
}
Kết quả
Mọi thứ vẫn diễn ra và như không có chuyện gì
Khi bạn sử dụng case-sensitive-paths-webpack-plugin
// webpack.config.js
const path = require('path')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve('build'),
publicPath: '/',
},
plugins: [new CaseSensitivePathsPlugin()],
}
Kết quả
Lập tức có mỗi lỗi không tìm thấy module
, để giải quyết bạn cần phải import chính xác module name có phân biệt hoa thường.
circular-dependency-plugin
Mục đích của plugin này để đảm bảo không xảy ra quá trình import chéo giữa 2 hay nhiều file
Demo
// index.js
import a from './a'
import b from './b'
a()
b()
// a.js
import b from './b'
export default function a() {
console.log('function a')
b()
}
// b.js
import a from './a'
export default function b() {
console.log('function b')
a()
}
Chúng ta sẽ import a vào b và b vào a
Khi bạn không sử dụng circular-dependency-plugin
// webpack.config.js
const path = require('path')
// const CircularDependencyPlugin = require('circular-dependency-plugin')
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve('build'),
publicPath: '/',
},
plugins: [
// new CircularDependencyPlugin({
// exclude: /node_modules/,
// }),
],
}
Kết quả
Sẽ không có bất kì warning
nào để cảnh báo chúng ta về việc phụ thuộc chéo giữa 2 file
Khi bạn sử dụng circular-dependency-plugin
// webpack.config.js
const path = require('path')
const CircularDependencyPlugin = require('circular-dependency-plugin')
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve('build'),
publicPath: '/',
},
plugins: [
new CircularDependencyPlugin({
exclude: /node_modules/,
}),
],
}
Kết quả
Lập tức warning
để chúng ta có thể cân nhắc điều chỉnh
html-webpack-plugin
Mục đích của plugin này để giúp webpack tự động tạo 1 hay nhiều file html (nâng cao) và liên kết các module sau khi build, ngoài ra có thể tối ưu và sử dụng các biến môi trường trong file html đầu ra.
Demo
Cấu hình webpack và tệp html mẫu cho plugin
Sau khi build
Tệp bundle đã được link tới tệp html tự động và kích hoạt tối ưu file html đầu ra
mini-css-extract-plugin
Mục đích của plugin này để gom rất cả các module css vào 1 file duy nhất
Demo
Mình sẽ phải sử dụng với css-loader
để giúp resolve các tệp css
như module
Các tệp ban đầu
Sau khi build
Một file main.css
duy nhất chứa tất cả css từ các tệp.
Để có thể minify css
bạn nên kết hợp với plugin optimize-css-assets-webpack-plugin
webpack-bundle-analyzer
Mục đích của plugin này để tạo ra một biểu đồ để bạn có thể hình dung thông tin của các tệp đầu ra, từ đó có thể biết file nào, library nào kích thước quá lớn mà có thể tiến hành tối ưu
Demo
Mình sẽ thêm module lodash
để bạn có thể nhìn thấy rõ hơn trong bản build vì lodash
có kích thước khá lớn
Sau khi build, webpack-bundle-analyzer
sẽ kích hoạt một server và mở 1 trang như sau
Bạn có thể nhìn thấy rõ các thông tin của mỗi tệp đầu ra.
terser-webpack-plugin
Mục đích của plugin này để minify các file js
Demo
Theo mặc định thì terser-webpack-plugin
đã kích hoạt gần như hầu hết các tính năng minify cần thiết, chúng ta chỉ nên điều chỉnh một vài option nếu thực sự cần.
Ở đây mình sẽ thử kích hoạt xóa các dòng console
khi build bằng việc enable terserOptions.compress.drop_console
Kết quả
Tất nhiên là file js đầu ra đã được inline nên không thể đọc. bạn cần dùng prettier
hay một công cụ nào đó format lại để kiểm tra
Thực sự các dòng console.log
mình sử dụng đã bị xóa trong file js này.
clean-webpack-plugin
Mục đích của plugin này rất đơn giản, nó sẽ kích hoạt xóa thư mục được chỉnh định trong
output.path
để tiến hành bản build mới mà không ghi đè lên thư mục cũ
Cấu hình rất đơn giản
// webpack.config.js
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve('build'),
publicPath: '/',
},
plugins: [new CleanWebpackPlugin()],
}
3. Kết luận
Qua bài viết này hi vọng sẽ giúp anh em hiểu và có thể dùng các webpack plugin
này cho các dự án sắp tới.
Ngoài ra còn rất nhiều plugin khác, anh em có thể tìm hiểu thêm, nó chắn chắn sẽ giúp ích.
Nếu bạn cảm thấy bài viết này hữu ích, hãy chia sẽ cho bạn bè để cùng nhau khám phá những điều mới mẽ trong thế giới JavaScript
này nhé
Cảm ơn anh em đã đọc bài viết này.
Toàn bộ ví dụ trên tại repo