官网:Vite中文网
首先要明白一点就是,vite无法取代webpack,它们各有所长,面向的客户与群体也是分明的,双方都有相对应的优势,我们所要明白的就是在哪种情况下,选择最适合的打包工具,然后配置出最合适的值,以及插件。
概述:下一代前端的打包与构建工具
打包工具,浏览器只认识html,css,js
typescript:如果遇见ts文件,需要使用tsc将typescript转换为js代码
React/Vue: 安装react-compiler / vue-complier,将我们所写的jsxx / vue文件转化为render函数
less/sass/postcss/component-style: 我们需要安装对应的less-loader, sass-loader等编译插件,转换为css
语法降级: 为了适应浏览器的版本,在开发中需要设置规定的一些浏览器;再就是将es语法降级,es6转换为es5的语法
体积优化: 希望文件的体积越小,优化性能. uglifyjs将我们的代码进行压缩成为体积更小,性能更高的文件
每一次文件都需要先走一遍,再运行
有一个东西,能够把这些东西全部集成,全部走一遍,直接让我们使用最后的结果
这个东西就是----构建工具
官网介绍:当我们开始构建越来越大型的应用时,需要处理的 JavaScript 代码量也呈指数级增长。包含数千个模块的大型项目相当普遍。基于 JavaScript 开发的工具就会开始遇到性能瓶颈:通常需要很长时间(甚至是几分钟!)才能启动开发服务器,即使使用模块热替换(HMR),文件修改后的效果也需要几秒钟才能在浏览器中反映出来。如此循环往复,迟钝的反馈会极大地影响开发者的开发效率和幸福感。
这里可以简单的用webpack做案例:
--webpack中既可以使用ES6引入也可以使用common.js规范
const Vue = require('vue') //commonjs规范
import Vue from 'vue' //ES6 module规范
--webpack转换的结果
const Vue = webpack_require('vue')
webpack支持多种的模块化代码,需要把所有的模块读一遍,需要统一模块.在服务器上面运行,并对语法有自己的解析
vite的ES module规范,不使用commonjs规范,只是用ES6 module规范,这样的弊端就是,不支持多种模块的开发,但是它侧重与运行的速度与兼容性
源码 通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载(例如基于路由拆分的代码模块)。
Vite 以 原生 ESM 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。
在我们下载的依赖中(node_modules),vite会处理(依赖预构件):原因是里里面的依赖有的是用ES写的,有的使用commonjs写的,但是vite只会处理使用ES写的依赖。方法就是把connonjs转化成为ES规范,首先vite会找到对应的依赖,然后调用esbuild(用go语言写的一个库),将其他规范转换成为ESmodule规范,然后放在当前目录下的node_modules/.vitre/deps,同时对ESmodule规范的各个模块进行统一集成。
解决三个问题:
不同的第三方包会有不同的导出格式 --> 现在转换后统一是ES moldule
对路径的处理上可以直接使用.vite/deps,方便路径的重写 --> 转换后全部放在目录下的node_modules/.vitre/deps
解决网路多包传输的性能问题(也是原生ESmodule规范不敢支持node_module的原因之一) -->ESmodule规范的各个模块进行统一集成,就是把里面引入的东西直接写进去,这样就不用再启动的使用,启动那么多的包。
npm create vite@latest
yarn create vite
这里和使用vue-cli一样,要先下载一个create-vite(vite脚手架)
create-vite内置了vite --> vue-cli内置了webpack一样
create-vite就是已经用vite搭建的项目,跟你预设好了vite的配置
webpack下载之后是webpack.config.js
vite下载之后是vite.config.js
在里面进行配置,就可以对文件的处理方式/插件/运行等,进行改变
因为 Vite 本身附带 TypeScript 类型,所以你可以通过 IDE 和 jsdoc 的配合来实现智能提示
/** @type {import('vite').UserConfig} */
export default {
// ...
}
/** @type {import('vite').UserConfig} */
const viteConfig = {
// ...
}
import { defineConfig } from 'vite'
export default defineConfig({
// ...
})
//另外你可以使用 defineConfig 工具函数,这样不用 jsdoc 注解也可以获取类型提示
在使用webpack的时候,我们要区分配置文件的环境:
webpack.dev.config
webpack.prod.config
webpack.base.config
webpackmeroe
这里的解决方法可以是,对输入的命令进行判断,如果是dev就使用开发环境,如果是build就是用生产环境。vite.dev.config.js是一套开发配置配置,vite.base.config.js是基础配置(都相同的),vite.prod.config.js是一套生产配置。
环境变量:会根据当前的代码环境产生值的变化的变量就叫做环境变量
代码环境: 开发环境,测试环境,预发布环境,灰度环境,生产环境
例子:百度地图的sdk,小程序的sdk
APP_KEY:测试环境和生产环境是不一样的key:
通过填写不同的key,环境变量也是不一样的,我们在使用
解决的方法:dotenv第三方库(vite内置了dotenv库)
会去读 .env这个文件 --> .env.development / .env.production
解析这个文件中的对应的环境变量,并将其注入到process对象下面,但是考虑到和其他和其他配置的冲突问题,不会直接注入到process对象下
涉及冲突的vite.config.js的一些配置:
--root
--envDir: 用来配置当前环境变量的文件地址
vite提供了一些补偿的措施,我们可以调用vite的loadEnv来手动确认env文件
拿到env文件里面的参数
const env = loadEnv(mode, process.cwd(), prefixes: "")
//process.cwd()表示当前文件所在的目录
//prefixes: ""默认是.env文件
//env里面就有所有的参数 env.APP_KEY就可以拿到参数
npm dev --mode development 会将mode设置为development传递进来
当我们调用loadEnv的时候会做以下几件事:
直接找到 .env文件,并解析其中的环境变量,并放进一个对象里面
会将传进来的mode这个变量的值进行拼接: “.env.developent" ,并根据提供的目录去找到对应的配置文件,并进行解析,
在客户端,vite会将对应的环境变量注入到import.mate.env中
vite做了一个拦截,直接用这个是拿不到的,为了防止将隐私性的变量直接送进import.mate.env中,对开头做了一个辨别
可以在vite中进行配置,envPrefix: "", //配置vite注入客户端环境变量校验的env前缀,默认是VITE_
所有的文件最后都会打包入dist中,对build进行配置
官网:Configuration Options | Rollup
利用hash算法,打包过后的文件名 [name] + [hash],当你的文件没有变化时,hash值是不会变化的,一旦文件内容变化,hash就会变化,文件名不一样。浏览器缓存机制是根据文件名来的,当加载的图片文件名一样时就会进行缓存,当文件名不一样时才会重新加载。
base64配置,将图片转换成为base64编码,一样可以显示。这里表示大于4000kb的才转换。
vite在读取main.js中引用的index.css文件
直接去使用fs模块去读取index.css中的内容
直接创建一个style标签,将index.css中文件内容直接copy进style标签里
将style标签插入到index.html的head中
将该文件中的内容直接替换成js脚本(方便热更新或者css模块化),同时设置Content-Type为js,从而让浏览器以JS脚本的形式来执行该css后缀的文件
问题:在联合开发的工程中,因为是不同的人在开发,在使用标签/className/id等的时候,就会出现相同的情况,这样就会出现类名/标签的覆盖问题。
解决:要想使使用的标签具有准确的指向性,就必须让标签是在哪个模块里面体现
原理:全部是基于node
vite是内置了的,可以直接解析,不用再安装
文件名是module.css(module是一种格式约定,表示需要开启css模块化)
他会将你的所有的类名进行一定规则的替换(将footer替换成为_footer_i22st_1)
同时创建一个映射对象{ footer : ”_footer_i22st_1“ }
将替换过后的内容塞进style标签中,然后放入head标签中
将componentA.module.css内容进行全部抹出,替换成js脚本
将创建的映射对象再脚本中进行默认导出
这里的css配置与上面的不同,上面的是模块化之后替换类名,自动创建映射对象,这样就不会类名重复,会产生覆盖的情况。下面是在vite.config.js中进行css模块的配置,原理也是对类名的修改,使其与其他模块的不一样,hash可以简单的理解为产生一个不一样的值,防止被覆盖。
localConvention: 修改生成的配置对象的key的展示形式(驼峰还是中划线的形式)
scopeBehaviour: 配置当前模块化行为还是全局化(有hash就是开启模块化的一个标识,因为他可以产生不同的hash值,这样我们的类名就不会被覆盖)
generateScopedName: 生成的类名的规则,(可以配置为函数,也可以配置成字符串规则)
hashPrefix: 生成hash会根据你的类名去进行生成,如果你想要hash更加独特一点,你可以配置hashPrefix,你配置的这个字符串最终也会参与到hash的生成(hash:只要你的字符串有一个字不一样,那么生成的hash就完全不一样,但是只要你来的字符串完全一样,生成的hash就全一样)
globalModulePaths: 代表你不想参与到css模块化的路径(假设引入一个css模块标签都不同,不会覆盖)
主要是配置一些css预处理的一些全局参数
这里以less为例讲解
安装 less npm add less 安装过后就可以使用less中的语法,lessc就回去编译less文件
less网站:Using Less.js | Less.js
官方网站:postcss-cli - npm
安装依赖
npm i -D postcss postcss-cli
创建postcss.config.js
简单的来讲,postcss是过滤器,那么这些插件就是一层层过滤层
less插件没有更新了,原因是每次less更新都需要从新适配/更新
也可以直接在vite.config.js中配置
postcss: {
plugins: [postcssPresetEnv()]
}
vite天生对postcss有非常良好的支持
postcss 他的工作原理其实与过滤器的原理一致:保证css执行起来是万无一失的
主要解决的问题: 兼容性
比如全局变量 :root { --globalColor:red }
css代码(都可以写) --> postcss --> 对高级的css语法进行降级 --> 前缀补全 --> 浏览器客户端
css代码(都可以写) --> babel --> 将新的ts语法转换为js语法 -->对高级的css语法进行降级 --> 浏览器客户端
我们如果写的是相对路径,那么他会尝试去拼接成绝对路径 commonjs 规范 注入几个变量dirname
const fs = require("fs");// 处理文件的模块(读文件,修改文件等一系列操作)
constpath=require("path");// path本质上就是一个字符串处理模块,它里面有非常多的路径字符串处理方法 require("./a");
// path.resolve在拼接字符串
const result=fs.readFileSvnc(path.resolve( __dirname, "./variable.css"));
// console.log("result",result.toString(),process.cwd(),__dirname +"./variable.css")
原因: node端去读取文件或者操作文件的时候,如果发现你用的是相对路径,则会去使process.cwd()来进行对应的拼接,但是使用process.cwd()拼接是在你node的运行文件下,这样如果文件不对就会报错。
使用绝对路径,__dirname代表当前目录,./variable.css这个是所用到的文件,不论是ES还是node都可以准确的找到对应的文件
这里讲解一下__dirname的原理:
每一个组件可以被认为是一个函数的自调用
(function (exports, require, module, __filename, __dirname) {
require("")
}())
//可以打印一下arguments, 就可以知道在后台打印的有五个对象,上面返回的
console.log("arguments", arguments)
除了动态的API以外,百分之九十资源都被视为静态资源(常见的就是图片,视频资源)
vite对静态资源是开箱即用的
静态资源通常放在assets目录下
在vite.config.js中进行配置,对路径进行起别名
resolve: {
alias: {
"@": path.resolve( __dirname, "./src"),
"@assets": path.resolve( __dirname, "./src/assets"),
}
}
默认是后面加上url,加上raw表示的是原文件
svg标签,上面有很多的属性,通过修改style中的fill来修改svg颜色
vite官方网站:插件 | Vite 官方中文文档
社区插件网站:GitHub - vitejs/awesome-vite: ⚡️ A curated list of awesome things related to Vite.js
vite内部内置了很多的插件,webpack处理less/sass/ts都需要下载插件,来进行处理,但是vite内部就已经配置好了,我们只需要直接使用即可
webpack与vite插件都是基本相同的用法
生命周期: 和vue/react一样,在vite的运行过程,到执行结束,这样一个过程就是vite的生命周期。
插件的作用: 就是在不用的生命周期阶段去调用不用的插件,来达到不同的目的。
相当于不需要你自己再配置别名,插件已经写好了,你只需要引入并配置即可
网站:GitHub - Subwaytime/vite-aliases: Alias auto generation for Vite
// vite.config.js
import { ViteAliases } from 'vite-aliases'
export default {
plugins: [
ViteAliases()
]
};