[打包优化]从0到1搭建element后台框架之优化

栏目: JavaScript · 发布时间: 5年前

内容简介:hello,咱又见了~~嘻嘻。本次主要来说说这个打包优化的问题。一个vue项目从开发到上线必须得经历打包过程,一个项目的打包优化与否都决定了你这个项目的运行速度以及用户体验。本次主要是针对开发环境与生产环境的配置也是开发中的必不可少的一环。本项目是由在项目根目录下新建

hello,咱又见了~~嘻嘻。本次主要来说说这个打包优化的问题。一个vue项目从开发到上线必须得经历打包过程,一个项目的打包优化与否都决定了你这个项目的运行速度以及用户体验。本次主要是针对 vue.config,js 的配置进行优化。 项目地址

开发环境与生产环境

开发环境与生产环境的配置也是开发中的必不可少的一环。本项目是由 vue-cli3 开发, vue-cli3 深度集成了 webpack ,如果不熟悉 vue-cli3 可以先去官网看看相关配置。

开发环境

在项目根目录下新建 .env.development 文件表明是开发环境。

VUE_APP_CURRENTMODE ="development" //当前的环境
    VUE_APP_LOGOUT_URL="http://localhost:3000/" //开发环境的地址
复制代码

生产环境

在项目根目录下新建 .env.production 文件表明是生产环境。

VUE_APP_CURRENTMODE ="development" //当前的环境
    VUE_APP_LOGOUT_URL="xxx" //生产环境的地址
复制代码

当然你也可以自己创建一个测试环境 .env.test ,同样可以像上边一样配置。

环境运用

那么接下来我们怎么用它呢?这里不得不说一下的是 package.json 里面的两个命令 serve , build ,其实对应的是全命令是 vue-cli-service serve --mode development , vue-cli-service build --mode production ,如果你想要在构建命令中使用开发环境变量,那么可以加入

"dev-build": "vue-cli-service build --mode development"
复制代码

接下来在 vue.config.js 运用它。

config.plugin('define').tap(args => {
          args[0]['process.env'].VUE_APP_LOGOUT_URL = JSON.stringify(process.env.VUE_APP_LOGOUT_URL)
          console.log(args[0])
          return args;
    });
复制代码

这里有必要说下,这段代码是写在 chainWebpack 配置项下面。这段代码其实运用了两个 webpack 插件 webpack-chain 允许配置链式操作,以及 webpack.DefinePlugin

  • webpack-chain:尝试通过提供可链式或顺流式的 API 创建和修改webpack 配置。了解更多
  • webpack.DefinePlugin:它的作用是定义全局常量,是常量。即在模块用它定义的全局常量,那么你就不能改变它。也就是说我定义了一个 process.env.VUE_APP_LOGOUT_URL 常量,在 src 文件夹下面都可以使用。了解更多

分包(code splitting)

首先思考,我们引入的第三方包与我们的业务代码一起打包会产生什么问题?

顾名思义,我们的业务代码变动比较频繁,而我们引入的第三方包基本上不会变动。浏览器会有缓存,没有变动的文件会直接从缓存中读取,这也间接的优化了网站的访问速速。 接下来配置 vue.config.js ,

分割第三方库

//代码分割
    config.optimization.minimize(true);
    config.optimization.splitChunks({
      chunks: 'all',
      cacheGroup:{
        //vue2-editor单独打一个包
          vueEdior: {
            name: 'vueEdior',
            test: /[\\/]node_modules[\\/]vue2-editor[\\/]/,
            priority: 10  // 优先级要大于 vendors 不然会被打包进 vendors
          },
          //其余的第三方包打进vendor
          vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10
          }
      }
    })
复制代码

分割共用文件

组件是vue项目的重要组成部分。相当一部分组件都可以公用,在不同的文件中引入,因此我们可以将这部分公用的组件直接分割出来。

config.optimization.minimize(true);
    config.optimization.splitChunks({
      chunks: 'all',
      cacheGroup:{
          vueEdior: {
            name: 'vueEdior',
            test: /[\\/]node_modules[\\/]vue2-editor[\\/]/,
            priority: 10  // 优先级要大于 vendors 不然会被打包进 vendors
          },
          public: {
            name: 'public',
            test: resolve('src/components'),
            minSize: 0, //表示在压缩前的最小模块大小,默认值是 30kb
            minChunks: 2, // 最小公用次数
            priority: 5, // 优先级
            reuseExistingChunk: true // 公共模块必开启
          },
          //其余的第三方包打进vendor
          vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10
          }
      }
    })
复制代码

打包完后会发现 dist/static/js ,多了一个 vueEditorpublic 文件,这就表明分割完成。

map文件处理和别名设置(alias)

map文件

我们可以进一步优化,打包默认生成map文件,从而导致包的体积过大,这时我们需要设定一个属性来关闭它。

productionSourceMap: false
复制代码

别名设置

alias 运用的好处在于不用一级级的去找,而是直接锁定位置,从而减少文件搜索时间。

//设置别名
    config.resolve.alias
      .set('@', resolve('src'))
      .set('@api', resolve('src/api/api'))//接口地址
      .set('@assets', resolve('src/assets'))
复制代码

gzip压缩与去console插件

如果上面的方式都编写了,文件依旧过大,这个时候不得不考虑代码压缩和去掉console插件了,可以说为了优化项目,“无所不用其极”。

gzip压缩

首先安装开始安装

cnpm install compression-webpack-plugin --save-dev
复制代码

然后在 configureWebpack 里面配置它

const CompressionWebpackPlugin = require('compression-webpack-plugin')
    new CompressionWebpackPlugin({
        filename: '[path].gz[query]',
        algorithm: 'gzip',
        test: new RegExp(
          '\\.(' +
          ['js', 'css'].join('|') +
          ')$',
        ),
        threshold: 10240,
        minRatio: 0.8,
      }),
复制代码

值得注意的是 gzip 压缩文件需要后端来配合支持,如果后端没有支持那么项目加载的依旧是没有压缩的文件。

去console插件

首先安装

cnpm install uglifyjs-webpack-plugin --save-dev
复制代码

然后在 configureWebpack 里面配置它

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
    new UglifyJsPlugin({
        uglifyOptions: {
          compress: {
            warnings: false,
            drop_debugger: true,
            drop_console: true,
          },
        },
        sourceMap: false,
        parallel: true,
      }),
复制代码

cdn引入

有的同学说后端没有支持 gzip 压缩加载,那怎么办?那只有凉拌咯~~~。

这里给大家介绍一个cdn引入的方式,有的第三方插件太大,导致单独分包后还是挺大的,这个时候可以考虑用cdn的方式引入文件。

无插件引入cdn

首先我们不让webpack打包用cdn引入的文件

//对一些不经常改动的库,可以通过cdn引入,webpack不对他们打包  
    let externals = {
      'vue': 'Vue',
      'axios': 'axios',
      'element-ui': 'ELEMENT',
      'vue-router': 'VueRouter',
      'vuex': 'Vuex',
      'echarts': 'echarts',
      'vue2-editor': 'VueEditor'
    }
复制代码

然后配置cdn

const cdn = {
      css: [
        //element-ui css
        'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
      ],
      js: [
        //vue
        'https://unpkg.com/vue@2.6.10/dist/vue.min.js',
        //axios
        'http://cdn.staticfile.org/axios/0.19.0-beta.1/axios.min.js',
        //vuex
        'https://unpkg.com/vuex@3.1.0/dist/vuex.min.js',
        //vue-router
        'https://unpkg.com/vue-router@3.0.6/dist/vue-router.min.js',
        //element
        'https://unpkg.com/element-ui@2.7.2/lib/index.js',
        //echarts
        'https://cdn.jsdelivr.net/npm/echarts@4.2.1/dist/echarts.min.js',
        //vue2-editor
        "https://unpkg.com/vue2-editor@2.6.6/dist/vue2-editor.js"
      ]
    }
复制代码

接下来在 chainWebpack 配置

process.env.VUE_APP_CURRENTMODE === 'production') {
      config.externals(externals)//忽略打包
      config.plugin('html')
        .tap(args => {
          args[0].cdn = cdn;
          return args
        })
    }
复制代码

这里需要解释的是 config.plugin('html') 其实是运用了 html-webpack-plugin 插件在其实例化的 options 挂载 cdn 对象,然后通过 ejs 模板语法,读取相关cdn。

紧接着我们需要在 public/index.html 中读取相关cdn

<% if (process.env.VUE_APP_CURRENTMODE === 'production') { %>
      <% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
        <link rel="stylesheet" href="<%=css%>" as="style">
      <% } %>
      <% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
        <script src="<%=js%>"></script>
      <% } %>
    <% } %>
复制代码

至此cdn引入完成

插件引入cdn

由于手动引入cdn太过麻烦,而且担心版本变化,每次都需要手动去更改,所以为了更好的开发体验,引入了自动匹配cdn插件, webpack-cdn-plugin 。接下来开始安装

cnpm install webpack-cdn-plugin --save
复制代码

实例化插件

const cdnPlugin = require('webpack-cdn-plugin')
复制代码

接下来开始在 configureWebpack 中引用

new cdnPlugin({
        modules: [
          { name: 'vue', var: 'Vue', path: 'dist/vue.min.js' },
          { name: 'axios', var: 'axios', path: 'dist/axios.min.js' },
          { name: 'vuex', var: 'Vuex', path: 'dist/vuex.min.js' },
          { name: 'element-ui', var: 'ELEMENT', path: 'lib/index.js', style: 'lib/theme-chalk/index.css' },
          { name: 'echarts', var: 'echarts', path: 'dist/echarts.min.js' },
          { name: 'vue2-editor', var: 'VueEditor', path: 'dist/vue2-editor.js' },
          { name: 'vue-router', var: 'VueRouter', path: 'dist/vue-router.min.js' },
        ],
        publicPath: '/node_modules'
      })
复制代码
  • name:插件名
  • var :项目中实例化的名字
  • path:路径名称
  • style:css路径名称
    更多了解请参考官方文档。
    总体来说引入第三方 cdn 确实能带来不错的效果,但是有可能不稳定,因此建议大家在实际开发中自己去申请一个专属的 cdn 域名,将网站所要用到库直接上传上去。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ASP.NET揭秘

ASP.NET揭秘

Stephen Walther、汤涛 / 汤涛 / 中国电力出版社 / 2004-8-1 / 95.00元

本书是美国亚马逊网站同类书长期销售冠军,并受到微软ASP.NET小组项目经理Rob Howard的大力推荐,中文版由中科院专家汤涛老师翻译,经典、权威是本书最好的诠释。 本书共分10部分,31章,囊括了在.NET框架下架建ASP.NET应用程序的各个层面。每一章也都不是泛泛而谈理论,而是围绕实际样例代码来组织,让读者马上可以上手,并且加深理解。书中还包含了两个完整的、立即就可以用得......一起来看看 《ASP.NET揭秘》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器