“嘉豪,新的 H5 项目要不用 Vite 整整?” ,听到这番话,被 Webpack 摧残许久的我留下了幸福的眼泪?
需要澄清一点,我们的 H5 项目体量较小,仅能通过短信链接打开。对于这种小的项目来说,实践一些新 姿势 技术是再好不过的,各位不要盲目跟风!
Vite
首先 Vite 这个单词咋个读喃?”歪特?v特?维特?“
对于这个问题,官方文档的第一句就给出了答案:Vite (French word for "fast", pronounced /vit/
),法语:快!看到 Vite 这个名字,感觉尤大也想打造自己的 V宇宙。
Run 起来?♂️
Vite 提供了十分方便的工具来初始化项目:
yarn create @vitejs/app project-name --template vue-ts
首先,Vite 只是一个打包工具,就像我们常用的 Webpack/Rollup/Parcel 一样,也就是说 Vite 并不是与 Vue 强相关的,使用 React 也一样。创建好项目之后,就可以执行 yarn serve
命令来运行本地 dev
环境:
{
"scripts": {
"dev": "vite", // start dev server
"build": "vite build", // build for production
"serve": "vite preview" // locally preview production build
}
}
经常用 Webpack 的开发者应该会清楚,启动本地 dev
环境时需要等八九秒甚至十几秒,但 Vite 很快啊!
宫廷玉液酒,一百八一杯。为啥这么快,听我跟你吹... 各位应该都听说过某公司 CTO 不好好工作,沉迷于开源写了一个快的飞起(我愿称其为世界第一快男)的打包工具 —— esbuild。而 Vite 在启动本地开发环境时,便是使用的 esbuild:
// vite/dist/node/chunks/dep-1bdbec90.js
// 第 68134 行
async function createServer$2(inlineConfig = {}) {
// ...
const server = {
// ...
transformWithEsbuild, // 第 68168 行
// ...
};
}
// 第26715 行
async function transformWithEsbuild(code, filename, options, inMap) {
const service = await ensureService();
try {
// ...
const result = await service.transform(code, resolvedOptions); // 第 26735 行
// ...
} catch {
// ...
}
}
// 第 26702 行
async function ensureService() {
if (!_servicePromise) {
_servicePromise = require('esbuild').startService();
}
return _servicePromise;
}
启动 vite serve
命令时调用顺序便是如此,最终会进入到 esbuild 的 startService
方法。u1s1,快也就开发者能体会得到,用户并无感知,所以你开发时启动再快,打包后的体积大也没什么卵用。所以,目前来说开发追求的是 “又小又快”!
对于代码压缩的配置,官方文档中有描述道:
- build.minify
- Type: boolean | 'terser' | 'esbuild'
- Default: 'terser'
- Set to false to disable minification, or specify the minifier to use. The default is Terser which is slower but produces smaller bundles in most cases. Esbuild minification is significantly faster, but will result in slightly larger bundles.
默认使用 terser 进行压缩,但是如果你觉得有点慢,可以设置成 esbuild,弊端就是 esbuild 压缩出来的会大一些。所以更建议使用 terser,毕竟做的产品是给用户做生产环境使用的。但 build
时候使用的却是 rollup:
// vite/dist/node/chunks/dep-1bdbec90.js
// 第 46730 行
var build$1 = {
// ...
build: build, // 第 46734 行
};
// 第 46446 行
async function build(inlineConfig = {}) {
// ...
try {
return await doBuild(inlineConfig); // 第 46449 行
}
finally {
// ...
}
}
// 第 46459 行
async function doBuild(inlineConfig = {}) {
// ...
const rollup = require('rollup'); // 第 46501 行
try {
const bundle = await rollup.rollup({
// ...
});
}
catch {
// ...
}
}
上面就是在执行 vite build
时的调用顺序,最后会走到 rollup 进行打包,同时在 doBuild
方法中还对 SSR 打包进行了处理,感兴趣的读者可以自行阅读 Vite 源码(已贴心的标注了具体行数)。
添砖 Java 加瓦?
按照上面的命令创建出来的项目仅支持 Vue 和 TS,如果需要支持更多的特性需要我们自行配置,下面会详细讲解。
Router
项目中使用的是 Vue 3 Composition API,故对应使用的是 Vue Router 4+:
yarn add vue-router@4
使用动态引入的方式实现懒加载:
export const routes = [
{ path: '/', component: () => import('@/pages/home/home.vue') },
// ...
// other pages
{ // 404 page
path: '/:pathMatch(.*)*',
component: () => import('@/pages/not-found/not-found.vue'),
},
];
在 main.ts
中的使用也与 Vue 2+ 稍有不同:
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import { routes } from './routes';
import App from './app.vue';
const app = createApp(App);
const router = createRouter({
history: createWebHistory(),
routes,
});
app.use(router);
app.mount('#app');
CSS Preprocessors
一般来说,现在的项目都会使用 Less 或 Scss,而不是直接使用 CSS,如果要使用预处理语言,则直接安装对应的预处理语言的依赖即可,就不赘述。而在使用时就与平时使用并无他样:
<style lang="less">
/* Your less code */
</style>
但有时我们可能定义一些全局使用的变量或 mixin
,这时候我们经常会使用类似于 less-loader
的 additionalData
在每个样式文件头部引入相应的全局文件,从而避免在每个文件中都写 @import "@/styles/mixins.less"
语句,使用 Vite 的操作其实也是一样:
export default defineConfig({
css: {
preprocessorOptions: {
less: {
additionalData:
'@import "@/styles/variables";\n@import "@/styles/mixins";\n',
},
},
},
});
使用 css.preprocessorOptions.less.additionalData
即可实现,并不需要再安装 某pack 需要安装的各种 loader,简简单单~
Alias
其实 Vite 和 Webpack 的配置方法有些相似,但速度却相差甚远(Webpack 骂骂咧咧退出直播间)。比如为了提升开发体验,我们会配置路径简写,将 /src
映射成 @
之类的:
export default defineConfig({
resolve: {
alias: {
'@': '/src',
dayjs: 'dayjs/esm',
},
},
});
与 Webpack 几乎一模一样,直接在 vite.config.ts
中配置 resolve.alias
字段即可,然后再在 tsconfig.json
中配置:
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}
项目中使用到了 dayjs
,在上面的例子中,将原本 dayjs
依赖中的 dayjs/index.js
路径手动改到了 dayjs/esm/index.js
(ESModule)。
Proxy
至于我们常用的 proxy
和静态资源的访问路径,Vite 也贴心地提供了对应字段来配置:
export default defineConfig({
base: '静态资源 URL',
server: {
proxy: {
'/api': {
target: '请求 URL',
changeOrigin: true,
},
},
},
})
无需多言,dddd(懂得都懂)!值得一提的是,之前我们都是通过 process.env.NODE_ENV
来获取环境变量,但在 Vite 中将其挪到了 import.meta.env
中。如要继续使用,则需在 npm script
中添加:
{
scripts: {
"start": "NODE_ENV=development vite"
}
}
Assets
项目中添加了很多有很多 svg
图标,当然 svg
可以通过 <img src="icon.svg" />
来展示,但更多时候我们会在通过 raw-loader
将其转成 string
引入。而在 Vite 中,可以通过在引入路径中添加 ?raw
的方式引入字符串:
import Icon from '@/assets/icon.svg?raw';
这样引入的就是 svg
的 XML 字符串,再通过 v-html
展示。Vite 自带 raw-loader
无需额外安装。
Postcss
Vite 也内置了 Postcss 8+,所以只需要在项目根目录添加相应的 postcss.config.js
文件即可。但有些 Postcss 插件使用到还是老版本的 API(比如我们使用的 postcss-px-to-viewport
),这就会在 console 中打印一个 warning,但并不妨碍使用。
What's more
Vite 虽然已经发布到了 2 大版本,但其更新还是很快,有些内容版本还是在频繁的更新,有些修修补补:
比如目前 Vite 仅支持兼容到 es2015; Vue 3 的测试环境按照其文档配置后还是不 work,后续还需再持续关注下测试的相关配置。
Vue 3 的类型检查一直是个大问题,我们无法通过 tsc
来直接做类型检查,但是我们可以通过尤大钦点的一个 VSCoder 插件 Volar 在开发阶段完成类型检查:
开发过程中,该插件会对有类型错误标出下划线,同时也可以运行 verifyAllScripts
检查所有文件的类型。
有个小故事,尤大是此插件作者的 Sponsor,有位开发者去 GitHub 中给作者提了个 issue,大致内容是“能不能基于 Volar 实现一个命令行版类似于 tsc
的类型检查工具”。作者回应道:
“后续会做,但目前优先级较低。”但尤雨溪到这个 issue 下回应道:“期待其实现...”,然后作者就为了尤大的资助做起了“舔狗”?
说来作者也真是效率!我3月2号上午和作者交流时,这个工具还在开发,睡了个午觉就已经发布了:
在项目中安装好后,只需运行 vue-tsc
即可实现类型检查!配置在 husky
或者 lint-staged
中,简直香的不要不要的!
End
总的来说,Vite 还是能满足大部分的开发需求,并且开发体验还是不错的。不会像 Webpack/Rollup 等需要些大堆的配置和脚本,基本是开箱即用,相比于我之前常用的 Parcel,快了不止一点。感兴趣的开发者还是可以尝试一下,但如果是用在正式生产项目,还是要慎重考虑一下!毕竟新人要上位还是要经历时间的考验~
欢迎关注公众号:Refactor,重构只为更好的自己!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!