需求 思路与实现 简单实现 做成插件 参考
需求 开发一个多页面项目,使用npm init vue@3
简单初始化后修改目录结构,包含一个根页面和两个独立的其他页面(分别放在不同的文件夹下并设置独立的入口),如下图所示。
参考官网的多页面配置 ,可以通过npm run build
构建、npm run preview
预览,在浏览器中正确浏览,当输入http://localhost:4567/document
(最后可以有斜杠也可由没有),能够正确显示不同文件夹中的页面内容。vite的配置(vite.config.ts
)如下所示,两个地方:root
改为根页面所在目录,build.rollupOptions.input
添加相应的入口页面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import { fileURLToPath, URL } from 'url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' export default defineConfig ({ root : path.resolve (__dirname, 'src/views' ), base : '/' , build : { outDir : path.resolve (__dirname, 'dist' ), assetsDir : 'assets' , rollupOptions : { input : { index : path.resolve (__dirname, 'src/views/index.html' ), download : path.resolve (__dirname, 'src/views/download/index.html' ), document : path.resolve (__dirname, 'src/views/document/index.html' ) } } }, plugins : [ vue () ], resolve : { alias : { '@' : fileURLToPath (new URL ('./src' , import .meta .url )) } } })
但在开发环境下npm run dev
,直接输入http://localhost:4567/document
无法正常访问,显示的还是首页,只有加上/
,也就是http://localhost:4567/document/
,才能正确访问。为了使前者也能正确访问,需要做进一步的配置。
思路与实现 简单实现 实现的思路很简单,就是做一个重定向,要进行重定向就要自己写一个插件plugins
,实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 plugins : [ vue (), { name : 'my-test-plugin' , configureServer (server ) { const route = '/document' ; server.middlewares .use (route, (req, res, next ) => { if (req.url === '/' && req.originalUrl === route) { res.writeHead (302 , { Location : `${route} /` }); return res.end (); } next (); }); } } ],
很简单,使用http的重定向状态302
在路由的最后加上一个斜杠/
就可以了。详细的开发服务器参考可以看官方文档(文末链接),这里用到的中间件接口和connect 一致,相较于express用起来难受一些,没有直接可调用的重定向接口(redirect)。
做成插件 devServerRouter.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import type { PluginOption } from 'vite' ;type objRouterItem = { oldPath : string ; newPath : string ; } type devServerRouterItem = string | objRouterItem | [string , string ];export default (items : devServerRouterItem[]): PluginOption => { return { name : 'vite-plugin-devServer-router' , configureServer (server ) { items.forEach (item => { let oldPath : string ; let newPath : string ; if (typeof item === 'string' ) { oldPath = item; newPath = item[item.length - 1 ] !== '/' ? `${item} /` : item; } else if (Array .isArray (item)) { oldPath = item[0 ]; newPath = item[1 ]; } else { oldPath = item.oldPath ; newPath = item.newPath ; } if (oldPath !== newPath) { server.middlewares .use (oldPath, (req, res, next ) => { if (req.url === '/' && (req.originalUrl && req.originalUrl === oldPath)) { res.writeHead (302 , { Location : newPath }); return res.end (); } next (); }); } }); } }; };
调用(vite.config.ts)
1 2 3 4 5 6 7 8 9 10 11 import { defineConfig } from 'vite' import devServerRouter from './src/plugins/devServerRouter' export default defineConfig ({ plugins : [ devServerRouter ([ ['/download' , '/download/' ], ['/document' , '/document/' ] ]) ], })
参考 插件 API | Vite 官方中文文档 (vitejs.dev)
JavaScript API | Vite 官方中文文档 (vitejs.dev)