bun-build.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import solidPlugin from "./packages/opencode/node_modules/@opentui/solid/scripts/solid-plugin"
  2. import path from "path"
  3. import fs from "fs"
  4. const version = "@VERSION@"
  5. const pkg = path.join(process.cwd(), "packages/opencode")
  6. const parser = fs.realpathSync(path.join(pkg, "./node_modules/@opentui/core/parser.worker.js"))
  7. const worker = "./src/cli/cmd/tui/worker.ts"
  8. const target = process.env["BUN_COMPILE_TARGET"]
  9. if (!target) {
  10. throw new Error("BUN_COMPILE_TARGET not set")
  11. }
  12. process.chdir(pkg)
  13. const manifestName = "opencode-assets.manifest"
  14. const manifestPath = path.join(pkg, manifestName)
  15. const readTrackedAssets = () => {
  16. if (!fs.existsSync(manifestPath)) return []
  17. return fs
  18. .readFileSync(manifestPath, "utf8")
  19. .split("\n")
  20. .map((line) => line.trim())
  21. .filter((line) => line.length > 0)
  22. }
  23. const removeTrackedAssets = () => {
  24. for (const file of readTrackedAssets()) {
  25. const filePath = path.join(pkg, file)
  26. if (fs.existsSync(filePath)) {
  27. fs.rmSync(filePath, { force: true })
  28. }
  29. }
  30. }
  31. const assets = new Set<string>()
  32. const addAsset = async (p: string) => {
  33. const file = path.basename(p)
  34. const dest = path.join(pkg, file)
  35. await Bun.write(dest, Bun.file(p))
  36. assets.add(file)
  37. }
  38. removeTrackedAssets()
  39. const result = await Bun.build({
  40. conditions: ["browser"],
  41. tsconfig: "./tsconfig.json",
  42. plugins: [solidPlugin],
  43. sourcemap: "external",
  44. entrypoints: ["./src/index.ts", parser, worker],
  45. define: {
  46. OPENCODE_VERSION: `'@VERSION@'`,
  47. OTUI_TREE_SITTER_WORKER_PATH: "/$bunfs/root/" + path.relative(pkg, parser).replace(/\\/g, "/"),
  48. OPENCODE_CHANNEL: "'latest'",
  49. },
  50. compile: {
  51. target,
  52. outfile: "opencode",
  53. autoloadBunfig: false,
  54. autoloadDotenv: false,
  55. //@ts-ignore (bun types aren't up to date)
  56. autoloadTsconfig: true,
  57. autoloadPackageJson: true,
  58. execArgv: ["--user-agent=opencode/" + version, "--use-system-ca", "--"],
  59. windows: {},
  60. },
  61. })
  62. if (!result.success) {
  63. console.error("Build failed!")
  64. for (const log of result.logs) {
  65. console.error(log)
  66. }
  67. throw new Error("Compilation failed")
  68. }
  69. const assetOutputs = result.outputs?.filter((x) => x.kind === "asset") ?? []
  70. for (const x of assetOutputs) {
  71. await addAsset(x.path)
  72. }
  73. const bundle = await Bun.build({
  74. entrypoints: [worker],
  75. tsconfig: "./tsconfig.json",
  76. plugins: [solidPlugin],
  77. target: "bun",
  78. outdir: "./.opencode-worker",
  79. sourcemap: "none",
  80. })
  81. if (!bundle.success) {
  82. console.error("Worker build failed!")
  83. for (const log of bundle.logs) {
  84. console.error(log)
  85. }
  86. throw new Error("Worker compilation failed")
  87. }
  88. const workerAssets = bundle.outputs?.filter((x) => x.kind === "asset") ?? []
  89. for (const x of workerAssets) {
  90. await addAsset(x.path)
  91. }
  92. const output = bundle.outputs.find((x) => x.kind === "entry-point")
  93. if (!output) {
  94. throw new Error("Worker build produced no entry-point output")
  95. }
  96. const dest = path.join(pkg, "opencode-worker.js")
  97. await Bun.write(dest, Bun.file(output.path))
  98. fs.rmSync(path.dirname(output.path), { recursive: true, force: true })
  99. const list = Array.from(assets)
  100. await Bun.write(manifestPath, list.length > 0 ? list.join("\n") + "\n" : "")
  101. console.log("Build successful!")