vite2实战介绍篇

关于vite基础阅读我上一篇文章# 一文了解vite基础

一、vite2 构建工具优缺点

传统工具开发环境构建方式和 vite 对比:

传统工具构建方式:

1.png
当冷启动开发服务器时,基于打包器的方式启动必须优先抓取并构建你的整个应用,然后才能提供服务。

vite 构建方式:

2.png
Vite 通过在一开始将应用中的模块区分为 依赖 和 源码 两类,改进了开发服务器启动时间。

依赖 大多为在开发时不会变动的纯 JavaScript。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会存在多种模块化格式(例如 ESM 或者 CommonJS)

Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。

源码 通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载(例如基于路由拆分的代码模块)。

Vite 以 原生 ESM 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。

更新对比

在传统的工具(webpack)更新:

基于打包器启动时,重建整个包的效率很低。原因显而易见:因为这样更新速度会随着应用体积增长而直线下降。

一些打包器的开发服务器将构建内容存入内存,这样它们只需要在文件更改时使模块图的一部分失活[1],但它也仍需要整个重新构建并重载页面。这样代价很高,并且重新加载页面会消除应用的当前状态,所以打包器支持了动态模块热重载(HMR):允许一个模块 “热替换” 它自己,而不会影响页面其余部分。这大大改进了开发体验 —— 然而,在实践中我们发现,即使采用了 HMR 模式,其热更新速度也会随着应用规模的增长而显著下降。

vite 更新:
在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失活[1](大多数时候只是模块本身),使得无论应用大小如何,HMR 始终能保持快速更新。

Vite 同时利用 HTTP 头来加速整个页面的重新加载(再次让浏览器为我们做更多事情):源码模块的请求会根据 304 Not Modified 进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求。

vite 一些缺点:

  1. vite 推出时间太短了,生态这块没有其他构建工具那么完善,同时很多问题和述求没有暴露出来
  2. 针对代码合并切割这块功能没有 webpack 强大(微前端, 代码切割)

二、resolve 解析

和 webpack 类似,resolve 字段用来表示如何来解析模块,首先我们看下常用的别名设置 alias

import { defineConfig, loadEnv } from 'vite'
export default ({ mode, command }) => {
  console.log(loadEnv(mode, process.cwd()).VITE_APP_BASE_PATH, 'base-path')
  return defineConfig({
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src'), // 设置 `@` 指向 `src` 目录
      }
    }
  })
}
复制代码

这样我们就能用@替换相对路径了,可以通过@来引入组件:

import Pagination from '@/components/pagination/index.vue'
复制代码

三、按需引入

我们在使用 element 时,经常会需要按需引入组件,在 vue-cli 中使用的是 babel 的一个插件 babel-plugin-component;vite 有自己的按需引入插件 vite-plugin-style-import,首先我们安装一下:

npm install vite-plugin-style-import -D
复制代码

然后在 vite.config.js 中进行配置

import styleImport from "vite-plugin-style-import";
export default defineConfig({
  plugins: [
    vue(),
    styleImport({
      libs: [
        {
          libraryName: "element-plus",
          esModule: true,
          ensureStyleFile: true,
          resolveStyle: (name) => {
            return `element-plus/lib/theme-chalk/${name}.css`;
          },
          resolveComponent: (name) => {
            return `element-plus/lib/${name}`;
          }
        }
      ]
    })
  ]
})
复制代码

接下来如果我们只希望引入部分组件,就可以在 main.js 中加入:

import { ElButton, ElSelect } from 'element-plus'

const app = createApp(App)
app.component(ElButton.name, ElButton)
app.component(ElSelect.name, ElSelect)
复制代码

四、gzip 压缩

插件安装

npm install vite-plugin-compression -D

# or yarn
yarn add vite-plugin-compression -D
复制代码

用法:

import viteCompression from 'vite-plugin-compression'
import { defineConfig, loadEnv } from 'vite'
export default ({ mode, command }) => {
  return defineConfig({
    plugins: [
      viteCompression()
    ],
  })
}
复制代码

五、文件打包分析

插件安装

npm install rollup-plugin-visualizer -D

# or yarn
yarn add rollup-plugin-visualizer -D
复制代码

用法:

import { visualizer } from 'rollup-plugin-visualizer'
import { defineConfig, loadEnv } from 'vite'
export default ({ mode, command }) => {
  return defineConfig({
    build: {
      rollupOptions: {
        plugins: [
          visualizer({ open: true, gzipSize: true })
        ]
      }
    }
  })
}
复制代码

六、将外部导入转换为全局变量,打包把模块排除

插件安装

npm install -D rollup-plugin-external-globals

# or yarn
yarn add rollup-plugin-external-globals -D
复制代码

用法:

import externalGlobals from 'rollup-plugin-external-globals'
import { defineConfig, loadEnv } from 'vite'
export default ({ mode, command }) => {
  return defineConfig({
    build: {
      rollupOptions: {
        external: ['vue', 'vuex', 'vue-router', 'axios', 'ElementPlus'],
        plugins: [
          externalGlobals({
            vue: 'Vue',
            'element-plus': 'ElementPlus',
            'vue-router': 'VueRouter',
            vuex: 'Vuex',
            axios: 'axios'
          })
        ]
      }
    }
  })
}
复制代码

七、vite 使用 rollup 插件

一般来说,只要一个 Rollup 插件符合以下标准,那么它应该只是作为一个 Vite 插件:

  • 没有使用 moduleParsed 钩子。
  • 它在打包钩子和输出钩子之间没有很强的耦合。
  • 如果一个 Rollup 插件只在构建阶段有意义,则在 build.rollupOptions.plugins 下指定即可。

建议在不确定是否能用的情况下使用 Vite 专属的插件:

  • Vite 插件应该有一个带 vite-plugin- 前缀、语义清晰的名称。
  • 在 package.json 中包含 vite-plugin 关键字。
  • 在插件文档增加一部分关于为什么本插件是一个 Vite 专属插件的详细说明(如,本插件使用了 Vite 特有的插件钩子)。

八、热更新

热更新(hot module replacement) ,简称 hmr ,是一种无需刷新浏览器即可更新代码效果的技术,实现该技术的关键点是要建立 浏览器服务器 之间的联系,还好我们现成就有一种技术可以实现:websocket 协议,普通的 http 协议为短连接,一次会话结束就会关闭,这显然没法满足我们时刻都需要关联 浏览器服务器 的需求,而websocket 为长连接,可以一直保持 浏览器服务器 之间的会话不中断,通过事件来互相传送数据,vite 也用了 websocket 来实现 热更新

热更新主体流程如下:

  1. 服务端基于 watcher 监听文件改动,根据类型判断更新方式,并编译资源
  2. 客户端通过 WebSocket 监听到一些更新的消息类型
  3. 客户端收到资源信息,根据消息类型执行热更新逻辑

九、❤️感谢阅读

  1. 如果本文对你有帮助,不要吝啬你的赞哟,你的「赞」是我前行的动力。
  2. 欢迎关注公众号  【前端冥想】 ,也可扫码加我微信备注  【加群】  拉你进交流分享群,一起学习进步。

企业微信截图_16281521162245.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享