Skip to content

Commit 44de41a

Browse files
authored
fix(exec): Support aliased imports with file extension (#494)
1 parent be89cc7 commit 44de41a

File tree

6 files changed

+64
-4
lines changed

6 files changed

+64
-4
lines changed

__fixtures__/test-project/api/src/services/contacts/contacts.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { QueryResolvers, MutationResolvers } from 'types/graphql'
22

3-
import { db } from 'src/lib/db'
3+
// Testing aliased imports with extensions
4+
import { db } from 'src/lib/db.js'
45

56
export const contacts: QueryResolvers['contacts'] = () => {
67
return db.contact.findMany()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { contacts } from 'api/src/services/contacts/contacts'
2+
13
export default async () => {
4+
const _allContacts = await contacts()
25
console.log('Hello from myNestedScript.ts')
36
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
I was getting errors like these when running scripts with `exec scriptName`:
2+
3+
```
4+
7:08:58 PM [vite] Pre-transform error: Failed to load url /api/src/lib/db.js (resolved id: /api/src/lib/db.js) in /Users/tobbe/tmp/cedar-0140-jobs/api/src/lib/jobs.ts. Does the file exist?
5+
7:08:58 PM [vite] Pre-transform error: Failed to load url /api/src/lib/logger.js (resolved id: /api/src/lib/logger.js) in /Users/tobbe/tmp/cedar-0140-jobs/api/src/lib/jobs.ts. Does the file exist?
6+
7:08:58 PM [vite] Pre-transform error: Failed to load url /api/src/lib/db.js (resolved id: /api/src/lib/db.js) in /Users/tobbe/tmp/cedar-0140-jobs/api/src/lib/jobs.ts. Does the file exist?
7+
7:08:58 PM [vite] Pre-transform error: Failed to load url /api/src/lib/logger.js (resolved id: /api/src/lib/logger.js) in /Users/tobbe/tmp/cedar-0140-jobs/api/src/lib/jobs.ts. Does the file exist?
8+
```
9+
10+
The issue is with these imports:
11+
12+
```ts
13+
import { db } from 'src/lib/db.js'
14+
import { logger } from 'src/lib/logger.js'
15+
```
16+
17+
In a TypeScript project the name of the source files for those imports are
18+
db.ts and logger.ts
19+
20+
When authoring TypeScript, that's to be transpiled to JavaScript and then run by
21+
Node, using the .js extension is typically what you should do, because that's
22+
what the files to import will be named when Node executes them. But now we're
23+
using vite-node, and vite-node runs the source files, not built files. And so
24+
the extension should be empty, to let vite-node guess the file extension, or .ts
25+
to explicitly tell it.
26+
27+
The solution is to update our custom resolver in packages/cli/src/lib/exec.js to
28+
remove .js imports and let vite figure out the file extension:

packages/cli/src/lib/exec.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,23 @@ export async function runScriptFunction({
6161
// from scripts/ because it doesn't know what the src/ alias is.
6262
// So we have to tell it to use the correct path based on what file
6363
// is doing the importing.
64+
// Also, to support both imports like 'src/lib/db.js' and
65+
// 'src/lib/db' in ts files we need to have special treatment for
66+
// the .js extension.
6467
if (importer.startsWith(apiImportBase)) {
6568
const apiImportSrc = importStatementPath(getPaths().api.src)
66-
return { id: id.replace('src', apiImportSrc) }
69+
let resolvedId = id.replace('src', apiImportSrc)
70+
if (importer.endsWith('.ts') || importer.endsWith('.tsx')) {
71+
resolvedId = resolvedId.replace(/\.jsx?$/, '')
72+
}
73+
return { id: resolvedId }
6774
} else if (importer.startsWith(webImportBase)) {
6875
const webImportSrc = importStatementPath(getPaths().web.src)
69-
return { id: id.replace('src', webImportSrc) }
76+
let resolvedId = id.replace('src', webImportSrc)
77+
if (importer.endsWith('.ts') || importer.endsWith('.tsx')) {
78+
resolvedId = resolvedId.replace(/\.jsx?$/, '')
79+
}
80+
return { id: resolvedId }
7081
}
7182

7283
return null

tasks/test-project/rebuild-test-project-fixture.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,10 @@ async function runCommand() {
421421
fs.mkdirSync(nestedPath, { recursive: true })
422422
fs.writeFileSync(
423423
path.join(nestedPath, 'myNestedScript.ts'),
424-
'export default async () => {\n' +
424+
"import { contacts } from 'api/src/services/contacts/contacts'\n" +
425+
'\n' +
426+
'export default async () => {\n' +
427+
' const _allContacts = await contacts()\n' +
425428
" console.log('Hello from myNestedScript.ts')\n" +
426429
'}\n\n',
427430
)

tasks/test-project/tui-tasks.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,20 @@ export async function apiTasks(
768768
)
769769

770770
await generateScaffold('contacts')
771+
772+
const contactsServicePath = fullPath(
773+
'api/src/services/contacts/contacts',
774+
)
775+
fs.writeFileSync(
776+
contactsServicePath,
777+
fs
778+
.readFileSync(contactsServicePath, 'utf-8')
779+
.replace(
780+
"import { db } from 'src/lib/db'",
781+
'// Testing aliased imports with extensions\n' +
782+
"import { db } from 'src/lib/db.js'",
783+
),
784+
)
771785
},
772786
},
773787
{

0 commit comments

Comments
 (0)