vue-cli3多頁應用配置與優化


項目背景

  • 公司的活動項目太多,每一個項目都要單獨配置部署環境太麻煩,所以創建了一個倉庫,src/pages/下面的每一個文件夾都是是一個項目
  • 優點是
     * 這樣就可以使用一個git倉庫,一個jenkins配置,很方便
     * 不需要多次配置域名和nginx服務
  • 缺點是
     * 該倉庫下的任何一個項目發布,其他的項目如果有變更也會一起發布了。這需要在發布項目前,review代碼,減少馬虎改寫了其他項目的代碼,引起不必要的線上bug
     * 修改了配置文件,發布后可能會影響src/pages/下的其他的線上項目,所以修改公共文件,配置文件都要注意,可以全局搜索下該文件被哪些項目引用,如果其他地方也引用了該文件,修改該文件就要慎重且通知測試來測試這塊改動。如utils文件下的公共js,很多項目都引用了。如果修改的是這類文件,review代碼的人也需要注意這塊代碼的改動
     * 針對上面的問題,其實有些公共文件可以抽取出來,放在git倉庫,使用tag引用,這樣就能減少上面的問題

項目准備

  • 技術框架:vue-cli3
  • 按照vue-cli3官方文檔搭建項目
  • 添加vue.config.js修改打包配置,滿足多頁面打包要求
  • 添加.env.development、.env.test、.env.beta、.env.production文件(環境變量)
  • 修改后的框架代碼可以參考 vue-cli3-mpa-spa
  • 詳細說明可以看REANDE.md里面的說明

第一版的vue.vonfig.js里面的代碼如下

let path = require('path')
let glob = require('glob')
 
function resolve (dir) {
    return path.join(__dirname, dir)
}
 
let pageNum=0
 
//配置pages多頁面獲取當前文件夾下的html和js
function getEntry(globPath) {
    let [entries,basename]=[{},'']

    glob.sync(globPath).forEach(function(entry,i) {
        basename = path.basename(entry, path.extname(entry));
        pathname = basename; // 正確輸出js和html的路徑
 
        let filename=entry.split('./src/pages/')[1]
        let middlePath=filename.split('/index.html')[0]
        let dirList=middlePath.split("/")
 

        entries[i+'-'+dirList[dirList.length-1]] = {
            entry: 'src/pages/' + middlePath + '/main.js',
            template: 'src/pages/' + middlePath + '/index.html',
            filename,
        }
  pageNum=i
    })
 
    return entries
}
 
let pages = getEntry('./src/pages/**/index.html');
 
module.exports = {
    css: {
        // 是否使用css分離插件 ExtractTextPlugin
        extract: true,
        // 開啟 CSS source maps?
        sourceMap: false,
        // css預設器配置項
        loaderOptions: {},
        // 啟用 CSS modules for all css / pre-processor files.
        modules: false
    },
 
    devServer: {
        disableHostCheck: true
    },
 
    chainWebpack: (config)=>{
        config.resolve.alias
            .set('@', resolve('src'))
            .set('assets',resolve('src/assets'))
            .set('components',resolve('src/components'))
            .set('utils',resolve('src/utils'))
            .set('api',resolve('src/api'))
    },
 
    pages
    
}

出現的問題

1、圖片過大,影響訪問速度,如src/pages/mpa-one/detail/App.vue里面引入的圖片,源文件是12MB,dist/img/map-one-details.png還是12MB

先看下vue-cli3默認對圖片做了哪些處理

執行npm run inspect或npm run inspectwebpack(package.json的srcipt字段里面配置的命令)

/* npm run inspect操作和npm run inspectwebpack的區別是前者將webpack文件打印在命令行里,后者將webpack文件打印在output.js(沒有該文件會自動創建並將內容寫入output.js)里面*/
/* 執行命令完成后,可以看到webapck打包文件,在module.rules里面看到關於image的配置,代碼如下,沒有做壓縮配置*/
/* config.module.rule('images') */
{
    test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,    
    use: [
        /* config.module.rule('images').use('url-loader') */
        {
            loader: 'url-loader',
            options: {
                limit: 4096,
                fallback: {
                    loader: 'file-loader',
                    options: {
                        name: 'img/[name].[hash:8].[ext]'
                    }
                }
            }
        }
    ]
}

解決方案:

a、對於項目中的圖片(尤其是大圖片)可以使用壓縮網站先壓縮一下
b、添加圖片壓縮配置,執行npm install image-webpack-loader --save-dev,在vue.config.js里面的chainWebpack字段里添加如下配置
先在命令行安裝插件npm i image-webpack-loader --D

config.module
    .rule('images')
    .use('image-webpack-loader')
    .loader('image-webpack-loader')

添加上述配置后再執行npm run build后看下dist里面的圖片發現從12MB降到2.88MB
將src/pages/mpa-one/detail/App.vue里面的圖片在網站上壓縮一下(從12MB到1.71MB),在src/pages/mpa-one/list/App.vue里面引入,再執行npm run build 發現從1.71MB降到1.54MB

注意圖片的引用問題

在 JavaScript 被導入或在 template/CSS 中通過相對路徑(./或../或@(別名,其他別名在vue.config.js里面添加)/)被引用。這類引用會被 webpack 處理。
放置在 public 目錄下或通過絕對路徑(/或http:xxxxx)被引用。這類資源將會直接被拷貝,而不會經過 webpack 的處理。
demo在src/mpa-one/detail/index.html

2、dist/js/chunk-vendor.js和chunk-common.js過大的問題

該問題是公司的項目中發現的,代碼就不貼出來了,vue.config.js里面的代碼是一樣的,src/pages/里面的內容不一樣,打包結果會以截圖的形式展示出來,項目里有單頁面應用也有多頁面應用,所以,下面的案例都會選這兩種案例展示說明

單頁面路由頁面(總的js大小為256.3KB)

多頁面(總的js大小為196.3KB)

可以看到這兩個項目都引入了chunk-vendor.js(177KB)和chunk-common.js(8.6KB)

chunk-vendor.js(177KB)和chunk-common.js(8.6KB)是什么?chunk-vendor.js為什么這個大?

原因:

上面的項目背景已經給大家說明了,因為這個倉庫的src/pages/下面的每一個文件夾都是一個活動項目,項目很多,vue.config.js里面除了將單頁面入口改為多頁面入口,添加了圖片壓縮,其他的打包機制都沒有修改
現有的打包機制適用單頁面應用,會將src/pages/下面所有的html頁面使用到的滿足條件的第三方的靜態資源(node_modules)打包到dist/js/chunk-vendor.js里面,和將滿足條件的除了打到chunk-vendor.js里面的其他靜態模塊(node_modules和其他的項目中的文件如utils文件資源)打到dist/js/chunk-common.js里面,最后將每個頁面剩下的js邏輯打到dist/js/xxx(頁面的名字).js每個頁面引入的是chunk-vendor.js、chunk-common.js和xxx(頁面的名字).js,如果是單頁面路由頁面,使用了路由懶加載,頁面還會有一些模塊js如(dist/js/chunk-xxx.js)。

倉庫里面放置的不是一個項目,所以隨着項目越來越大,chunk-vendor.js和chunk-common.js會越來越大,每個頁面引入的多余的代碼會越來越多,所以對於這個問題,做了多頁面打包的處理。修改內容為,將每個頁面都引入的第三方庫作為提取到dist/js/chunk-vendor.js,刪除chunk-common.js(去掉默認配置common),將每個頁面剩余的js打包到dist/js/xxx(頁面的名字).js。這樣頁面就不會引入多余的js文件了

針對這個問題,對vue.config.js的chainWebpack字段添加下面的代碼

做如下修改

 // 公共資源提取,
 // vendors提取的是第三方公共庫(滿足提取規則的node_modules里面的且頁面引入的),這些文件會打到dist/js/chunk-vendors.js里面
 // 提取規則是每個頁面都引入的才會打到chunk-vendors.js里面(如vue.js)
 // 控制條件是minChunks字段,所以該字段的值是當前activity/src/projects里面的html的個數
 // common提取的應該是除了vendors提取后,剩余的滿足條件的公共靜態模塊
 // 我們的項目不需要common,所以將common置為{},覆蓋默認common配置
 config.optimization.splitChunks({
    cacheGroups: {
        vendors: {
            name: 'chunk-vendors',
            minChunks: pageNum,
            test: /node_modules/,
            priority: -10,
            chunks: 'initial'
        },
        common: {}
     }
});

再次執行打包命令

單頁面路由頁面(總的js大小為161.6KB)

多頁面(總的js大小為167.9KB)

可以看到優化后的頁面總資源大小比沒有優化之前的小了

spa頁面js(256.3KB => 161.6KB)
mpa頁面js(196.3KB => 167.9KB)

經過優化,頁面的js還是挺大的,查看項目,發現spa頁面有引入vconsole工具,用於調試的,所以配置下在生產環境不引入該工具
spa和mpa都引入了一個modal的組件(彈框),該組件里面有引入jquery,用的jquery很少,所以可以將jquery去掉,用原生的代碼實現

vconsole優化:由於每個頁面測試環境都需要引入該包用於調試,在每個頁面引入很麻煩,所以,可以在vue.config.js里面配置,代碼如下
先在命令行里面安裝npm install vconsole-webpack-plugin --save-dev
  

  const vConsolePlugin = require('vconsole-webpack-plugin');
  //開發環境
  let pluginsDev = [
    //移動端模擬開發者工具
    new vConsolePlugin({
      filter: [], // 需要過濾的入口文件
      enable: true 
    }),
  ];

  
  if(process.env.NODE_ENV !== 'production') {
    config.plugins = [...config.plugins, ...pluginsDev];
  }

再將頁面的jquery去掉,改用原生js寫法,再執行npm run build打包部署到服務器后

spa頁面

mpa頁面

可以看到優化后的頁面總資源大小比沒有優化之前的小了

經過上面的優化,頁面的js總資源數字如下
spa頁面js(161.6KB => 106.2KB)
mpa頁面js(167.9KB => 137.9KB)

上面兩次優化后

spa頁面js(256.3KB => 106.2KB)減少了150KB
mpa頁面js(196.3KB => 137.9KB)減少了60KB

另外訪問我們公司的集成環境和beta環境(非生產環境)發現js文件都是很大的,不是gzip包

生產環境的js不大,因為服務器配置的問題,生產環境配置了使用gzip的文件,如圖response header里面的content-encoding的值是gzip,非生產環境沒有這個字段,如果服務器配置了,是會有的

上面所述如有問題,評論里幫我指出,呃呃....第一次寫博客,寫博客也挺累的啊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM