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

改进:仅根据实际 pages 配置响应虚拟入口,不在配置内的 html 资源由 vite 正常响应 #15

Closed
jiadesen opened this issue Jan 10, 2023 · 24 comments
Labels
enhancement New feature or request

Comments

@jiadesen
Copy link
Contributor

jiadesen commented Jan 10, 2023

如题

@emosheeep
Copy link
Owner

之前考虑过,不过因为实际使用的时候没有遇到相关场景所以也就搁置了,周末有空看下

@emosheeep
Copy link
Owner

我发现,不在配置内的文件依旧响应了,但是打包后的产物依旧是不包含的那些未配置的文件的,比如说example里面的index.html,产物里面并不存在这个文件,是不是会造成一些疑惑

@emosheeep emosheeep reopened this Feb 21, 2023
@jiadesen
Copy link
Contributor Author

jiadesen commented Feb 21, 2023

vite 现在的默认行为是:

  1. 对于单页应用,使用根目录的 index.html 即可,所有配置默认即可,也没有必要使用这个插件。
  2. 对于多页应用,需要参照官方多页应用模式配置使用,而且一旦使用,构建产出将严格按照配置进行构建,这就意味着,如果将 main 注释掉,将不会构建默认的 index 入口,但该入口在开发环境依然可以访问
// vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        // 注释 index 入口
        // main: resolve(__dirname, 'index.html'),
        nested: resolve(__dirname, 'nested/index.html'),
      },
    },
  },
})

不在配置内的文件依旧响应了,但是打包后的产物依旧是不包含的那些未配置的文件的

所以,对于多入口需求,我们和官方设计保持一致,构建产物将严格按照多入口配置进行。

@jiadesen
Copy link
Contributor Author

再看官方文档关于index.html 与项目根目录的描述,其中很重要的一句话是 在开发期间 Vite 是一个服务器,而 index.html 是该 Vite 项目的入口文件。这就意味着,项目所有的资源在开发期间都可以单独访问,这是Vite 只需要在浏览器请求源码时进行转换并按需提供源码的基础

@emosheeep
Copy link
Owner

我准备提供一下preview服务器的一些默认配置,遇到了一点问题,我再看看🤔

@jiadesen
Copy link
Contributor Author

准备提供一下preview服务器的一些默认配置

没太明白,有什么诉求以及想达到的效果,可以详细说说么?

@jiadesen
Copy link
Contributor Author

jiadesen commented Feb 21, 2023

是 vite 的 preview 服务么?如果是的话这应该跟插件本身没有关系。

@emosheeep
Copy link
Owner

是的,因为开发和构建用的工具不一样,经常出现本地开发和线上效果不一样。所以总需要验证本地产物正确性。但是目前只做了开发服务器的配置,没有配置预览服务器,需要简单配置一下html fallback

@jiadesen
Copy link
Contributor Author

预览服务是独立的,和开发服务可以共存啊,你是想通过开发服务访问产物么?

@jiadesen
Copy link
Contributor Author

经常出现本地开发和线上效果不一样

这个问题也详细说说?我想我可以提供一些解决方案

@emosheeep
Copy link
Owner

经常出现本地开发和线上效果不一样

这个问题也详细说说?我想我可以提供一些解决方案

没事,这个问题主要来自于 rollup 和 esbuild 的表现不一致,发现一个解决一个就好了

@jiadesen
Copy link
Contributor Author

jiadesen commented Feb 21, 2023

发现一个解决一个就好了

这个很难受啊,比如使用 vant,通过提取所有 vant 样式到一个文件来解决开发和产物表现不一致的问题:

// 构建配置
build: {
    // 底层 Rollup 打包配置
    rollupOptions: {
        output: {
            manualChunks(id) {
                const regVantStyles =
                    /[\\/]node_modules[\\/]vant(.*)\.(s?css|less|sass)$/;

                switch (true) {
                    case regVantStyles.test(id):
                        return "chunk-vant-styles";
                }
            },
        },
    },
},

@emosheeep
Copy link
Owner

你这种还只是样式,我们直接是报错,比如开发时正常运行,线上报错,xxx is not a function,排查发现是一个函数的打包出来变成了default,就是原本 a(),现在要用a.default()。这中很明显就是打包工具差异性造成的,需要做一些额外配置才能保持一致

@jiadesen
Copy link
Contributor Author

这么严重...我这使用 @vitejs/plugin-legacy 配合 .browserslistrc 配置一切都还好,兼容性目标跟 vue3 对齐,ios10 能跑往上就不再看了...

Chrome >= 51
iOS >= 10

@emosheeep
Copy link
Owner

不是浏览器问题,是产物问题,commonjs和esm的转换问题默认行为不一致

@emosheeep
Copy link
Owner

#26
感兴趣可以看下

@jiadesen
Copy link
Contributor Author

emosheeep added a commit that referenced this issue Feb 21, 2023
@emosheeep
Copy link
Owner

vite 现在的默认行为是:

  1. 对于单页应用,使用根目录的 index.html 即可,所有配置默认即可,也没有必要使用这个插件。
  2. 对于多页应用,需要参照官方多页应用模式配置使用,而且一旦使用,构建产出将严格按照配置进行构建,这就意味着,如果将 main 注释掉,将不会构建默认的 index 入口,但该入口在开发环境依然可以访问
// vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        // 注释 index 入口
        // main: resolve(__dirname, 'index.html'),
        nested: resolve(__dirname, 'nested/index.html'),
      },
    },
  },
})

不在配置内的文件依旧响应了,但是打包后的产物依旧是不包含的那些未配置的文件的

所以,对于多入口需求,我们和官方设计保持一致,构建产物将严格按照多入口配置进行。

https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/index.ts#L642-L643

我查看了官方的配置,官方根据 appType 为 mpa 还是 spa 来决定是否采用 spaFallback,这里应该就是你说的逻辑吧,对应的 htmlFallbackMiddleware 在这里

然后我感觉我们之前的实现有问题,也就是这块
https://github1s.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/htmlFallback.ts#L7

          {
            /** Vite's default behavior */
            from: /.*/,
            to: ctx => {
              const { parsedUrl: { pathname } } = ctx;
              return normalizePath(pathname?.endsWith('.html') ? pathname : `${pathname}/index.html`);
            },
          },

]
这里重定向有问题,pathname 如果是,/test/icon.svg 他会重定向到 /test/icon.svg/index.html

@emosheeep emosheeep reopened this Mar 31, 2023
@emosheeep
Copy link
Owner

我觉得好像我们和这里保持一致就行了,判断下,如果只有一个page就认为是 spa 否则认为是 mpa,然后用官方的 fallback 插件就行

@jiadesen
Copy link
Contributor Author

这里重定向有问题,pathname 如果是,/test/icon.svg 他会重定向到 /test/icon.svg/index.html

不是有 htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'] 么,我这里测试没观察到问题...

@jiadesen
Copy link
Contributor Author

要不你先改改看,我也研究下

@emosheeep
Copy link
Owner

emosheeep commented Mar 31, 2023

是这样,我的场景

createMpaPlugin({
        rewrites: [
          // 开发环境使用boe.html作为entry
          { from: /\/audit\/((?!.*\.svg)).*/, to: '/audit/boe.html' },
        ],
        pages: [
          { name: 'boe', data: { iconPath: '/icon-boe.svg' } },
          { name: 'prod', data: { iconPath: '/icon-prod.svg' } },
        ],
      }),

我怀疑是不是我的rewrites写的有问题

@emosheeep
Copy link
Owner

有空再改改看,先搬砖了

@emosheeep
Copy link
Owner

emosheeep commented Mar 31, 2023

image

上面那个配置,它就会变成这样,但是这个路劲他其实是vite 的 public目录下的内容 我发现很神奇的是,这个路径如果不直接通过浏览器地址栏输入,他就是可以正常被解析到图片的,但是如果在浏览器地址栏直接输入这个地址,就会出现这个问题,奇怪,是哪里理解的不对吗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants