Vite 是什么
作者原话: Vite,一个基于浏览器原生 ES Modules 的开发服务器。利用浏览器去解析模块,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue 文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。
ES Modules
ES Modules 是浏览器支持的一种模块化方案,允许在代码中实现模块化
<template>
<img alt="Vue logo" src="https://juejin.cn/post/assets/logo.png" />
<XzTable msg="Hello Vue 3.0 + Vite" />
</template>
<script>
import XzTable from './components/XzTable'
export default {
name: 'App',
components: { XzTable }
}
</script>
复制代码
当浏览器解析 import HelloWorld from ‘./components/XzTable’时,会往当前域名发送一个请求获取对应的资源。
vite实现原理是什么?
主要功能就是通过劫持浏览器的这些请求,并在后端进行相应的处理将项目中使用的文件通过简单的分解与整合,然后再返回给浏览器渲染页面
vite做了什么?
当我们加上type=”module”的时候,浏览器就会像服务器发起一个GET http://localhost:3000/src/main.js请求main.js文件
浏览器请求到了main.js文件,检测到内部含有import引入的包,又会对其内部的import引用发起http请求获取模块的内容文件;
1. 重写引入模块路径前面加上/@modules/, 重写后浏览器会再次发送请求
2.拦截含有/@modules/的请求, 去node_modules引入对应的模块并返回
**平时引用:**import xxx from ‘xxx’
因此 Vite 在拦截的请求里,对直接引用 node_modules 的模块都做了路径的替换,换成了 /@modules/ 并返回回去。而后浏览器收到后,会发起对 /@modules/xxx 的请求,然后被 Vite 再次拦截,并由 Vite 内部去访问真正的模块,并将得到的内容再次做同样的处理后,返回给浏览器。
注意:在 Vite 中约定若 path 的请求路径满足 /^/@modules// 格式时,被认为是一个 node_modules 模块
3. 解析.vue文件
拆成3个请求,(分别对应 script、style 和template)
将vue文件解析成render函数返回给浏览器渲染页面:
当请求的是vue文件时,koa中间件检测到请求的是vue模板文件,则会在请求后面添加一个type参数,koa通过这个参数来判断是请求vue模板文件,并编译成js文件返回给浏览器
与webpack的区别
Bundle
当我们使用如 webpack 类的打包工具时。最终会将所有的代码打包入一个 bundle.js 文件中。
当我们修改模块中的一个子模块a.js,整个bundle.js 都需要重新打包,随着项目规模的扩大,重新打包(热更新)的时间越来越长;
Bundleless
由于浏览器只会对import引用到的模块发起 HTTP 请求,所以 Vite 没必要对项目里所有的文件先打包后返回,而是只编译浏览器发起 HTTP 请求的模块即可。这里是不是有点按需加载的味道?
浏览器解析到import { a } from ‘./a’ 时,只会发起 HTTP 请求 a.js;所以理论上热更新的速度不会随着文件增加而变慢。
Bundle :每次启动和文件变化都要重新打包返回bundle.js给浏览器;
Bundleless:文件的处理由浏览器的请求驱动,单文件的变动只需处理单个文件;
特点:
- 去掉打包步骤,快速的冷启动
- 及时的模块热更新,不会随着模块变多而使得热更新变慢
- 真正的按需编
vue3
yarn global add create-vite-app@1.18.0 create-vite-app vue3-xiaozzao
与vue2大致一样,除了以下几点
1.Vue 3 的 Template 支持多个根标签,Vue 2 不支持
2.Vue 3 有 createApp(),而 Vue 2 的是 new Vue()
3.createApp(组件),new Vue({template, render})
组合式API之 setup()
setup 函数是一个新的组件选项。作为在组件内使用 Composition API 的入口点。创建组件实例,然后初始化 props ,紧接着就调用setup 函数。从生命周期钩子的视角来看,它会在 beforeCreate 钩子之前被调用。
接收参数:Props、context
setup(props,context){ console.log(props.id) context.emit(‘upDate’,val) const state = reactive({ name:”, }) const getList = ()=>{ } return { name, getList } }
没有this
this在setup中不可用,方法和声明周期都可以写在setup中,如果在方法中访问setup中的变量时,直接变量名就可以使用。方法名和变量名要在setup中return出去才可以正常执行。