1. 項目優化
項目優化策略:
- 使用進度條nprogress
- 生成打包報告
- 第三方庫啟用 CDN
- Element-UI 組件按需加載
- 路由懶加載
- 首頁內容定制
① 使用進度條nprogress
在頁面加載過程中會在頂部有一個進度條去提示用戶,需要使用第三方包nprogress:
什么時候使用進度條呢?當我們發起了axios請求,即觸發了request攔截器,就展示進度條;如果出發了response攔截器,證明響應成功了,成功之后立即隱藏進度條。
在main.js入口文件中添加如下代碼:
② 生成打包報告
打包時,為了直觀地發現項目中存在的問題,可以在打包時生成報告。生成報告的方式有兩種:
- 通過命令行參數的形式生成報告
// 通過 vue-cli 的命令選項可以生成打包報告 // --report 選項可以生成 report.html 以幫助分析包內容 vue-cli-service build --report
- 通過可視化的UI面板直接查看報告( 推薦)
在可視化的UI面板中,通過控制台和分析面板,可以方便地看到項目中所存在的問題。
運行npm run build命令,就會生成一個dist目錄,該目錄下的代碼就是用於生產環境下發布的。
在項目發布階段,不允許有console.log()代碼,這只是用於開發階段方便我們調試的。
我們希望在運行階段npm run serve,能夠正常的打印一些信息,但是在build階段不希望打印對應的console。此時我們就需要對我們的項目單獨的進行配置。我們可以使用Babel的插件,在項目build階段,把所有的console都移除掉:babel-plugin-transform-remove-console
在babel.config.js文件中添加下面這行代碼:
但是有一個問題,因為babel.config.js是全局配置文件,不管是開發階段還是發布階段都會生效。那如何解決呢?
如何獲取到mode值來區分是開發階段還是發布階段呢?
③ 通過 vue.config.js 修改 webpack 的默認配置
通過 vue-cli 3.0 工具生成的項目,默認隱藏了所有 webpack 的配置項,目的是為了屏蔽項目的配置過程,讓程序員把工作的重心,放到具體功能和業務邏輯的實現上。
如果程序員有修改 webpack 默認配置的需求,可以在項目根目錄中,按需創建 vue.config.js 這個配置文件,從而對項目的打包發布過程做自定義的配置( 具體配置參考 https://cli.vuejs.org/zh/config/#vue-config-js)。
// vue.config.js // 這個文件中,應該導出一個包含了自定義配置選項的對象 module.exports = { // 選項... }
④ 為開發模式與發布模式指定不同的打包入口
默認情況下, Vue項目的開發模式與發布模式,共用同一個打包的入口文件(即 src/main.js)。為了將項目的開發過程與發布過程分離,我們可以為兩種模式,各自指定打包的入口文件,即:
- 開發模式的入口文件為 src/main-dev.js
- 發布模式的入口文件為 src/main-prod.js
⑤ configureWebpack 和 chainWebpack
在 vue.config.js 導出的配置對象中,新增 configureWebpack 或 chainWebpack 節點,來自定義 webpack的打包配置。
在這里, configureWebpack 和 chainWebpack 的作用相同,唯一的區別就是它們修改 webpack 配置的方式不同:
- chainWebpack 通過鏈式編程的形式,來修改默認的 webpack 配置
- configureWebpack 通過操作對象的形式,來修改默認的 webpack 配置
兩者具體的使用差異,可參考如下網址:https://cli.vuejs.org/zh/guide/webpack.html#webpack-%E7%9B%B8%E5%85%B3
⑥ 通過 chainWebpack 自定義打包入口
代碼示例如下:
entry代表默認的打包入口文件名稱(dist目錄中的入口文件),clear表示清空默認的打包入口,add表示添加新的打包入口文件
module.exports = { chainWebpack: config => { config.when(process.env.NODE_ENV === 'production', config => { config.entry('app').clear().add('./src/main-prod.js') }) config.when(process.env.NODE_ENV === 'development', config => { config.entry('app').clear().add('./src/main-dev.js') }) } }
⑦ 通過 externals 加載外部 CDN 資源
默認情況下,通過 import 語法導入的第三方依賴包,最終會被打包合並到同一個文件中,從而導致打包成功后,單文件體積過大的問題。
默認導入的幾個第三方依賴包都會合並到第一個js文件中去,就會導致該js文件過大。如果將這些可以拆出去的依賴項給生成到external節點中去,在打包期間,會先檢查我們程序員有沒有在external中聲明一些第三方依賴包,如果有,則webpack不會把這些依賴包打包合並到第一個js文件中去,而是在用到這些依賴包時,直接在window全局對象中去找現成的對象使用。external節點就是可以排除某些依賴項,讓它們不被打包到最終的文件里去。
為了解決上述問題,可以通過 webpack 的 externals 節點,來配置並加載外部的 CDN 資源。凡是聲明在externals 中的第三方依賴包,都不會被打包。
具體配置代碼如下:
config.set('externals', { vue: 'Vue', 'vue-router': 'VueRouter', axios: 'axios', lodash: '_', echarts: 'echarts', nprogress: 'NProgress', 'vue-quill-editor': 'VueQuillEditor' })
同時,需要在 public/index.html 文件的頭部,添加如下的 CDN 資源引用:
<!-- nprogress 的樣式表文件 --> <link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" /> <!-- 富文本編輯器 的樣式表文件 --> <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css" /> <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css" /> <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css" />
<script src="https://cdn.staticfile.org/vue/2.5.22/vue.min.js"></script> <script src="https://cdn.staticfile.org/vue-router/3.0.1/vue-router.min.js"></script> <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script> <script src="https://cdn.staticfile.org/lodash.js/4.17.11/lodash.min.js"></script> <script src="https://cdn.staticfile.org/echarts/4.1.0/echarts.min.js"></script> <script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script> <!-- 富文本編輯器的 js 文件 --> <script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.4/dist/vue-quill-editor.js"></script>
在main-prod.js文件中import導入的樣式表最終也會合並到最終的文件中去,所以需要刪除,在public下面的index.html中引入:
凡是在打包期間,如果發現下面這個,它會直接去window全局對象下面查找下面的對象,為了保證window全局對象中包含下面這些對象 ,我們需要把對應的css和js文件全部放在靜態資源的index.html的頭部引用
⑧ 通過 CDN 優化 ElementUI 的打包
雖然在開發階段,我們啟用了 element-ui 組件的按需加載,盡可能的減少了打包的體積,但是那些被按需加載的組件,還是占用了較大的文件體積。此時,我們可以將 element-ui 中的組件,也通過 CDN 的形式來加載,這樣能夠進一步減小打包后的文件體積。
具體操作流程如下:
- 在 main-prod.js 中,注釋掉 element-ui 按需加載的代碼
- 在 index.html 的頭部區域中,通過 CDN 加載 element-ui 的 js 和 css 樣式
<!-- element-ui 的樣式表文件 --> <link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.8.2/themechalk/index.css" /> <!-- element-ui 的 js 文件 --> <script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script>
注釋掉main-prod.js文件中引入的element文件:
體積比較大的幾個文件都優化的比較小了:
⑨ 首頁內容定制
不同的打包環境下,首頁內容可能會有所不同。我們可以通過插件的方式進行定制,插件配置如下:
chainWebpack: config => { config.when(process.env.NODE_ENV === 'production', config => { config.plugin('html').tap(args => { args[0].isProd = true return args }) }) config.when(process.env.NODE_ENV === 'development', config => { config.plugin('html').tap(args => { args[0].isProd = false return args }) }) }
在不同的開發環境下顯示不同的標題:
在 public/index.html 首頁中,可以根據 isProd 的值,來決定如何渲染頁面結構:
<!-- 按需渲染頁面的標題 --> <title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>電商后台管理系統</title> <!-- 按需加載外部的 CDN 資源 --> <% if(htmlWebpackPlugin.options.isProd) { %> <!-- 通過 externals 加載的外部 CDN 資源--> <% } %>
如果處於開發模式,就沒必要加載這些外部cdn資源,開發模式的資源都是通過import導入到項目中使用的
<%= %>表示輸出的意思
<% %>表示寫我們正常的語句
⑩ 路由懶加載
當打包構建項目時, JavaScript 包會變得非常大,影響頁面加載。如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就更加高效了。
具體需要 3 步:
- 安裝 @babel/plugin-syntax-dynamic-import 包。
- 在 babel.config.js 配置文件中聲明該插件。
- 將路由改為按需加載的形式,示例代碼如下:
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue') const Baz = () => import(/* webpackChunkName: "group-boo" */ './Baz.vue')
關於路由懶加載的詳細文檔,可參考如下鏈接: https://router.vuejs.org/zh/guide/advanced/lazy-loading.html
第一步,安裝懶加載的依賴包:
第二步,將插件配置到項目中去:
第三步,將所有的組件導入方式都改造為懶加載的導入方式:
2. 項目上線
項目上線相關配置:
- 通過 node 創建 web 服務器
- 開啟 gzip 配置
- 配置 https 服務
- 使用 pm2 管理應用
① 通過 node 創建 web 服務器
創建 node 項目,並安裝 express,通過 express 快速創建 web 服務器,將 vue 打包生成的 dist 文件夾,托管為靜態資源即可,關鍵代碼如下:
const express = require('express') // 創建 web 服務器 const app = express() // 托管靜態資源 app.use(express.static('./dist')) // 啟動 web 服務器 app.listen(80, () => { console.log('web server running at http://127.0.0.1') })
然后執行node app.js啟動服務器
② 開啟 gzip 配置
使用 gzip 可以減小文件體積, 使傳輸速度更快。
可以通過服務器端使用 Express 做 gzip 壓縮。其配置如下:
// 安裝相應包 npm install compression -S // 導入包 const compression = require('compression'); // 啟用中間件 app.use(compression());
③ 配置 HTTPS 服務
為什么要啟用 HTTPS 服務?
- 傳統的 HTTP 協議傳輸的數據都是明文,不安全
- 采用 HTTPS 協議對傳輸的數據進行了加密處理,可以防止數據被中間人竊取,使用更安全
申請 SSL 證書( https://freessl.org)
- 進入 https://freessl.cn/ 官網,輸入要申請的域名並選擇品牌。
- 輸入自己的郵箱並選擇相關選項。
- 驗證 DNS(在域名管理后台添加 TXT 記錄)。
- 驗證通過之后, 下載 SSL 證書( full_chain.pem 公鑰; private.key 私鑰)。
在后台項目中導入證書
const https = require('https'); const fs = require('fs'); const options = { cert: fs.readFileSync('./full_chain.pem'), key: fs.readFileSync('./private.key') } https.createServer(options, app).listen(443);
④ 使用 pm2 管理應用
如果我們把開啟服務器的終端窗口關閉掉,那我們的網站服務就停止了,我們就不能訪問網站了。但是如果我們在服務器上保留很多的終端窗口就很難管理,如果我們在關閉終端之后,網站還能正常的訪問,如何解決呢?
- 在服務器中安裝 pm2: npm i pm2 -g
- 啟動項目: pm2 start 腳本 --name 自定義名稱
- 查看運行項目: pm2 ls
- 重啟項目: pm2 restart 自定義名稱
- 停止項目: pm2 stop 自定義名稱
- 刪除項目: pm2 delete 自定義名稱
然后關掉終端,網站仍可以繼續訪問。
代碼地址:https://github.com/Emliy-zcy/Backstage-Management-System-Based-on-vue