Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants