Faster debug builds (#16354)

This commit is contained in:
Jarred Sumner
2025-01-12 20:03:24 -08:00
committed by GitHub
parent da5a1a9b6a
commit 22436ede12
8 changed files with 83 additions and 68 deletions

View File

@@ -200,7 +200,10 @@ pub fn build(b: *Build) !void {
b.option([]const u8, "codegen_path", "Set the generated code directory") orelse
"build/debug/codegen",
);
const codegen_embed = b.option(bool, "codegen_embed", "If codegen files should be embedded in the binary") orelse false;
const codegen_embed = b.option(bool, "codegen_embed", "If codegen files should be embedded in the binary") orelse switch (b.release_mode) {
.off => false,
else => true,
};
const bun_version = b.option([]const u8, "version", "Value of `Bun.version`") orelse "0.0.0";
@@ -527,36 +530,36 @@ fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void {
.{ .file = "ZigGeneratedClasses.zig", .import = "ZigGeneratedClasses" },
.{ .file = "ResolvedSourceTag.zig", .import = "ResolvedSourceTag" },
.{ .file = "ErrorCode.zig", .import = "ErrorCode" },
.{ .file = "runtime.out.js" },
.{ .file = "runtime.out.js", .enable = opts.shouldEmbedCode() },
.{ .file = "bake.client.js", .import = "bake-codegen/bake.client.js", .enable = opts.shouldEmbedCode() },
.{ .file = "bake.error.js", .import = "bake-codegen/bake.error.js", .enable = opts.shouldEmbedCode() },
.{ .file = "bake.server.js", .import = "bake-codegen/bake.server.js", .enable = opts.shouldEmbedCode() },
.{ .file = "bun-error/index.js", .enable = opts.shouldEmbedCode() },
.{ .file = "bun-error/bun-error.css", .enable = opts.shouldEmbedCode() },
.{ .file = "fallback-decoder.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/assert.js" },
.{ .file = "node-fallbacks/buffer.js" },
.{ .file = "node-fallbacks/console.js" },
.{ .file = "node-fallbacks/constants.js" },
.{ .file = "node-fallbacks/crypto.js" },
.{ .file = "node-fallbacks/domain.js" },
.{ .file = "node-fallbacks/events.js" },
.{ .file = "node-fallbacks/http.js" },
.{ .file = "node-fallbacks/https.js" },
.{ .file = "node-fallbacks/net.js" },
.{ .file = "node-fallbacks/os.js" },
.{ .file = "node-fallbacks/path.js" },
.{ .file = "node-fallbacks/process.js" },
.{ .file = "node-fallbacks/punycode.js" },
.{ .file = "node-fallbacks/querystring.js" },
.{ .file = "node-fallbacks/stream.js" },
.{ .file = "node-fallbacks/string_decoder.js" },
.{ .file = "node-fallbacks/sys.js" },
.{ .file = "node-fallbacks/timers.js" },
.{ .file = "node-fallbacks/tty.js" },
.{ .file = "node-fallbacks/url.js" },
.{ .file = "node-fallbacks/util.js" },
.{ .file = "node-fallbacks/zlib.js" },
.{ .file = "node-fallbacks/assert.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/buffer.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/console.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/constants.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/crypto.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/domain.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/events.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/http.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/https.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/net.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/os.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/path.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/process.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/punycode.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/querystring.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/stream.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/string_decoder.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/sys.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/timers.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/tty.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/url.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/util.js", .enable = opts.shouldEmbedCode() },
.{ .file = "node-fallbacks/zlib.js", .enable = opts.shouldEmbedCode() },
}) |entry| {
if (!@hasField(@TypeOf(entry), "enable") or entry.enable) {
const path = b.pathJoin(&.{ opts.codegen_path, entry.file });

View File

@@ -1234,12 +1234,12 @@ declare module "bun" {
/**
* Deletes the file. ( same as unlink )
*/
delete(): Promise<void>
delete(): Promise<void>;
/**
* Provides useful information about the file.
*/
stat(): Promise<Stats>
stat(): Promise<Stats>;
}
interface NetworkSink extends FileSink {
/**

View File

@@ -2496,7 +2496,7 @@ pub const ModuleLoader = struct {
if (specifier.eqlComptime(Runtime.Runtime.Imports.Name)) {
return ResolvedSource{
.allocator = null,
.source_code = String.init(Runtime.Runtime.source_code),
.source_code = String.init(Runtime.Runtime.sourceCode()),
.specifier = specifier,
.source_url = specifier,
.hash = Runtime.Runtime.versionHash(),

View File

@@ -1,7 +1,7 @@
import assert from "node:assert";
import { existsSync, writeFileSync, rmSync, readFileSync } from "node:fs";
import { existsSync, readFileSync, rmSync } from "node:fs";
import { basename, join } from "node:path";
import { argParse } from "./helpers";
import { argParse, writeIfNotChanged } from "./helpers";
// arg parsing
let { "codegen-root": codegenRoot, debug, ...rest } = argParse(["codegen-root", "debug"]);
@@ -28,7 +28,7 @@ function convertZigEnum(zig: string) {
async function run() {
const devServerZig = readFileSync(join(base_dir, "DevServer.zig"), "utf-8");
writeFileSync(join(base_dir, "generated.ts"), convertZigEnum(devServerZig));
writeIfNotChanged(join(base_dir, "generated.ts"), convertZigEnum(devServerZig));
const results = await Promise.allSettled(
["client", "server", "error"].map(async file => {
@@ -69,7 +69,7 @@ async function run() {
`;
const generated_entrypoint = join(base_dir, `.runtime-${file}.generated.ts`);
writeFileSync(generated_entrypoint, combined_source);
writeIfNotChanged(generated_entrypoint, combined_source);
result = await Bun.build({
entrypoints: [generated_entrypoint],
@@ -124,7 +124,7 @@ async function run() {
}
}
writeFileSync(join(codegenRoot, `bake.${file}.js`), code);
writeIfNotChanged(join(codegenRoot, `bake.${file}.js`), code);
}),
);
@@ -169,7 +169,7 @@ async function run() {
console.log("-> bake.client.js, bake.server.js, bake.error.js");
const empty_file = join(codegenRoot, "bake_empty_file");
if (!existsSync(empty_file)) writeFileSync(empty_file, "this is used to fulfill a cmake dependency");
if (!existsSync(empty_file)) writeIfNotChanged(empty_file, "this is used to fulfill a cmake dependency");
}
}

View File

@@ -5258,18 +5258,10 @@ function createNativeStreamReadable(Readable) {
var handleNumberResult = function (nativeReadable, result, view, isClosed) {
if (result > 0) {
const slice = view.subarray(0, result);
const remainder = view.subarray(result);
view = slice.byteLength < view.byteLength ? view.subarray(result) : undefined;
if (slice.byteLength > 0) {
nativeReadable.push(slice);
}
if (isClosed) {
ProcessNextTick(() => {
nativeReadable.push(null);
});
}
return remainder.byteLength > 0 ? remainder : undefined;
}
if (isClosed) {

View File

@@ -17,7 +17,24 @@ comptime {
pub const FallbackModule = struct {
path: Fs.Path,
package_json: *const PackageJSON,
code: string,
code: *const fn () string,
// This workaround exists to allow bun.runtimeEmbedFile to work.
// Using `@embedFile` forces you to wait for the Zig build to finish in
// debug builds, even when you only changed JS builtins.
fn createSourceCodeGetter(comptime code_path: string) *const fn () string {
const Getter = struct {
fn get() string {
if (bun.Environment.codegen_embed) {
return @embedFile(code_path);
}
return bun.runtimeEmbedFile(.codegen_eager, code_path);
}
};
return Getter.get;
}
pub fn init(comptime name: string) FallbackModule {
@setEvalBranchQuota(99999);
@@ -35,7 +52,7 @@ pub const FallbackModule = struct {
.source = logger.Source.initPathString(import_path ++ name ++ "/package.json", ""),
.side_effects = .false,
},
.code = @embedFile(code_path),
.code = createSourceCodeGetter(code_path),
};
}
};
@@ -74,7 +91,7 @@ pub fn contentsFromPath(path: string) ?string {
module_name = module_name[0 .. std.mem.indexOfScalar(u8, module_name, '/') orelse module_name.len];
if (Map.get(module_name)) |mod| {
return mod.code;
return mod.code();
}
return null;

View File

@@ -149,12 +149,15 @@ pub const Fallback = struct {
};
pub const Runtime = struct {
pub const source_code = @embedFile("runtime.out.js");
pub const hash = brk: {
@setEvalBranchQuota(source_code.len * 50);
break :brk bun.Wyhash11.hash(0, source_code);
};
pub fn sourceCode() string {
return if (Environment.codegen_embed)
@embedFile("runtime.out.js")
else
bun.runtimeEmbedFile(.src_eager, "runtime.out.js");
}
pub fn versionHash() u32 {
const hash = bun.Wyhash11.hash(0, sourceCode());
return @truncate(hash);
}