Skip to content

fix(model): don't require TimelineComponent for media-only option. close #21686 - #21749

Open
MohammadWasi wants to merge 1 commit into
apache:releasefrom
MohammadWasi:fix/media-timeline-dependency
Open

MohammadWasi wants to merge 1 commit into
apache:releasefrom
MohammadWasi:fix/media-timeline-dependency

Conversation

@MohammadWasi

@MohammadWasi MohammadWasi commented Sep 5, 2026

Copy link
Copy Markdown

Brief Information

This pull request is in the type of:

  • bug fixing
  • new feature
  • others

What does this PR do?

Stops ECharts from wrongly requiring TimelineComponent when an option uses the { baseOption, media } form without a timeline.

Fixed issues

Details

Before: What was the problem?

Using the modular build without registering TimelineComponent, an option structured with baseOption + media but no timeline reported:

Component timeline is used but not imported.
import { TimelineComponent } from 'echarts/components';
echarts.use([TimelineComponent]);

Depending on the environment this surfaces as an exception during setOption, forcing users to register a component they don't use.

Root cause: in OptionManager.parseRawOption, when a baseOption is declared, the parser injects the root timeline into it for merge purposes:

if (!baseOption.timeline) {
    baseOption.timeline = timelineOnRoot; // `undefined` when no timeline is configured
}

This leaves an own timeline key on baseOption whose value is undefined. checkMissingComponents then iterates every key of the option and reports any mainType whose class isn't registered — so the empty timeline entry is wrongly flagged as a missing TimelineComponent. It only reproduces with the { baseOption, media } form because the plain root-option path doesn't inject that key.

After: How does it behave after the fixing?

checkMissingComponents now skips component options whose value is null/undefined, since such an entry means the component isn't actually used. An option with baseOption + media and no timeline works with the modular build without registering TimelineComponent. Genuine missing-component reporting is unchanged (a real timeline: {...} still reports when unregistered).

each(option, function (componentOption, mainType) {
    // A `null`/`undefined` option value means the component is not actually used.
    if (componentOption != null && !ComponentModel.hasClass(mainType)) {
        // ...report as missing...
    }
});

The fix is guarded by __DEV__ (this check only runs in development builds), so there is no production behavior change.

Regression test

Added a case to test/ut/spec/model/componentMissing.test.ts asserting that a { baseOption, media } option without a timeline does not report TimelineComponent as missing. Verified it fails on master (reproduces the bug) and passes with this fix. The full test/ut/spec/model suite passes, along with npm run lint and npm run checktype.

Document Info

One of the following should be checked.

  • This PR doesn't relate to document changes
  • The document should be updated later
  • The document changes have been made in apache/echarts-doc#xxx

Misc

Security Checking

  • This PR uses security-sensitive Web APIs.

ZRender Changes

  • This PR depends on ZRender changes (ecomfe/zrender#xxx).

Related test cases or examples to use the new APIs

Added a Jest regression test in test/ut/spec/model/componentMissing.test.ts.

@echarts-bot

echarts-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

Thanks for your contribution!
The community will review it ASAP. In the meanwhile, please checkout the coding standard and Wiki about How to make a pull request.

Please DO NOT commit the files in dist, i18n, and ssr/client/dist folders in a non-release pull request. These folders are for release use only.

@plainheart
plainheart requested a review from 100pah September 12, 2026 00:58
@plainheart plainheart added this to the 6.1.1 milestone Sep 12, 2026

@plainheart plainheart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi, can you change the merge target to the release branch?

@MohammadWasi
MohammadWasi changed the base branch from master to release September 12, 2026 01:54
@MohammadWasi

Copy link
Copy Markdown
Author

Hi, can you change the merge target to the release branch?

Done

@plainheart

Copy link
Copy Markdown
Member

@MohammadWasi rebase is required.

 apache#21686

When an option uses the full `{ baseOption, media }` form without a
`timeline`, `OptionManager.parseRawOption` injects an empty `timeline`
key into `baseOption` (`baseOption.timeline = timelineOnRoot`, where
`timelineOnRoot` is `undefined`). `checkMissingComponents` then iterated
that key and wrongly reported `TimelineComponent` as "used but not
imported", even though no timeline is configured.

Guard `checkMissingComponents` so component options whose value is
`null`/`undefined` are not treated as used. Adds a regression test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MohammadWasi
MohammadWasi force-pushed the fix/media-timeline-dependency branch from fce827d to ba9ae73 Compare September 12, 2026 02:00
@MohammadWasi

MohammadWasi commented Sep 12, 2026

Copy link
Copy Markdown
Author

@MohammadWasi rebase is required.

@plainheart Rebased onto release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] baseOption with media incorrectly requires TimelineComponent when no timeline is configured

2 participants