Skip to content

Instantly share code, notes, and snippets.

@lg
Created July 3, 2022 20:47
Show Gist options
  • Save lg/663e33abc3cd5c6b10c78d21c679f3f9 to your computer and use it in GitHub Desktop.
Save lg/663e33abc3cd5c6b10c78d21c679f3f9 to your computer and use it in GitHub Desktop.
use ESBuild to bundle and transpile typescript files to javascript
import * as esbuild from "esbuild-wasm"
import esbuildWasmUrl from "esbuild-wasm/esbuild.wasm?url"
import Path from "path"
let isEsbuildWasmInitialized = false
export const tsToJs = async (tree: Record<string, string>) => {
if (!isEsbuildWasmInitialized) {
await esbuild.initialize({ wasmURL: esbuildWasmUrl })
isEsbuildWasmInitialized = true
}
const out = await esbuild.build({
entryPoints: ["index.ts"],
plugins: [ESBuildFakeFS(tree)],
logOverride: { "commonjs-variable-in-esm": "silent" },
bundle: true,
write: false,
})
return out.outputFiles[0].text
}
// mostly from: https://github.com/evanw/esbuild/issues/1952
const ESBuildFakeFS = (tree: Record<string, string>) => {
const map = new Map(Object.entries(tree))
return {
name: "ESBuildFakeFS",
setup: (build: esbuild.PluginBuild) => {
build.onResolve({ filter: /.*/, }, (args: esbuild.OnResolveArgs) => {
if (args.kind === "entry-point")
return { path: `/${args.path}` }
if (args.kind === "import-statement") {
const dirname = Path.dirname(args.importer)
const path = Path.join(dirname, args.path)
return { path }
}
throw Error("not resolvable")
})
build.onLoad({ filter: /.*/ }, (args: esbuild.OnLoadArgs) => {
const path = map.has(args.path) ? args.path : `${args.path}.ts`
if (!map.has(path))
throw Error("not loadable")
const ext = Path.extname(path)
const contents = map.get(path)!
const loader = ({ ".ts": "ts", ".tsx": "tsx", ".js": "js", ".jsx": "jsx" }[ext]) as esbuild.Loader || "default"
return { contents, loader }
})
}
}
}
const scraperCode = import.meta.glob("../scrapers/*.ts", { as: "raw" })
const fetchAwardAvailability = async ({ signal, meta, queryKey }: ReactQuery.QueryFunctionContext) => {
const scraperQuery = meta as ScraperForRoute
const scraperPath = (name: string) => {
const localPath = Object.keys(scraperCode).find((scraperKey) => scraperKey.indexOf(`${name}.ts`) > -1)
if (!localPath) throw new Error(`Could not find scraper ${name}`)
return localPath
}
const jsCode = await tsToJs({
"/index.ts": scraperCode[scraperPath(scraperQuery.scraper)] as unknown as string,
"/common.ts": scraperCode[scraperPath("common")] as unknown as string
})
const postData: { code: string, context: ScraperQuery } = { code: jsCode, context: scraperQuery }
// axios post...
return scraperResults.flightsWithFares
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment