Hiện tại các website đang có xu hướng trở thành những web app với các đặc tính như:
Webpack là công cụ giúp gói gọn toàn bộ file js, css(bao gồm cả scss,sass,..). Việc gói gọn không phải là lộn xộn hết cả lên mà nó được gói theo cấu trúc project, từ phần modul này sang phần kia.
Webpack còn rất nhiều chức năng hữu dụng nữa, vd như optimize hay tuỳ chọn chạy trên môi trường khác nhau(dev hoặc production), watch file,… Mình đã xem qua webpack sử dụng plugin nén 1 file js từ 6mb xuống còn 76 kb. : )).
Với sự contribute của một cộng đồng dev khổng lồ nên webpack là tool hỗ trợ rất tốt cho các dev js, việc sử dụng webpack để dùng cho các project lớn là đều hết sức tuyệt vời.
Vậy chúng ta sử dụng nó như thế nào, trong lập trình thì bất kì một bài toán nào cũng phải có input và output, vậy webpack cũng thế, ta tạo một file webpack.config.js
với đoạn code sau
module.exports = {
entry: './index.js',// entry sẽ là input
output: { filename: 'bundle.js' } // như cái tên của nó thì sẽ là ouput
Vậy có input và output rồi thì thiếu cái gì nữa. Đó là module, vậy hiểu đơn giản thì nó là nơi khai báo loaders, preLoaders, postLoaders, mình thấy trong thực tế chỉ dùng 2 cái đầu là chủ yếu, nên mình sẽ viết 2 cái đầu thôi (cái thứ 3 nói trắng ra là chưa dùng và không biết :v )
preLoaders: Là các tiền xử lý được nạp khi chạy các modul loader. Nó sẽ load các ESLint(check cú pháp) JSHint. Thường mình sẽ config cái này khi code trên môi trường dev. Còn môi trường product sẽ xoá đi đỡ mất công phải check các kiểu mất thời gian
module : {
loaders : [
{
test : /\.jsx?/,// complier những file có đuôi jsx
include : APP_DIR,
loader : 'babel-loader'
},
{
test: /\.js$/, // là value chuỗi regex , khi phân tích modul thì webpack sẽ chỉ tìm những file
//khớp với định dạng này
exclude: /node_module/, // bỏ qua các thư mục hoặc file khi khai bảo ở đây
loader: 'babel-loader', // load .Ở đây là vì mình chuyển đổi code es6 =>es5 nên dung babel
query: {
optional: 'runtime',
cacheDirectory: true,
presets: ['es2015']
}
}
]
}
Đã nói đến webpack thì không thể không nhắc đến code splitting, đây là tính năng mình thích nhất ở webpack, mình sẽ đưa ra một vd đơn giản thế này, trong một dự án thì việc import rất nhiều thư viện vào cùng một lúc là điều hết sức bình thường, nếu ta có file A.js import thư viên C chẳng hạn và cũng có một file B.js import thư viên C, vậy khi webpack build thì sẽ thành 1 file mà chứa code 2 lần cái thư viện C, vậy việc này có thể gây giảm performance
Có 3 cách tiếp cận để split code hiện tại:
Entry Point: cách này khá thủ công và thường là sẽ không dùng đến, nếu như trường hợp ở dưới cả hai 2 index.js và lib.js đều cùng add một thư viện C thì thành như kiểu mình đã sử dụng thư viên C 2 lần
const path = require('path');
const webpack = require('webpack');
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
lib: './src/lib.js'
},
plugins: [
new HTMLWebpackPlugin({
title: 'bla bla'
}),
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
Prevent duplication:
Ở prevent duplication thì chúng ta sẽ cho vào một plugin splitChunks, nhiệm vụ của nó sẽ lấy tất cả các thư viện được import trong project, nó sẽ được tách ra thành các file riêng biệt, đến khi nào code logic của ta cần những thư viện đó thì nó sẽ tự động import
const path = require('path');
const webpack = require('webpack');
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
lib: './src/lib.js'
},
plugins: [
new HTMLWebpackPlugin({
title: 'bla bla'
}),
optimization: {
splitChunks: {
chunks: 'all'
}
}
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
Dynamic imports
Ở trong hàm này, hàm getCompoment sẽ return dynamic imports và trả về lodash, tại sao ta lại làm phức tạp thêm thế này, đơn giản là vì dynamic imports nó import lodash khi cần và nó giúp tăng performance.
function getComponent() {
return import(/* webpackChunkName: "lodash" */ 'lodash').then(_ => {
var element = document.createElement('div');
var _ = _.default;
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}).catch(error => 'An error occurred while loading the component');
}
getComponent().then(component => {
document.body.appendChild(component);
})
Run webpack theo code dưới đây:
const path = require('path');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js' // chỉ cần file index ,không như 2 TH kia
},
output: {
filename: '[name].bundle.js',
chunkFilename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
Với sử đóng góp rất nhiều từ cộng đồng nên số lượng plugin là rất lớn, mình không kể hết đc nhưng phải kể đến các plugin không thế thiếu khi run project như UglifyJSPlugin webpackDashboard, webpackbundleanalyzer,…
Cách sử dụng:
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js',
lib: './src/lib.js'
},
plugins:
[
new HTMLWebpackPlugin({ title: 'Code Splitting' }),
new webpack.optimize.CommonsChunkPlugin({ name: 'common' })
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
– webpack.config.js: File này là file chạy chung cho cả 2 môi trường
– webpack.config.dev.js: Chỉ chạy cho môi trường dev, ở đây bạn có thể thêm các plugin auto log data. Để thuận tiện code việc phát triển sản phẩm
– webpack.config.prod.js: Chỉ triển khai trên môi trường production, ở đây thường mọi người sẽ config minify, xoá comment,…
Unpublished comment
Viết câu trả lời