vite+vue3+ts+vant搭建项目
背景
最近在做公司项目的技术栈迁移, 基于老项目的技术栈是vue2,因此新的技术栈采用vue3+vant的模式。 并且新增ts+eslint的配置提高项目的可维护性, 项目打包工具在正式环境打包依旧采用webpack,而开发环境存在两种打包模式vite和webpack 。vite基于浏览器ES Moudle,有打包快,体积小等优势,利于项目进行快速开发。但是由于vite本身暂时不推荐用于生产环境且生产环境需要更高的维稳性,因此开发和生产都共建一套webpack打包方式,方便日常问题的排查。本文只记录大概的开发框架以及打包配置,仅供参考。
项目结构
基础配置
在明确好技术栈之后,先搭建vu3+webpack+ts+babel的环境配置。介于老项目有用到Node修改静态页面的值,因此不考虑vue-cli的脚手架。yarn init
初始化页面,再安装vue3+babel7+typescript等依赖项。此处不做详细赘述,主要注意以下几点:
babel.config.js文件需要对vant框架需做额外插件处理
plugins: [ [ 'import', { libraryName: 'vant', libraryDirectory: 'es', style: true }, 'vant' ] ] 复制代码
ts配置时需要去除掉node_modules, 避免对依赖项进行校验,额外增加项目编译时间
"exclude": ["node_modules"] 复制代码
项目引用路径的简写除了在webpack文件中需要配置,tsconfig.json也需要额外配置
// webpack.base.js "alias": { // 用@直接指引到src目录下 '@': path.resolve(__dirname, '../src'), '@libs': path.resolve(__dirname, '../src/libs'), '@cp': path.resolve(__dirname, '../src/components'), "@store": path.resolve(__dirname, '../src/store'), } //tsconfig.json "paths": { "@/*": ["src/*"], "@libs/*": ["src/libs/*"], "@cp/*": ["src/components/*"], "@store/*": ["src/store/*"], "@store": ["src/store"] }, 复制代码
vite配置
1.安装vite等项目依赖
yarn add vite @vitejs/plugin-vue vite-plugin-style-import
2.安装less处理样式,配置vite编译方式
// vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import styleImport from 'vite-plugin-style-import' import path from 'path' export default defineConfig({ plugins: [ vue(), styleImport({ // 处理vant框架的引入 libs: [ { libraryName: 'vant', esModule: true, resolveStyle: name => { return `vant/es/${name}/style` } } ] }) ], // 路径别名 resolve: { alias: { '@': path.resolve(__dirname, './src'), '@libs': path.resolve(__dirname, './src/libs'), '@cp': path.resolve(__dirname, './src/components'), '@store': path.resolve(__dirname, './src/store') } }, css: { preprocessorOptions: { less: { modifyVars: { hack: `true; @import (reference) "${path.resolve( __dirname, './src/styles/global.less' )}";` }, javascriptEnabled: true // 支持less嵌入js文件 } } }, server: { port: 9999, // 端口号 open: true, // 是否自动在浏览器打开 https: false, // 是否开启 https } }) 复制代码
以下几点同样也需要注意:
1. 和webpack类似,路径别名需要额外在vite.config.js配置
2. vite没有内置Less或者Sass的编译依赖,需要额外安装和配置
3. @vitejs/plugin-vue只针对vue3 如果需要对Vue2支持则需要安装vite-plugin-vue2,具体请参考vite-plugin-vue2
vite-ssr服务配置
由于老项目基于node向静态页面注入参数,因此额外配置ssr服务。在build文件中新建viteServer.js 配置vite服务端内容以及根据已有的index.html文件配置新的入口文件
启动命令node build/viteServer.js
入口配置
// vite.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <!--需要额外注入的内容--> <!--preload-links--> </head> <body> <div id="app"></div> <script type="module" src="/src/vite/entry-client.js"></script> </body> </html> 复制代码
vue渲染方式更改
import { createSSRApp } from 'vue' import App from '../App.vue' import store from '@store/index' export function createApp() { const app = createSSRApp(App) return { app, store } } 复制代码
vite-ssr配置
const fs = require('fs') const express = require('express') const path = require('path') const { createServer: createViteServer } = require('vite') async function createServer() { const app = express() // 以中间件模式创建 vite 应用,这将禁用 Vite 自身的 HTML 服务逻辑 // 并让上级服务器接管控制 const vite = await createViteServer({ logLevel: 'error', server: { middlewareMode: 'ssr', watch: { // During tests we edit the files too fast and sometimes chokidar // misses change events, so enforce polling for consistency usePolling: true, interval: 100 } } }) // 使用 vite 的 Connect 实例作为中间件 app.use(vite.middlewares) app.use('/render', async (req, res) => { // 服务 index.html res.setHeader('X-Frame-Options', 'allow-from *') const url = req.originalUrl const isSupportWebp = req.headers['accept'].toLowerCase().includes('image/webp') try { // 1. 读取 index.html let template = fs.readFileSync( path.resolve(__dirname, '../src/vite/vite.html'), 'utf-8' ) // 2. 应用 vite HTML 转换。这将会注入 vite HMR 客户端, // 同时也会从 Vite 插件应用 HTML 转换。 // 例如:@vitejs/plugin-react-refresh 中的 global preambles template = await vite.transformIndexHtml(url, template) // 4. 渲染应用的 HTML。这假设 entry-server.js 导出的 `render` // 函数调用了适当的 SSR 框架 API。 // 例如 ReactDOMServer.renderToString() const appScript = `<script>window.TA = window.TA || {};</script>` // 5. 注入渲染后的应用程序 HTML 到模板中。 const html = template.replace(``, appScript) // 6. 返回渲染后的 HTML。 res.status(200).set({ 'Content-Type': 'text/html' }).end(html) } catch (e) { // 如果捕获到了一个错误,让 vite 来修复该堆栈,这样它就可以映射回你的实际源码中。 vite.ssrFixStacktrace(e) console.error(e) res.status(500).end(e.message) } }) app.use( express.static('./', { extensions: ['html'] }) ) return { app, vite } } createServer().then(({ app }) => { app.listen(7777, () => { console.log('localhost:7777') }) }) 复制代码
结语
此文章主要是用来总结vite+vue的搭建过程,由于笔者也是处于vite的初学阶段, 有什么写的不严谨的地方希望大家可以提出宝贵的意见。
作者:推啊前端团队
链接:https://juejin.cn/post/7023636850182996005