Skip to content

build: align package.json exports with @ui5/webcomponents convention - #38

Open
miloshevb wants to merge 3 commits into
mainfrom
build/moduleEntry
Open

miloshevb wants to merge 3 commits into
mainfrom
build/moduleEntry

Conversation

@miloshevb

Copy link
Copy Markdown
Member

Remove the default-entry fields (main, module, types) and the exports["."] block that all pointed at a single component (dist/Geomap.js). This treated one component as the package's default export, which does not match how UI5 Web Components packages are structured deliberately expose no default entry and require consumers to import components via subpaths.

Adopt the subpath-only exports shape:

  • ./src/* raw TypeScript sources (useful inside monorepos)
  • ./dist/* compiled output (explicit, keeps the catch-all
    below from double-mapping)
  • ./package.json for tools that read the manifest at runtime
  • ./bundle.esm.js exposes the existing root-level self-contained
    bundle to published consumers
  • ./* → ./dist/* catch-all so consumers can write
    @ui5/webcomponents-geomap/Geomap.js without the
    /dist/ prefix

Also expand the files whitelist to include src/ and bundle.esm.js so the new entries actually resolve in the published tarball.

Note: the commit that introduced the removed fields (bcedc5e, "build: fix package.json for publish") claimed to "match @ui5/webcomponents convention" but did the opposite — the real convention is to have no default entry at all. This commit corrects that.

BREAKING CHANGE: import "@ui5/webcomponents-geomap" (the bare package specifier) no longer resolves — it now throws ERR_PACKAGE_PATH_NOT_EXPORTED, matching every other @ui5/webcomponents-* package. Consumers must use subpath imports, e.g. import "@ui5/webcomponents-geomap/dist/Geomap.js" or import "@ui5/webcomponents-geomap/Geomap.js". The README and docs already only use the subpath form.

Comment thread package.json
"./dist/*": "./dist/*",
"./package.json": "./package.json"
"./package.json": "./package.json",
"./bundle.esm.js": "./bundle.esm.js",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks for the pointer. I looked into it and I'd like to push back on this one — the two extra entries in @ui5/webcomponents/package.json appear to be stale references that don't actually resolve in the published package.

I verified against the current npm tarball (@ui5/webcomponents@2.28.1):

$ node -e 'import("@ui5/webcomponents/bundle.esm.js")'
ERR_MODULE_NOT_FOUND  '.../node_modules/@ui5/webcomponents/bundle.esm.js'
$ node -e 'import("@ui5/webcomponents/bundle.common.js")'
ERR_MODULE_NOT_FOUND  '.../node_modules/@ui5/webcomponents/bundle.common.js'
$ node -e 'import("@ui5/webcomponents/bundle.scoped.esm.js")'
ERR_MODULE_NOT_FOUND  '.../node_modules/@ui5/webcomponents/bundle.scoped.esm.js'

What actually ships in the tarball is dist/bundle.esm.js, dist/bundle.scoped.esm.js, and dist/bundle.common.bootstrap.js (not bundle.common.js — that file doesn't exist anywhere in the package). None of them live at the package root, so the explicit exports entries point at missing files. The "./": "./dist/" wildcard doesn't rescue them because specific subpath keys take precedence over patterns in Node's exports resolution.

For our package: we only produce a hand-written bundle.esm.js at root (for the test pages). We don't build
equivalents of bundle.common.js or bundle.scoped.esm.js. Adding those two exports here would reproduce the same ERR_MODULE_NOT_FOUND behavior rather than giving consumers something usable.

We can add them later if we introduce real common/scoped bundles — but for now I'd prefer not to ship dead export entries. WDYT?

Comment thread package.json
"./bundle.esm.js": "./bundle.esm.js",
"./*": "./dist/*"
},
"files": [

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

why do you use files to filter the included files? Isn't the .gitgnore or fallback .npmignore sufficient?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It doesn't work as-is in our repo. Here's why - our .gitignore contains:

  • dist/
  • src/generated

npm's publish-filter precedence is files → .npmignore → .gitignore. If we drop files and have no .npmignore, npm falls back to .gitignore and excludes dist/ from the published package — which breaks everything, since dist/ is our main shipped artifact.

Upstream (ui5/webc/packages/main) can rely on an ignore-based approach because it's a monorepo: there's no per-package .gitignore, and each package has its own .npmignore that selectively lists what to exclude (test/, cypress/, config/, etc.) — crucially, it does NOT list dist/, so dist gets published. The root-repo .gitignore is irrelevant to npm once a per-package .npmignore exists.

We have 2 options:

  • keep files - whitelist, deterministic, npm's recommended practice but it deviates the upstream style (ui5/webc)
  • replace with .npmignore - matches upstream style but new files leak into publish unless explicitly ignored.

@adrian-bobev what's your POV on this?

This branch has not been deployed

No deployments
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.

2 participants