Skip to content

Commit 1765bf5

Browse files
committed
Use TS parser instead, es-module-lexer does not support jsx
1 parent ff75677 commit 1765bf5

File tree

4 files changed

+34
-17
lines changed

4 files changed

+34
-17
lines changed

packages/app/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@
6262
"camelcase-keys": "9.1.3",
6363
"chokidar": "3.6.0",
6464
"diff": "5.2.0",
65-
"es-module-lexer": "1.7.0",
6665
"esbuild": "0.25.5",
6766
"express": "4.21.2",
6867
"graphql-request": "6.1.0",

packages/app/src/cli/models/extensions/specifications/type-generation.ts

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {fileExists, findPathUp, readFileSync} from '@shopify/cli-kit/node/fs'
22
import {dirname, joinPath, relativizePath, resolvePath} from '@shopify/cli-kit/node/path'
33
import {AbortError} from '@shopify/cli-kit/node/error'
44
import ts from 'typescript'
5-
import {init, parse} from 'es-module-lexer'
65
import {createRequire} from 'module'
76

87
const require = createRequire(import.meta.url)
@@ -63,21 +62,43 @@ async function fallbackResolve(importPath: string, baseDir: string): Promise<str
6362

6463
async function parseAndResolveImports(filePath: string): Promise<string[]> {
6564
try {
66-
await init
67-
6865
const content = readFileSync(filePath).toString()
6966
const resolvedPaths: string[] = []
7067

7168
// Load TypeScript configuration once
7269
const {compilerOptions} = loadTsConfig(filePath)
7370

74-
const [imports] = parse(content)
71+
// Determine script kind based on file extension
72+
let scriptKind = ts.ScriptKind.JSX
73+
if (filePath.endsWith('.ts')) {
74+
scriptKind = ts.ScriptKind.TS
75+
} else if (filePath.endsWith('.tsx')) {
76+
scriptKind = ts.ScriptKind.TSX
77+
}
78+
79+
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, scriptKind)
7580

7681
const processedImports = new Set<string>()
82+
const importPaths: string[] = []
83+
84+
const visit = (node: ts.Node): void => {
85+
if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
86+
importPaths.push(node.moduleSpecifier.text)
87+
} else if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
88+
const firstArg = node.arguments[0]
89+
if (firstArg && ts.isStringLiteral(firstArg)) {
90+
importPaths.push(firstArg.text)
91+
}
92+
} else if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
93+
importPaths.push(node.moduleSpecifier.text)
94+
}
95+
96+
ts.forEachChild(node, visit)
97+
}
7798

78-
for (const pattern of imports) {
79-
const importPath = pattern.n
99+
visit(sourceFile)
80100

101+
for (const importPath of importPaths) {
81102
// Skip if already processed
82103
if (!importPath || processedImports.has(importPath)) {
83104
continue
@@ -149,7 +170,7 @@ export function createTypeDefinition(
149170
// Throw specific error for the target that failed, matching the original getSharedTypeDefinition behavior
150171
throw new AbortError(
151172
`Type reference for ${target} could not be found. You might be using the wrong @shopify/ui-extensions version.`,
152-
`Fix the error by ensuring you have the correct version of @shopify/ui-extensions, for example ${year}.${month}.0, in your dependencies.`,
173+
`Fix the error by ensuring you have the correct version of @shopify/ui-extensions, for example ~${year}.${month}.0, in your dependencies.`,
153174
)
154175
}
155176
}
@@ -160,8 +181,8 @@ export function createTypeDefinition(
160181
const target = targets[0] ?? ''
161182
return `//@ts-ignore\ndeclare module './${relativePath}' {\n const shopify: import('@shopify/ui-extensions/${target}').Api;\n const globalThis: { shopify: typeof shopify };\n}\n`
162183
} else if (targets.length > 1) {
163-
const unionType = targets.map((target) => `import('@shopify/ui-extensions/${target}').Api`).join(' | ')
164-
return `//@ts-ignore\ndeclare module './${relativePath}' {\n const shopify: ${unionType};\n const globalThis: { shopify: typeof shopify };\n}\n`
184+
const unionType = targets.map((target) => ` import('@shopify/ui-extensions/${target}').Api`).join(' |\n')
185+
return `//@ts-ignore\ndeclare module './${relativePath}' {\n const shopify: \n${unionType};\n const globalThis: { shopify: typeof shopify };\n}\n`
165186
}
166187

167188
return null
@@ -173,7 +194,7 @@ export function createTypeDefinition(
173194
const {year, month} = parseApiVersion(apiVersion) ?? {year: 2025, month: 10}
174195
throw new AbortError(
175196
`Type reference could not be found. You might be using the wrong @shopify/ui-extensions version.`,
176-
`Fix the error by ensuring you have the correct version of @shopify/ui-extensions, for example ${year}.${month}.0, in your dependencies.`,
197+
`Fix the error by ensuring you have the correct version of @shopify/ui-extensions, for example ~${year}.${month}.0, in your dependencies.`,
177198
)
178199
}
179200
}

packages/app/src/cli/models/extensions/specifications/ui_extension.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,7 @@ Please check the configuration in ${uiExtension.configurationPath}`),
10651065
await expect(extension.contributeToSharedTypeFile?.(typeDefinitionsByFile)).rejects.toThrow(
10661066
new AbortError(
10671067
'Type reference for admin.unknown.action.render could not be found. You might be using the wrong @shopify/ui-extensions version.',
1068-
'Fix the error by ensuring you have the correct version of @shopify/ui-extensions, for example 2025.10.0, in your dependencies.',
1068+
'Fix the error by ensuring you have the correct version of @shopify/ui-extensions, for example ~2025.10.0, in your dependencies.',
10691069
),
10701070
)
10711071

@@ -1211,7 +1211,7 @@ Please check the configuration in ${uiExtension.configurationPath}`),
12111211

12121212
// Then - should generate union type for shared module
12131213
expect(types).toContain(
1214-
`//@ts-ignore\ndeclare module './shared/utils.js' {\n const shopify: import('@shopify/ui-extensions/admin.product-details.action.render').Api | import('@shopify/ui-extensions/admin.orders-details.block.render').Api;\n const globalThis: { shopify: typeof shopify };\n}\n`,
1214+
`//@ts-ignore\ndeclare module './shared/utils.js' {\n const shopify: \n import('@shopify/ui-extensions/admin.product-details.action.render').Api |\n import('@shopify/ui-extensions/admin.orders-details.block.render').Api;\n const globalThis: { shopify: typeof shopify };\n}\n`,
12151215
)
12161216
})
12171217
})
@@ -1272,7 +1272,7 @@ Please check the configuration in ${uiExtension.configurationPath}`),
12721272
// Then - should generate union types for shared files
12731273
// when targets are from different surfaces (admin vs checkout)
12741274
expect(types).toContain(
1275-
`//@ts-ignore\ndeclare module './src/components/Shared.jsx' {\n const shopify: import('@shopify/ui-extensions/admin.product-details.action.render').Api | import('@shopify/ui-extensions/purchase.checkout.block.render').Api;\n const globalThis: { shopify: typeof shopify };\n}\n`,
1275+
`//@ts-ignore\ndeclare module './src/components/Shared.jsx' {\n const shopify: \n import('@shopify/ui-extensions/admin.product-details.action.render').Api |\n import('@shopify/ui-extensions/purchase.checkout.block.render').Api;\n const globalThis: { shopify: typeof shopify };\n}\n`,
12761276
)
12771277
})
12781278
})

pnpm-lock.yaml

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)