19.Vue项目优化

前言

中间其他页面的内容都大同小异,业务无非就是增删改查,使用的组件也大多都是ElementUI组件,看到这里,大家基本上查看下官方文档就能够进行大部分业务功能的开发,因此暂时就不对项目其他页面的业务内容开发继续进行说明。接下来着重对完成项目完成后的优化步骤进行说明。

1.项目优化

1.1项目优化策略

项目优化策略大致可分为以下5个部分:
1.生成打包报告
2.第三方启用CDN
3.ElementUI组件按需加载
4.路由懒加载
5.首页内容定制

1.2通过nprogress添加进度条

1.在项目中执行:npm i --save nprogress,下载nprogress依赖
当然,因为是vue项目,也可以直接在vue ui中安装运行依赖nprogress 0.2.0
在这里插入图片描述
2.安装完成后,需要在发起请求的时候进行使用。在main.js中引入插件和插件样式,在request拦截器中展示进度条 NProgress.start(),在response拦截器中隐藏进度条NProgress.done()。

// 导入 NProgress 包对应的js和css
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// 在request拦截器中,展示进度条 NProgress.start()

//设置拦截器,登录时会自动执行(挂载Authorization,有权限的请求就能请求成功了)
axios.interceptors.request.use(config => {
    
    
  // console.log(config)
  NProgress.start()
  config.headers.Authorization = window.sessionStorage.getItem('token')
  // 在最后必须要返回 config
  return config
})

// 在respose拦截器中,隐藏进度条 NProgress.done()
axios.interceptors.response.use(config => {
    
    
  NProgress.done()
  return config
})

这样每次页面在进行接口查询的时候就会显示进度条

1.3 解决serve命令中提示的警告

1.进入vue ui中,执行serve命令,可以看到项目存在警告。通常来说警告大多都是eslint导致,或者是某个变量声明了,但是从来没有使用。
在这里插入图片描述
查看输出,根据提示解决对应的警告即可。

1.4 在执行build命令时所有的console

在vue ui中执行build命令,查看对应的错误,发现基本上都是console报错,因为项目在build(发布)阶段时不允许console输出的
在这里插入图片描述
1.安装插件
但是我们又希望在进行开发阶段的时候,又希望保留console,这时候就可以使用babel-plugin-transform-remove-console插件了,这个插件可以移除所有的console。这个依赖是开发依赖,就是只有开发时候使用,打包上线后就不再需要了。
在这里插入图片描述
2.在项目根目录babel.config.js文件中添加如下代码

// 这是项目发布阶段需要用到的babel插件
const prodPlugins = []
if(process.env.NODE_ENV === 'production'){
    
    
  prodPlugins.push('transform-remove-console')
}

module.exports = {
    
    
  "presets": [
    "@vue/cli-plugin-babel/preset"
  ],
  "plugins": [
    [
      "component",
      {
    
    
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ],
    // 发布产品时候的插件数组
    ...prodPlugins
  ]
}

使用process.env.NODE_ENV === 'production'判断是否是发布阶段,如果是的话,就使用transform-remove-console

小知识...prodPlugins中的...是展开运算符,表示将prodPlugins数组中的元素展开添加到另一个数组中,因为此时prodPlugins = [‘transform-remove-console’],所以相当于添加了’transform-remove-console’到这一行。重新运行serve后即可生效。

1.5 生成打包报告

打包时,为了直观地发现项目中存在的问题,可以在打包时,生成打包报告。打包的方式有两种:
1.运行命令行的方式:vue-cli-service-build --report,生成report.html文件(不推荐)
2.直接在可视化的ui面板中查看(推荐):在控制台和分析面板中查看:
(1)分析面板可以只管的查看项目中各个插件占项目的体积比例
在这里插入图片描述
(2)控制台面板还可以看到运行时的速度、资源和依赖项。其中资源中后面带感叹号的说明文件体积太大,需要优化。可以想象一个页面在加载时加载的js如此之大,就很有可能造成页面假死的情况。因此就需要对这中情况进行优化。
在这里插入图片描述

1.6 通过vue.config.js修改webpack的默认配置

1.创建vue.config.js文件
通过vue-cli 3.0创建的项目,默认隐藏了所有webpakc的配置项,这是为了让程序员将工作的重心放在具体的功能和业务逻辑的实现上。
如果程序员有修改webpack的需求,可以在项目的根目录创建vue.config.js这个配置文件,从而对项目的打包发布过程做自定义的配置(具体配置参考https://cli.vuejs.org/zh/config/#vue-config-js

2.为开发模式和发布模式指定不同的打包入口
默认情况下,Vue的开发模式和发布模式,共用一个打包的入口文件(即src/main.js),为了将项目的开发过程和发布过程分离,我们可以为两种模式,各自指定打包的入口文件,即
(1)开发模式的入口文件为src/main-dev.js
(2)发布模式的入口文件为src/main-prod.js

3.configureWeback和chainWebpack
在vue.config.js导出的配置对象中,新增configureWeback或chainWebpack节点,来定义webpack的打包配置。
在这里configureWeback和chainWebpack的作用相同,唯一的区别就是它们修改webpack配置的方式不同:
(1)chainWebpack通过链式编程的方式,来修改默认的webpack配置
(2)configureWebpack通过操作对象的形式,修改默认的webpack配置

4.通过chainWebpack自定义打包入口
在vue.config.js中:

// 这个文件要自己创建,用于修改入口文件
module.exports = {
    
    
  // 发布模式
  chainWebpack: config =>{
    
    
    config.when(process.env.NODE_ENV === 'production',config =>{
    
    
      config.entry('app').clear().add('./src/main-prod.js') 
    })

    // 开发模式
    config.when(process.env.NODE_ENV === 'development',config =>{
    
    
      config.entry('app').clear().add('./src/main-dev.js')
    })
  }
}

既然入口文件配置已经修改,那么入口文件也要修改,将原来的main.js复制为main-dev.js和main.prod.js文件,在删除原来的main.js文件即可。
在这里插入图片描述

1.7 通过externals加载外部CND资源

默认情况下,通过import导入的第三方依赖包,最终会被合并到同一个文件中,从而导致打包成功后,单文件体积过大的问题
为了解决上诉问题,可以通过webpack的externals节点,来配置并加载外部的CDN资源,凡是声明在externals中的第三方依赖包,都不会被打包。
在这里插入图片描述
(1)将main-prod.js中通过import的依赖在vue.config.js的发布模式externals中进行声明
在这里插入图片描述

// 这个文件要自己创建,用于修改入口文件
module.exports = {
    
    
  // 发布模式
  chainWebpack: config =>{
    
    
    config.when(process.env.NODE_ENV === 'production',config =>{
    
    
      config.entry('app').clear().add('./src/main-prod.js')
      // config.set 只有发布模式需要,去全局查找这些,使用cdn从public从引入对应的css和js资源
      // 避免打包后依赖包在一个js中,文件过大的问题
      config.set('externals',{
    
    
        vue:'Vue',
        'vue-router':'VueRouter',
        axios:'axios',
        lodash:'_',
        'echarts':'echarts',  
        nprogress:'NProgress',
        'vue-quill-editor':'VueQuillEditor'
      })  
    })

    // 开发模式
    config.when(process.env.NODE_ENV === 'development',config =>{
    
    
      config.entry('app').clear().add('./src/main-dev.js')
    })
  }
}

(2)需要在public/index.html文件的头部,添加如下的CDN资源CSS引用:
将main-prod.js中的import引入的外部依赖样式删除,并且在public/index.html文件中添加对应的CND资源CSS文件
在这里插入图片描述

    <!-- nprogress 的样式文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css">
    <!-- 富文本编辑器 的样式文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css">

(3)需要在public/index.html文件的头部,添加如下的CDN资源JS引用:
main-prod.js中的import引入的外部依赖,在public/index.html文件中添加对应的CND资源JS文件(需要注意的是,引入的js版本需要和package.json文件中的一致)
在这里插入图片描述

    <!-- js文件 -->
    <script src="https://cdn.staticfile.org/vue/2.6.11/vue.min.js"></script>
    <script src="https://cdn.staticfile.org/vue-router/3.2.0/vue-router.min.js"></script>
    <script src="https://cdn.staticfile.org/axios/0.19.2/axios.min.js"></script>
    <script src="https://cdn.staticfile.org/lodash/4.17.20/lodash.min.js"></script>
    <script src="https://cdn.staticfile.org/echarts/5.0.2/echarts.min.js"></script>
    <script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>

    <!-- 富文本 的js文件 -->
    <script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-quill-editor.min.js"></script>

过程中遇到的问题:
(1)这个时候因为配置问题,控制台可能会报错(没报错就忽略):
在这里插入图片描述
Uncaught TypeError: Cannot redefine property: $router
不能重新定义$router,说明是重复定了$router。通常是因为在项目中安装了vue-router的依赖并且用Vue.use()使用了vue-router,还在index.html页面引入了vue-router.js文件。
解决方案:

npm uninstall vue-router --dev-save

以上方法若不成功,删除package.json中的依赖vue-router,删除node_modules文件,重新 npm install 就可以了。
(2)echarts的js引入不生效,在build包中依然存在。查看代码,之前开发的时候是通过按需导入的,使用的require语法,所以无法被externals所替代,将echarts修改为import全局引入即可。

1.8 通过CDN优化ElementUI

可以看到,目前需要优化的依赖只剩下ElementUI,优化方式和上个步骤相同
在这里插入图片描述
在main–prod.js中注释elementUI的导入,在public/index.html中添加elementUI对应的css和js的CDN资源自可
在这里插入图片描述
此时发布打包时就不会打包elementUI的依赖,对应的chunk-vendors.js文件体积也大大减小。项目里过大的图片可以进行压缩或者上传后使用网上的资源即可。
在这里插入图片描述

1.9 首页内容定制

不同的打包环境下,首页内容可能会有所不同,我们可以通过插件的方式进行配置,插件配置如下
(1)为html新增一个自定义属性isProd,在开发模式和发布模式取不同的布尔值
在这里插入图片描述

// 这个文件要自己创建,用于修改入口文件
module.exports = {
    
    
  // 发布模式
  chainWebpack: config =>{
    
    
    config.when(process.env.NODE_ENV === 'production',config =>{
    
    
      config.entry('app').clear().add('./src/main-prod.js')
      // config.set 只有发布模式需要,去全局查找这些,使用cdn从public从引入对应的css和js资源
      // 避免打包后依赖包在一个js中,文件过大的问题
      config.set('externals',{
    
    
        vue:'Vue',
        'vue-router':'VueRouter',
        axios:'axios',
        lodash:'_',
        'echarts':'echarts',  
        nprogress:'NProgress',
        'vue-quill-editor':'VueQuillEditor'
      })  

      // 为html新增一个自定义属性
      config.plugin('html').tap(args =>{
    
    
        args[0].isProd = true
        return args
      })
    })

    // 开发模式
    config.when(process.env.NODE_ENV === 'development',config =>{
    
    
      config.entry('app').clear().add('./src/main-dev.js')

      config.plugin('html').tap(args =>{
    
    
        args[0].isProd = false
        return args
      })
    })
  }
}

(2)在首页中使用isProd
在这里插入图片描述

<title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商管理系统</title>

    <% if(htmlWebpackPlugin.options.isProd){
    
     %>
    <!-- nprogress 的样式文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css">
    <!-- 富文本编辑器 的样式文件 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css">
    <!-- 引入elementUI样式 -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.4.5/theme-chalk/index.css">

    <!-- js文件 -->
    <script src="https://cdn.staticfile.org/vue/2.6.11/vue.min.js"></script>
    <script src="https://cdn.staticfile.org/axios/0.19.2/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
    <script src="https://cdn.staticfile.org/echarts/5.0.2/echarts.min.js"></script>
    <script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>
    <script src="https://cdn.staticfile.org/element-ui/2.4.5/index.js"></script>

    <!-- 富文本 的js文件 -->
    <script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-quill-editor.min.js"></script>

    <% } %>

在开发模式下网页标题显示dev -
在这里插入图片描述
在发布模式下引用对应的依赖cdn,因为router比较特殊,引用cdn需要删除本地的依赖,因此不包括在其中。

2.1 路由懒加载

当打包构建项目时,JavaScript报会变得非常大,影响页面加载。如果我们能将不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应的组件,这样就更高效了。
具体需要3步:
(1)安装开发依赖@babel/plugin-syntax-dynamic-import包
(2)在babel.config.js文件中声明该插件
在这里插入图片描述

(3)将路由修改为按需加载的形式。
在这里插入图片描述
在这里插入图片描述
发现发布后的dist包多了对应的map文件,用于访问时加载。而此时的chunk-vendors.js和app.js文件的大小发生了明显的变化
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39055970/article/details/114384321