[WEBPACK] Webpack siêu tốc 2: Cấu hình Typescript, alias, hash bundle
https://xdevclass.com/webpack-sieu-toc-2-cau-hinh-typescript-alias-hash-bundle/
Last updated
Was this helpful?
https://xdevclass.com/webpack-sieu-toc-2-cau-hinh-typescript-alias-hash-bundle/
Last updated
Was this helpful?
C:\Users\Administrator\Desktop\practice\public\index.html
C:\Users\Administrator\Desktop\practice\src\add.ts
C:\Users\Administrator\Desktop\practice\src\app.d.ts
C:\Users\Administrator\Desktop\practice\src\index.scss
C:\Users\Administrator\Desktop\practice\src\index.ts
C:\Users\Administrator\Desktop\practice\src\loadImage.ts
C:\Users\Administrator\Desktop\practice\src\subtract.ts
C:\Users\Administrator\Desktop\practice\package.json
C:\Users\Administrator\Desktop\practice\tsconfig.json
C:\Users\Administrator\Desktop\practice\webpack.config.js
Nội dung bài viết
Tạo một project mới và khởi tạo file package.json
với câu lệnh npmnpm init
Cài Webpack và các style loader cho css và sass
yarn add webpack webpack-cli webpack-dev-server style-loader css-loader sass sass-loader file-loader -D
Mình sẽ không giải thích gì thêm về lý do tại sao mình lại cài những devDependencies này nữa. Nếu anh em nào không hiểu có thể đọc lại bài trước
Copy các dòng lệnh này vào mục script
trong package.json
"start": "webpack serve --mode development","build": "webpack --mode production"
yarn add html-webpack-plugin -D
Mình sẽ giải thích vì sao cài devDepedency này phía dưới
Typescript là ngôn ngữ được xây dựng trên Javascript, giúp bạn có thể viết code giống javascript nhưng có kiểu dữ liệu rõ ràng. Anh em có thể tưởng tượng Typescript giống như SASS vậy, Typescript sẽ được biên dịch sang Javascript cho trình duyệt đọc được.
Vì anh em có thể dùng Typescript để biên dịch sang phiên bản Javascript version phù hợp nên không cần dùng babel ở trong trường hợp này.
yarn add typescript ts-loader -D
Giải thích:
typescript: Phần lõi của ngôn ngữ Typescript
ts-loader: Giúp tích hợp Typescript vào webpack
Cấu trúc thư mục
index.html
<!DOCTYPE html><html> <head> <title>Training Webpack</title> </head> <body> <div id="root"> <h1>Học Webpack siêu tốc 2</h1> </div> <noscript> You need to enable JavaScript to run this app. </noscript> </body></html>
Nếu mọi người để ý thì file html mình không import bất cứ file js nào cả. Lý do thì mình sẽ giải thích phía dưới, mọi người cứ tạo file index.html như vậy trước đã nha.
add.ts export const add = (a = 1, b = 2) => a + b export const treeShaking = () => { console.log('Dòng này sẽ không có trong file build')}
app.d.ts declare module '*.jpg' { const src: string export default src
}
Giải thích tại sao lại có file này: Vì Typescript bắt type rất chặt chẽ, và các file như file ảnh, css, video thì không được Typescript coi là module, nên sẽ không cho import. Vậy nên bạn phải khai báo type cho mỗi loại file.
index.scss $color: #ddd;#root { text-align: center; background-color: $color; padding: 100px;}
loadImage.ts import logo from './logo.jpg' const component = () => { const element = document.createElement('div') const webpackLogo = new Image() webpackLogo.src = logo webpackLogo.width = 200 element.appendChild(webpackLogo) return element} document.getElementById('root')?.appendChild(component())
subtract.ts export const subtract = (a, b) => a - b
index.ts
import { subtract } from './subtract' import { add } from '@@/src/add'import './loadImage' import './index.scss' console.log(`1 + 2 = ${add(1, 2)}`) console.log(`8 - 2 = ${subtract(8, 2)}`)
Nhớ thêm 1 ảnh logo.jpg vào thư mục src nha
tsconfig.json { "compilerOptions": { "target": "ES5", "allowJs": true, "strict": true, "module": "ESNext", "moduleResolution": "node", "noImplicitAny": false, "sourceMap": true, "baseUrl": ".", "paths": { "@/*": ["src/*"], "@@/*": ["./*"] } }, "include": ["src/**/*"]}
Giải thích: Muốn chi tiết hơn thì anh em có thể xem tại đây
target: là version javascript khi được build
allowJs: Cho phép dùng file js trong project Typescript
strict: chế độ strict mode cho Typescript
module: sau khi biên dịch ra mã javascript thì mã này được viết dưới dạng module ESNext. Riêng option này có rất nhiều tùy chọn, khuyên anh em không nên chọn CommonJs, vì nó sẽ làm mất đi tính năng Tree-Shaking của webpack (anh em nào chưa rõ tree-shaking thì đọc lại bài trước giúp mình nha).
noImplicitAny: Không cho phép ngầm hiểu any
sourceMap: cho phép hiện souremap TS ( về vấn đề sourcemap với TS thì bạn phải mở trong tsconfig.json và trong webpack mới đầy đủ nhé, thiếu một cái là sẽ không còn chính xác đâu)
baseUrl: đường dẫn cơ sở, thường là “.”. Nếu bạn dùng option paths dưới đây thì phải quy định baseUrl
paths: tạo alias để thuận tiện việc import. Ví dụ thay vì bạn dùng ../../../
thì bây giờ bạn có thể rút ngắn lại thành @/
. Việc cấu hình alias ở tsconfig.json chỉ giúp editor code hiểu, nó không có tác dụng với webpack. Vì thế bạn phải cấu hình với alias với webpack phía dưới nữa.
include: quy định các file được sử dụng trong chương trình.
webpack.config.js const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = (env, agrv) => { const isDev = agrv.mode === 'development' return { entry: './src/index.ts', module: { rules: [ { test: /\.(ts|tsx)$/, use: 'ts-loader', exclude: /node_modules/ }, { test: /\.(s[ac]ss|css)$/, use: [ 'style-loader', { loader: 'css-loader', options: { sourceMap: isDev ? true : false } }, { loader: 'sass-loader', options: { sourceMap: isDev ? true : false } } ] }, { test: /\.(png|svg|jpg|gif)$/, use: [ { loader: 'file-loader', options: { name: '[path][name].[ext]' } } ] } ] }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'], alias: { '@': path.resolve('src'), '@@': path.resolve() } }, output: { path: path.resolve('dist'), publicPath: '', filename: 'bundle.[hash:6].js', environment: { arrowFunction: false, bigIntLiteral: false, const: false, destructuring: false, dynamicImport: false, forOf: false, module: false } }, devtool: isDev ? 'source-map' : false, devServer: { contentBase: 'public', port: 3000, hot: true, watchContentBase: true }, plugins: [ new HtmlWebpackPlugin({ template: 'public/index.html' }) ] }}
Giải thích:
entry: File đầu vào cho webpack, file này thường là file import mọi file khác
module: Chứa các loader của webpack
resolve.extensions: Thứ tự ưu tiên các file khi import
alias: Tạo alias thuận tiện cho việc import trong webpack
output.path: Đường dẫn thư mục build
output.filename: Tên file bundle sau khi được build. [hast:6]
nghĩa là bundle sẽ được thêm 1 đoạn hash 6 ký tự ngẫu nhiên. Việc này nhằm mục đích hạn chế trình duyệt cache Javascript khi bạn update một version Javascript mới cho website của bạn.
Lúc này sẽ nãy ra 1 vấn đề, mỗi lần build thì ta sẽ có 1 file bundle mới, vậy chẳng lẻ ta lại phải vào public/index.html
sửa đường dẫn file js hay sao?
Đừng lo, chúng ta sẽ dùng 1 plugin là HtmlWebpackPlugin sẽ giúp chúng ta tạo 1 file html mới từ file html ban đầu. File html mới này sẽ dùng template là file public/index.html
và tự động thêm đoạn src là file js mới được build vào.
Vì thế mà plugins ta dùng HtmlWebpackPlugin
output.publicPath: Chứa đường dẫn tương đối mà từ file index.html
trỏ đến các file trong thư mục dist sau khi build. Lưu ý là file index.html được build nằm trong thư mục dist.
output.environment: Mặc định webpack generate ra code dùng 1 số cú pháp của ES6, nhưng target mình mong muốn là ES5 nên mình cần chỉnh một số thông số như sau.
arrowFunction: Hỗ trợ arrow function.
bigIntLiteral: Hỗ trợ BigInt
const: Hỗ trợ khai báo const và let
destructuring: Hỗ trợ destructuring
dynamicImport: Hỗ trợ async import
forOf: Hỗ trợ vòng lặp forOf cho các array
module: Hỗ trợ moudle ES6 (import … from ‘…’)’
output.devtool: tùy chọn sourcemap
devServer.contentBase: Chứa đường dẫn tương đối đến file index.html
devServer.port: port khi chạy localhost
devServer.hot: Chế độ hot reload. Mặc định thì ở dev server thì webpack sẽ refresh lại trang mỗi khi có thay đổi nhỏ trong code.
devServer.publicPath: Chứa đường dẫn tương đối từ thư mục root trỏ đến thư mục build (ở đây là dist). Chú ý phải thêm /
ở trước và sau. Nhưng vì dùng HtmlWebpackPlugin nên ta sẽ tính từ chính thư mục dist. Vì thế giá trị cần dùng là /
. Ở đây mình không dùng giá trị nào cả, vì mặc định nó đã là /
devServer.watchContentBase: Nếu bạn có thay đổi gì trong file index.html thì trình duyệt cũng tự động reload.
Để chạy khi devyarn start
Để build ra thành phẩm phục vụ deployyarn build
Thư mục dist
Github: link github project, folder bài 2 nhé
Tiếp tục bài trước thì hôm nay chúng ta cùng tìm hiểu Webpack thông qua một số setting nâng cao hơn. Để hiểu được bài hôm nay thì các bạn phải nắm được các kiến thức căn bản ở bài trước đã nha ;-). Oke bắt đầu thôi
Ta sẽ xây dựng cấu trúc thư mục tương tự bài trước nhưng, chỉ khác một chút là đổi .js
sang .ts
Các bạn sẽ thấy xuất hiện thư mục dist và file index.html được build ra trong đó. Chúng ta dùng chính file dist/index.html
để chạy nha
Cảm ơn mọi người đã đọc đến đây, bài này khá đơn giản nếu mọi người đã hiểu bài trước . Hẹn gặp lại ở bài Cấu hình Typescript React Webpack hoàn chỉnh nhé