-
Notifications
You must be signed in to change notification settings - Fork 7
/
mod.ts
67 lines (54 loc) · 1.99 KB
/
mod.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 'https://deno.land/x/esbuild@v0.14.53/wasm.js'
import { denoPlugin } from 'https://deno.land/x/esbuild_deno_loader@0.5.2/mod.ts'
import stripShebang from 'https://esm.sh/strip-shebang@2.0.0'
import { encode } from 'https://deno.land/std@0.151.0/encoding/base64url.ts'
import { toFileUrl } from 'https://deno.land/std@0.151.0/path/mod.ts'
export type Module = Promise<Record<'default' | string, any>>
const AsyncFunction = (async function () {}).constructor
function moduleToAsyncFunction(moduleString: string): Module {
const [ before, after ] = moduleString.split('export {')
const body =
stripShebang(before)
+ (after
? 'return {' + after.replaceAll(/(\w+) (as) (\w+)/gi, '$3: $1')
: '')
return AsyncFunction(body)()
}
export async function importModule(moduleName: string): Module {
try {
return await import(moduleName)
} catch {
esbuild.initialize({ worker: false })
const result = await esbuild.build({
bundle: true,
entryPoints: [ import.meta.resolve(moduleName) ],
plugins: [ denoPlugin() ],
write: false,
logLevel: 'silent',
format: 'esm',
})
esbuild.stop()
return moduleToAsyncFunction(result.outputFiles[ 0 ].text)
}
}
export async function importString(moduleString: string): Module {
try {
return await import(`data:text/tsx;base64,${ encode(moduleString) }`)
} catch {
esbuild.initialize({ worker: false })
const result = await esbuild.build({
bundle: true,
plugins: [ denoPlugin() ],
write: false,
logLevel: 'silent',
format: 'esm',
stdin: {
contents: moduleString,
loader: 'tsx',
sourcefile: toFileUrl(Deno.cwd()).href
},
})
esbuild.stop()
return moduleToAsyncFunction(result.outputFiles[ 0 ].text)
}
}