Skip to content

feat(core)!: refine bundler options#1714

Merged
meteorlxy merged 12 commits into
mainfrom
bundler-refine
Jul 23, 2026
Merged

feat(core)!: refine bundler options#1714
meteorlxy merged 12 commits into
mainfrom
bundler-refine

Conversation

@Mister-Hope

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

Copy link
Copy Markdown
Member

Summary

Refine the Bundler interface and bundler configuration hooks to give plugin authors the tools they need to configure bundler-specific behavior correctly and completely.


Problems & Rationale

1. Complex comparison to identify the active bundler

Plugins in extendsBundlerOptions need to know which bundler is active to add the right options (e.g. viteOptions vs chainWebpack). The only discriminator was bundler.name, which is the full scoped package name.

- app.options.bundler.name === '@vuepress/bundler-webpack'
+ app.options.bundler.type === 'webpack'

2. Missing merge helper in extendsBundlerOptions

When a plugin accepts user bundler options and wants to merge them into the resolved options, it needs the correct merge function (vite.mergeConfig vs webpack-merge differ in semantics). The hook only passes (options, app) — no merge helper.

We considered adding mergeConfig as a hook parameter, but all extends* hooks share the uniform signature (extendable: T, app: App):

// hooks.ts — every extends hook follows this pattern
extendsMarkdownOptions: ExtendsHook<MarkdownOptions>
extendsMarkdown: ExtendsHook<Markdown>
extendsPageOptions: ExtendsHook<PageOptions>
extendsPage: ExtendsHook<Page>
extendsBundlerOptions: ExtendsHook<BundlerOptions>

Adding a third parameter would break this consistency. So mergeConfig is exposed on the Bundler object instead:

  export interface Bundler {
    name: string
+   type: string
    dev: (app: App) => Promise<() => Promise<void>>
    build: (app: App) => Promise<void>
+   mergeConfig: <Config extends Record<string, any>>(
+     currentConfig: Config,
+     newConfig: DeepPartial<Config>,
+   ) => Config
  }

Plugins access it naturally: app.options.bundler.mergeConfig(...).

3. configureWebpack / configureVite cannot remove array items

The old merge-on-return model was purely additive — array items could only be appended, never deleted.

  // resolveWebpackConfig.ts
  const configureWebpackResult = options.configureWebpack?.(...)

- // if `configureWebpack` returns a configuration object,
- // use webpack-merge to merge it
  if (configureWebpackResult) {
-   return merge(webpackConfig, configureWebpackResult)
+   webpackConfig = configureWebpackResult
  }

Returning a value now fully replaces the config. To merge explicitly, use the mergeConfig callback parameter passed to the hook.

Note: the mergeConfig from vite always create a fresh new object at every level while merging.


Breaking changes

  • Bundler interface now requires type and mergeConfig.
  • configureWebpack return value replaces the config. Use the passed mergeConfig parameter to merge instead.

@coveralls

coveralls commented May 21, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 30002162063

Coverage remained the same at 73.154%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1087
Covered Lines: 793
Line Coverage: 72.95%
Relevant Branches: 552
Covered Branches: 406
Branch Coverage: 73.55%
Branches in Coverage %: Yes
Coverage Strength: 47.36 hits per line

💛 - Coveralls

Comment thread packages/bundler-vite/src/types.ts Outdated
Comment thread packages/bundler-vite/src/types.ts Outdated
Comment thread packages/bundler-vite/src/types.ts Outdated
Comment thread packages/bundler-webpack/src/types.ts
Co-authored-by: Mister-Hope <mister-hope@outlook.com>
Comment thread packages/bundler-webpack/src/types.ts Outdated
@meteorlxy

meteorlxy commented Jul 23, 2026

Copy link
Copy Markdown
Member
  • feat(bundler-vite): add configureVite option
  • feat(bundler-vite): export viteMergeConfig function
  • feat(bundler-webpack): export webpackMergeConfig function
  • feat(core): add type field to bundlers to indicate the underlying bundler
  • feat(core): add mergeConfig field to bundlers to provide config merging helper

BREAKING CHANGE: core - Bundler interface now requires type and mergeConfig.
BREAKING CHANGE: bundler-webpack - configureWebpack return value now replaces the config object directly. Use the webpackMergeConfig helper to merge configs manually instead.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines VuePress bundler configuration ergonomics for plugin authors by introducing a stable bundler discriminator (bundler.type) and changing the configureWebpack / configureVite hooks to support full config replacement (enabling array item removal), while also exposing bundler-specific merge utilities from bundler packages.

Changes:

  • Add Bundler.type and migrate core logic to use it instead of comparing bundler.name.
  • Change configureWebpack and introduce configureVite to allow returning a full config that replaces the generated config.
  • Re-export bundler merge helpers (webpackMergeConfig, viteMergeConfig) from the bundler packages.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/core/tests/app/resolveAppOptions.spec.ts Updates app-options test fixture to include new bundler.type.
packages/core/src/types/bundler.ts Extends the Bundler interface with a new type discriminator.
packages/core/src/app/resolveAppMarkdown.ts Switches bundler detection from bundler.name to bundler.type.
packages/bundler-webpack/src/webpackBundler.ts Sets webpack bundler type: 'webpack'.
packages/bundler-webpack/src/types.ts Updates configureWebpack documentation for new behavior.
packages/bundler-webpack/src/resolveWebpackConfig.ts Changes configureWebpack return behavior to replace (not merge) webpack config.
packages/bundler-webpack/src/index.ts Re-exports webpack-merge as webpackMergeConfig.
packages/bundler-vite/src/viteBundler.ts Sets vite bundler type: 'vite'.
packages/bundler-vite/src/types.ts Adds configureVite option for post-resolution Vite config modification/replacement.
packages/bundler-vite/src/resolveViteConfig.ts Implements configureVite handling with replacement-on-return behavior.
packages/bundler-vite/src/index.ts Re-exports Vite mergeConfig as viteMergeConfig.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/core/src/types/bundler.ts
Comment thread packages/bundler-vite/src/resolveViteConfig.ts
Comment thread packages/bundler-webpack/src/resolveWebpackConfig.ts
Comment thread packages/bundler-webpack/src/types.ts
@meteorlxy meteorlxy changed the title feat!: refine bundler options feat(core)!: refine bundler options Jul 23, 2026
@meteorlxy
meteorlxy merged commit 7ced1d9 into main Jul 23, 2026
18 checks passed
@meteorlxy
meteorlxy deleted the bundler-refine branch July 23, 2026 11:23
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.

4 participants