theme-graph CLI never calls getWebComponentMap, so custom-element references are never resolved
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 234
- Forks
- 92
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 6
Description
Summary
bin/theme-graph declares a WebComponentMap, passes a getWebComponentDefinitionReference resolver built on it, but never calls getWebComponentMap — so the map is always empty and the resolver always returns undefined.
The result: custom-element references (<my-widget>) are never resolved to the asset that defines them, so an asset referenced only as a custom element is missing from the CLI's graph and looks like dead code.
Calling getWebComponentMap fixes it — verified below.
Versions
@shopify/theme-graph0.3.2@shopify/theme-check-common3.29.0- Node 24.11.1, Windows 11
The code
bin/theme-graph:
/** @type {import('@shopify/theme-graph').WebComponentMap} */
const webComponentDefs = new Map(); // <- created empty
const dependencies = {
// ...
getWebComponentDefinitionReference: (customElementName) =>
webComponentDefs.get(customElementName), // <- always undefined
};
$ grep -c getWebComponentMap bin/theme-graph
0
getWebComponentMap is exported from the package and works correctly; the CLI just never invokes it to populate the map.
Reproduction
sections/widget.liquid — custom element plus an explicit script tag
<script src="{{ 'my-widget.js' | asset_url }}" defer></script>
<my-widget></my-widget>
{% schema %}{"name":"widget"}{% endschema %}
sections/ce-only.liquid — custom element only, no explicit asset reference
<my-orphan-widget></my-orphan-widget>
{% schema %}{"name":"ce-only"}{% endschema %}
assets/my-widget.js
class W extends HTMLElement {}
customElements.define('my-widget', W);
assets/my-orphan-widget.js
class O extends HTMLElement {}
customElements.define('my-orphan-widget', O);
npx theme-graph minitheme > graph.json
Actual (CLI)
nodes: 8 edges: 6
IN GRAPH my-widget.js <- only because of the explicit asset_url script tag
ABSENT my-orphan-widget.js <- referenced as <my-orphan-widget>, not resolved
sections/ce-only.liquid is in the graph as a section entry point but has zero outbound edges.
With the map populated (library path)
Same theme, same buildThemeGraph, the only change being one added call:
const webComponentDefs = await getWebComponentMap(root, { fs: NodeFS, getSourceCode });
web components discovered: my-orphan-widget, my-widget
nodes: 9 edges: 8
IN GRAPH my-widget.js
IN GRAPH my-orphan-widget.js <- now resolved
So the resolution logic is correct and complete; only the CLI's wiring is missing.
Suggested fix
In bin/theme-graph, replace the empty map with a populated one:
const webComponentDefs = await getWebComponentMap(rootUri, {
fs: NodeFileSystem,
getSourceCode,
});
(after the preload, so the source-code cache is warm).
Why it matters
Custom-element-per-component is the dominant architecture in current commercial themes. On a production Clean Canvas Enterprise 2.3.0 theme, four assets (side-drawer.js, quantity-input.js, quantity-input.css, product-recommendations.js) were referenced only via their custom-element tags and were absent from the CLI graph — indistinguishable from genuinely dead assets.
Since the VS Code extension's dependencies / references / dead-code features are built on this graph, anything consuming the CLI output will report these as unused. Related failure mode to #1279 and to #1290 (the parse-error case).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read bin/theme-graph and trace how webComponentDefs is initialized and passed to getWebComponentDefinitionReference. Run the provided minitheme reproduction with npx theme-graph, then verify that the custom-element-only asset appears in graph.json and that the graph counts and edges reflect the resolved reference.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100