一,最基礎的環境
1,初始化環境
yarn init (npm init)
複製程式碼
2,安裝webpack webpack-cli
說明webpack-cli 在4.0版本已經脫離了webpack 需要單獨按照,個人建議最好把按照包安裝在專案環境裡,這樣可以確保整個專案用的版本一樣
複製程式碼
yarn add webpack
yarn add webpack-cli
複製程式碼
3,在package.json 新增script
"scripts": { "build": "webpack --mode production" }
4,我們在專案目錄下新增一個檔案src/index.js
(這是webpack預設的入口檔案)
5,執行命令
yarn run dev
複製程式碼
6, webpack.config.js的基本內容
const path = require('path')
const UglifyPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [path.resolve(__dirname, 'src')]
},
],
},
// 程式碼模組路徑解析的配置
resolve: {
modules: [
"node_modules",
path.resolve(__dirname, 'src')
],
extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"],
},
plugins: [
new UglifyPlugin(),
// 使用 uglifyjs-webpack-plugin 來壓縮 JS 程式碼
// 如果你留意了我們一開始直接使用 webpack 構建的結果,你會發現預設已經使用了 JS 程式碼壓縮的外掛
// 這其實也是我們命令中的 --mode production 的效果,後續的小節會介紹 webpack 的 mode 引數
],
}
複製程式碼
基本解析:
注意:loader 和plugins都需要單獨安裝, 安裝到 devDependencies 因為這些外掛都只是構建程式碼時候有用
二,常用plugins
1,UglifyPlugin
這個用來進行js程式碼壓縮
yarn add uglifyjs-webpack-plugin --dev
複製程式碼
2,html-webpack-plugin
這個使用者把打包好的js檔案動態插入到index.html 預設入口檔案為根目錄下index.html 出口檔案預設為dist目錄下index.tml
yarn add uglifyjs-webpack-plugin --dev
複製程式碼
也允許自己定義
module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 配置輸出檔名和路徑
template: 'assets/index.html', // 配置檔案模板
}),
],
}
複製程式碼
⚠️為什麼需要這個外掛?為什麼要動態插入? 主要是因為我們進行打包 為了防止瀏覽器快取,往往需要給打包出來到檔案新增[hash]。 所以就需要動態插入
3,extract-text-webpack-plugin@next
如果只用 css-loader & style-loader來轉換程式碼,css會程式設計js程式碼動態插入到html中 如果想把css單獨成一個檔案,就需要使用這個plugin
4,DefinePlugin
DefinePlugin 是 webpack 內建的外掛,可以使用 webpack.DefinePlugin 直接獲取。
這個外掛用於建立一些在編譯時可以配置的全域性常量,這些常量的值我們可以在 webpack 的配置中去指定,例如:
5,copy-webpack-plugin
我們一般會把開發的所有原始碼和資原始檔放在 src/ 目錄下,構建的時候產出一個 build/ 目錄,通常會直接拿 build 中的所有檔案來發布。有些檔案沒經過 webpack 處理,但是我們希望它們也能出現在 build 目錄下,這時就可以使用 CopyWebpackPlugin 來處理了。
一般開發時,會在根目錄下static目錄直接拷貝過去
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: 'static',
ignore: ['.*']
}
])
yarn add copy-webpack-plugin -D
複製程式碼
6,ProvidePlugin
ProvidePlugin 也是一個 webpack 內建的外掛,我們可以直接使用 webpack.ProvidePlugin 來獲取。
該元件用於引用某些模組作為應用執行時的變數,從而不必每次都用 require 或者 import,其用法相對簡單:
new webpack.ProvidePlugin({
identifier: 'module',
// ...
})
// 或者
new webpack.ProvidePlugin({
identifier: ['module', 'property'], // 即引用 module 下的 property,類似 import { property } from 'module'
// ...
})
複製程式碼
在你的程式碼中,當 identifier 被當作未賦值的變數時,module 就會被自動載入了,而 identifier 這個變數即 module 對外暴露的內容。
注意,如果是 ES 的 default export,那麼你需要指定模組的 default 屬性:identifier: ['module', 'default'],。
7,IgnorePlugin
IgnorePlugin 和 ProvidePlugin 一樣,也是一個 webpack 內建的外掛,可以直接使用 webpack.IgnorePlugin 來獲取。
這個外掛用於忽略某些特定的模組,讓 webpack 不把這些指定的模組打包進去。例如我們使用 moment.js,直接引用後,裡邊有大量的 i18n 的程式碼,導致最後打包出來的檔案比較大,而實際場景並不需要這些 i18n 的程式碼,這時我們可以使用 IgnorePlugin 來忽略掉這些程式碼檔案,配置如下
module.exports = {
// ...
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
}
複製程式碼
8,optimize-css-assets-webpack-plugin
css 程式碼壓縮
const optimizeCss = require('optimize-css-assets-webpack-plugin');
plugins: [
new optimizeCss()
]
yarn add optimize-css-assets-webpack-plugin -D
複製程式碼
三,常用loaders
1,babel-loader
這個loader可以把es6 + 程式碼轉換為es5到程式碼。因為瀏覽器對於es6的程式碼相容不好,但是es6很多新語法對於我們開發工作提升很高。所以需要把 es6程式碼做轉換。
yarn add babel-loader @babel/core --dev
複製程式碼
2,css-loader & style-loader
css-loader 負責解析 CSS 程式碼,主要是為了處理 CSS 中的依賴,例如 @import 和 url() 等引用外部檔案的宣告; style-loader 會將 css-loader 解析的結果轉變成 JS 程式碼,執行時動態插入 style 標籤來讓 CSS 程式碼生效。
{
test: /\.css/,
include: [
path.resolve(__dirname, 'src'),
],
use: [
'style-loader',
'css-loader',
],
}
複製程式碼
注意:['style-loader','css-loader']這裡的配置是有順序的,但規則應用順序是從右到左的。也就是先 css-loader,再style-loader
yarn add css-loader style-loader --dev
複製程式碼
3,less-loader
css 預編譯器
module.exports = {
// ...
module: {
rules: [
{
test: /\.less$/,
// 因為這個外掛需要干涉模組轉換的內容,所以需要使用它對應的 loader
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'less-loader',
],
}),
},
],
},
// ...
}
yarn add less less-loader -D
複製程式碼
4,file-loader & url-loader & image-webpack-loader
file-loader 可以用於處理圖片檔案
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {},
},
],
}
yarn add file-loader -D
複製程式碼
簡答地說,url-loader封裝了file-loader。url-loader不依賴於file-loader,即使用url-loader時,只需要安裝url-loader即可,不需要安裝file-loader,因為url-loader內建了file-loader。
通過上面的介紹,我們可以看到,url-loader工作分兩種情況:
1)檔案大小小於limit引數,url-loader將會把檔案轉為DataURL;
2)檔案大小大於limit,url-loader會呼叫file-loader進行處理,引數也會直接傳給file-loader。因此我們只需要安裝url-loader即可。
url-loader
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
yarn add url-loader -D
複製程式碼
image-webpack-loader可以用來做圖片壓縮
{
loader: 'image-webpack-loader',
options: {
mozjpeg: { // 壓縮 jpeg 的配置
progressive: true,
quality: 65
},
optipng: { // 使用 imagemin-optipng 壓縮 png,enable: false 為關閉
enabled: false,
},
pngquant: { // 使用 imagemin-pngquant 壓縮 png
quality: '65-90',
speed: 4
},
gifsicle: { // 壓縮 gif 的配置
interlaced: false,
},
webp: { // 開啟 webp,會把 jpg 和 png 圖片壓縮為 webp 格式
quality: 75
},
}
yarn add image-webpack-loader
複製程式碼
5,NamedModulesPlugin(), && HotModuleReplacementPlugin()
熱模組替換相關
plugins: [ // ... new webpack.NamedModulesPlugin(), // 用於啟動 HMR 時可以顯示模組的相對路徑 new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的外掛 ],
四, 本地伺服器 webpack-dev-server & webpack-dev-middleware
1, webpack-dev-server使用
新增script
"start": "webpack-dev-server --mode development"
複製程式碼
new webpack.NamedModulesPlugin(), // 用於啟動 HMR 時可以顯示模組的相對路徑 new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的外掛
webpack-dev-server當更多配置檢視https://webpack.docschina.org/configuration/dev-server/
yarn add webpack-dev-server -D
2 ,webpack-dev-middleware使用
我們也可以使用webpack-dev-middleware 來啟動靜態伺服器 使用如下 首先安裝 webpack-dev-middleware 依賴:
npm install webpack-dev-middleware --save-dev
複製程式碼
接著建立一個 Node.js 服務的指令碼檔案,如 app.js:
const webpack = require('webpack')
const middleware = require('webpack-dev-middleware')
const webpackOptions = require('./webpack.config.js') // webpack
複製程式碼
配置檔案的路徑
// 本地的開發環境預設就是使用 development mode
webpackOptions.mode = 'development'
const compiler = webpack(webpackOptions)
const express = require('express')
const app = express()
app.use(middleware(compiler, {
// webpack-dev-middleware 的配置選項
}))
// 其他 Web 服務中介軟體
// app.use(...)
app.listen(3000, () => console.log('Example app listening on port 3000!'))
複製程式碼
新增script
"start": "node app.js"
複製程式碼
五,配置拆分
webpack.base.js:基礎部分,即多個檔案中共享的配置 webpack.development.js:開發環境使用的配置 webpack.production.js:生產環境使用的配置 因此,只要有一個工具能比較智慧地合併多個配置物件,我們就可以很輕鬆地拆分 webpack 配置,然後通過判斷環境變數,使用工具將對應環境的多個配置物件整合後提供給 webpack 使用。這個工具就是 webpack-merge。