Vue-cli5
Vue CLI 是一個基於 Vue.js 進行快速開發的完整系統,提供:
- 透過 @vue/cli 實現的互動式的專案腳手架。
- 透過 @vue/cli + @vue/cli-service-global 實現的零配置原型開發。
- 一套完全圖形化的建立和管理 Vue.js 專案的使用者介面
安裝依賴
npm install
如果本地網路卡頓,使用臨時映象,當命令列視窗關閉即失效
npm --registry http://mirrors.cloud.tencent.com/npm/ install express
開發模式
npm run dev
or
npm run serve
打包模式
npm run build
自動上傳
需要在gulpfile.js
配置伺服器資訊
npm run upload
專案配置功能
- ✅開啟檔案Gzip壓縮
- ✅編譯去掉註釋
- ✅開發服務配置
- ✅編輯器別名設定
- ✅配置環境變數
- ✅多頁面應用配置
- ✅請求路由動態新增
- ✅網路請求封裝
- ✅網路異常重連
- ✅配置全域性less
- ✅開啟分析打包日誌
- ✅打包進度
- ✅全域性元件通訊
- ✅注入全域性變數
- ✅打包CDN替換NPM包
- ✅複製檔案
- ✅新增可選鏈運運算元
- ✅抽離重複檔案合併
- ✅配置px轉換rem
- ✅動態修改主題
- ✅自動上傳伺服器
- ✅Nginx配置
- ✅全域性事件通訊
完整配置
開啟檔案Gzip壓縮
config.plugin('CompressionPlugin')
.use('compression-webpack-plugin', [{
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240, // 只處理比這個值大的資源。按位元組計算
minRatio: 0.8 // 只有壓縮率比這個值小的資源才會被處理
}])
編譯去掉註釋
config.optimization.minimizer[TerserPluginIndex] = new TerserPlugin({
terserOptions: {
warnings: false,
format: {
comments: false,
},
compress: {
drop_debugger: true, // 註釋console
drop_console: true,
pure_funcs: ['console.log'], // 移除console
},
},
extractComments: false, // 是否將註釋提取到一個單獨的檔案中
parallel: true, // 是否並⾏打包
});
開發服務配置
module.exports = {
devServer: {
open: false, // 自動啟動瀏覽器
host: "0.0.0.0",
port: 9007, // 埠號
proxy: {
"/api": {
target: "https://www.api.com", // 目標代理介面地址
pathRewrite: {
"^/api": "/"
}
}
},
hot: true,// 熱更新
headers: {
'Access-Control-Allow-Origin': '*', // 微前端應用除錯
},
}
}
編輯器別名設定
放置在根目錄下,檔名為jsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
],
"__ROOT__/*": [
"*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
配置環境變數
放置在根目錄下,.env.development
、.env.production
、.env.test
,等等模式檔案
命令切換
vue-cli-service build --mode development
vue-cli-service build --mode production
vue-cli-service build --mode test
配置環境檔案
.env # 在所有的環境中被載入
.env.local # 在所有的環境中被載入,但會被 git 忽略
.env.[mode] # 只在指定的模式中被載入
.env.[mode].local # 只在指定的模式中被載入,但會被 git 忽略
多頁面應用配置
module.exports = {
pages: {
index: {
// page 的入口
entry: 'src/index/main.js',
// 模板來源
template: 'public/index.html',
// 在 dist/index.html 的輸出
filename: 'index.html',
// 當使用 title 選項時,
// template 中的 title 標籤需要是 <title><%= htmlWebpackPlugin.options.title %></title>
title: 'Index Page',
// 在這個頁面中包含的塊,預設情況下會包含
// 提取出來的通用 chunk 和 vendor chunk。
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
// 當使用只有入口的字串格式時,
// 模板會被推導為 `public/subpage.html`
// 並且如果找不到的話,就回退到 `public/index.html`。
// 輸出檔名會被推導為 `subpage.html`。
subpage: 'src/subpage/main.js'
}
}
網路請求封裝
檔案放置http/request.js
- 基於axios封裝
- 網路請求攔擊
- 網路響應攔截
- 封裝常用post、get、upload、download、併發請求
const http = axios.create({
timeout: 1000 * 60,
withCredentials: true, // 表示跨域請求時是否需要 使用憑證
headers: {
"Content-Type": "application/json",
}
});
網路異常重連
基於axios發生異常重連
config.reconnectCount = config.reconnectCount || 1;
if (config.reconnectCount >= 3) { // 檢查重試次數是否達到最大值
return Promise.reject(error)
}
const backoff = new Promise(function (resolve) { // 建立新的Promise來處理
setTimeout(function () {
resolve()
}, 2000)
})
config.reconnectCount += 1 // 增加重試次數
return backoff.then(function () { // 返回promise,其中呼叫axios來重試請求
return http(config)
})
配置全域性less
module.exports = {
css: {
loaderOptions: {
less: {
lessOptions: {
javascriptEnabled: true,
modifyVars: {}, // 這裡也闊以宣告less變數
},
additionalData: ` @import "~@/assets/css/variables.less";`,
},
}
},
}
開啟分析打包日誌
npm i webpack-bundle-analyzer -D
const WebpackBundleanAlyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
plugins.push(new WebpackBundleanAlyzer({analyzerPort: 9601}))
打包進度
npm i webpackbar -D
const WebpackBar = require('webpackbar');
plugins.push(new WebpackBar({name: 'PC', color: '#07c160'}))
全域性元件通訊
npm i mitt -S
import mitt from 'mitt'
app.provide('$mitt', mitt())
注入全域性變數
new webpack.DefinePlugin({
__APP__: JSON.stringify({
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
})
})
// 在Vue單頁面中
console.log(lastBuildTime) // 2023-02-23 20:22:48
打包CDN替換NPM包
使用vue inspect --plugins檢視html是否在結果陣列中
// 見多頁面應用
Object.keys(pages).forEach(key => {
config.plugin(`html-${key}`).tap(args => {
args[0].cdn = isBuild ? cdn.build : cdn.dev;
return args;
});
})
// 單頁面應用
config.plugin(`html`).tap(args => {
args[0].cdn = isBuild ? cdn.build : cdn.dev;
return args;
});
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vue-cli5模板</title>
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"/>
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script type="text/javascript" src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
</body>
</html>
複製檔案
npm i copy-webpack-plugin -D
const CopyWebpackPlugin = require('copy-webpack-plugin')
plugins.push(new CopyWebpackPlugin({
patterns: [
{from: resolve('./README.md'), to: resolve('./dist')}
],
options: {concurrency: 100}, // 併發數
}))
新增可選鏈運運算元
npm i @babel/plugin-proposal-optional-chaining -D
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
"@babel/plugin-proposal-optional-chaining" // 新增該外掛
]
}
抽離重複檔案合併
config.optimization.splitChunks({
cacheGroups: {
styles: {
name: 'styles',
test: /\.(s?css|less|sass)$/,
chunks: 'all',
priority: 10
},
common: {
name: 'chunk-common',
chunks: 'all',
minChunks: 2, // 拆分前必須共享模組的最小 chunks 數。
maxInitialRequests: 5, // 打包後的入口檔案載入時,還能同時載入js檔案的數量(包括入口檔案)
minSize: 0, // 生成 chunk 的最小體積
priority: 1, // 最佳化將優先考慮具有更高 priority(優先順序)的快取組
reuseExistingChunk: true // 如果當前 chunk 包含已從主 bundle 中拆分出的模組,則它將被重用,而不是生成新的模組
},
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
chunks: 'all',
priority: 2,
reuseExistingChunk: true
},
}
})
配置px轉換rem
npm i postcss-pxtorem -D
npm i lib-flexible -S
在入口檔案引入
import 'lib-flexible/flexible'
在根目錄新建.postcssrc.js
檔案
module.exports = {
plugins: {
'postcss-pxtorem': {
rootValue: 37.5, //換算基數,
unitPrecision: 3, //允許REM單位增長到的十進位制數字,小數點後保留的位數。
propList: ['*'],
exclude: /(node_module)/, //預設false,可以(reg)利用正規表示式排除某些資料夾的方法,例如/(node_module)/ 。如果想把前端UI框架內的px也轉換成rem,請把此屬性設為預設值
selectorBlackList: ['.van'], //要忽略並保留為px的選擇器,本專案我是用的vant ui框架,所以忽略他
mediaQuery: false, //(布林值)允許在媒體查詢中轉換px。
minPixelValue: 1 //設定要替換的最小畫素值
}
}
}
動態修改主題
<template>
<a-config-provider>
<router-view></router-view>
</a-config-provider>
</template>
<script setup>
import {ConfigProvider} from 'ant-design-vue';
ConfigProvider.config({
theme: {
primaryColor: '#25b864',
},
});
</script>
自動上傳伺服器
執行命令
npm run upload
配置自己的伺服器賬號和密碼
const gulp = require("gulp")
const ftp = require("gulp-ftp");
//伺服器配置資訊
const serverSeting = {
host: "伺服器域名",
port: 21, //虛擬主機預設21,伺服器預設22
user: "使用者名稱",
pass: "密碼",
remotePath: "/dist/"
};
//把打包好的檔案上傳到伺服器
gulp.task("server", () => {
// 遠端目錄
return gulp.src("/home/usr/www/**/*").pipe(ftp(serverSeting));
});
gulp.task('upload', gulp.series('server'))
Nginx配置
nginx常用的操作命令
#修改配置reload後看服務啟動是否正常
nginx -t;
#過載nginx
nginx reload
#啟動 nginx
start nginx
#重啟 nginx
nginx -s reload
#快速停止 nginx
nginx -s stop
#完整有序地停止 nginx
nginx -s quit
這裡列舉一份比較常用的nginx配置,具體的實際,需要看具體
server {
listen 9999; # 監聽埠
server_name localhost; # 域名可以有多個,用空格隔開
location / {
root C:\工作\project\client_admin_system\dist; #站點根目錄,即網頁檔案存放的根目錄, 預設主頁目錄在nginx安裝目錄的html子目錄。
index index.html index.htm; #目錄內的預設開啟檔案,如果沒有匹配到index.html,則搜尋index.htm,依次類推
}
# 反向代理
location /api {
rewrite ^.+api/?(.*)$ /$1 break;
proxy_pass http://192.168.1.100:7001; #node api server 即需要代理的IP地址
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#error_page 404 /404.html; #對錯誤頁面404.html 做了定向配置
# redirect server error pages to the static page /50x.html
#將伺服器錯誤頁面重定向到靜態頁面/50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
UI元件
修改css變數
document.documentElement.style.setProperty('--primary-color', 'red');
如果使用Vue-cli3搭建的專案請看
一份完整的Vue-cli3專案基礎配置項如果使用Vite搭建的專案請看
一份完整的Vite3專案基礎配置項