Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Vite 在 max 中的启动报错问题 #10433

Closed
fz6m opened this issue Feb 6, 2023 · 3 comments · Fixed by #10770
Closed

[Bug] Vite 在 max 中的启动报错问题 #10433

fz6m opened this issue Feb 6, 2023 · 3 comments · Fixed by #10770

Comments

@fz6m
Copy link
Contributor

fz6m commented Feb 6, 2023

以下是在 #10337 的当时探究结果汇总,留次记录。

由于 Vite 迭代仍在进行,storybook 也有类似问题,可能存在过时,有待进一步跟进和思考解法。

TL;DR

太长不看版:

现在用 vite 模式启动 max (或是一个需要预构建依赖非常多的项目),需要等几秒再打开浏览器(等等 vite 预构建),否则 vite 会报错,不能马上打开浏览器发送请求。

以下是问题详细说明与探索路径。

关于 max 模板项目无法在 vite 4 中启动 dev 开发的问题

问题原因

启动项目后,在 vite 编译好 .vite/deps_temp ,生成 .vite/deps_temp/_metadata.json 之前,不能打开浏览器访问项目,否则 这一行 vite 代码 就会报错 :

  await renameDir(processingCacheDir, depsCacheDir)

该行的作用是将 .vite/deps_temp rename 到 .vite/deps

但是这个时候预编译还没完成,根本没有 .vite/deps_temp/* ,所以就爆炸了,我们预期的是编译结束后再进入该逻辑,但此时没编译完成就进入了该逻辑,原因未知,推测这和依赖数量有关系,比如 umi 普通模板项目,在浏览器访问时马上就编译好了,因为依赖很少,所以这一行代码没有问题,但像 max 模板项目或者 issue 9986 中的 storybook 项目,依赖非常多,所以此时还没编译好就走到这个逻辑了。

而完成这些依赖编译更是需要 20s+ 的时间(此时不考虑人工指定跳过某些依赖的优化,因为确实依赖非常多)。

所以不能在 .vite/deps_temp/_metadata.json 编译好前用浏览器访问项目。

探索 1

顺着这个思路,我们用前置中间件拦截请求,不断去轮询检测 .vite/deps_temp/_metadata.json.vite/deps/_metadata.json 的存在性,只有编译结束后我们才放行请求。

此尝试可以解决 vite 如上所示的一行代码报错问题,但至少需要刷新 3 次页面才能正常进入项目,推测这和 vite 又发现了新的依赖需要多次优化有关:

screenshot_2023-01-29_18-41-39

目前已知的信息

  1. 根据 vite issue 9986 反馈,这似乎是竞争条件引起的,但我不这么认为,通过如上探索暴露了两个问题:
    i. vite 的预编译没结束就进入了 commit 逻辑。
    ii. vite 多次优化依赖不能在一次请求中完成,要用户多次请求,多次发现依赖,才能完成全部的依赖预构建(这是一个初步猜测)。

  2. vite 3 版本:不会 rename 报错,同样需要用户刷新多次( >=3 )页面,否则依赖预编译不会完成。

  3. vite 4.0.3 版本没有删除 .vite/deps 的逻辑,但到了 vite 4.0.4 通过 vite PR #11499 增加了该逻辑后,就会引发 rename 报错的问题。遂尝试 4.0.3 的表现:
    i. 我的尝试:发现不会 rename 报错,但同样需要刷新页面至少 3 次,vite 对依赖的预构建才能全部完成,进入项目。
    ii. @xierenyuan 尝试:还是有随机引发报错的情况。(但我没有发生过一次报错)

设备带来的差异

@xierenyuan :本地没有需要多次刷新的问题,但需要等待 20s+ ,主要是 pro-component 被挂起了。

现在的解法

还没想到如何 hack 解决,初步判断无解。

根据目前的探索来看,有两个可能的跑通项目办法:

  1. vite >= 4.0.4: 通过前置的阻塞中间件拦截请求,当预构建完毕后,用户再刷新多次页面,才能看到项目内容。

  2. vite = 4.0.3 (包含对 vite >= 4.0/4 patch 的情况):用户需要多次刷新页面,才能看到项目内容。

有待进一步探索和寻求帮助。

如上所述中前置阻塞脚本的草稿
import { IApi } from '@umijs/max';
import fs from 'fs';
import path from 'path';

const isCompileOver = (dir: string) =>
  fs.existsSync(path.join(dir, '_metadata.json'));

export default (api: IApi) => {
  const viteDir = path.join(api.paths.absNodeModulesPath, '.vite');
  const tempDir = path.join(viteDir, 'deps_temp');
  const depsDir = path.join(viteDir, 'deps');
  let prevTimer: ReturnType | null = null;
  const nextCheck = (next: any) => {
    if (isCompileOver(depsDir) || isCompileOver(tempDir)) {
      console.log('over');
      next();
      return 
    } else {
      console.log('pending...');
      if (prevTimer) {
        clearTimeout(prevTimer);
      }
      prevTimer = setTimeout(() => {
        nextCheck(next);
      }, 500);
    }
  };

  api.addBeforeMiddlewares(() => [
    (req, res, next) => {
      nextCheck(next);
    },
  ]);
};

Originally posted by @fz6m in #10337 (comment)

@codedart2018
Copy link

第一次用vite就遇到控制台蛋疼的红警

@JohnChan1996
Copy link

遇到 deps_temp 不存在导致项目启动失败爆红的情况,目前的解决方案是关闭 server 下的 open(open:false),在启动项目完成之后,等待 5-10 秒钟,然后再手动打开项目。。

@xierenyuan
Copy link
Member

vitejs/vite#9986 看起来 vite 修复呢 等发正式版 我升级看看

@fz6m fz6m changed the title [Bug] Vite 在 max 中的启动问题 [Bug] Vite 在 max 中的启动报错问题 Mar 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants