关于vue.config.js的一些配置和一些打包性能优化

安装了一些插件如下:

npm i compression-webpack-plugin -D
npm i terser-webpack-plugin -D
npm i vue-cli-plugin-webpack-bundle-analyzer -D

优化方案:去除项目的所有的console.log和采用gzip压缩,依赖的cdn引入

const TerserPlugin = require('terser-webpack-plugin')
const CompressionWebpackPlugin = require('compression-webpack-plugin')

const buildcfg = {
  title: '这儿配置的时候html的标题',
  port: 80, // 本地服务端口号
  outputDir: 'worker', // 打包输出文件名
  env: process.env.VUE_APP_TITLE, // 环境变量值
  publicPath: process.env.BASE_URL, // 打包后文件链接
  productionGzip: true, // 是否使用gzip
  productionGzipExtensions: ['js', 'css'], // 需要gzip压缩的文件后缀
  closeConsole: false, // 是否移除console
  sourcemapUpload: false, // 是否上传sourcemap到sentry
  gitBuild: true, // 是否启用git打包限制
  cdnFlag: false, // 是否启用cdn加载
  externals: { // 忽略打包
    'vue': 'Vue',
    'vue-router': 'VueRouter',
    'vuex': 'Vuex',
    'axios': 'axios'
  }
}

//目前项目里面还没有使用cdn优化方案,其实cdn加载就是说我们在平时的写demo的时候再head中引入的cdn链接,
//这样就可以在使用第三方的框架或者插件的时候,不用去安装。
// 实际上也就是一个项目的优化过程,我们通过config.externals(buildcfg.externals)也就是webpack配置中的
//externals方法,再传入我们要忽略的打包文件,写文件名的时候要注意:是这个框架或者插件默认导出的名字,
//不是我们import name的时候的名字。
const cdn = {//随便写了一些cdn,只是表达意思而已
  dev: {
    css: [],
    js: [ 'https://cdn.bootcss.com/vue/2.6.11/vue.runtime.min.js',
    'https://cdn.bootcss.com/vue-router/3.1.2/vue-router.min.js',
    'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
    'https://cdn.bootcss.com/axios/0.19.2/axios.min.js',
    'https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js',
    'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js']
  },
  prod: {
    css: [],
    js: [ 'https://cdn.bootcss.com/vue/2.6.11/vue.runtime.min.js',
    'https://cdn.bootcss.com/vue-router/3.1.2/vue-router.min.js',
    'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
    'https://cdn.bootcss.com/axios/0.19.2/axios.min.js',
    'https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js',
    'https://cdn.bootcss.com/echarts/3.7.1/echarts.min.js']
  }
}
console.log(`环境变量:${buildcfg.env},
是否上传sourcemap到sentry:${buildcfg.sourcemapUpload},
打包后文件baseURL:${buildcfg.publicPath},
是否启用gzip压缩:${buildcfg.productionGzip},
是否移除console:${buildcfg.closeConsole},
是否启用cdn加载:${buildcfg.cdnFlag}
`)
module.exports = {
 //打包后项目在什么文件名下跑,这个需要在配置环境变量里面配,
 //比如配置开发环境BASE_URL=/dev/worker/,那么当我们通过npm run serve的时候,
 //项目就跑在http://localhost:8080/dev/worker/
 //如果是生产环境打包BASE_URL=/test/worker/,项目就跑到http://域名/test/worker/
 //去看打包的html,里面引入资源文件的时候会自带加上BASE_URL,<script src=/test/worker/js/chunk-vendors.b87d508a.js>
 //搞这个,而不是在根路径是因为服务器上部署的不止一个前端项目,为了做区分。
  publicPath: buildcfg.publicPath,
  outputDir: buildcfg.outputDir,//打包输出的文件名
  //设置为 true 或 'warning' 时,eslint-loader 会将 lint 错误输出为编译警告。默认情况下,警告仅仅会被输出到命令行,且不会使得编译失败。
  lintOnSave: true,
  productionSourceMap: buildcfg.sourcemapUpload,//不知道是什么
  chainWebpack: (config) => {
    config.module.rule('worker')
      .test(/\.worker\.js$/)
      .use('worker-loader')
      .loader('worker-loader').end();
    config.module.rule('js').exclude.add(/\.worker\.js$/)
    //以上的loader链式操作在现在的项目中没有用到,不知道是什么意思
	//下面就是搞cdn打包优化的,如果是生产环境打包或者是可视化打包,就忽略externals中的依赖包
    if (~['analyz', 'production'].indexOf(buildcfg.env) && buildcfg.cdnFlag) {
      config.externals(buildcfg.externals)
    }
    //这个地方就是把配置好的cdn搞到html中
    用法:在html中引入手动写
    <!--循环引入-->
    //<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
    <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>" crossorigin="anonymous"></script>
    <% } %>
    config.plugin('html').tap(args => {
      args[0].title = buildcfg.title
      if (buildcfg.cdnFlag) {
        if (~['analyz', 'production'].indexOf(buildcfg.env)) {
          args[0].cdn = cdn.prod
        } else {
          args[0].cdn = cdn.dev
        }
      }
      return args
    })
  },
  configureWebpack: (config) => {
  //如果是打包生产环境或者打包可视化
    if (~['analyz', 'production'].indexOf(buildcfg.env)) {
      config.mode = 'production'
      //closeConsole 为false,也就是不移除console.log
      //&&运算符中如果第一个为false,就不会看后面的了
      buildcfg.closeConsole && config.plugins.push(
        new TerserPlugin({
          terserOptions: {
            warnings: false,
            compress: {
              drop_console: true,//川true就是干掉所有的console.*这些函数的调用
              drop_debugger: false,//干掉那些debugger
              pure_funcs: ['console.log']// 如果你要干掉特定的函数比如console.info ,又想删掉后保留其参数中的副作用,那用pure_funcs来处理
            }
          }
        })
      )
      //下面的操作就是开启gzip压缩
      buildcfg.productionGzip && config.plugins.push(
        new CompressionWebpackPlugin({
          test: new RegExp('\\.(' + buildcfg.productionGzipExtensions.join('|') + ')$'),
          threshold: 8192,
          minRatio: 0.8
        })
      )
    } else {
      config.mode = 'development'
    }
  },
  css: {
    loaderOptions: {
      scss: {//向 scss相关的 loader 传递选项,用于全局使用
        additionalData: `@import "~@/commons/css/var.scss";`//添加的scss变量
      }
    }
  },
  devServer: {
    open: true,
    // port: buildcfg.port,
    disableHostCheck: true,
    // proxy: {
    //   '/api': {
    //     target: '',
    //     ws: true,
    //     pathRewrite: {
    //       '^/api': '/'
    //     }
    //   },
    //   // '/ws': {
    //   //     target: '',
    //   //     ws: true,
    //   //     pathRewrite: {
    //   //         '^/ws': '/'
    //   //     }
    //   // }
    // }
  },
  pluginOptions: {//这是一个不进行任何 schema 验证的对象,因此它可以用来传递任何第三方插件选项。
    webpackBundleAnalyzer: {//这是安装的vue-cli-plugin-webpack-bundle-analyzer
      openAnalyzer: buildcfg.env === 'analyz',//默认值:true。在默认浏览器中自动打开报告
      analyzerMode: buildcfg.env === 'analyz' ? 'server' : 'disabled'//默认值:server。在server模式下,分析器将启动HTTP服务器以显示捆绑包报告。这就是打包之后搞一个网页显示我们项目打包之后的大小kb信息
    }
  }
}
Logo

前往低代码交流专区

更多推荐