手把手教你Vue项目打包优化

702 阅读9分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

CDN介绍

CDN作用

在CDN里存放的资源都是全国性的,发请求时会根据客户端所在的地理地址来请求当地服务器所对应的资源

无CDN

项目的所有资源全在自己服务器上,那么只要用户发请求,就会不断的请求自己的服务器(访问地区、访问人数,都会导致客户端访问资源的速度变慢)

有CDN

将项目需要用的第三方资源放在CDN服务器上,这样用户发请求时,通过CDN链入的第三方资源会在CDN服务器上请求(核心代码还是在自己服务器上)

CDN收费

存储私有资源

CDN免费

存储开源项目

www.jsdelivr.com/网站,将所有的CDN上的开源项目都存储起来了,这时我们可以免费使用它的CDN资源

无CDN:资源全在自己的服务器

有CDN:资源存放在CDN服务器上,全国有很多CDN服务器帮忙存储

总结:我的服务器只放我的核心代码(自己写的代码),所有第三方的资源(库、图片、样式)放到CDN中去

总结:CDN就是一个存放资源的服务器,当客户端请求第三方资源时,去请求CDN服务器,并会根据客户端所在的地理地址来请求当地服务器所对应的资源,访问速度加快,并且第三方的资源也不需要被打包,减少打包后文件体积过大问题

打包优化-第三方包优化1

打包优化:

  • 在保证功能可用的前提下,让我们的文件尽可能小
  • 在保证功能可用的前提下,让我们的页面显示出来的速度更快一些

打包命令---生成dist文件

1、用webpack命令进行项目打包

image.png

2、打包后的项目运行:

1、命令运行:

打包后的项目可以依赖 live-serve 工具帮助运行
​
全局安装live-server:npm i  live-server -g
​
直接cmd小窗口使用live-server全局包命令运行(在打包后的dist目录下使用命令运行)

2、安装 live-server后可直接右键运行

image.png

3、打包之后,会得到dist目录,如果希望可以双击打开index.html,则需要提前在vue.config.js中配置:vue.config.js中

{
    publicPath: './'
}

3、观察打包后的文件:**

image.png 4、问题:

1、直接打包后生成的项目文件会非常大,为什么?

直接打包不做打包优化时,会将在开发期间下载到本地的第三方包也进行打包,导致整个项目文件非常大

2、哪些第三方的包被一起打包了?

image.png

3、如何知道哪个第三方的包影响的空间最严重呢?

1、查看打包日志

2、使用vue ui命令,也可查看

打包日志---查看依赖项大小

1、使用打包日志查看哪些包印象严重

  • 打开package.json配置文件中,为script 节点下的在build打包命令后添加 --report 参数

image.png

  • 重新运行打包命令npm run build
  • 项目被打包后,在dist目录下会生成一个report.html静态网页,在浏览器中打开这个网页,就会看到详细的打包报告

image.png

  • 将网页打开后,里面可以清晰的看见每个被打包的js文件占据的大小

image.png

startt:打包之前所有js文件所占据的空间大小

Parsed:打包之后所有js文件所占据的空间大小(主要观察打包后还有哪些js文件很大,进行优化)

Gzipped:服务端的压缩技术(上线后用户真正请求时的大小)

2、直接使用vue ui命令,页面比打包日志界面更清晰

它可以本地运行,也进行打包,和小窗口的命令是一样的,只不过这里的界面化了

命令:

image.png

界面:

image.png

将当前项目导入进去,查看任务项,打包运行成功后,会将依赖项从大到小依次排序,比日志方块查看更直接

打包处理---CDN引入

注意,在开发项目时,文件资源还是可以从本地node_modules中取出,而只有项目上线了,才需要去使用外部资源。此时我们可以使用环境变量来进行区分。具体如下:

在**vue.config.js**文件中:

1、判断当前环境,决定依赖项是否需要打包,并配置无需打包的依赖项

let externals = {}
const isProduction = process.env.NODE_ENV === 'production' // 判断是否是生产环境,如果是生产环境,则以下几项无需打包
if (isProduction) {
  externals = {
      //无需打包的依赖包 
      //import导包的包名: window全局的成员名称,
      'vue': 'Vue',
      'element-ui': 'ELEMENT',
      'xlsx': 'XLSX'
  }
  }
}

2、配置externals配置项

  1. 未配置 externals 之前:

    1. 凡是 import 导入的第三方模块,在最终打包完成后,会被合并到 chunk-vendors.js
    2. 缺点:导致单个文件的体积过大
  2. 配置了 externals 之后:

    1. webpack 在进行打包时,会把 externals 节点下声明的第三方包排除在外
    2. 因此最终打包生成的 js 文件中,不会包含 externals 节点下的包
    3. 好处:优化了打包后项目的体积

vue.config.js 配置文件里,在里面新增 configureWebpack 节点如下:

module.exports = {
  // 省略其它代码...
  configureWebpack: {
    // 打包优化 在这个节点下配置的第三方包都不会进行打包
    externals:externals//externals对象里存放的都是无需打包的依赖项
  }
}

image.png

3、找到 public/index.html 依次注入 CDN的css 和 js。

CDN已经将所有开源项目都存储起来了,在项目中我们只需要将请求的开源资源让用户去请求CDN服务器

//判断当前环境引入CDN资源(也可直接引入)
<% if(process.env.NODE_ENV==='production' ){%>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    <script src='https://unpkg.com/element-ui/lib/index.js'></script>
    <script src='https://cdn.jsdelivr.net/npm/xlsx@0.16.6/dist/xlsx.full.min.js'></script>
<%}%>

image.png

还有其他方法,可看人资打包优化老师的笔记,也可看juejin.cn/post/700404…

打包加上判断环境变量,当执行npm run build 时,会根据环境而判断是否需要打包

引入时判断环境变量是,只能线上环境才能加载CDN,不写判断时,本地加载会加载,又会加载CDN上的,会加载两次

大事件时老师教的方案

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

打包优化-第三方包优化2

大事件没有进行任何判断,是不严谨的

打包优化:

  • 在保证功能可用的前提下,让我们的文件尽可能小
  • 在保证功能可用的前提下,让我们的页面显示出来的速度更快一些

第一步:执行打包命令

第二步:查看依赖项大小

第三步:配置CDN

CDN已经将所有开源项目都存储起来了,在项目中我们只需要将请求的开源资源让用户去请求CDN服务器

了解configureWebpack节点下的externals属性:

  1. 未配置 externals 之前:

    1. 凡是 import 导入的第三方模块,在最终打包完成后,会被合并到 chunk-vendors.js
    2. 缺点:导致单个文件的体积过大
  2. 配置了 externals 之后:

    1. webpack 在进行打包时,会把 externals 节点下声明的第三方包排除在外
    2. 因此最终打包生成的 js 文件中,不会包含 externals 节点下的包
    3. 好处:优化了打包后项目的体积

具体操作:

这里没有对环境变量进行判断,直接将依赖项写入configureWebpack节点里

1、在项目根目录下创建 vue.config.js 配置文件,在里面新增 configureWebpack 节点如下:

module.exports = {
  // 省略其它代码...
  configureWebpack: {
    // 打包优化
    externals: {
      // import导包的包名: window全局的成员名称,在这个节点下配置的第三方包都不会进行打包
      echarts: 'echarts',           
      'element-ui': 'ELEMENT',
      vue: 'Vue'.....
    }
  }
}

2、配置后的第三方资源已经不会进行打包,需在CDN网站中,找到第三方资源,在index.html中手动配置CDN上的第三方资源路径(因为最终项目运行还是需要第三方资源)

 js导入时使用变量接受,则不需注释,因为代码中使用了变量
 对于import导入的CSS可以注释后在html导入

3、重新运行 npm run build 命令,对比配置 externals 前后文件的体积变化。

注意:代码无需发生任何变化,只需解决哪些第三方资源无需被打包,然后全局引入CDN上的第三方资源即可(因为最终项目运行还是需要第三方资源)。

打包优化-第三方包优化

1、externals下配置不用打包的第三方资源(可判断环境环境变量)

2、html下引入CDN服务器上的第三方资源(注意版本要一致,可判断环境环境变量引入CDN)

打包优化-路由懒加载

参考 vue-router 的官方文档,进行路由懒加载的配置

  1. 什么是路由懒加载:

    • 仅在需要的时候,加载路由对应的组件页面
  2. 好处:

    • 可以提高 index.html 首页的打开速度

配置路由懒加载的核心步骤:

  1. 运行如下的命令,安装 babel 插件:

    npm install  @babel/plugin-syntax-dynamic-import   -D
    
  2. 修改项目根目录下的 babel.config.js 配置文件,新增 plugins 节点:

    module.exports = {
      presets: ['@vue/cli-plugin-babel/preset'],
      // 实现路由组件按需导入的 babel 插件
    + plugins: ['@babel/plugin-syntax-dynamic-import']
    }
    
  3. /src/router/index.js 模块中,基于 const 组件 = () => import('组件的存放路径') 语法,改造每个路由组件的导入方式。例如:

// 导入 Reg 组件
// import Reg from '@/views/Reg/Reg.vue'
const Reg = () => import('@/views/Reg/Reg.vue')
​
// 导入 Login 组件
// import Login from '@/views/Login/Login.vue'
const Login = () => import('@/views/Login/Login.vue')

人资中的[vue-element-admin]里已经将路由都配置为了懒加载,无需操纵1、2步,直接组件按懒加载的方式导入即可

打包优化魔法注释

通过在注释中指定webpackChunkName,可以人为设置这个文件的名字(打包后文件名)

代码如下(示例):
components = () => import(/* webpackChunkName:"login"*/ "../component/Login.vue")

小结

  • 没设置路由懒加载前:所有页面对应的组件会全部打包到一个.js文件中
  • 设置在路由懒加载后:页面对应的组件会全部打包到一个独立.js文件中,而且只有在进入这个路由页面之后才会加载。

打包优化-去掉console-log

在vue.config.js中,配置:

#1
const prodPlugin = []// 存储console-log
if (process.env.NODE_ENV === 'production') {
  // 如果是生产环境,则自动清理掉打印的日志,但保留error 与 warn
  prodPlugin.push([
    'transform-remove-console',
    {
      // 保留 console.error 与 console.warn
      exclude: ['error', 'warn']
    }
  ])
}

#2
//在production节点配置里配置
module.exports = {
    //...其他代码
  'env': {
    'production': {
      'plugins': [...prodPlugin]
    }
  }
}

image.png

\