webpack現在可謂炙手可熱,要是不懂,就難免讓人覺得有點跟不上時代。
其實webpack只是一種工具,我們以使用為目的去學習它,就一點也不難哦,本篇文章讓您在一個小時內上手webpack,沒時間學習也可以先收藏哦。
webpack主要用於相容性處理,程式碼預處理轉換處理,壓縮處理。
如轉換ES6語法,轉換JSX 指令等
CSS字首補全/前處理器,程式碼壓縮混淆,圖片壓縮等。
webpack的組態檔預設為webpack.config.js。
webpack --config命令可用於指定組態檔。
安裝nodejs和npm,直接在nodejs官網下載安裝包即可,npm作為nodejs附屬包同時自動安裝,無需另外安裝。
使用nodejs安裝包安裝後可用命令列在cmd視窗檢視安裝版本。
首先,建立專案目錄(空目錄),使用命令列建立一個初始化的package.json。
npm init -y
向專案目錄中安裝webpack依賴,安裝後目錄中出現node_modules檔案。
npm install webpack webpack-cli --save-dev
注意到上文命令列中包含字尾 --save-dev,含義如下。
主要區別在於打包後是否保留該依賴,webpack本身是打包工具,當然不需要保留啦。
安裝成功後檢視安裝情況。
./node_modules/.bin/webpack -v
現在我們就可以使用webpack做專案了,首先做一個最簡單的例子。
首先z在專案目錄中建立組態檔webpack.config.js,
'use strict'
const path = require('path'); // 引入一個依賴
module.exports = {
entry: './src/index.js', // 入口
output: { // 出口
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
mode: 'production'
};
在上面檔案中,我們指定入口為’./src/index.js’,輸出檔案在dist資料夾中,名字為’bundle.js’。
翻譯一下也就是,webpack會以’./src/index.js’為入口,將其與其所有的依賴打包為一個出口檔案’bundle.js’放置在目錄dist中。
我們首先建立檔案’./src/index.js’與其依賴檔案’./src/helloworld.js’。
在index.js中引入helloworld.js檔案。
// './src/index.js'
import { helloworld } from './helloworld';
document.write(helloworld());
// './src/helloworld.js'
export function helloworld() {
return 'hello webpack'
}
此時專案結構如下圖。
檔案准備完畢,我們使用webpack命令列打包。
./node_modules/.bin/webpack
專案目錄下,出現了資料夾dist,其中含有bundle.js,與前面組態檔出口路徑與名稱對應。
可以看到,bundle.js檔案是入口檔案的整合版,執行效果與入口檔案是相同的,只是少了依賴而已。
剛剛使用./node_modules/.bin/webpack
打包,未免繁瑣,這裡可以通過在package.json中對scripts新增設定的方式,設定快捷命令。
{
"name": "webpackTest",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0"
}
}
rm -rf dist // 刪除之前的打包檔案
npm run build // 打包檔案 生成與剛剛相同的檔案
剛剛的組態檔中見過,用於指定打包檔案入口。
單入口情況下為字串,多入口情況下為key-value物件。
剛剛的範例為單入口檔案。
剛剛的組態檔中見過,用於指定編譯後的檔案輸出。
// 單入口 單出口
module.exports = {
entry: './src/index.js', // 入口
output: { // 出口
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
}
};
// 多入口 多出口
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
}
output: { // 出口
path: path.join(__dirname, 'dist'),
filename: '[name].js'
}
};
可以看到,對於多入口出口設定,output中內容沒有太大改變,其實是使用預留位置[name]來實現檔案動態命名的,打包後的dist目錄中,有著對應入口檔案的n個出口檔案,名稱與entry中的key值一致。
上面的組態檔中,打包結果為dist中出現兩個檔案,分別為app.js和search.js。
webpack原生支援js和json,通過loaders做其他檔案型別的轉換,如vue等,將其他檔案型別轉化為有效的模組,新增到依賴圖中。
本身是一個函數,接受原始檔作為引數,返回轉換的結果。
常見loaders:
babel-loader | 轉換ES6.ES7等 |
---|---|
css-loader | 支援.css檔案的載入和解析 |
less-loader | 將less檔案轉換為css |
ts-loader | 將TS轉換成JS |
file-loader | 進行圖片 字型等的打包 |
raw-loader | 將檔案以字串的形式匯入 |
thread-loader | 多程序打包JS和CSS |
用法
module.exports = {
module: {
rules: [
{test:/\.txt$/,use:'raw-loader'} // 匹配規則 loader名稱
]
}
}
外掛,增強功能。作用於整個構建過程。
常用外掛
用法
module.exports = {
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
// 建立html檔案去承載輸出的bundle
]
}
指定當前的構建環境是:production development none
預設為 production。
通過對mode的不同設定,可以使用webpack不同內建函數。
使用babel-loader完成。
npm i @babel/core @babel/preset-env babel-loader -D
在src同級目錄下建立babel組態檔.babelrc,書寫設定。
{
"presets": [
"@babel/preset-env"
]
}
修改webpack組態檔。
rules: [
{
test:/.js$/,
use: 'babel-loader'
}
]
設定完成後檢視效果。
rm -rf dist
npm run build
此時已經解析成功了。
那如果是React語法如何解析呢。
安裝babel-react。
npm i react react-dom @babel/preset-react -D
修改babel組態檔.babelrc。
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
書寫一個簡單的react-js檔案,檔案的含義是將一個模板放置到一個DOM節點上。
npm run build 構建即可檢視效果。
將輸出的JS檔案放置到一個新建的html檔案中,檔案中含有對應的節點,就可以成功插入了。
解析CSS使用css-loader,將css轉換為commonjs物件,使用style-loader,將樣式通過
首先在專案中安裝兩個依賴。
npm i style-loader css-loader -D
在專案中建立css檔案,寫入一些樣式,並在剛剛的react的js檔案中引入使用。
在webpack組態檔中rules中新增loader。
module: {
...
rules: [
{
test: /.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
}
再編譯,生成的js檔案,放置在html中就有對應效果了。
但是這時候還是沒有單獨的css檔案的,要將css檔案分離出來,要使用外掛extract-text-webpack-plugin。
也可以使用mini-css-extract-plugin,都是用來抽離css樣式,防止將樣式打包在js中引起頁面樣式載入錯亂的現象
extract-text-webpack-plugin 4.0的beta版本才支援webpack4.x 或者使用mini-css-extract-plugin
extract-text-webpack-plugin 預設版本 在webpack3.x可用
npm install extract-text-webpack-plugin --save-dev
var Ex = require('extract-text-webpack-plugin');
// ...省略
module: {
loaders: [{
test: /\.css/,
loader: Ex.extract('style-loader', 'css-loader','less-loader') // 單獨打包出CSS,這裡設定注意下
}]
},
plugins: [
new Ex("[name].css")
]
如果我們想要一個載入器陣列,我們必須使用use,如果它只是一個載入器,那麼我們必須使用loader。
安裝less和less-loader依賴。
npm i less less-loader -D
將剛剛的css檔案轉換為less檔案,之後在webpack中設定rules。
{
test: /.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
然後打包檢視效果即可。
使用file-loader處理檔案。
在src目錄下放置圖片logo.png,並在專案中引入使用。
npm i file-loader -D
在webpack組態檔中設定使用。
{
test: /.(png|jpg|gif|jpeg)$/,
use: 'file-loader'
}
打包即可。
與圖片相同使用file-loader。
剛剛已經安裝過依賴了,無需再安裝,我們直接在css中引入和使用字型即可。
在webpack組態檔中新增設定。
{
test: /.(woff|woff2|eit|ttf|otf)$/,
use: 'file-loader'
}
然後打包編譯即可。
檔案監聽是指在發現原始碼發生變化時,自動構建新的輸出檔案。
webpack開啟監聽模式,有兩種方式。
首先我們使用第一種方式。
在package.json的scripts中新增設定watch。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"watch": "webpack --watch"
},
然後執行構建的時候,使用 npm run watch構建。
webpack會輪詢判斷檔案的最後編輯時間是否變化,變化後會等待一段時間後執行。
剛剛說了第二種方式,也可在組態檔中設定。
webpack相關設定。
module.export = {
// 預設false 也就是不開啟
watch: true,
// 只有開啟監聽模式時下面的設定才有效
watchOptions: {
// 忽略的檔案 預設為空
ignored:/node_modules/,
// 監聽後等待時候 預設300
aggregateTimeout:300,
// 輪詢時間 預設1000
poll:1000
}
}
如此,當我在編輯了檔案的時候,儲存後webpack就會自動編譯。
剛剛新增了自動構建功能,但是構建完成後需要我們手動重新整理瀏覽器,瀏覽器的自動重新整理在webpack中也有體現,就叫做熱更新。
也就是webpack-dev-server。
安裝該包依賴。
npm i webpack-dev-server -D
我們在在package.json的scripts中新增設定dev。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"watch": "webpack --watch",
"dev": "webpack-dev-server --open"
},
在webpack設定中引入並註冊熱更新外掛,並進行設定。
// webpack.config.js
const webpack = require('webpack');
// webpack.config.js
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: './dist',
hot:true
}
熱更新的內容不會儲存到磁碟,而是放置在記憶體中。
這時可能會有一個報錯:
Cannot find module 'webpack-cli/bin/config-yargs'
是因為webpack-cli
的新版本對webpack-dev-server
版本的不相容,之後降低webpack-cli
的版本為 "^3.3.12"
。
npm i webpack-cli@3.3.12 -D 就ok了。
webpack已經內建了uglifyjs-webpack-plugin外掛進行JS壓縮。
使用外掛optimize-css-assets-webpack-plugin,同時使用cssnano。
安裝依賴。
npm i optimize-css-assets-webpack-plugin
npm i cssnano -D
參照外掛。
plugins: [
...,
new OptimizeCSSAssetsPlugin({
assetNameRegExp: /.css$/g,
cssProcessor: require('cssnano')
})
]
然後打包,打包成的就是壓縮的css了。
設定外掛html-webpack-plugin,設定壓縮引數。
在html中新建html模板。
在webpack組態檔中引入html-webpack-plugin。
import HtmlWebpackPlugin = require(html-webpack-plugin)
在組態檔中設定外掛。
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
...
plugins: [new HtmlWebpackPlugin()],
};
上面是最簡單用法,這將會生成一個包含以下內容的 dist/index.html
檔案。
如果你有多個 webpack 入口,他們都會在已生成 HTML 檔案中的 <script>
標籤內引入。
如果在 webpack 的輸出中有任何 CSS 資源(例如,使用 MiniCssExtractPlugin 提取的 CSS),那麼這些資源也會在 HTML 檔案 <head>
元素中的 <link>
標籤內引入。
也可以為這個外掛傳入一寫引數,來指定入口html等值。