打包時,爲了直觀地發現項目中存在的問題,能夠在打包時生成報告。生成報告的方式有兩種:javascript
vue-cli
的命令選項能夠生成打包報告--report
選項能夠生成 report.html 以幫助分析包內容vue-cli-service build --report
經過 vue-cli 3.0 工具生成的項目,默認隱藏了全部 webpack 的配置項css
若是有修改 webpack 默認配置的需求,能夠在項目根目錄中,按需建立 vue.config.js 這個配置文件,從而對項目的打包發佈過程作自定義的配置
(具體配置參考:地址)。html
默認狀況下,Vue項目的開發模式與發佈模式,共用同一個打包的入口文件(即 src/main.js)。爲了將項目的開發過程與發佈過程分離,咱們能夠爲兩種模式,各自指定打包的入口文件,即:vue
在 vue.config.js 導出的配置對象中,新增 configureWebpack 或 chainWebpack 節點,來自定義 webpack 的打包配置。java
在這裏, configureWebpack 和 chainWebpack 的做用相同,惟一的區別就是它們修改 webpack 配置的方式不一樣:webpack
二者具體的使用差別,可參考以下網址:地址ios
module.exports = { chainWebpack: config => { config.when(process.env.NODE_ENV === 'production', config => { // entry默認打包入口 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') }) } }
默認狀況下,經過 import 語法導入的第三方依賴包,最終會被打包合併到同一個文件中,從而致使打包成功後,單文件體積過大的問題。web
爲了解決上述問題,能夠經過 webpack 的 externals
節點,來配置並加載外部的 CDN 資源。凡是聲明在externals
中的第三方依賴包,都不會被打包。vue-router
// vue.config.js config.set('externals', { vue: 'Vue', 'vue-router': 'VueRouter', axios: 'axios' })
// vue.config.js module.exports = { chainWebpack: config => { config.when(process.env.NODE_ENV === 'production', config => { // entry默認打包入口 config.entry('app').clear().add('./src/main-prod.js') config.set('externals', { vue: 'Vue', 'vue-router': 'VueRouter', axios: 'axios' }) }) config.when(process.env.NODE_ENV === 'development', config => { config.entry('app').clear().add('./src/main-dev.js') }) } }
須要在 public/index.html 文件的頭部,添加 CDN 資源引用:vue-cli
<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>
雖然在開發階段,咱們啓用了 element-ui 組件的按需加載,儘量的減小了打包的體積,可是那些被按需加載的組件,仍是佔用了較大的文件體積。此時,咱們能夠將 element-ui 中的組件,也經過 CDN 的形式來加載,這樣可以進一步減少打包後的文件體積。
<!-- element-ui 的 css 文件 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"/> <!-- element-ui 的 js 文件 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script>
不一樣的打包環境下,首頁內容可能會有所不一樣。咱們能夠經過插件的方式進行定製,插件配置以下:
module.exports = { chainWebpack: config => { // 發佈模式 config.when(process.env.NODE_ENV === 'production', config => { config.entry('app').clear().add('./src/main-prod.js') // 插件名稱 html tap修改插件的相關參數 args 是參數項 config.plugin('html').tap(args => { // 添加isProd自定義屬性 args[0].isProd = true return args }) }) // 開發模式 config.when(process.env.NODE_ENV === 'development', config => { config.entry('app').clear().add('./src/main-dev.js') 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 資源--> <% } %>
// public/index.html <!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" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <title><%= htmlWebpackPlugin.options.isProd ? '':'dev -' %>Emrof記錄</title> <!-- 是否加載CDN資源 --> <% if(htmlWebpackPlugin.options.isProd){ %> <!-- element-ui 的 css 文件 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.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 type="text/javascript" src="https://cdn.jsdelivr.net/npm/wangeditor@latest/dist/wangEditor.min.js" ></script> <!-- element-ui 的 js 文件 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <% } %> </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> <!-- built files will be auto injected --> </body> </html>
當打包構建項目時,JavaScript 包會變得很是大,影響頁面加載。若是咱們能把不一樣路由對應的組件分割成不一樣的代碼塊,而後當路由被訪問的時候才加載對應組件,這樣就更加高效了。
具體須要 3 步:
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue') const Baz = () => import(/* webpackChunkName: "group-boo" */ './Baz.vue')
關於路由懶加載的詳細文檔,參考以下:地址
使用 gzip 能夠減少文件體積,使傳輸速度更快。
能夠經過服務器端使用 Express 作 gzip 壓縮。其配置以下:
// 安裝相應包 npm install compression -S // 導入包 const compression = require('compression'); // 啓用中間件 app.use(compression());
const express = require('express') // const expressJwt = require('express-jwt') const compression = require('compression'); // 建立服務器 const app = express() // gzip 壓縮 app.use(compression()); app.listen(8889, () => { console.log('服務器啓動成功!'); })