前言
有开发经验的小伙伴都知道,在使用Webpack作为基础的各类开发工具前,我们需要配置很多Webpack相关的环境配置,比如entry、output、plugins等。Webpack配置过程繁琐不说,随着使用的累积,整个项目的编译会越来越慢。
得益于浏览器对ES Module的支持,出现了基于浏览器原生ES imports的开发服务器:Vite。
因其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动,大大减少了程序员在前端开发过程中的时间消耗。
尤雨溪的微博原话是这样解释的:
Vite,一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue 文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。针对生产环境则可以把同一份代码用 rollup 打。虽然现在还比较粗糙,但这个方向我觉得是有潜力的,做得好可以彻底解决改一行代码等半天热更新的问题。
如何使用Vite呢?
那么我们先来看一下如何使用Vite
初始化一个项目,注意:Node
需要12.0.0版本以上。
打开命令行输入(my-app为project-name):
$ npm init vue@latest my-app
根据提示选择vue模板,然后通过以下指令启动项目:
$ cd my-app
$ npm install
$ npm run dev
效果如下:
项目结构如下:
跟Vue Cli构建的项目不同的是,配置文件变成了vite.config.js
,具体的配置项可以查看官方文档。
Vite常见的配置
我们来看看在vite.config.js
文件中的常见配置有哪些:
base
这是开发或生产环境服务的公共基础路径,打完包的/dist/index.html
文件中引入资源也是以这个路径为基础。
resolve.alias
为了方便在项目代码内部引用文件时,书写路径方便而设置的路径别名。
当使用文件系统路径的别名时,请始终使用绝对路径。 相对路径的别名值会原封不动地被使用,因此无法被正常解析。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
// 路径别名
alias: {
'@': path.resolve(__dirname, '/src')
}
}
})
resolve.extensions
在导入文件时可以省略的扩展名列表。
导入时想要省略的扩展名列表。注意,不建议忽略自定义导入类型的扩展名(例如:.vue
),因为它会影响 IDE 和类型支持。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
// 路径别名
alias: {
'@': path.resolve(__dirname, '/src')
},
//文件类型,默认值
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
}
})
server
开发服务器选项的配置,这个配置项内置多种开发时用的选项。
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
// 路径别名
alias: {
'@': path.resolve(__dirname, '/src')
},
//文件类型,默认值
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
},
server: {
// 指定服务器应该监听哪个 IP 地址
host: '127.0.0.1',
// 指定开发服务器端口
port: 8080,
// 在开发服务器启动时自动在浏览器中打开应用程序
open: true,
// 为开发服务器配置自定义代理规则
proxy: {
'/api': 'http://localhost:4567'
}
}
})
Vite原理分析
ES 模块是 Vite
的基础,通过下图浏览器对ES 模块的支持情况,我们可以知道除了IE 浏览器之外,主流浏览器较新的版本都已经支持了ES 模块。
ES 模块的特点是,在script
标签中设置type=module
之后,浏览器可以直接使用export
和import
的方式实现导入模块和导出模块了。效果如下:
//a.js
export const message = 'hello world';
<script type="module">
import { message } from './a.js'
</script>
当script
标签中的代码执行时,浏览器会发起http
请求获得a.js
。
而Vite是如何使用ES模块的呢?
启动我们使用Vite构建的项目,在浏览器打开后,打开控制台,点击Network
,效果如下:
script设置了 type=module
属性,并且 src 引入 /src/main.js
,打开main.js
效果如下:
再查看vue.js和App.vue的加载路径,效果如下:
代码从http://localhost:3000/node_modules/.vite/vue.js?v=5484949c
获得了createApp方法,并且从http://localhost:3000/src/App.vue
获得了根组件。Vite省去了打包的过程,直接从浏览器中按照ES 模块的方式获得了代码。
Webpack
的编译打包方式很难做到按需加载,会将所有的资源打包到一个boundle
文件中。而随着项目的业务内容增多,打包的boundle
文件也会越来越大。为了减小boundle
的体积,引入import()的方式来实现按需加载,但是这样的方式引入的代码还是需要提前打包。后来使用webpack的tree shaking
功能删除没有使用的代码块。
但以上的方式都没有Vite
优雅。虽然Vite
的方式目前只能用于开发环境,但Vite
真正做到了按需编译,并且不需要提前打包,这样大大提高了我们开发的效率。