iamxiyang / vite-plugin-html-redirect

一个 Vite 小插件,解决使用 Vite 开发阶段路由带 .html 后缀时访问 404 的问题。

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

README

一个 Vite 小插件,解决使用 Vite 开发阶段路由带 .html 后缀时访问 404 的问题。

NPM

使用方法

安装

npm i vite-plugin-html-redirect -D

or

yarn add vite-plugin-html-redirect -D

配置

// vite.config.(t|j)s
import ViteHtmlRedirect from 'vite-plugin-html-redirect'

export default defineConfig({
  plugins: [ViteHtmlRedirect({})],
})

开发原因

我使用 Vite 初始化了一个 Vue3+VueRouter 的项目。

我通过浏览器进行访问,但当我刷新时总会 404,经过排查发现是因为我的路由地址带有 .html 的后缀,如 a.htmlb/123.html。经过查看 Vite 的源码,发现以下代码片段:

// indexHtmlMiddleware 会对html文件进行处理
if (!middlewareMode || middlewareMode === 'html') {
  // transform index.html
  middlewares.use(indexHtmlMiddleware(server))
  // handle 404s
  // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
  middlewares.use(function vite404Middleware(_, res) {
    res.statusCode = 404
    res.end()
  })
}
// 判断是以.html结尾 且 req.headers['sec-fetch-dest'] !== 'script',就获取文件名去读取对应的html文件,而我是通过路由配置的当然不存在这个文件,此时抛错下一步就是返回404
export function indexHtmlMiddleware(
  server: ViteDevServer
): Connect.NextHandleFunction {
  // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
  return async function viteIndexHtmlMiddleware(req, res, next) {
    if (res.writableEnded) {
      return next()
    }

    const url = req.url && cleanUrl(req.url)
    // spa-fallback always redirects to /index.html
    if (url?.endsWith('.html') && req.headers['sec-fetch-dest'] !== 'script') {
      const filename = getHtmlFilename(url, server)
      if (fs.existsSync(filename)) {
        try {
          let html = fs.readFileSync(filename, 'utf-8')
          html = await server.transformIndexHtml(url, html, req.originalUrl)
          return send(req, res, html, 'html', {
            headers: server.config.server.headers
          })
        } catch (e) {
          return next(e)
        }
      }
    }
    next()
  }

因此路由配置以 .html 结尾在进行开发时会返回 404,我翻了一遍文档,没有发现什么配置项和现有插件能够解决我的问题,因此我尝试借助插件 API 写了一个小插件,解决了这个问题,如果你有类似问题希望能帮助到你,如果你有更好的方案也请告诉我。

思路是匹配到 .html 结尾时,自动重定向到 ./index.html 这个文件。

About

一个 Vite 小插件,解决使用 Vite 开发阶段路由带 .html 后缀时访问 404 的问题。

License:MIT License


Languages

Language:JavaScript 100.0%