Vite入门分享
一、 基本概念
新型前端构建工具,设计的目的就是为了项目构建
1、为什么选Vite
● 上手简单(提供开箱即用的配置)
● 开发效率高(启动和更新更快)
● 社区成本低(兼容rollup插件)
缺点:
目前 Vite 还是使用的 es module 模块不能直接使用生产环境(兼容性问题)。默认情况下,无论是 dev 还是 build 都会直接打出 ESM 版本的代码包,这就要求客户浏览器需要有一个比较新的版本,这放在现在的国情下还是有点难度的。不过 Vite 同时提供了一些弥补的方法,使用 build.polyfillDynamicImport 配置项配合 @vitejs/plugin-legacy 打包出一个看起来兼容性比较好的版本。
生产环境使用 rollup 打包会造成开发环境与生产环境的不一致。
很多 第三方 sdk 没有产出 ems 格式的的代码,这个需要自己去做一些兼容
2、浏览器支持
1、能支持 原生 ESM 语法的 script 标签、原生 ESM 动态导入 和 import.meta 的浏览器
2、传统浏览器可以通过官方插件 @vitejs/plugin-legacy支持
3、目前支持的模板预设
查看 create-vite 以获取每个模板的更多细节
| JavaScript | TypeScript |
|---|---|
| vanilla | vanilla-ts |
| vue | vue-ts |
| react | react-ts |
| preact | preact-ts |
| lit | lit-ts |
| svelte | svelte-ts |
4、搭建项目--以vue3为例
1、前置
● 兼容性问题
Vite 需要 Node.js 版本 14.18+,16+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本
● 安装
目前是推荐使用yarn安装
使用npm安装,部分mac在esbuild的时候有可能会出现问题
下面是一个issues提出的会出现的问题和解决方法
npm create vite my-vue-app --template vue
2、目录结构
┌─pubic 静态文件等不需要编译的内容
├─src 业务页面文件存放的目录
│ ├─assets 存放静态资源-图片js等
│ │ └─logo.png
│ └─components
│ └─HelloWorld.vue 组件页面
│ └─App.vue 存放项目源代码
│ └─main.js js入口文件
│ └─style.css 全局样式文件
├─index.html Vite 项目的入口文件
├─package.json 项目配置文件
└─vite.config.js vite配置文件
和vue-cli最大不同是index.html文件位置
浏览器不会先编译App.vue, 而是直接加载index文件,然后通过script标签加载src下面的main.js,然后这个文件请求到达vite下面的server后,被加载的文件才会去编译。
3、使用css
1、 全局样式的styles.css文件
● style.css文件
:root { // 指文档的根元素,在其中定义的变量可作为全局变量
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
--main-text-color: red;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
color: var(--main-text-color); // 使用定义的变量
}
● 在main.js文件中引入
import './style.css'
● 其他文件中使用全局样式定义的变量, HelloWorld.vue组件中
<template>
<h1>{{ msg }}</h1>
<p class='custom-color'>HelloWorld中使用全局自定义颜色</p>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
.custom-color{
color: var(--main-text-color);
}
</style>
效果:
2、PostCSS
vite官方已经集成了PostCss
以使用@postcss-plugins/console’为例
● 安装:npm install @postcss-plugins/console
● 创建postcss.config.js文件
module.exports={
plugins: [require('@postcss-plugins/console')]
}
● 使用
#app {
@console.error hello;
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
color: var(--main-text-color);
}
3、@import alias-----配置别名
在vite.config.js文件中配置
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@src': '/src'
}
}
})
使用
main.js
import { createApp } from 'vue'
// import './style.css'
import '@src/style.css'
import App from './App.vue'
createApp(App).mount('#app')
4、css-modules
任何以 .module.css 为后缀名的 CSS 文件都被认为是一个 CSS modules 文件。
CSS模块化的一种解决方案
● 避免类名重复导致样式覆盖问题;
● JS & CSS 共享变量
● 可扩展
tips:这个只是防止class类名重复 进行导致的覆盖 如果不同的类名下相同的属性 还是会覆盖的
5、css pre-processors
scss less 预处理器 css的解决方案
● 安装
$npm i less
● 新建less文件---test.less
@bgGreenColor: green;
.bg-green{
background-color: @bgGreenColor;
}
● 组件中使用
import '@assets/css/test.less'
<template>
<p class='bg-green'>背景绿色</p>
</template>
4、处理静态资源
1、将资源引入为 URL
HelloWorld组件中使用图片
import vueLogo from '@assets/vue.svg'
<template>
<img :src="vueLogo" alt="">
</template>
2、url--------显式 URL 引入
// 显式加载资源为一个 URL
import assetAsURL from './asset.js?url'
3、raw-------将资源引入为字符串
// 以字符串形式加载资源
import assetAsString from './shader.glsl?raw'
4、worker---导入脚本作为 Worker
// 加载为 Web Worker
import Worker from './worker.js?worker'
5、集成eslint和prettier
prettier主要负责代码格式化,eslint则主要用于代码质量校验,在编写过程中eslint对于不符合规范 (对prettier和eslint通过几个插件进行结合保证统一性) 的片段会有错误或警告提示
6、环境变量
1、内建变量
Vite 在一个特殊的 import.meta.env 对象上暴露环境变量。
这里有一些在所有情况下都可以使用的内建变量
console.log(import.meta.env, import.meta.env.MODE)
2、生产环境替换
生产环境,不能用import.meta.env.MODE来获取对象
用build命令,打包出来的env直接是一个对象,对于具体的值直接是字符串
7、打包及部署
1、 部署的目录--- vite.config.js 中设置正确的 base
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from "path";
export default defineConfig(({ command, mode }) => {
// 根据当前工作目录中的 `mode` 加载 .env 文件
const { VITE_BASE_URL, VITE_DROP_CONSOLE, VITE_OUTPUT_PATH } = loadEnv(mode, process.cwd())
return {
plugins: [vue()],
base: VITE_BASE_URL // 开发或生产环境服务的公共基础路径
}
})
部署在域名的根目录下
base默认 ' / '
部署在域名的某二级目录(h5)下
base为 /h5/
tips: 开发环境和生产环境
● 开发环境不需要对所有资源打包,只是使用esbuild对依赖进行预构建,将CommonJS和UMD发布的依赖转换为浏览器支持的ESM,同时提高了后续页面的加载性能(lodash的请求)。Vite会将于构建的依赖缓存到node_modules/.vite目录下,它会根据几个源来决定是否需要重新运行预构建,包括 packages.json中的dependencies列表、包管理器的lockfile、可能在vite.config.js相关字段中配置过的。只要三者之一发生改变,才会重新预构建。
● 同时,开发环境使用了浏览器缓存技术,解析后的依赖请求以http头的max-age=31536000,immutable强缓存,以提高页面性能。
● 在生产环境,由于嵌套导入会导致发送大量的网络请求,即使使用HTTP2.x(多路复用、首部压缩),在生产环境中发布未打包的ESM仍然性能低下。因此,对比在开发环境Vite使用esbuild来构建依赖,生产环境Vite则使用了更加成熟的Rollup来完成整个打包过程。因为esbuild虽然快,但针对应用级别的代码分割、CSS处理仍然不够稳定,同时也未能兼容一些未提供ESM的SDK。
● 为了在生产环境中获得最佳的加载性能,仍然需要对代码进行tree-shaking、懒加载以及chunk分割(以获得更好的缓存)
二、 高级应用
1、 HMR
Vite 的热加载原理,其实就是在客户端与服务端建立了一个 websocket 连接,当代码被修改时,服务端发送消息通知客户端去请求修改模块的代码,完成热更新
支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块
3、预编译优化
执行npm run dev命令后,Vite先把本地server启动,之后通过项目的入口收集依赖,把没有提供esm格式的依赖和内部大量的依赖提前打包,这个过程成为:预优化(Pre-Bundling)。
预优化后在页面需要加载依赖时,通过http方式把资源请求回来,做到按需加载。
开发作者将打包模块分为两种:入口模块 和 依赖模块。
入口模块:直接 import 的模块或者通过 include 制定的模块,如:import Vue from 'vue';
依赖模块:入口模块自身的依赖,也就是 dependencies
伪代码,每个依赖打包前都执行以下逻辑:
if 入口模块
将模块解析为namespace='dep'的处理流程
else
if 为browser-external模块
将模块解析为namespace='browser-external'的处理流程
if 以http(s)引入的模块
将模块解析为外部引用模块
else
直接解析路径
三、 Rollup
常用于第三方类库的打包工具, 具体看官网配置