Update extension templates to Bundler module resolution - #424
Conversation
Generated Preact POS extensions currently use Node module resolution, which TypeScript deprecates and which does not understand modern package exports consistently. Configure all shipped POS templates to emit ESNext modules and use Bundler resolution, matching the repository's existing extension-template precedent.\n\nResolves shop/issues-retail#33804.
|
It looks like there are lots more templates with this issue than just ours from https://github.com/search?q=repo%3AShopify%2Fextensions-templates+"moduleResolution"%3A+"node"&type=code. Should we make this a wider update? And if so, use that to align on these being the correct config options (that is what the AI recommended, but I haven't dug into if its right) |
|
Great callout @henryStelle. I added for the rest. |
henryStelle
left a comment
There was a problem hiding this comment.
I looked up these tsconfig options and these look like the correct changes. It would probably be good to get an 👍 from at least one of the other extension teams.
Co-authored-by: AI (Pi/GPT-5.6 Sol) <noreply@pi.dev>
Exact-head resolver-only verificationLocal read-only reproduction against
These are local reproduction results, not hosted CI or live deployment results. |



Background
Resolves shop/issues-retail#33804.
Generated POS Preact extensions import
@shopify/ui-extensions/preact, but their legacy Node10 module resolution does not understand that package's modernexportsentry. TypeScript 6 also rejects the deprecatednoderesolution mode withTS5107.Solution
Replace
"moduleResolution": "node"with"moduleResolution": "Bundler"in every generated extension configuration that still uses the legacy resolver.This is intentionally a resolver-only change:
targetandnoEmitsettings, and continue to omitmodule.ESNextplusBundler.Bundlerwas introduced in TypeScript 5.Existing generated projects are not modified.
The exact tested head is
d5352b09dc5f4a05cb053be7812f1dd4c9862771.Testing
Verified from exact base
c05f026ad348e1c340b06effe6ba7a51ee0cffabagainst the final candidate:moduleResolutionreplacements fromnodetoBundler, with no other changed lines.target: ES2020, omitmodule, usemoduleResolution: Bundler, and retainnoEmit: true.@shopify/ui-extensions/preactwith Node10 and resolves it to the package's exportedbuild/ts/preact.d.tsentry with Bundler.TS5107for the base POS configuration and reports no diagnostics for the resolver-only candidate.shopify app buildcommands covered all 70 valid generated cases twice: ten current-head controls and ten resolver-only candidate builds. All 75 JavaScript files, 70 source maps, 75 metafiles, and 18 generated declarations were byte-identical between control and candidate and deterministic across repeat builds.git diff --checkpasses. No legacymoduleResolution: "node"setting remains.TypeScript 4.9 and older cannot read
moduleResolution: "Bundler"; TypeScript 5 or newer is the intentional baseline for newly generated extensions.This PR deliberately leaves
moduleomitted as it was before. TypeScript 5 derives ES2015 from the existing ES2020 target, while TypeScript 6 derives ES2020. Defining a version-independent module syntax policy is separate from this resolver ticket. The affected template sources currently use neitherimport.metanor dynamic imports.Checklist
Co-authored by AI.