• Vue+express项目优化上线(1)


    Vue+express项目优化上线(1)

    1.Vue项目优化

    1.1 项目优化策略

    • 生成打包报告
    • 第三方库启用CDN
    • Element-UI组件按需加载
    • 路由懒加载
    • 首页内容定制

    1.2 通过nprogress添加加载进度条

    • 安装运行依赖后,导入并在axios拦截器中使用

    • //设置request拦截器
      axios.interceptors.request.use(config => {
        //展示进度条
        Nprogress.start()
        //为请求头添加一个Authorization的属性,值为sessionStorage中存储的token
        config.headers.Authorization = window.sessionStorage.getItem('token')
        return config
      })
      //设置response拦截器
      axios.interceptors.response.use(config => {
        //隐藏进度条
        Nprogress.done()
        return config
      })
      

    1.3 在发布阶段移除所有console

    • 安装babel-plugin-transform-remove-console开发依赖

    • 使用方法可参考官方文档

      • babel.config.js文件初步使用

        //该文件全局共享,开发阶段和发布阶段都会生效
        module.exports = {
          "presets": [
            "@vue/cli-plugin-babel/preset"
          ],
          "plugins": [
            [
              "component",
              {
                "libraryName": "element-ui",
                "styleLibraryName": "theme-chalk"
              }
            ],
            "transform-remove-console"
          ]
        }
        
    • 只在发布阶段移除所有console

      //这是项目发布阶段要用到的 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
        ]
      }
      

    1.4 生成打包报告

    在打包时生成报告有两种方式:

    • 通过命令行参数

      //通过 vue-cli 的命令选项可以生成打包报告
      // --report 选项可以生成 report.html 以帮助分析包内容
      vue-cli-service build --report
      
    • 通过可视化UI面板直接查看

      • 控制台 AND 分析

    1.5 通过创建vue.config.js修改webpack的默认配置

    • 在vue.config.js导出的配置对象中,新增 configureWebpack 或 chainWebpack 节点,来自定义 webpack 的打包配置

    • configureWebpack 和 chainWebpack 的作用相同,唯一区别是它们修改 webpack配置的方式不同

      • chainWebpack通过链式编程的形式,来修改默认的webpack配置
      • configureWebpack通过操作对象的形式,来修改默认的webpack配置
    • 通过chainWebpack自定义打包入口

      • main.js入口文件复制一份,分别命名main-dev.js&main-prod.js

      • //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')
                })
            }
        }
        

    1.6 通过 externals 加载外部CDN资源

    • 默认情况下,通过 import 语法导入的第三方依赖包,最终会被打包合并到一个文件中,导致打包成功后,单文件体积过大问题

    • 通过webpackexternals节点,配置并加载外部CDN资源,凡是声明在externals中的第三方依赖包,都不会被打包

    • 在 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.set('externals', {
                      vue: 'Vue',
                      'vue-router': 'VueRouter',
                      axios: 'axios',
                      echarts: 'echarts',
                      nprogress: 'NProgress',
                  })
              })
      
              //开发模式
              config.when(process.env.NODE_ENV === 'development', config => {
                  config.entry('app').clear().add('./src/main-dev.js')
              })
          }
      }
      
    • 在index.html文件中导入CDN资源

      <head>
          <meta charset="utf-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width,initial-scale=1.0">
          <link rel="icon" href="<%= BASE_URL %>favicon.ico">
          <title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>522人事工资管理后台网站</title>
      
          <% if(htmlWebpackPlugin.options.isProd){ %>
      
          <!--nprogress的样式表文件-->
          <link href="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
          <!--element-ui的样式表-->
          <link href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.9.0/theme-chalk/index.css" rel="stylesheet">
      
          <!--js文件-->
          <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.9.0-rc.1/echarts.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.9.0/index.js"></script>
      
          <% } %>
      </head>
      
    • 优化后进行打包,js文件大小减少了大半,警告减少了一个

    • 此处遇坑:即使使用了项目依赖对应版本的element-ui的cdn,打包后显示也不正常,切换多个版本后解决

    1.7 首页内容定制

    • 不同的打包环境下,首页内容可能会有所不同,我们可以通过插件的方式进行定制

    • 在开发与发布环境中为isProd设置不同的值

      //为html插件新增自定义属性isProd
                  config.plugin('html').tap(args => {
                      args[0].isProd = true
                      return args
                  })
      
    • index.html中根据isProd展示不同内容

      <head>
          <meta charset="utf-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width,initial-scale=1.0">
          <link rel="icon" href="<%= BASE_URL %>favicon.ico">
          <title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>title</title>
      
          <% if(htmlWebpackPlugin.options.isProd){ %>
      
          <!--nprogress的样式表文件-->
          <link href="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.css" rel="stylesheet">
          <!--element-ui的样式表-->
          <link href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.4.5/theme-chalk/index.css" rel="stylesheet">
      
          <!--js文件-->
          <script src="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/echarts/4.9.0-rc.1/echarts.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.min.js"></script>
          <script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.4.5/index.js"></script>
      
          <% } %>
      </head>
      

    1.8 路由懒加载

    • 打包项目时,js包巨大,影响页面加载,可以把不同路由对应组件分割成不同的代码块,当路由被访问时才加载对应组件,提升效率

    • 安装@babel/plugin-syntax-dynamic-import开发依赖

    • 配置在babel.config.js文件中

    • 改造router/index.js文件

      import Vue from 'vue'
      import VueRouter from 'vue-router'
      
      /*
      import Login from "@/views/Login";
      import Home from "@/views/Home";
      import Welcome from "@/views/Welcome";
      import Users from "@/views/user/users";
      import Rights from "@/views/power/Rights";
      import Roles from "@/views/power/Roles";
      import Positions from "@/views/staff/Positions";
      import Staffs from "@/views/staff/Staffs";
      import Events from "@/views/event/Events";
      import Attendance from "@/views/staff/Attendance";
      import Reports from "@/views/report/Reports";
      */
      
      //路由懒加载
      const Login = () => import(/* webpackChunkName: "login_home_welcome" */ '../views/Login')
      const Home = () => import(/* webpackChunkName: "login_home_welcome" */ '../views/Home')
      const Welcome = () => import(/* webpackChunkName: "login_home_welcome" */ '../views/Welcome')
      
      const Users = () => import(/* webpackChunkName: "users_rights_roles" */ '../views/user/Users')
      const Rights = () => import(/* webpackChunkName: "users_rights_roles" */ '../views/power/Rights')
      const Roles = () => import(/* webpackChunkName: "users_rights_roles" */ '../views/power/Roles')
      
      const Attendance = () => import(/* webpackChunkName: "attendance_positions_staffs" */ '../views/staff/Attendance')
      const Positions = () => import(/* webpackChunkName: "attendance_positions_staffs" */ '../views/staff/Positions')
      const Staffs = () => import(/* webpackChunkName: "attendance_positions_staffs" */ '../views/staff/Staffs')
      
      const Events = () => import(/* webpackChunkName: "events" */ '../views/event/Events')
      
      const Reports = () => import(/* webpackChunkName: "reports" */ '../views/report/Reports')
      
      Vue.use(VueRouter)
      
      const routes = [
        { path: '/', redirect: '/login'},//访问根路径时重定向到:/login
        { path: '/login', component: Login },
        { path: '/home', component: Home, redirect: '/welcome', children: [
            { path: '/welcome', component: Welcome },
            { path: '/users', component: Users },
            { path: '/rights', component: Rights },
            { path: '/roles', component: Roles },
            { path: '/positions', component: Positions },
            { path: '/staffs', component: Staffs },
            { path: '/events', component: Events },
            { path: '/attendance', component: Attendance },
            { path: '/reports', component: Reports }
          ]}
      ]
      
      const router = new VueRouter({
        routes
      })
      
      export default router
      
      
    • 优化后js大文件被分割成数个小文件

    1.9 分离前后端项目

    • 由于在项目初始时,因种种原因,将express服务端代码写在vue脚手架搭建的项目中,因此需要进行分离
    • 创建一个服务端文件夹,进入文件夹,运行命令 npm init -y,初始化一个包管理配置文件
    • 使用npm i安装express服务端所需要的所有依赖
    • 转移服务端代码

    2.项目上线

  • 相关阅读:
    理解WebKit和Chromium: Web应用和Web运行环境
    理解WebKit和Chromium: 网页渲染的基本过程
    【闲谈】我的大学
    使用GDAL将下载的Google卫星图像转为带坐标的tif
    Linux下使用GDAL进行开发(automake使用)
    Linux下编译GDAL
    【Unity技巧】统一管理回调函数——观察者模式
    【Unity技巧】使用单例模式Singleton
    【Unity插件】LitJson杂谈
    理解WebKit和Chromium:Chromium资源磁盘缓存
  • 原文地址:https://www.cnblogs.com/liutaodashuaige/p/14083349.html
Copyright © 2020-2023  润新知