Skip to content

feat: add @vaadin/vaadin-core and @vaadin/vaadin meta packages - #12747

Open
totally-not-ai[bot] wants to merge 7 commits into
mainfrom
feat/meta-packages
Open

feat: add @vaadin/vaadin-core and @vaadin/vaadin meta packages#12747
totally-not-ai[bot] wants to merge 7 commits into
mainfrom
feat/meta-packages

Conversation

@totally-not-ai

@totally-not-ai totally-not-ai Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

This repository now builds the @vaadin/vaadin-core and @vaadin/vaadin packages, which ship every component in one npm package. Their dependencies and entry point imports are generated from the workspace, so a new component is always included instead of being added by hand.

What changed

This change is additive for the repository: it adds two new packages and a script, and touches no existing component.

For users of the published packages it is a behavior change: importing @vaadin/vaadin-core or @vaadin/vaadin now registers components that the hand-maintained entry points had missed. The free entry point was last updated in 2023, so it left out badge, breadcrumbs, card, markdown, master-detail-layout, popover, slider and switch, and the commercial one had no import for map. Applications that import these packages get more components registered than before, and therefore a larger bundle. Nothing is removed or renamed.

  • New packages/vaadin-core and packages/vaadin, with a README, a package.json, a generated entry point and tests. packages/vaadin-core also carries the Apache-2.0 LICENSE file.
  • New scripts/generateMetaPackages.js. It sorts a package into @vaadin/vaadin-core when it is licensed under Apache-2.0 and into @vaadin/vaadin when it is not, pins every workspace dependency to the repository version, and imports a vaadin-*.js entry point only when it registers a custom element or an iconset. Theme packages are dependencies but are not imported, since they ship styles and icons.
  • @vaadin/router, @vaadin/vaadin-usage-statistics and @vaadin/vaadin-development-mode-detector stay dependencies of @vaadin/vaadin-core, as they are on npm today. This repository does not build them, so the generator leaves them alone and their version is bumped in the committed package.json.
  • New scripts: yarn release:meta regenerates the files and now runs as part of yarn release, so what is published always matches the repository. yarn lint:meta only checks the committed files and fails when a component is missing.
  • scripts/buildWebtypes.js skips the new vaadin package, DEVELOPMENT.md documents the workflow, and yarn.lock is deduplicated so the usage statistics and development mode detector resolve to a single version.

Use case

A developer starting a prototype wants every Vaadin component available without adding a package per component. They install one package and import it once:

// Registers all free components: vaadin-button, vaadin-grid, vaadin-card, ...
import '@vaadin/vaadin-core';
<vaadin-card>
  <vaadin-button theme="primary">Save</vaadin-button>
</vaadin-card>

For the commercial components as well (charts, crud, dashboard, grid-pro, map, rich-text-editor), they import @vaadin/vaadin instead, which also includes everything from @vaadin/vaadin-core. For production, importing only the packages an application uses keeps the bundle small.

Test summary

# Status What the test verifies Why it matters
1 Importing @vaadin/vaadin-core registers the core components, including the ones missing from the old hand-written entry point (badge, card, markdown, master-detail-layout, popover, slider, switch) This is the bug the change fixes; a regression would silently drop components again
2 Secondary entry points are imported too, so elements their main entry point does not register (e.g. vaadin-grid-column, vaadin-login-form, vaadin-breadcrumbs-item) are available The generator walks imports to decide this; a mistake leaves half a component unusable
3 @vaadin/vaadin-core does not register commercial components (vaadin-chart, vaadin-map) The Apache-2.0 / commercial split is the contract of the free package
4 Importing @vaadin/vaadin registers the commercial components and the core ones @vaadin/vaadin must ship everything
5 gap yarn lint:meta fails when the committed files are out of date, and the generator keeps the external dependencies untouched Only checked in CI on the generated output; a broken generator would be noticed when the check fires, not by a unit test
  • vaadin-core.test.js — "should register the core components" → 1; "should register the components of the other entry points" → 2; "should not register the commercial components" → 3
  • vaadin.test.js — "should register the commercial components" → 4; "should register the core components as well" → 4

The generator script itself has no unit tests: it is a build-time script, and its output is pinned by the committed files plus yarn lint:meta in CI. READMEs, the LICENSE file and package metadata are not tested.

Both packages ship every component in one npm package and were published
from the vaadin/vaadin-core and vaadin/vaadin repositories so far, with
their dependencies generated by the platform from versions.json and the
imports of their entry point maintained by hand. That entry point had
drifted: the free one was last updated in 2023, so importing it left out
badge, breadcrumbs, card, markdown, master-detail-layout, popover,
slider and switch, and the commercial one had no import for map.

Here their dependencies and the imports of their entry point are
generated from the workspace instead, by scripts/generateMetaPackages.js:
a package belongs to @vaadin/vaadin-core when it is licensed under
Apache-2.0 and to @vaadin/vaadin when it is not, and an entry point is
imported when it registers a custom element or an iconset. Their version
is the version of the repository, which Lerna keeps in lockstep with the
packages they pin, rather than the platform version.

`yarn lint:meta` fails when a component is missing from the generated
files, so adding one to the repository covers them as well.

The router, the usage statistics and the development mode detector, which
the published @vaadin/vaadin-core also depends on, are left out: they are
not part of this repository.
The `.sort()` calls had no compare function, which S2871 reports as a bug
since the default one sorts by code unit. They now use `localeCompare`
with an explicit locale, so the generated files stay the same whichever
locale the machine of the build has. The generated files are unchanged.

`THEME_PACKAGES` and `metaPackageDirs` are sets rather than arrays, as
they are only used for lookups.
A sort with no compare function orders by code unit rather than by
locale, so the previous `localeCompare` call was the one that could
differ between machines, through their ICU data, and its comment claimed
the opposite. The compare function is now an explicit code unit
comparison, which keeps SonarCloud happy without depending on a
collation. The generated files are unchanged.
The router, the usage statistics and the development mode detector are
dependencies of `@vaadin/vaadin-core` on npm today, so the package has to
keep them. This repository does not build them and they have versions of
their own, so they stay in the committed `package.json` and the generator
now leaves every dependency it does not build alone, generating only the
packages of the workspace.

The description, the keywords and the license of the two packages are the
ones they are published with as well, so that nothing about them changes
but where they are built.
Keeping every dependency the workspace does not provide made the list
implicit: a package removed from the repository, or made private, would
drop out of the workspace and thus be kept as if it were external,
leaving the meta package depending on a version that is never published.
The three packages this repository does not build are now named, so a
removed component disappears from the meta packages as it should, which
`yarn lint:meta` then reports.
Comment thread package.json Outdated
Comment thread yarn.lock Outdated
`generate:meta` is now `release:meta`, next to the other scripts that
produce what a release publishes. `lint:meta`, which only verifies the
committed files, keeps its name.

The exact versions the meta packages pin also left `yarn.lock` with two
copies of the usage statistics and the development mode detector, as the
ranges of the other packages still resolved to older versions of them.
Both now resolve to the pinned version, which satisfies every range.

@web-padawan web-padawan 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.

Could also deprecate these packages via issueWarning() as we plan to remove them in V26: vaadin/platform#8481. Let's first discuss this with a team. Personally, I don't have a strong opinion.

Comment thread .github/workflows/verify.yml Outdated
run: yarn lint:types

- name: Check meta packages
run: yarn lint:meta

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.

suggestion: remove this. The release script is always run before publishing new version, so meta packages should be always up to date.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed. yarn release runs release:meta before publishing, so what ends up on npm always matches the repository regardless of the committed files. yarn lint:meta is still there for whoever wants to check them locally, and DEVELOPMENT.md now says that the release is what guarantees it.

The release regenerates the meta packages before publishing, so what is
published always matches the repository and the workflow does not need
to verify the committed files. `yarn lint:meta` still reports whether
they are up to date for whoever wants to check.
@sonarqubecloud

Copy link
Copy Markdown

@totally-not-ai

Copy link
Copy Markdown
Contributor Author

@web-padawan On deprecating them: I have left it out of this PR, since it changes what applications see at runtime and is worth agreeing on separately.

It is a small change when the team decides: the entry points are generated, so scripts/generateMetaPackages.js would emit an issueWarning() call (from @vaadin/component-base/src/warnings.js) after the imports, in both packages, naming the individual packages as the replacement. The warning fires once per message, so an application would see it once at startup.

Worth weighing against that: the audience is not only applications importing the package directly. If the deprecation lands in a 25.x patch, anything that happens to pull one of them in also starts logging it, and there is no way for an application to silence it. Doing it in the first 25.x feature release rather than a patch, with the removal in V26 per vaadin/platform#8481, would give the notice a natural place. Happy to add it either way once there is a decision.

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.

1 participant