From 02380e2f6dad80b506a27b741b3d47944c0fa95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claud=C3=A9ric=20Demers?= Date: Tue, 20 Oct 2026 08:41:52 -0400 Subject: [PATCH] Build the theme graph without an assets folder getWebComponentMap read the assets folder without checking that it exists, so it rejected for a theme without one, and so did building its graph. The language server caches the graph as a promise, and its rebuild awaits the cached one first, so that theme never got a graph, even after the folder was created. A missing assets folder now means no web components. Other errors, like an assets folder that can't be read, still reject. Co-Authored-By: Claude Opus 5.5 --- .changeset/web-components-without-assets.md | 5 +++++ .../theme-graph/src/getWebComponentMap.spec.ts | 14 ++++++++++++++ packages/theme-graph/src/getWebComponentMap.ts | 3 +++ 3 files changed, 22 insertions(+) create mode 100644 .changeset/web-components-without-assets.md create mode 100644 packages/theme-graph/src/getWebComponentMap.spec.ts diff --git a/.changeset/web-components-without-assets.md b/.changeset/web-components-without-assets.md new file mode 100644 index 000000000..b114fcbcb --- /dev/null +++ b/.changeset/web-components-without-assets.md @@ -0,0 +1,5 @@ +--- +'@shopify/theme-graph': patch +--- + +Build the theme graph for a theme without an `assets` folder. `getWebComponentMap` used to reject, so the language server never had a graph for that theme, even after the folder was created. diff --git a/packages/theme-graph/src/getWebComponentMap.spec.ts b/packages/theme-graph/src/getWebComponentMap.spec.ts new file mode 100644 index 000000000..2c16c9d65 --- /dev/null +++ b/packages/theme-graph/src/getWebComponentMap.spec.ts @@ -0,0 +1,14 @@ +import { path } from '@shopify/theme-check-common'; +import { MockFileSystem } from '@shopify/theme-check-common/src/test'; +import { describe, expect, it } from 'vitest'; +import { getWebComponentMap } from './getWebComponentMap'; +import { makeGetSourceCode } from './graph/test-helpers'; + +describe('Unit: getWebComponentMap', () => { + it('returns an empty map for a theme without an assets folder', async () => { + const rootUri = path.normalize('file:/'); + const fs = new MockFileSystem({ 'sections/main.liquid': '' }, rootUri); + const map = await getWebComponentMap(rootUri, { fs, getSourceCode: makeGetSourceCode(fs) }); + expect(map.size).toBe(0); + }); +}); diff --git a/packages/theme-graph/src/getWebComponentMap.ts b/packages/theme-graph/src/getWebComponentMap.ts index 6c3fb01cc..3c483038b 100644 --- a/packages/theme-graph/src/getWebComponentMap.ts +++ b/packages/theme-graph/src/getWebComponentMap.ts @@ -2,6 +2,7 @@ import { path, recursiveReadDirectory } from '@shopify/theme-check-common'; import { ancestor as visit } from 'acorn-walk'; import { Dependencies, Void, WebComponentMap } from './types'; import { CallExpression } from 'acorn'; +import { exists } from './utils'; /** * Regular expression for web component names @@ -26,6 +27,8 @@ export async function getWebComponentMap( ): Promise { const webComponentDefs: WebComponentMap = new Map(); const assetRoot = path.join(rootUri, 'assets'); + if (!(await exists(fs, assetRoot))) return webComponentDefs; + const jsFiles = await recursiveReadDirectory(fs, assetRoot, ([fileName]) => fileName.endsWith('.js'), );