emosheeep / vite-plugin-virtual-mpa

Out-of-box MPA plugin for Vite, generate multiple entries using only one template.
https://stackblitz.com/~/github.com/emosheeep/vite-plugin-virtual-mpa
MIT License
120 stars 15 forks source link

Unable to parse HTML; parse5 error code invalid-first-character-of-tag-name #30

Closed luy19 closed 1 year ago

luy19 commented 1 year ago

执行任务: pnpm run dev的时候出现错误

[vite] Internal server error: Unable to parse HTML; parse5 error code invalid-first-character-of-tag-name
 at C:/vite-project/index.html:7:10
5  |    </head>
6  |    <body>
7  |      <h1><%= title %></h1>
   |           ^
8  |    </body>
9  |  </html>

相关文件如下: index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <h1><%= title %></h1>
  </body>
</html>

package.json

{
  "name": "vite-project",
  "type": "module",
  "scripts": {
    "dev": "vite"
  },
  "devDependencies": {
    "vite": "^4.2.0",
    "vite-plugin-virtual-mpa": "^1.7.0"
  }
}

vite.config.js

import { defineConfig } from "vite";
import { createMpaPlugin } from "vite-plugin-virtual-mpa";
export default defineConfig({
  plugins: [
    createMpaPlugin({
      pages: [
        {
          name: "index",
          data: {
            title: "Vite App",
          },
        }
      ],
    }),
  ],
});
emosheeep commented 1 year ago

这种应该是文件更新的时候造成的错误,你重启一下应该就好了,你可以先试试

luy19 commented 1 year ago

这种应该是文件更新的时候造成的错误,你重启一下应该就好了,你可以先试试

我尝试过重新安装后再启动,问题依旧

emosheeep commented 1 year ago

辛苦给个最小复现demo,可以fork仓库,在demo里改

luy19 commented 1 year ago

辛苦给个最小复现demo,可以fork仓库,在demo里改

最小复现demo里只有问题中提到的三个文件index.html, package.json, vite.config.js

luy19 commented 1 year ago

特别的,在执行任务: pnpm run dev的时候,浏览器需要同时打开http://localhost:5173/,不然这个错误可能不显示。

emosheeep commented 1 year ago

确实能复现了,emm,我还在想为什么🤔,暂时没有思路,我看好像重启了下就好了...

luy19 commented 1 year ago

确实能复现了,emm,我还在想为什么🤔,暂时没有思路,我看好像重启了下就好了...

据我的分析,是下面这条rewrite规则有问题: https://github.com/emosheeep/vite-plugin-virtual-mpa/blob/d4313f1c553742511eb28654d8714e2bbb89aff1/workspaces/plugin/src/plugin.ts#L82-L89 我的临时解决方案是在vite.config.js增加一个plugin

const rewriteMiddlewarePlugin = {
  name: "rewrite-middleware",
  configureServer(serve) {
    serve.middlewares.use((req, res, next) => {
      if (req.url === "/") {
        req.url = "index.html";
      }
      next();
    });
  },
};
emosheeep commented 1 year ago

我去,说起来,我最近在工作中遇到了别的问题,也和这条规则有关,我感觉这条规则确实有问题,看来我的改改这块。参考了一下vite官方 https://github.com/emosheeep/vite-plugin-virtual-mpa/issues/15#issuecomment-1491394936

jiadesen commented 1 year ago

@luy19 @emosheeep 跟 rewrite 规则无关,错误发生在这里

https://github.com/emosheeep/vite-plugin-virtual-mpa/blob/d4313f1c553742511eb28654d8714e2bbb89aff1/workspaces/plugin/src/plugin.ts#L245-L251

emosheeep commented 1 year ago

怎么说

jiadesen commented 1 year ago

怎么说

vite 本身就会报这个错误,因为处理不了 <%= VITE_FOO %> 这种 ejs 语法,以下步骤复现:

  1. pnpm create vite
  2. index.html 随便插入任意一段 ejs 语法 ,例如:<div><%= VITE_TEST %></div>
  3. pnpm dev
  4. 访问页面即可看到错误
emosheeep commented 1 year ago

不是,我理解的是我们的页面第1次访问的时候他没有走到我们的处理逻辑,他是走着默认的处理逻辑,所以识别不了,因为我们没有转换,走到他原来的那个transform index

jiadesen commented 1 year ago

下边这条规则确实有问题,就像 #15 提到的 svg 问题,其实不光是 svg 资源,图片、字体等等资源都无法直接用链接访问,我也在想应该怎么处理这个问题,目前看更倾向于直接删掉这个规则

https://github.com/emosheeep/vite-plugin-virtual-mpa/blob/d4313f1c553742511eb28654d8714e2bbb89aff1/workspaces/plugin/src/plugin.ts#L82-L89

jiadesen commented 1 year ago

不是,我理解的是我们的页面第1次访问的时候他没有走到我们的处理逻辑,他是走着默认的处理逻辑,所以识别不了,因为我们没有转换,走到他原来的那个transform index

你可以打个 log,出问题的访问 accept*/*url/

image

交由 vite 处理后报错,所以问题根源是 vite 本身无法处理 ejs 语法

emosheeep commented 1 year ago

是的,所有的素材类文件基本上都是没有办法直接访问的。 vite里面也有一条通配的规则,跟你这个很类似,但是处理逻辑会有一点不太一样。

emosheeep commented 1 year ago

不是,我理解的是我们的页面第1次访问的时候他没有走到我们的处理逻辑,他是走着默认的处理逻辑,所以识别不了,因为我们没有转换,走到他原来的那个transform index

你可以打个 log,出问题的访问 accept*/*url/

image

交由 vite 处理后报错,所以问题根源是 vite 本身无法处理 ejs 语法

我现在不在电脑前,但是我猜测这个问题可能是我们这个中间件的注册时机不太对。或许可以尝试一下在return的函数里边注册,做一个后置兜底钩子。

luy19 commented 1 year ago

不是,我理解的是我们的页面第1次访问的时候他没有走到我们的处理逻辑,他是走着默认的处理逻辑,所以识别不了,因为我们没有转换,走到他原来的那个transform index

你可以打个 log,出问题的访问 accept*/*url/

image

交由 vite 处理后报错,所以问题根源是 vite 本身无法处理 ejs 语法

理论上说,vite-plugin-virtual-mpa应该负责把包含ejs语法的模板文件处理好之后再交给vite。

jiadesen commented 1 year ago

理论上说,vite-plugin-virtual-mpa应该负责把包含ejs语法的模板文件处理好之后再交给vite。

这个插件是支持 ejs 语法的,参见:

https://github.com/emosheeep/vite-plugin-virtual-mpa/blob/d4313f1c553742511eb28654d8714e2bbb89aff1/workspaces/plugin/src/plugin.ts#L111-L134

问题在于访问 http://localhost:5173/ 时会直接交由 vite 处理,vite 会默认重定向到根目录 index.html 文件,然而 ejs 语法 vite 还不支持,直接抛出了错误。

顺便提一句,vite 最新版本已经支持了一种 HTML 环境变量替换,参见:HTML 环境变量替换

luy19 commented 1 year ago

理论上说,vite-plugin-virtual-mpa应该负责把包含ejs语法的模板文件处理好之后再交给vite。

这个插件是支持 ejs 语法的,参见:

https://github.com/emosheeep/vite-plugin-virtual-mpa/blob/d4313f1c553742511eb28654d8714e2bbb89aff1/workspaces/plugin/src/plugin.ts#L111-L134

问题在于访问 http://localhost:5173/ 时会直接交由 vite 处理,vite 会默认重定向到根目录 index.html 文件,然而 ejs 语法 vite 还不支持,直接抛出了错误。

顺便提一句,vite 最新版本已经支持了一种 HTML 环境变量替换,参见:HTML 环境变量替换

又绕回来了,这样的争论是无意义的,为什么vite-plugin-virtual-mpa不能优先于vite处理它呢?比如说这样:https://github.com/emosheeep/vite-plugin-virtual-mpa/issues/30#issuecomment-1492845641

emosheeep commented 1 year ago

我理解肯定是要先经过插件处理再交给 vite 的。我们之前那个规则问题在与,是我们自己将/→/index.html,但是还没来得及做转换就流转到vite的transformIndex钩子里了

emosheeep commented 1 year ago

确实能复现了,emm,我还在想为什么🤔,暂时没有思路,我看好像重启了下就好了...

据我的分析,是下面这条rewrite规则有问题:

https://github.com/emosheeep/vite-plugin-virtual-mpa/blob/d4313f1c553742511eb28654d8714e2bbb89aff1/workspaces/plugin/src/plugin.ts#L82-L89

我的临时解决方案是在vite.config.js增加一个plugin

const rewriteMiddlewarePlugin = {
  name: "rewrite-middleware",
  configureServer(serve) {
    serve.middlewares.use((req, res, next) => {
      if (req.url === "/") {
        req.url = "index.html";
      }
      next();
    });
  },
};

1.8.0 发布了,这个规则已经移除