This repository has been archived by the owner on May 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 35
/
list_imports.ts
67 lines (57 loc) · 2.06 KB
/
list_imports.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import * as esbuild from '@netlify/esbuild'
import isBuiltinModule from 'is-builtin-module'
import { tmpName } from 'tmp-promise'
import { JS_BUNDLER_ZISI, RUNTIME_JS } from '../../../../utils/consts'
import { safeUnlink } from '../../../../utils/fs'
// Maximum number of log messages that an esbuild instance will produce. This
// limit is important to avoid out-of-memory errors due to too much data being
// sent in the Go<>Node IPC channel.
const ESBUILD_LOG_LIMIT = 10
const getListImportsPlugin = ({ imports, path }: { imports: Set<string>; path: string }): esbuild.Plugin => ({
name: 'list-imports',
setup(build) {
build.onResolve({ filter: /.*/ }, (args) => {
const isEntryPoint = args.path === path
const isImport = !isEntryPoint && !isBuiltinModule(args.path)
if (isImport) {
imports.add(args.path)
}
return {
namespace: 'list-imports',
external: isImport,
}
})
},
})
const listImports = async ({ functionName, path }: { functionName: string; path: string }): Promise<string[]> => {
// We're not interested in the output that esbuild generates, we're just
// using it for its parsing capabilities in order to find import/require
// statements. However, if we don't give esbuild a path in `outfile`, it
// will pipe the output to stdout, which we also don't want. So we create
// a temporary file to serve as the esbuild output and then get rid of it
// when we're done.
const targetPath = await tmpName()
const imports = new Set<string>()
try {
await esbuild.build({
bundle: true,
entryPoints: [path],
logLevel: 'error',
logLimit: ESBUILD_LOG_LIMIT,
outfile: targetPath,
platform: 'node',
plugins: [getListImportsPlugin({ imports, path })],
target: 'esnext',
})
} catch (error) {
error.customErrorInfo = {
type: 'functionsBundling',
location: { bundler: JS_BUNDLER_ZISI, functionName, runtime: RUNTIME_JS },
}
throw error
} finally {
await safeUnlink(targetPath)
}
return [...imports]
}
export { listImports }