Skip to content

feat(bundler-helper): add bundler-helper package#1708

Open
Mister-Hope wants to merge 4 commits into
mainfrom
bundler-helper
Open

feat(bundler-helper): add bundler-helper package#1708
Mister-Hope wants to merge 4 commits into
mainfrom
bundler-helper

Conversation

@Mister-Hope
Copy link
Copy Markdown
Member

@Mister-Hope Mister-Hope commented May 19, 2026

This PR migrated bundler related functions from @vuepress/helper to @vuepress/bundler-helper (a new package in core).

We are going to have 3 bundlers now, so such helper is quite useful.

Also it's better to align the package with core.

Plus, the package solves sevel problems:

  1. Providing config and let them being merged to final config automatically. For Webpack this might be easy, but for vite this is not easy, as mergeViteConfig function is not available (could be a PR later).
  2. It's complex for developers to handle bundler config in plugins and themes:

Code from official docs (Ref):

export default {
  extendsBundlerOptions: (bundlerOptions, app) => {
    // extends options of @vuepress/bundler-vite
    if (app.options.bundler.name === '@vuepress/bundler-vite') {
      bundlerOptions.vuePluginOptions ??= {}
      bundlerOptions.vuePluginOptions.template ??= {}
      bundlerOptions.vuePluginOptions.template.compilerOptions ??= {}
      const isCustomElement =
        bundlerOptions.vuePluginOptions.template.compilerOptions.isCustomElement
      bundlerOptions.vuePluginOptions.template.compilerOptions.isCustomElement =
        (tag) => {
          if (isCustomElement?.(tag)) return true
          if (tag === 'my-custom-element') return true
        }
    }

    // extends options of @vuepress/bundler-webpack
    if (app.options.bundler.name === '@vuepress/bundler-webpack') {
      bundlerOptions.vue ??= {}
      bundlerOptions.vue.compilerOptions ??= {}
      const isCustomElement = bundlerOptions.vue.compilerOptions.isCustomElement
      bundlerOptions.vue.compilerOptions.isCustomElement = (tag) => {
        if (isCustomElement?.(tag)) return true
        if (tag === 'my-custom-element') return true
      }
    }
  },
}

Now:

import { addCustomElement } from 'vuepress/bundler-helper'

export default {
  extendsBundlerOptions: (bundlerOptions, app) => {
    addCustomElement(bundlerOptions, app, 'my-custom-element')
  }
}

@coveralls
Copy link
Copy Markdown

coveralls commented May 19, 2026

Coverage Report for CI Build 26090929246

Coverage decreased (-0.4%) to 72.564%

Details

  • Coverage decreased (-0.4%) from the base build.
  • Patch coverage: 6 uncovered changes across 1 file (2 of 8 lines covered, 25.0%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
packages/utils/src/packageManager/getRunningPackageManager.ts 8 2 25.0%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1069
Covered Lines: 772
Line Coverage: 72.22%
Relevant Branches: 542
Covered Branches: 397
Branch Coverage: 73.25%
Branches in Coverage %: Yes
Coverage Strength: 45.46 hits per line

💛 - Coveralls

@meteorlxy
Copy link
Copy Markdown
Member

  • The name pattern bundler-[bundler-name] is for bundlers. That's why we name another package as bundlerutils. (Similarly, rollup has pluginutils)

  • Any necessity to put this package into core instead of ecosystem?

@Mister-Hope
Copy link
Copy Markdown
Member Author

Mister-Hope commented May 19, 2026

  1. Bundler updates are made in core, and this aligns support for bundler helper package in each release. We should consider that bundler configs changed in time, so moving this to core ensures there is no support mismatch in future.
  2. Having this package under ecosystem makes no help for users. They just do not realize we have such helpers at all. This even happens at default theme, I believe at least 1/5 people fails to find default theme docs in 3 minutes. So having a easy reachable vuepress/bundler-helper is enough as a motivation.
  3. A lot of current vuepress users are developers using other languages as VitePress do not have such plugin systems. Bundlers are unfamilar concept for them (in their languages there just compiler and packer). So it helps that core wraps complex bundler options with helper functions.

@meteorlxy
Copy link
Copy Markdown
Member

Re1: That increases the complexity of core, which is not necessary.

Re2: That means we should improve the documentation, but not move it to core.

Re3: Users who do not familiar with bundlers should not update bundler options, should they?

IMO only advanced users / theme & plugin authors would try updating bundler options themselves, and they should be aware of the official ecosystem.

@Mister-Hope
Copy link
Copy Markdown
Member Author

Mister-Hope commented May 19, 2026

Re1: That increases the complexity of core, which is not necessary.

Again: so moving this to core ensures there is no support mismatch in future.

Avoiding possible future behavior mismatch is necessary. With a sub-export, we ensures our bundler helper is always up-to-date with current bundler.

Re2: That means we should improve the documentation, but not move it to core.

Again: So having a easy reachable vuepress/bundler-helper is enough as a motivation.

The following looks like bullshit💩:

Details examples in official docs
export default {
  extendsBundlerOptions: (bundlerOptions, app) => {
    // extends options of @vuepress/bundler-vite
    if (app.options.bundler.name === '@vuepress/bundler-vite') {
      bundlerOptions.vuePluginOptions ??= {}
      bundlerOptions.vuePluginOptions.template ??= {}
      bundlerOptions.vuePluginOptions.template.compilerOptions ??= {}
      const isCustomElement =
        bundlerOptions.vuePluginOptions.template.compilerOptions.isCustomElement
      bundlerOptions.vuePluginOptions.template.compilerOptions.isCustomElement =
        (tag) => {
          if (isCustomElement?.(tag)) return true
          if (tag === 'my-custom-element') return true
        }
    }

    // extends options of @vuepress/bundler-webpack
    if (app.options.bundler.name === '@vuepress/bundler-webpack') {
      bundlerOptions.vue ??= {}
      bundlerOptions.vue.compilerOptions ??= {}
      const isCustomElement = bundlerOptions.vue.compilerOptions.isCustomElement
      bundlerOptions.vue.compilerOptions.isCustomElement = (tag) => {
        if (isCustomElement?.(tag)) return true
        if (tag === 'my-custom-element') return true
      }
    }

    // even more for the comming rspack
    // new shit here
  },
}

If VuePress core inisit leveling up the developing difficulty like this, it is expected that no new active contributors appears in our ecosystem.

We should not build high walls for developers and users. A lot of plugins WILL FAIL to run with vite/webpack with the default setting.

I strongly inisit that our core should decrease the difficulty handling our bundler combinations with richer starter tools. The core SHOULD earse/lower the differences between bundlers just like how it's code is written. This should NOT be a ecosystem work.

I try to ask a lot of project which supports VitePress to support VuePress, and a lot of anwser is No, besides the reason that we are in RC stage, a steedy understanding needs with our bundler system is the other major reason.

Re3: Users who do not familiar with bundlers should not update bundler options, should they?

No, I've seen lots of reasonable needs comming from my theme users.

E.g.:

  • They imported a 3-rd party custom-component, that requires a customElement setting.
  • They imported a heavy library, which requires manual chunking and preload/prefetch disabling (that's why I am still pushing effort to improve this option).

Updated

Another major reason is that VuePress produces heavy/dirty bundelr config to make itself work. A careless override of any root config (e.g.: the whole resolve part) likely breaks how VuePress works.

At least the core are supposed to provide helpers like this:

addViteConfig(bundlerOptions, app, {
  // simplest option that is required
})

addWebpackConfig(bundlerOptions, app, {
  // simplest option that is required
})

addRspackConfig(bundlerOptions, app, {
  // simplest option that is required
})

We are providing a documentation tool, not a devloping tool, so it's faire that we requires the core to care adjusting bundling behavior.

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 this pull request may close these issues.

3 participants