zoukankan      html  css  js  c++  java
  • 记一次vue-cli 3.0 build包太大导致首屏过长的解决方案

    1、路由懒加载

    在 Webpack  中,我们可以使用动态 import语法来定义代码分块点 (split point): import('./Foo.vue') // 返回 Promise
    
    如果您使用的是 Babel,你将需要添加 syntax-dynamic-import 插件,才能使 Babel 可以正确地解析语法。
    
    结合这两者,这就是如何定义一个能够被 Webpack 自动代码分割的异步组件。
    
    const Foo = () => import('./Foo.vue')
    
    在路由配置中什么都不需要改变,只需要像往常一样使用 Foo:
    
    const router = new VueRouter({
      routes: [
        { path: '/foo', component: Foo }
      ]
    })
    
    复制代码

    2、服务器和webpack打包同时配置Gzip

    Gzip是GNU zip的缩写,顾名思义是一种压缩技术。它将浏览器请求的文件先在服务器端进行压缩,然后传递给浏览器,浏览器解压之后再进行页面的解析工作。在服务端开启Gzip支持后,我们前端需要提供资源压缩包,通过Compression-Webpack-Plugin插件build提供压缩  
    
    // 安装插件
    
    cnpm i --save-dev compression-webpack-plugin
     
    // 在vue-config.js 中加入
    const CompressionWebpackPlugin = require('compression-webpack-plugin');
    const productionGzipExtensions = ['js', 'css'];
    const isProduction = process.env.NODE_ENV === 'production';
     
    .....
    module.exports = {
    ....
     // 配置webpack
     configureWebpack: config => {
      if (isProduction) {
       // 开启gzip压缩
       config.plugins.push(new CompressionWebpackPlugin({
        algorithm: 'gzip',
        test: /.js$|.html$|.json$|.css/,
        threshold: 10240,
        minRatio: 0.8
       }))
      }
     }
    }
    复制代码

    3、优化打包chunk-vendor.js文件体积过大

     当我们运行项目并且打包的时候,会发现chunk-vendors.js这个文件非常大,那是因为webpack将所有的依赖全都压缩到了这个文件里面,这时我们可以将其拆分,将所有的依赖都打包成单独的js。
    // 在vue-config.js 中加入
    .....
    module.exports = {
    ....
     // 配置webpack
     configureWebpack: config => {
      if (isProduction) {
        // 开启分离js
        config.optimization = {
          runtimeChunk: 'single',
          splitChunks: {
            chunks: 'all',
            maxInitialRequests: Infinity,
            minSize: 20000,
            cacheGroups: {
              vendor: {
                test: /[\/]node_modules[\/]/,
                name (module) {
                  // get the name. E.g. node_modules/packageName/not/this/part.js
                  // or node_modules/packageName
                  const packageName = module.context.match(/[\/]node_modules[\/](.*?)([\/]|$)/)[1]
                  // npm package names are URL-safe, but some servers don't like @ symbols
                  return `npm.${packageName.replace('@', '')}`
                }
              }
            }
          }
        };
      }
     }
    }
    // 至此,你会发现原先的vender文件没有了,同时多了好几个依赖的js文件  
    复制代码

    4、启用CDN加速

    用Gzip已把文件的大小减少了三分之二了,但这个还是得不到满足。那我们就把那些不太可能改动的代码或者库分离出来,继续减小单个chunk-vendors,然后通过CDN加载进行加速加载资源。
    // 修改vue.config.js 分离不常用代码库
    // 如果不配置webpack也可直接在index.html引入
    module.exports = {
     configureWebpack: config => {
      if (isProduction) {
       config.externals = {
        'vue': 'Vue',
        'vue-router': 'VueRouter',
        'moment': 'moment'
       }
      }
     }
    }
    // 在public文件夹的index.html 加载
    <!-- CND -->
    <script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.runtime.min.js"></script>
    <script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
    复制代码

    5、完整vue.config.js代码

    const path = require('path')
    
    // 在vue-config.js 中加入
    // 开启gzip压缩
    const CompressionWebpackPlugin = require('compression-webpack-plugin');
    // 判断开发环境
    const isProduction = process.env.NODE_ENV === 'production';
    
    const resolve = dir => {
      return path.join(__dirname, dir)
    }
    
    // 项目部署基础
    // 默认情况下,我们假设你的应用将被部署在域的根目录下,
    // 例如:https://www.my-app.com/
    // 默认:'/'
    // 如果您的应用程序部署在子路径中,则需要在这指定子路径
    // 例如:https://www.foobar.com/my-app/
    // 需要将它改为'/my-app/'
    // iview-admin线上演示打包路径: https://file.iviewui.com/admin-dist/
    const BASE_URL = process.env.NODE_ENV === 'production'
      ? '/'
      : '/'
    
    module.exports = {
      //webpack配置
      configureWebpack:config => {
        // 开启gzip压缩
        if (isProduction) {
          config.plugins.push(new CompressionWebpackPlugin({
            algorithm: 'gzip',
            test: /.js$|.html$|.json$|.css/,
            threshold: 10240,
            minRatio: 0.8
          }));
          // 开启分离js
          config.optimization = {
            runtimeChunk: 'single',
            splitChunks: {
              chunks: 'all',
              maxInitialRequests: Infinity,
              minSize: 20000,
              cacheGroups: {
                vendor: {
                  test: /[\/]node_modules[\/]/,
                  name (module) {
                    // get the name. E.g. node_modules/packageName/not/this/part.js
                    // or node_modules/packageName
                    const packageName = module.context.match(/[\/]node_modules[\/](.*?)([\/]|$)/)[1]
                    // npm package names are URL-safe, but some servers don't like @ symbols
                    return `npm.${packageName.replace('@', '')}`
                  }
                }
              }
            }
          };
          // 取消webpack警告的性能提示
          config.performance = {
            hints:'warning',
                //入口起点的最大体积
                maxEntrypointSize: 50000000,
                //生成文件的最大体积
                maxAssetSize: 30000000,
                //只给出 js 文件的性能提示
                assetFilter: function(assetFilename) {
              return assetFilename.endsWith('.js');
            }
          }
        }
      },
      // Project deployment base
      // By default we assume your app will be deployed at the root of a domain,
      // e.g. https://www.my-app.com/
      // If your app is deployed at a sub-path, you will need to specify that
      // sub-path here. For example, if your app is deployed at
      // https://www.foobar.com/my-app/
      // then change this to '/my-app/'
      publicPath: BASE_URL,
      // tweak internal webpack configuration.
      // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
      devServer: {
        host: 'localhost',
        port: 8080, // 端口号
        hotOnly: false,
        https: false, // https:{type:Boolean}
        open: true, //配置自动启动浏览器
        proxy:null // 配置跨域处理,只有一个代理
    
      },
      // 如果你不需要使用eslint,把lintOnSave设为false即可
      lintOnSave: true,
      css:{
        loaderOptions:{
          less:{
            javascriptEnabled:true
          }
        },
        extract: true,// 是否使用css分离插件 ExtractTextPlugin
        sourceMap: false,// 开启 CSS source maps
        modules: false// 启用 CSS modules for all css / pre-processor files.
      },
      chainWebpack: config => {
        config.resolve.alias
          .set('@', resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components'))
          .set('@c', resolve('src/components'))
      },
      // 打包时不生成.map文件
      productionSourceMap: false
      // 这里写你调用接口的基础路径,来解决跨域,如果设置了代理,那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串
      // devServer: {
      //   proxy: 'localhost:3000'
      // }
    }
  • 相关阅读:
    李宏毅强化学习完整笔记!开源项目《LeeDeepRL-Notes》发布
    做开源界的MATLAB,PyMiner 需要更多热爱开源的你加入
    开源翻译公告 2020.10.26:新上线了几个文档
    《线性代数》(同济版)——教科书中的耻辱柱
    Docker之四:容器之间通信
    Docker之二:linux下Docker安装
    Docker之三:Dockerfile镜像
    Docker之一:概念及命令
    idea使用之配置
    二、redis基本命令学习
  • 原文地址:https://www.cnblogs.com/love314159/p/14275666.html
Copyright © 2011-2022 走看看