import { test, expect, describe } from "bun:test";
import { readFileSync } from "fs";
import { bunEnv, bunExe } from "harness";
import { join } from "path";
describe("Bun.build", () => {
test("passing undefined doesnt segfault", () => {
try {
// @ts-ignore
Bun.build();
} catch (error) {
return;
}
throw new Error("should have thrown");
});
test("invalid options throws", async () => {
expect(() => Bun.build({} as any)).toThrow();
expect(() =>
Bun.build({
entrypoints: [],
} as any),
).toThrow();
expect(() =>
Bun.build({
entrypoints: ["hello"],
format: "invalid",
} as any),
).toThrow();
expect(() =>
Bun.build({
entrypoints: ["hello"],
target: "invalid",
} as any),
).toThrow();
expect(() =>
Bun.build({
entrypoints: ["hello"],
sourcemap: "invalid",
} as any),
).toThrow();
});
test("returns errors properly", async () => {
Bun.gc(true);
const build = await Bun.build({
entrypoints: [join(import.meta.dir, "does-not-exist.ts")],
});
expect(build.outputs).toHaveLength(0);
expect(build.logs).toHaveLength(1);
expect(build.logs[0]).toBeInstanceOf(BuildMessage);
expect(build.logs[0].message).toMatch(/ModuleNotFound/);
expect(build.logs[0].name).toBe("BuildMessage");
expect(build.logs[0].position).toEqual(null);
expect(build.logs[0].level).toEqual("error");
Bun.gc(true);
});
test("returns output files", async () => {
Bun.gc(true);
const build = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/index.js")],
});
expect(build.outputs).toHaveLength(1);
expect(build.logs).toHaveLength(0);
Bun.gc(true);
});
test("Bun.write(BuildArtifact)", async () => {
Bun.gc(true);
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/index.js")],
});
await Bun.write("/tmp/bun-build-test-write.js", x.outputs[0]);
expect(readFileSync("/tmp/bun-build-test-write.js", "utf-8")).toMatchSnapshot();
Bun.gc(true);
});
test("rebuilding busts the directory entries cache", () => {
Bun.gc(true);
const { exitCode, stderr } = Bun.spawnSync({
cmd: [bunExe(), join(import.meta.dir, "bundler-reloader-script.ts")],
env: bunEnv,
stderr: "pipe",
stdout: "inherit",
});
if (stderr.byteLength > 0) {
throw new Error(stderr.toString());
}
expect(exitCode).toBe(0);
Bun.gc(true);
});
test("outdir + reading out blobs works", async () => {
Bun.gc(true);
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/index.js")],
outdir: "/tmp/bun-build-test-read-out",
});
expect(await x.outputs.values().next().value?.text()).toMatchSnapshot();
Bun.gc(true);
});
test("BuildArtifact properties", async () => {
Bun.gc(true);
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/index.js")],
});
const [blob] = x.outputs;
expect(blob).toBeTruthy();
expect(blob.type).toBe("text/javascript;charset=utf-8");
expect(blob.size).toBeGreaterThan(1);
expect(blob.path).toBe("./index.js");
expect(blob.hash).toBeTruthy();
expect(blob.hash).toMatchSnapshot("hash");
expect(blob.kind).toBe("entry-point");
expect(blob.loader).toBe("jsx");
expect(blob.sourcemap).toBe(null);
Bun.gc(true);
});
test("BuildArtifact properties + entry.naming", async () => {
Bun.gc(true);
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/index.js")],
naming: {
entry: "hello",
},
});
const [blob] = x.outputs;
expect(blob).toBeTruthy();
expect(blob.type).toBe("text/javascript;charset=utf-8");
expect(blob.size).toBeGreaterThan(1);
expect(blob.path).toBe("./hello");
expect(blob.hash).toBeTruthy();
expect(blob.hash).toMatchSnapshot("hash");
expect(blob.kind).toBe("entry-point");
expect(blob.loader).toBe("jsx");
expect(blob.sourcemap).toBe(null);
Bun.gc(true);
});
test("BuildArtifact properties sourcemap", async () => {
Bun.gc(true);
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/index.js")],
sourcemap: "external",
});
const [blob, map] = x.outputs;
expect(blob.type).toBe("text/javascript;charset=utf-8");
expect(blob.size).toBeGreaterThan(1);
expect(blob.path).toBe("./index.js");
expect(blob.hash).toBeTruthy();
expect(blob.hash).toMatchSnapshot("hash index.js");
expect(blob.kind).toBe("entry-point");
expect(blob.loader).toBe("jsx");
expect(blob.sourcemap).toBe(map);
expect(map.type).toBe("application/json;charset=utf-8");
expect(map.size).toBeGreaterThan(1);
expect(map.path).toBe("./index.js.map");
expect(map.hash).toBeTruthy();
expect(map.hash).toMatchSnapshot("hash index.js.map");
expect(map.kind).toBe("sourcemap");
expect(map.loader).toBe("file");
expect(map.sourcemap).toBe(null);
Bun.gc(true);
});
// test("BuildArtifact properties splitting", async () => {
// Bun.gc(true);
// const x = await Bun.build({
// entrypoints: [join(import.meta.dir, "./fixtures/trivial/index.js")],
// splitting: true,
// });
// expect(x.outputs).toHaveLength(2);
// const [indexBlob, chunkBlob] = x.outputs;
// expect(indexBlob).toBeTruthy();
// expect(indexBlob.type).toBe("text/javascript;charset=utf-8");
// expect(indexBlob.size).toBeGreaterThan(1);
// expect(indexBlob.path).toBe("/index.js");
// expect(indexBlob.hash).toBeTruthy();
// expect(indexBlob.hash).toMatchSnapshot("hash index.js");
// expect(indexBlob.kind).toBe("entry-point");
// expect(indexBlob.loader).toBe("jsx");
// expect(indexBlob.sourcemap).toBe(null);
// expect(chunkBlob).toBeTruthy();
// expect(chunkBlob.type).toBe("text/javascript;charset=utf-8");
// expect(chunkBlob.size).toBeGreaterThan(1);
// expect(chunkBlob.path).toBe(`/foo-${chunkBlob.hash}.js`);
// expect(chunkBlob.hash).toBeTruthy();
// expect(chunkBlob.hash).toMatchSnapshot("hash foo.js");
// expect(chunkBlob.kind).toBe("chunk");
// expect(chunkBlob.loader).toBe("jsx");
// expect(chunkBlob.sourcemap).toBe(null);
// Bun.gc(true);
// });
test("new Response(BuildArtifact) sets content type", async () => {
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/index.js")],
});
const response = new Response(x.outputs[0]);
expect(response.headers.get("content-type")).toBe("text/javascript;charset=utf-8");
expect(await response.text()).toMatchSnapshot("response text");
});
test.todo("new Response(BuildArtifact) sets etag", async () => {
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/index.js")],
});
const response = new Response(x.outputs[0]);
expect(response.headers.get("etag")).toBeTruthy();
expect(response.headers.get("etag")).toMatchSnapshot("content-etag");
});
// test("BuildArtifact with assets", async () => {
// const x = await Bun.build({
// entrypoints: [join(import.meta.dir, "./fixtures/with-assets/index.js")],
// loader: {
// ".blob": "file",
// ".png": "file",
// },
// });
// console.log(x);
// const [blob, asset] = x.outputs;
// expect(blob).toBeTruthy();
// expect(blob instanceof Blob).toBe(true);
// expect(blob.type).toBe("text/javascript;charset=utf-8");
// expect(blob.size).toBeGreaterThan(1);
// expect(blob.path).toBe("/index.js");
// expect(blob.hash).toBeTruthy();
// expect(blob.hash).toMatchSnapshot();
// expect(blob.kind).toBe("entry-point");
// expect(blob.loader).toBe("jsx");
// expect(blob.sourcemap).toBe(null);
// throw new Error("test was not fully written");
// });
test("errors are returned as an array", async () => {
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "does-not-exist.ts")],
});
expect(x.success).toBe(false);
expect(x.logs).toHaveLength(1);
expect(x.logs[0].message).toMatch(/ModuleNotFound/);
expect(x.logs[0].name).toBe("BuildMessage");
expect(x.logs[0].position).toEqual(null);
});
test("warnings do not fail a build", async () => {
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/jsx-warning/index.jsx")],
});
expect(x.success).toBe(true);
expect(x.logs).toHaveLength(1);
expect(x.logs[0].message).toBe(
'"key" prop before a {...spread} is deprecated in JSX. Falling back to classic runtime.',
);
expect(x.logs[0].name).toBe("BuildMessage");
expect(x.logs[0].position).toBeTruthy();
});
test("test bun target", async () => {
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/bundle-ws.ts")],
target: "bun",
});
expect(x.success).toBe(true);
const [blob] = x.outputs;
const content = await blob.text();
// use bun's ws
expect(content).toContain('import {WebSocket} from "ws"');
expect(content).not.toContain("var websocket = __toESM(require_websocket(), 1);");
});
test("test node target, issue #3844", async () => {
const x = await Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/bundle-ws.ts")],
target: "node",
});
expect(x.success).toBe(true);
const [blob] = x.outputs;
const content = await blob.text();
expect(content).not.toContain('import {WebSocket} from "ws"');
// depends on the ws package in the test/node_modules.
expect(content).toContain("var websocket = __toESM(require_websocket(), 1);");
});
test("module() throws error", async () => {
expect(() =>
Bun.build({
entrypoints: [join(import.meta.dir, "./fixtures/trivial/bundle-ws.ts")],
plugins: [
{
name: "test",
setup: b => {
b.module("ad", () => {
return {
exports: {
hello: "world",
},
loader: "object",
};
});
},
},
],
}),
).toThrow();
});
});
one-repro1'>jarred/standalone-repro1
Unnamed repository; edit this file 'description' to name the repository. | |
Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|