[Feature]: Separate component asset generation from application-owned bundling
- Dominant language
- Rust
- Stars
- 90
- Forks
- 23
- Avg merge
- 13h 14m
- Merged PRs (30d)
- 68
Description
### Problem or need
The current component-asset output combines two separate responsibilities:
- **WebUI responsibilities:** determine a component root’s required templates and styles, generate their metadata, and validate/register them safely.
- **Application bundler responsibilities:** decide eager versus lazy loading, chunk boundaries, shared-module extraction, filenames, public paths, and asset delivery.
Today WebUI also encodes the second category into generated assets:
```js
imports: [{
href: new URL("./chunk-shared.webui.js", import.meta.url).href,
load: () => import("./chunk-shared.webui.js")
}]
```
This works well as a standalone browser-loaded ESM graph, but in a bundled application it creates a second chunking and URL-resolution system inside the application bundler.
Applications that need to control packaging must then rewrite generated source, override internal dynamic imports, resolve public paths, and maintain custom loader wiring. Because that integration follows WebUI’s generated format and runtime registration details, framework upgrades can easily break it.
### Desired ownership boundary
WebUI should emit ordinary, composable JavaScript modules that describe and register the compiled component graph.
Internal component dependencies should use static relative imports:
```js
import shared from "./chunk-shared.webui.js";
```
The application should own the only meaningful loading decision:
```ts
// Lazy
const { create } = await import(
"./generated/settings-dialog.webui.js"
);
// Or eager
import { create } from
"./generated/settings-dialog.webui.js";
```
Once imported, the generated entry should internally handle:
- component definition;
- graph validation;
- styles and templates registration;
- CSS readiness;
- deduplication and retry;
- element creation.
No application-authored `defineComponentAssets()` manifest, registration calls, generated-source rewriting, or loader setup should be required.
### Why static internal imports are sufficient
A component cannot be created until its complete required closure is available. Internal dynamic imports therefore do not add useful lazy semantics; they primarily prescribe additional chunk boundaries.
Static imports preserve the dependency graph while allowing Webpack, Rspack, Vite, Rollup, esbuild, or the native ESM loader to decide how modules are grouped and cached.
### Related work
- #360 introduced static component assets.
- #365 added shared dependency chunks.
- This request is about separating those assets’ semantic graph from application-owned packaging and delivery.
Contributor guide
Research direction
Start by reading related issues #360 and #365, then trace the component asset generator and generated entry modules described here. Verify how internal dependencies are currently loaded and registered. Done means generated assets use static internal imports while the application controls eager or lazy loading without manifests, source rewriting, or custom loader setup.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, rollup, rust, typescript, vite, webpack
- Domain
- build-system, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100