- Giới thiệu Webpack
- Tự động chạy Webpack với npm-watch
- Build SCSS và gộp CSS
- Loader
- Copy file với copy-webpack-plugin
Giới thiệu Webpack, khái niệm và sử dụng cơ bản
Webpack là một module bundler cho JS (bundler - có nghĩa nó có tính năng gộp nhiều file nguồn JS thành một file,
trong quá trình gộp nó đưa vào đầy đủ các dependency - thư viện - cũng như thực hiện một số chuyển đổi - ví dụ tối ưu minify ...),
nó là một package của NodeJS - quản lý bởi npm
(phải tải + cài đặt NodeJS trước)
Phần này sử dụng Webpack để giúp gộp JS, CSS (gồm cả dịch SCSS thành CSS). Hãy bắt đầu sử dụng Webpack
một cách đơn giản như sau:
Tạo một thư mục lưu code đặt tên là webpack-example
, trong thư mục đó gõ lệnh sau, để nó sinh ra file
package.json
nếu chưa có:
npm init -y
Webpack
là package NodeJS, cài đặt nó chỉ việc thực hiện lệnh sau trong thự mục dự án:
npm i -D webpack webpack-cli
Sau lệnh này thì đã có webpack
mà các dependency để webpack chạy.
Giờ hãy tạo ra 3 file nguồn js làm ví dụ như sau:
src/js/a.js
"use strict"; function Pop1() { alert("Thông báo 1"); } export {Pop1} //xuất hàm Pop1
src/js/b.js
"use strict"; function Pop2() { alert("Thông báo 2"); } export {Pop2}
src/js/app.js
import { Pop1 } from './a.js'; import { Pop2 } from './b.js'; function Abc() { alert("Abc"); } export {Pop1, Pop2, Abc}
Trong đó, file app.js
nạp thành phần từ a.js
và b.js
. Giờ cần thiết
để Webpack build file app.js
với các dependency (a.js, b.js) thành 1 file duy nhất lưu
ở dist/app.min.js
Thực hiện tạo ra file cấu hình của Webpack có tên là webpack.config.js
, cập nhật cho nó nội dung như sau:
const path = require('path'); const devMode = true; module.exports = { mode: devMode ? 'development' : 'production', entry: [ './src/js/app.js', // file nguồn Webpack làm việc ], output: { filename: 'app.min.js', // tên file xuất ra path: path.resolve(__dirname, 'dist'), // thư mục lưu library: 'mylib', // tên thư viện (tự đặt) libraryTarget: 'var', }, optimization: { // We no not want to minimize our code. //minimize: false }, };
Sau khi có file cấu hình webpack.config.js
, mở file package.json
- tại mục scripts
sửa thành như sau:
/.. "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, /..
Thực hiện gõ lệnh sau để webpack tiến hành gộp file và sinh ra app.min.js
:
nmp run build
File app.min.js
đã có, bạn có thể mở ra kiểm kết quả. Hoặc tạo ra 1 file test.html
với nội
dung sau để kiểm tra.
<!DOCTYPE html> <html> <head> <script src="dist/app.min.js"></script> </head> <body> <script> mylib.Pop1(); mylib.Pop2(); mylib.Abc(); </script> </body> </html>
Tự động chạy Webpack khi file nguồn cập nhật
Muốn mỗi khi file nguồn sửa đổi, cập nhật thì Webpack build lại, trước tiên cài đặt vào nmp-watch
npm install npm-watch
Sau đó mở file package.json
thêm vào scrips
đoạn script: "watch": "npm-watch"
,
và thêm vào cấu hình như sau
/.. "watch": { //Thêm vào "build": "{src,othersrc}/js/*.js" // loại file thay đổi dẫn đến scrip watch chạy }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "watch": "npm-watch" //thêm vào }, /..
Để kích hoạt watch, gõ lệnh
nmp run watch
Build và gộp SCSS, CSS với Webpack
Để làm việc với CSS, SCSS
cài thêm một số package sau:
npm i node-sass postcss-loader postcss-preset-env sass-loader css-loader cssnano mini-css-extract-plugin cross-env file-loader
Giả sử có file nguồn src/scss/site.scss
muốn biên dịch thành CSS
lưu tại dist/css/site.min
Hãy mở file webpack.config.js
cập nhật thêm phần hỗ trợ chuyển đổi SCSS như sau:
const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const postcssPresetEnv = require('postcss-preset-env'); const devMode = false; module.exports = { mode: devMode ? 'development' : 'production', entry: [ './src/js/app.js', './src/scss/site.scss' // file nguồn CSS ], output: { filename: 'app.min.js', path: path.resolve(__dirname, 'dist'), library: 'mylib', libraryTarget: 'var', }, module: { rules: [ { // Thiết lập build scss test: /\.(sa|sc)ss$/, use: [ { loader: MiniCssExtractPlugin.loader }, { // Interprets CSS loader: 'css-loader', options: { importLoaders: 2 } }, { // minify CSS và thêm autoprefix loader: 'postcss-loader', options: { ident: 'postcss', // Đặt chế độ tối ưu plugins: devMode ? () => [] : () => [ postcssPresetEnv({ browsers: ['>1%'] }), require('cssnano')() ] } }, { loader: 'sass-loader' } ] }, { // Thiết lập lưu các ảnh sử dụng bởi CSS // lưu dưới đường dẫn images cùng file site.css test: /\.(png|jpe?g|gif)$/, use: [ { loader: 'file-loader', options: { name: '[name].[ext]', // Image sử dụng bởi CSS lưu tại publicPath: '../images', emitFile: false } } ] } ] }, plugins: [ // Xuất kết quả với CSS - sau khi qua loader MiniCssExtractPlugin.loader new MiniCssExtractPlugin({ filename: devMode ? 'css/site.css' : 'css/site.min.css' }) ] };
Giờ thì khi build bằng Webpack
nó sẽ biên dịch SCSS cho bạn. Thử kiểm tra bằng cách soạn
mã nguồn site.scss - giả sử có biên dịch cả bootstrap.
Cài đặt bootstrap
npm install bootstrap
Mở file site.scss cập nhật
//Gộp Bootstrap // Có thể thiết lập các biến biến như màu $warning ... @import '../../node_modules/bootstrap/scss/bootstrap.scss'; .bigsize { font-size: 60px; font-weight: normal; line-height: 65px; }
Giờ hãy chạy lệnh để xem kết quả: nmp run webpack
Loader với Webpack
Loader là cách chỉ ra cho Webpack xử lý loại file củ thể, cấu hình cần tối thiểu chỉ ra
test
chỉ ra loại file cần chuyển đổiuse
các loader sử dụng cho file đó
const path = require('path'); module.exports = { module: { rules: [ { test: /\.txt$/, use: [ {loader: "loader1"}, {loader: "loader2"} ] } ] } };
Các loader thực hiện từ dưới lên trên, như ở ví dụ trên đối với file CSS nó sẽ chuyển đổi dần qua các loader:
sass-loader
-> postcss-loader
-> css-loader
-> MiniCssExtractPlugin.loader
Copy file với copy-webpack-plugin
Nếu muốn copy khi chạy Webpack, hãy cài đặt copy-webpack-plugin
npm install copy-webpack-plugin
Sau đó ở file webpack.config.js
nạp plugin này vào và cấu hình copy, ví dụ (những đoạn mã thêm vào):
/.. const CopyPlugin = require('copy-webpack-plugin'); /.. module.exports = { /.. plugins: [ /.. new CopyPlugin([ { from: 'node_modules/bootstrap/dist/js/bootstrap.js', to: 'js/bootstrap.js' }, { from: 'node_modules/bootstrap/dist/js/bootstrap.min.js', to: 'js/bootstrap.min.js' }, ]), ] };