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

Glob support in optimizeDeps.include #5419

Closed
4 tasks done
sxzz opened this issue Oct 25, 2021 · 22 comments · Fixed by #12414
Closed
4 tasks done

Glob support in optimizeDeps.include #5419

sxzz opened this issue Oct 25, 2021 · 22 comments · Fixed by #12414
Assignees
Labels
enhancement New feature or request p2-nice-to-have Not breaking anything but nice to have (priority)

Comments

@sxzz
Copy link
Member

sxzz commented Oct 25, 2021

Clear and concise description of the problem

In some libraries, files in different paths need to be loaded frequently. The page will be refreshed every pre-build. So it is necessary to pre-build all the files that may be used at startup.

So I think glob should be supported to easily add files that may be needed.

image

Suggested solution

support glob in optimizeDeps.include/exclude

Alternative

No response

Additional context

Related issue #699 #1545
Related pr #1571

Validations

@sxzz
Copy link
Member Author

sxzz commented Oct 25, 2021

Chinese: 在某些库中,需要频繁地加载不同路径下的文件。每次预编译都会刷新页面。所以需要把可能要用到的所有文件都在启动时预编译。因此我想应该支持 glob 来更便捷地添加可能需要的文件。

@bluwy bluwy added the p2-nice-to-have Not breaking anything but nice to have (priority) label Mar 28, 2022
@bluwy
Copy link
Member

bluwy commented Mar 28, 2022

I have a need of this before for packages with many sub-exports, e.g. my-pkg/some-module and many other modules that could be known ahead of time. But Vite currently only understands what you import and dynamically prebundle thereafter.

I think globbing would be tricky to work with exports since only a subset of files are allowed to be imported, I wonder if the better solution is to have Vite auto optimize all sub-exports if the exports field exists.

@ghost
Copy link

ghost commented Jun 2, 2022

We have non-blocking optimization #8280, and it seems that this feature becomes unimportant.

@patak-dev
Copy link
Member

Interesting. I think we could try Blu's proposal here, or maybe to avoid surprises only support something like include: ['my-pkg/*'] to include all the exports of that package. Or maybe a generic glob over all the names of dependencies in the package JSON plus their exports? Maybe it is fast enough.

@sxzz
Copy link
Member Author

sxzz commented Jun 24, 2022

I think this feature is still needed.

Kapture.2022-06-24.at.21.01.40.mp4

image

Reproduction repo: https://github.com/sxzz/vite-optimize-deps (cannot work on stackblitz)

Reproduction steps:

  1. clear all cache, rm -fr node_modules/.vite
  2. run vite --force
  3. Once the page is loaded you can see these messages on the terminal.
9:01:28 p.m. [vite] ✨ new dependencies optimized: element-plus/es, element-plus/es/components/card/style/css
9:01:28 p.m. [vite] ✨ optimized dependencies changed. reloading
  1. Click About, vite will refresh the page. It means all states will be reseted, and the terminal will display the messages belows.
9:01:35 p.m. [vite] ✨ new dependencies optimized: element-plus/es/components/button/style/css
9:01:35 p.m. [vite] ✨ optimized dependencies changed. reloading
  1. Click About again, it will work finally.

@sapphi-red
Copy link
Member

sapphi-red commented Jun 26, 2022

@sxzz I found that * could be used for exclude actually (it is not documented in Vite so it may change in future though). https://esbuild.github.io/api/#external

Setting ['./node_modules/element-plus/es/components/*/style/css2.mjs'] to optimizeDeps.exclude reduces reload.

Also for your specific case, ['./node_modules/element-plus/es/components/base/style/css2.mjs'] will work too.

@patak-dev
Copy link
Member

I think we should add support for glob imports, at least document that * works. Thanks for taking the time to check this @sapphi-red, the second one is a nice trick to for element-plus.

@sxzz let us know if this works for you, better to wait to beta.3 though to test as there are a few other PRs to improve dev server perf about to be merged

@patak-dev
Copy link
Member

@sapphi-red do you have a repro of this working with that exclude? Trying it now and I still see the reloads (that could be related to something different)

@sxzz
Copy link
Member Author

sxzz commented Jun 26, 2022

@sapphi-red Hmmmm seems that it can't work for me.
image

@sapphi-red
Copy link
Member

sapphi-red commented Jun 26, 2022

It worked for me with npm and yarn(non pnp). But it didn't work with pnpm.
It seems symlink is affecting this.

@sapphi-red
Copy link
Member

This worked with pnpm. So symlinks does not work well.

import { defineConfig, normalizePath } from 'vite'
import vue from '@vitejs/plugin-vue'
import fs from 'fs/promises'
import path from 'path'
import url from 'url'

const exclude = './' + normalizePath(
  path.relative(
    url.fileURLToPath(new URL('./', import.meta.url)),
    path.join(
      await fs.realpath('./node_modules/element-plus/'),
      'es/components/*/style/css2.mjs'
    )
  )
)

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  optimizeDeps: {
    exclude: [exclude]
  }
})

@sxzz
Copy link
Member Author

sxzz commented Jun 26, 2022

Stills can't work for me.
image

@sapphi-red
Copy link
Member

The first reload is expected. Does it reload two times?

@patak-dev
Copy link
Member

Something odd is going on. I'll check it out. The first reload shouldnt be there either

@sxzz
Copy link
Member Author

sxzz commented Jun 26, 2022

@sapphi-red Yes,
image

@sapphi-red
Copy link
Member

@sxzz Your screenshot shows reloading is happening once and pre-bundle is happening twice.

@sxzz
Copy link
Member Author

sxzz commented Jun 26, 2022

Oh, just found it can avoid to refresh page now, and I had a better experience now as the same as 2.x.

image

But it seems to be complicated for users to write such a config.

Actually, I wrote a config to pre-optimize deps to fix this issue before.

optimizeDeps: {
  include: await glob(['element-plus/es/components/*/style/css.mjs'], {
    cwd: $r('node_modules'),
    onlyFiles: true,
  }),
},

Suggestion: Third-party dep can provide a metafile to help Vite consider which files should be included or excluded to be optimized. Out of the box for Vite users.

By the way, I have a question: Why some times it is possible to optimize dep without refreshing the page, and sometimes it is necessary to refresh the page.

@patak-dev
Copy link
Member

@sxzz see this comment #8721 (comment)

@patak-dev
Copy link
Member

@sxzz as a summary of the new strategy:

  • By default, dynamic routes are not crawled because it looks at this point like a better default.
  • You can add the most common visited routes to optimizeDeps.entries and there wouldn't be any reloads. Adding this to the config works well in beta.4:
optimizeDeps: {
    entries: ['src/App.vue', 'src/components/Footer.vue'],
    ...
  • You could also achieve the same with optimizeDeps.include of some key deps, which leads to a faster cold start.

We need more data to see if not crawling dynamic routes is the best default here. An alternative could be to crawl by default leading to no reloads but slower cold start and let the user opt-out of certain dynamic imports:

optimizeDeps: {
    scanDynamicImports: string | Regex | (string | Regex)[] | boolean

By default it would be scanDynamicImports: true

@sxzz
Copy link
Member Author

sxzz commented Jun 27, 2022

@patak-dev I see. Thanks for your answer.

@patak-dev
Copy link
Member

@sxzz the idea above is now implemented in:

I think that 'dynamic-scan' should be the best for vue-router based projects, at the expense of keeping the complexity of the esbuild scanner around.

This for out-of-the-box cold start, the best possible perf is still 'lazy' + including some deps in optimizeDeps.include (I'm going to work on DX around hinting wich ones should be included)

Let me know if you test the PR.

@sxzz
Copy link
Member Author

sxzz commented Jul 1, 2022

Repo: https://github.com/sxzz/vite3-optimize-deps

  • pre-scan / dynamic-scan is great, but the users have to add some esbuild plugins to optimizeDeps.esbuildOptions.plugins. If some plugins is not supported on esbuild, then some files cannot be found and optimized.
  optimizeDeps: {
    devStrategy: 'dynamic-scan',
    esbuildOptions: {
      plugins: [
        Transform({
          plugins: [
            VueEsbuild(),
            ComponentsEsbuild({
              resolvers: [ElementPlusResolver()],
            }),
          ],
        }),
      ],
    },
  },

dynamic-scan without esbuild plugins / lazy / refreshing 2 times.

  vite:deps new dependencies found: vue +0ms
  vite:deps Crawling dependencies using entries:
  vite:deps   /Users/kevin/Developer/reproduction/vite3-optimize-deps/src/App.vue +0ms
  vite:deps Scan completed in 6.83ms: {
  vue: '/Users/kevin/Developer/reproduction/vite3-optimize-deps/node_modules/.pnpm/vue@3.2.37/node_modules/vue/dist/vue.runtime.esm-bundler.js'
} +7ms
  vite:deps deps bundled in 30.24ms +39ms
  vite:deps ✨ optimized dependencies unchanged +1ms
  vite:deps new dependencies found: element-plus/es
  vite:deps   element-plus/es/components/button/style/css +212ms
  vite:deps deps bundled in 367.61ms +369ms
10:18:51 p.m. [vite] ✨ optimized dependencies changed. reloading
  vite:deps new dependencies found: element-plus/es/components/card/style/css +463ms
  vite:deps deps bundled in 336.22ms +338ms

dynamic-scan with esbuild plugins / no refreshing.

  vite:deps new dependencies found: vue +0ms
  vite:deps Crawling dependencies using entries:
  vite:deps   /Users/kevin/Developer/reproduction/vite3-optimize-deps/src/App.vue +0ms
  vite:deps Scan completed in 68.39ms: {
  'element-plus/es': '/Users/kevin/Developer/reproduction/vite3-optimize-deps/node_modules/.pnpm/element-plus@2.2.6_vue@3.2.37/node_modules/element-plus/es/index.mjs',
  'element-plus/es/components/button/style/css': '/Users/kevin/Developer/reproduction/vite3-optimize-deps/node_modules/.pnpm/element-plus@2.2.6_vue@3.2.37/node_modules/element-plus/es/components/button/style/css.mjs',
  vue: '/Users/kevin/Developer/reproduction/vite3-optimize-deps/node_modules/.pnpm/vue@3.2.37/node_modules/vue/dist/vue.runtime.esm-bundler.js',
  'element-plus/es/components/card/style/css': '/Users/kevin/Developer/reproduction/vite3-optimize-deps/node_modules/.pnpm/element-plus@2.2.6_vue@3.2.37/node_modules/element-plus/es/components/card/style/css.mjs'
} +68ms
  vite:deps deps bundled in 698.01ms +771ms
  vite:deps ✨ optimized dependencies unchanged +0ms

  • eager is the best. Without any optimizeDeps.esbuildOptions.plugins. The page can be opened directly without any refreshes. All deps will be optimized for the first time.
  vite:deps new dependencies found: vue
  vite:deps   element-plus/es
  vite:deps   element-plus/es/components/button/style/css
  vite:deps   element-plus/es/components/card/style/css +4s

@github-actions github-actions bot locked and limited conversation to collaborators Jun 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request p2-nice-to-have Not breaking anything but nice to have (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants