zoukankan      html  css  js  c++  java
  • vuecli3多页应用配置与优化

    项目背景

    • 公司的活动项目太多,每一个项目都要单独配置部署环境太麻烦,所以创建了一个仓库,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,非生产环境没有这个字段,如果服务器配置了,是会有的

    上面所述如有问题,评论里帮我指出,呃呃....第一次写博客,写博客也挺累的啊

  • 相关阅读:
    Java数据结构与算法(15)
    SpringJMS解析--使用示例
    Java数据结构与算法(14)
    Java数据结构与算法(13)
    Java数据结构与算法(12)
    如何实践设计原则-面向对象设计原则
    软件架构的两大流派:组成派、决策派
    软件 可变与不可变 及封装可变性
    Java数据结构与算法(11)
    搭建本地yum仓库及自制rpm包(无需镜像)
  • 原文地址:https://www.cnblogs.com/HYZhou2018/p/10419703.html
Copyright © 2011-2022 走看看