本文總結Webpack4常見的配置翘簇。
1设捐、基礎配置(讓項目跑起來)
2、webpack處理css
3思恐、webpack處理sass文件
4荒吏、webpack為sass添加source map
5敛惊、webpack為css添加CSS3前綴
6渊鞋、抽離樣式表為單獨的css文件并打版本號
7绰更、webpack壓縮CSS
8、webpack壓縮js
9锡宋、webpack添加頁面模板
10儡湾、webpack清理打包后的dist目錄
11、webpack處理圖片
12执俩、webpack壓縮圖片
13徐钠、webpack把小圖片轉為base64
14、webpack處理文字
15役首、webpack配置js使用sourceMap
16尝丐、webpack開啟熱更新和代理配置
17、webpack啟用babel轉碼
18衡奥、alias對文件路徑優(yōu)化
19爹袁、使用happypack并發(fā)執(zhí)行任務
案例中自帶不細說:
1、定義全局變量
2矮固、合并提取webpack公共配置
3失息、使用靜態(tài)資源路徑publicPath(CDN)
1、基礎配置
讓項目跑起來
項目初始化:
npm init
安裝webpack档址、vue盹兢、與vue-loader:
npm i webpack vue vue-loader -D
webpack4 已經啟用webpack-cli :
npm i webpack-cli -s -d
解析.vue文件,與內聯(lián)css:
npm i css-loader vue-template-compiler -D
并按照下面目錄構建項目
app.vue
<template>
<div> luckfine </div>
</template>
<script>
export default {
data () {
//text: 'luckfine'
}
}
</script>
<style>
</style>
index.js
// index.js
import Vue from 'vue'
import App from '../components/app.vue'
const root = document.createElement('div')
document.body.appendChild(root)
new Vue({
render: (h) => h(App)
}).$mount(root)
webpack.js
// webpack.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
entry: path.join(__dirname, 'src/spa/index.js'),
mode:'develop',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader'
}
]
},
plugins:[
new VueLoaderPlugin()
],
}
在package.json 文件里的scripts對象里面添加一個腳本:
(注意:webpack4中已經在啟動時用mode指定啟動環(huán)境)
"scripts": {
"build": "webpack --config webpack.config.js --mode=development"
},
讓我們的spa項目先跑起來
npm install webpack-dev-server -s -d
npm install html-webpack-plugin -d -s
// webpack.config.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.join(__dirname, 'src/h5/pages/demo.js'),
mode:'develop',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist')
},
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader'
}
]
},
resolve: {
extensions: [
'.vue', '.js'
],
modules: ["node_modules"],
alias: {
vue: 'vue/dist/vue.min.js',
components: path.resolve(__dirname + '/src/components/'),
'@': path.resolve('src')
}
},
plugins:[
new HtmlWebpackPlugin(),
new VueLoaderPlugin()
],
devServer: {
historyApiFallback: {
index: `/dist/h5/index.html`
},
host: '0.0.0.0',
disableHostCheck: true
}
}
添加項目快捷啟動
"dev": "webpack-dev-server --inline --hot --mode=development",
npm run dev
項目已經跑起來了守伸,開始webpack的配置
2绎秒、webpack處理css
npm i -D css-loader style-loader
// webpack.config.js
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader'
},
{
test: /\.css/,
use: ['style-loader', 'css-loader'] // use的順序從右往左
}
]
},
3、webpack處理sass文件
npm install sass-loader node-sass -D
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader'
},
{
test: /\.(sc|sa|c)ss$/,
use: ['style-loader', 'css-loader', 'sass-loader'] // use的順序從右往左
}
]
},
4尼摹、webpack為sass添加source map
{
test: /\.(sc|sa|c)ss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
添加后
5见芹、webpack為css添加CSS3前綴
npm i -D postcss-loader autoprefixer postcss
在剛才的index.css 加上display: flex;
根目錄新建一個postcss.config.js
module.exports = {
plugins: [
require('precss'),
require('autoprefixer')
]
}
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader'
},
{
test: /\.(sc|sa|c)ss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
},
6校辩、抽離樣式表為單獨的css文件并打版本號
npm install webpack-merge -s -d
npm i -D mini-css-extract-plugin
//webpack.prod.config.js
const merge = require('webpack-merge')
const webpack = require('webpack');
const baseConfig = require('./webpack.config.js')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const devMode = process.env.NODE_ENV !== 'production'
module.exports = merge(baseConfig, {
module: {
rules: [
{
test: /\.(sc|sa|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: devMode ? '[name].css' : '[name].[hash:8].css',
chunkFilename: devMode ? '[id].css': '[id].[hash:8].css'
})
]
})
"dist": "webpack --config webpack.prod.config.js --mode=production",
7、webpack壓縮CSS
npm i -D optimize-css-assets-webpack-plugin
optimization: {
minimizer: [
// 壓縮CSS
new OptimizeCSSAssertsPlugin({})
]
},
8辆童、webpack壓縮js
npm i -D uglifyjs-webpack-plugin
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
optimization: {
minimizer: [
// 壓縮CSS
new OptimizeCSSAssertsPlugin({}),
// 壓縮JS
new UglifyJsPlugin({
// 有很多可以配置
cache: true,
parallel: true,
sourceMap: true,
uglifyOptions: {
// 在UglifyJs刪除沒有用到的代碼時不輸出警告
warnings: false,
output: {
// 刪除所有的注釋
comments: false,
// 最緊湊的輸出
beautify: false
},
compress: {
// 刪除所有的 `console` 語句
// 還可以兼容ie瀏覽器
drop_console: true,
// 內嵌定義了但是只用到一次的變量
collapse_vars: true,
// 提取出出現(xiàn)多次但是沒有定義成變量去引用的靜態(tài)值
reduce_vars: true,
}
}
})
]
},
Uglify-js不支持es6語法宜咒,請使用terser插件, 于是我們更改使用terser插件試試, 其實你繼續(xù)用uglifyjs-webpack-plugin也可以, 只需要配合babel先轉下。
const TerserPlugin = require('terser-webpack-plugin');
optimization: {
minimizer: [
// 壓縮CSS
new OptimizeCSSAssertsPlugin({}),
// 壓縮JS
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true
})
]
},
更多配置見官網terser-webpack-plugin把鉴。
9故黑、webpack添加頁面模板
html-webpack-plugin插件可以把js/css注入到一個模板文件, 所以不需要再手動更改引用。
創(chuàng)建一個模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<meta name="format-detection" content="telephone=no">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
// 打包模板
new HtmlWebpackPlugin({
inject: true,
hash: true,
cache: true,
chunksSortMode: 'none',
title: '頁面模板', // 可以由外面?zhèn)魅? filename: 'index.html', // 默認index.html
template: 'src/spa/index.html',
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true
}
}),
],
10庭砍、webpack清理打包后的dist目錄
npm i -D clean-webpack-plugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
plugins:[
new CleanWebpackPlugin()
]
11场晶、webpack處理圖片
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'file-loader',
options: {
limit: 1,
name: '[name].[hash].[ext]'
},
},
]
}
12、webpack壓縮圖片
npm i -D image-webpack-loader
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'file-loader',
options: {
limit: 1,
name: '[name].[hash].[ext]'
},
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
}
]
}
目前圖片112kb,壓縮后31kb
13怠缸、webpack把圖片轉為base64
npm i -D url-loader
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'url-loader',
options: {
// 具體配置見插件官網
limit: 10000,
name: '[name]-[hash:5].[ext]'
},
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
}
]
},
14诗轻、webpack處理文字
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
// 文件大小小于limit參數,url-loader將會把文件轉為DataUR
limit: 10000,
name: '[name]-[hash:5].[ext]',
output: 'fonts/'
}
},
15揭北、webpack配置js使用sourceMap
devtool: 'inline-source-map'
16扳炬、webpack開啟熱更新和代理配置
devServer: {
clientLogLevel: 'warning', // 輸出日志級別
hot: true, // 啟用熱更新
contentBase: path.resolve(__dirname, 'dist'), // 告訴服務器從哪里提供內容
publicPath: '/', // 此路徑下的打包文件可在瀏覽器下訪問
compress: true, // 啟用gzip壓縮
// publicPath: './',
disableHostCheck: true,
host: '0.0.0.0',
port: 8080,
open: true, // 自動打開瀏覽器
overlay: { // 出現(xiàn)錯誤或者警告時候是否覆蓋頁面線上錯誤信息
warnings: true,
errors: true
},
quiet: true,
watchOptions: { // 監(jiān)控文件相關配置
poll: true,
ignored: /node_modules/, // 忽略監(jiān)控的文件夾, 正則
aggregateTimeout: 300, // 默認值, 當你連續(xù)改動時候, webpack可以設置構建延遲時間(防抖)
}
},
webpack啟用babel轉碼
npm i -D babel-loader @babel/core @babel/preset-env @babel/runtime @babel/plugin-transform-runtime
// 編譯js
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader?cacheDirectory', // 通過cacheDirectory選項開啟支持緩存
options: {
presets: ['@babel/preset-env']
}
}
},
添加.babelrc文件
// 僅供參考
{
"presets": [
[
"@babel/preset-env"
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": false,
"absoluteRuntime": "@babel/runtime"
}
]
]
}
18、alias對文件路徑優(yōu)化
配置alias方便路徑的檢索效率搔体。 加快模塊的查找速度
resolve: {
extensions: ['.vue', '.js'],
modules: ['node_modules'],
alias: {
components: __dirname + '/src/components/',
assets: __dirname + '/src/assets/'
}
},
19恨樟、使用happypack并發(fā)執(zhí)行任務
在 Loader 配置中,所有文件的處理都交給了 happypack/loader 去處理疚俱,使用緊跟其后的 querystring ?id=babel 去告訴 happypack/loader 去選擇哪個 HappyPack 實例去處理文件劝术。
const HappyPack = require('HappyPack')
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: [
{
// 一個loader對應一個id
loader: "happypack/loader?id=luckfine"
}
]
},
new HappyPack({
// 用唯一的標識符id,來代表當前的HappyPack是用來處理一類特定的文件
id:'luckfine',
//如何處理 用法和loader 的配置一樣
loaders: [{
loader: 'babel-loader?cacheDirectory=true',
}],
//共享進程池
threadPool: happyThreadPool,
//允許 HappyPack 輸出日志
verbose: true,
}),
本文源碼:https://github.com/luckFine/vue-webpack.git
可手抖star呆奕,歡迎有遺漏補充养晋。