一, 初始化自己的專案
(1). 初始化npm
npm init
<!--一路回車,會生成package.json檔案-->
複製程式碼
(2). 在根目錄下新建src, build 資料夾,新建index.html作為html模版
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Vue-webpack</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app"></div>
</body>
</html>
複製程式碼
(3). 安裝依賴
由於webpack4及以後的版本中webpack和webpack-cli是配套的,所以兩個必須同時安裝,webpack-cli設計思路是命令式的幫助配置webpack,免於寫webpack配置檔案,但並未完善,並沒有感覺多快。
npm i webpack webpack-cli -D
複製程式碼
二, 配置webpack
在build目錄下新建一下三個檔案:
webpack.base.config.js
webpack.dev.config.js
webpack.prod.config.js
複製程式碼
分別應用於基礎公用配置編寫,開發環境配置編寫,生產環境配置編寫
(1). webpack.base.config.js配置
const path = require('path')
module.exports = {
entry: {
app: '../src/index.js'
},
output: {
// __dirname是node中的一個全域性變數
path: path.resolve(__dirname, '../dist'),
filename: '[name].[hash:5].js'
},
module: {
rules: []
},
plugins: []
}
複製程式碼
(2). webpack.dev.config.js配置
const merge = require('webpack-merge')
const path = require('path')
const baseConf = require('./webpack.base.config')
// 通過merge合併development和base的配置
module.exports = merge(baseConf, {
// webpack4中必須指定開發環境,也可以在npm script指令碼中指定
mode: 'development',
devtool: 'souce-map',
devServer: {
contentBase: path.resolve(__dirname, '../dist'),
port: 3000
}
})
複製程式碼
(3). webpack.prod.config.js配置
const merge = require('webpack-merge')
const path = require('path')
const baseConf = require('./webpack.base.config')
module.exports =merge(baseConf, {
mode: 'production',
devtool: 'source-map',
module: {
rules: []
},
plugins: []
})
複製程式碼
(4). 配置基本外掛
npm i webpack clean-webpack-plugin html-webpack-plugin -D
複製程式碼
由於html-webpack-plugin外掛prod和dev環境都用的貸,所以放在base下
const htmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new htmlWebpackPlugin({
template: path.resolve(__dirname, '../index.html'),
})
]
複製程式碼
clean-webpack-plugin外掛放在prod環境下,打包前清除dist目錄下的檔案
const cleanWebpackPlugin = require('clean-webpack-plugin')
plugins: [
// 新版本的外掛只接受一個物件配置作為引數
new cleanWebpackPlugin({
root: path.resolve(__dirname, '../dist/')
}),
]
複製程式碼
(5). npm script指令碼配置
"build": "webpack --config build/webpack.prod.config.js",
"dev": "webpack-dev-server --progress --config build/webpack.dev.config.js"
複製程式碼
在src/index.js下寫
alert('hello world')
複製程式碼
分別執行
npm run dev
npm run build
複製程式碼
檢視打包成功與否
三, 配置plugins和loader (1). 配置babel來轉換ES6語法
npm i @babel/runtime @babel/core @babel/plugin-transform-runtime @babel/preset-env babel-loader -D
複製程式碼
在根目錄下新建.babelrc檔案並配置:
{
"presets": [
[
"@babel/preset-env", {
"targets": {
"browsers": ["> 1%", "last 2 versions"]
},
// 用來treeshaking,不要將es6模組轉換為common.js
"modules": false,
"useBuiltIns": "usage"
}
]
],
}
複製程式碼
在webpack.base.config.js的module下:
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {}
}]
}
複製程式碼
現在可以在index.js中寫es6語法
(2). 處理樣式
在這裡我個人比較喜歡原生css + css-module
npm i postcss-loader css-loader style-loader autoprefixer -D
複製程式碼
在webpack.base.config.js的module下:
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},{
loader: 'css-loader',
options: {
/* 是否壓縮 */
minimize: true,
/* 啟用 css-modules */
modules: true,
/* 定義編譯出來的名稱 */
localIdentName: '[path][name]_[local]_[hash:base64:5]'
}
},
{
/* 將css3屬性新增上廠商字首 */
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
/* 根據.browserlist加 css 各瀏覽器字首 */
require('autoprefixer')({
browsers: ['last 2 versions']
})
]
}
}
]
}
複製程式碼
(3). 處理file檔案
// 各種loader 按自己需求配置就行
npm i file-loader url-loader img-loader -D
複製程式碼
(4). .vue檔案
.vue的單檔案寫法給了開發很大的便利,採用vue-loader編譯template模版編。其中vue-loader 和 vue-template-compiler必須一起安裝,我們也可以用vue-style-loader替換style-loader將樣式插入模版中
npm i vue-loader vue-style-loader vue-template-compiler -D
npm i vue -S
複製程式碼
在webpack.base.config.js的module下:
const vueLoaderPlugin = require('vue-loader/lib/plugin')
module: {
rules: [
{
test: /.vue$/,
loader: 'vue-loader'
}
]
}
plugins: [
new vueLoaderPlugin()
]
複製程式碼
vueLoaderPlugin外掛是必須的,它可以將之前定義過的module規則(比如說處理es6語法等等)應用到.vue相應的程式碼塊中。 現在可以在src檔案下寫vue程式碼了:
// index.js
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})
// App.vue 利用css-module
<template>
<div :class="$style.page">
<div :class="$style.left">back</div>
<div :class="$style.right">for</div>
</div>
</template>
<script>
export default {
}
</script>
<style module>
.div {
font-size: 15px;
cursor: pointer;
border: 1px solid black;
height: 30px;
line-height: 30px;
vertical-align: middle;
border-radius: 5px;
margin:0 2px;
text-align: center;
box-shadow: 1px 1px gray
}
.page {
/* composes: div; */
display: flex;
}
.left {
composes: div;
width: 45px;
}
.right {
composes: div;
width: 45px;
}
</style>
複製程式碼
三, 優化 (1). 配置resolve
webpack.base.config.js下:
resolve: {
alias:{
'vue$': 'vue/dist/vue.esm.js',
'@': path.resolve(__dirname, '../src'),
},
extensions: ['*', '.js', '.json', '.vue'],
},
複製程式碼
(2) 開啟熱更新
webpack4配置熱更新較為簡單
1) 設定devServer.hot = true
2) 開啟 webpack.HotModuleReplacementPlugin外掛
複製程式碼
vue-style-loader內建了style-loader,css熱更新開箱即用。js熱更新需要在入口js檔案面加入一句判斷:
if (module.hot) {
module.hot.accept();
}
複製程式碼
(3) 配置happypack
happyloader將任務分解成多個子程式去併發執行,子進行處理完之後將結果傳送給
主程式。例如因為babel-loader要分析將程式碼轉化成ast,引入響應的polyfill,是一個很耗時的工作。
利用happyloader去處理babel-loader,所有需要經過babel-loader處理的檔案都先
交給了happypack/loader去處理。每通過new HappyPack()例項就是告訴happyPack核心排程器
如何通過一系列Loader去轉換一類檔案,並且可以制定如何為這類轉換器分配子程式
複製程式碼
安裝:
npm i happypack
複製程式碼
配置:
const happyPack = require('happypack')
const happyThreadPool = happyPack.ThreadPool({size: os.cpus().length})
{
test: /\.js$/,
// exclude: /node_modules/,
use: [{
loader: 'happypack/loader?id=happybabel'
}]
},
plugins: [
new happyPack({
id: 'happybabel',
loaders: [{
loader: 'babel-loader?cacheDirectory=true',
}],
verbose: true,
// 共享程式池
threadPool: happyThreadPool
})
]
複製程式碼
(4). 提取runtime 程式碼
webpack4新增的 optimization.runtimeChunk 和 optimization.splitChunks用來替代 webpack3 中 commonsChunkPlugin 進行程式碼分割
optimize: {
runtimeChunk: {
name: 'manifest'
}
},
//剩餘拆分第三方程式碼可以利用 optimization.splitChunks 配置
複製程式碼
(5). 動態連結庫DLL
第三方程式碼 比如react vue vue-router等除了版本更迭,剩下不會有太大變化,所以可以將其放到 dll 動態連結庫中,優化打包速率。
1). build目錄下新建 webpack.dll.config.js 並配置
const webpack = require('webpack')
const path = require('path')
const CleanWebpackPlugin = require("clean-webpack-plugin");
module.exports = {
entry: {
vendors: ['vue']
},
output: {
filename: '[name].[hash:5].dll.js',
// 存放dll庫
path: path.resolve(__dirname, "../src/assets/dll"),
// 動態連結庫全域性變數名稱
library: "_dll_[name]"
},
plugins: [
new CleanWebpackPlugin({
root: path.resolve(__dirname, "../src/assets/dll.js")
}),
new webpack.DllPlugin({
//需要和動態連結庫全域性變數名稱相同,因為通過全域性變數名稱找到相對應的第三方庫
name: '_dll_[name]',
path: path.resolve(__dirname,'[name].dll.manifest.json')
})
]
}
2). 在webpack.dev.config.js下
new webpack.DllReferencePlugin({
manifest: require('./vendors.dll.manifest.json')
}),
3) npm scrip中:
"dll": "webpack --mode production --config build/webpack.dll.config.js"
複製程式碼
先npm run dll 再進行npm run build打包,明顯可以看出打包的程式碼小的多。
(5) 提取css
webpack4利用 mini-css-extract-plugin 外掛
安裝並引用外掛即可
總結:
webpack更新版本太快,webpack5好像出來了,一切以官方文件為準複製程式碼