Vue3+TS项目中如何使用Vite替换Webpack ?
前言
最近因工作需要,需要把Vue3项目使用的 webpack替换为Vite。之前之所以使用webpack原因在于其生态较为成熟全面。但随着vite的社区的不断发展,其生态也逐渐的繁荣起来。所以存着事件是检验真理的唯一标准的原则,尝试一下vite对于webpack的优势到底在哪?
环境搭建
安装vite
npm install vite -D
删除packge.json中vue-cli相关的模块。
找到scripts
字段,修改项目的运行与构建命令
"scripts": {
"dev": "vite --mode dev",
"serve": "vite --mode prod",
"build:prod": "vite build --mode prod",
"lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix"
}
public 下的index.html文件 需要移动到根目录下。并且注意以下两点:
- 引入静态文件时不需要使用
%PUBLIC_URL%
作为占位符,可以直接写/
来访问,vite会将其解析到public根目录下 - 通过
<script type="module" src="...">
标签直接指向Vue的入口文件(文件后缀可以为js或者ts)
有关此变更的详细解释请移步:index.html 与项目根目录
参数配置
在上线部署包的时候我们需要知道发版是否成功因此我们需要知道本次的githash 所以我们引入了vite-plugin-version-mark。配合其他插件和文件可以详细的打印本次发版的内容。
import dayjs from 'dayjs';
import pkg from './package.json';
import { vitePluginVersionMark } from 'vite-plugin-version-mark
const { name, version } = pkg;
const __APP_INFO__ = {
pkg: { name, version },
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
};
了解具体配置 点击这里
在webapck中,我们也许看到过这样的代码 。
module.exports = {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'
}
process.env是Nodejs提供的一个API,其返回一个对象,包含了当前Shell的所有环境变量。比如,process.env.HOME返回用户的主目录。
vite中,我们的代码运行在浏览器环境中,因此是无法识别process.env变量的。(这意味着,vite中识别环境变量的方式与webpack中不同)。
vite.config.js运行在node环境中,因此,可以识别process.env变量
既然vite中已经没有process了,那么如何获取到不同的环境参数呢?
Vite 在一个特殊的 import.meta.env 对象上暴露环境变量。这里有一些在所有情况下都可以使用的内建变量:
-
import.meta.env.MODE: {string} 应用运行的模式。
-
import. meta.env.BASE_URL: {string} 部署应用时的基本 URL。他由base配置项决定。
-
import. meta.env.PROD: {boolean} 应用是否运行在生产环境。
-
import. meta.env.DEV: {boolean} 应用是否运行在开发环境 (永远与 import.meta.env.PROD相反)。
-
import.meta.env.SSR: {boolean} 应用是否运行在 server 上。
我们在项目的根目录下,创建 .env文件,写入测试内容;
# API_PATH
VITE_API_ENV='dev'
VITE_API_PATH= '/api'
VITE_PATH_PREFIX= ''
详情请点击 这里 查看具体配置
接着去除开发环境的console.log 和debugg
drop_console: command === 'build' && loadEnv(mode, __dirname).VITE_API_ENV === 'prod',
drop_debugger: command === 'build' && loadEnv(mode, __dirname).VITE_API_ENV === 'prod'
引入visualizer 分析打包后的包的各项的参数。
plugins: [
visualizer({
emitFile: false,
open: true //如果存在本地服务端口,将在打包后自动展示
}),
]
最后,我们创建vite.config.ts
文件,配置最终如下所示:
import { defineConfig, loadEnv } from "vite";
import { resolve } from "path";
import vue from "@vitejs/plugin-vue";
import dayjs from 'dayjs';
import pkg from './package.json';
import { visualizer } from "rollup-plugin-visualizer";
import { vitePluginVersionMark } from 'vite-plugin-version-mark'
const prod = process.env.NODE_ENV === "production";
const { name, version } = pkg;
const __APP_INFO__ = {
pkg: { name, version },
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
};
export default defineConfig({
plugins: [
vue(),
visualizer({
emitFile: false,
open: true //如果存在本地服务端口,将在打包后自动展示
}),
vitePluginVersionMark({
// name: 'test-app',
// version: '0.0.1',
ifGitSHA: true,
ifShortSHA: true,
ifMeta: true,
ifLog: true,
ifGlobal: true,
})],
server: {
host: true,
port: 8088,
proxy: {}
},
resolve: {
// 设置路径别名
alias: {
"@": resolve(__dirname, "./src"),
}
},
base: prod ? "/api" : "./",
define: {
__APP_INFO__: JSON.stringify(__APP_INFO__),
},
build: {
minify: 'terser',
terserOptions: {
compress: {
drop_console: command === 'build' && loadEnv(mode, __dirname).VITE_API_ENV === 'prod',
drop_debugger: command === 'build' && loadEnv(mode, __dirname).VITE_API_ENV === 'prod',
},
},
},
});
vite 与webpack的比较
vite本地启动时间
webpack本地启动时间
可以明显的看到vite 的本地启动时间远远小于webpack的时间,速度将近快了10倍。体验效果极佳。
原因分析:
webpack dev server 在启动时需要先build一遍,而这个过程需要消耗很多时间
而Vite 不同的是 执行vite serve 时,内部直接启动了web Server, 并不会先编译所有的代码文件。
但是webpack 这类工具的做法是将所有模块提前编译、打包进bundle里。
vite打包后项目分析
webpack打包后项目分析
从上图很容易的看到 vite打包后的体积要比webpack打包后小的多得多。(本项目大概是1/3) 最主要的原因是:
- 浏览器环境并不支持模块化,webpack打的包需要做相关的转化。
- 零散模块文件会产生大量的http请求(大量请求在浏览器端会出现并发请求资源的问题)
而vite的打包原理是基于es新特性 Dynamic imports 实现的,那对老浏览器必然会有兼容问题 处理方案还是 Polyfill。
如果符合以下几点中的一点,我建议不要替换
- 目前项目并没有那么大的打包压力,本地开发效率也还行。
- 用了一些特殊的插件,
Vite
找不到同类替代品。 - 项目的历史包袱比较重,杂七杂八的代码很多,替换带来的成本会很高,而且可能最终会失败。
- 对浏览器兼容性要求较高的,比如需要兼容 IE 老版本。
转载自:https://juejin.cn/post/7212864793652461629