aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-04-14 23:09:14 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-04-14 23:09:14 -0700
commite977bfb5a79e48b91430a8df6eff1da617ff2da6 (patch)
tree938c00a51ab070968817f60926f7743193fa8b2a
parent81e11ae58663d07b960c9da4d36f378d09bfbfdb (diff)
downloadbun-e977bfb5a79e48b91430a8df6eff1da617ff2da6.tar.gz
bun-e977bfb5a79e48b91430a8df6eff1da617ff2da6.tar.zst
bun-e977bfb5a79e48b91430a8df6eff1da617ff2da6.zip
Implement `--transform` CLI flag
-rw-r--r--src/bundler.zig73
-rw-r--r--src/bundler/bundle_v2.zig8
-rw-r--r--src/cli.zig5
-rw-r--r--src/cli/build_command.zig74
-rw-r--r--src/linker.zig7
-rw-r--r--src/options.zig4
6 files changed, 63 insertions, 108 deletions
diff --git a/src/bundler.zig b/src/bundler.zig
index 8c9775808..e471bddc6 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -986,7 +986,7 @@ pub const Bundler = struct {
}
switch (loader) {
- .jsx, .tsx, .js, .ts, .json, .toml => {
+ .jsx, .tsx, .js, .ts, .json, .toml, .text => {
var result = bundler.parse(
ParseOptions{
.allocator = bundler.allocator,
@@ -1053,6 +1053,9 @@ pub const Bundler = struct {
output_file.value = .{ .move = file_op };
},
+ .dataurl, .base64 => {
+ Output.panic("TODO: dataurl, base64", .{}); // TODO
+ },
.css => {
const CSSBuildContext = struct {
origin: URL,
@@ -1476,7 +1479,6 @@ pub const Bundler = struct {
.input_fd = input_fd,
};
},
- // TODO: use lazy export AST
.toml => {
var expr = TOML.parse(&source, bundler.log, allocator) catch return null;
var stmt = js_ast.Stmt.alloc(js_ast.S.ExportDefault, js_ast.S.ExportDefault{
@@ -1720,46 +1722,15 @@ pub const Bundler = struct {
return entry_point_i;
}
- pub fn bundle(
+ pub fn transform(
+ bundler: *Bundler,
allocator: std.mem.Allocator,
log: *logger.Log,
opts: Api.TransformOptions,
) !options.TransformResult {
- var bundler = try Bundler.init(allocator, log, opts, null, null);
- bundler.configureLinker();
- try bundler.configureRouter(false);
- try bundler.configureDefines();
- bundler.macro_context = js_ast.Macro.MacroContext.init(&bundler);
-
- if (bundler.env.map.get("BUN_CONFIG_MINIFY_WHITESPACE") != null) {
- bundler.options.minify_whitespace = true;
- }
-
- if (bundler.env.map.get("BUN_CONFIG_INLINE") != null) {
- bundler.options.inlining = true;
- }
-
- var skip_normalize = false;
- var load_from_routes = false;
- if (bundler.options.routes.routes_enabled and bundler.options.entry_points.len == 0) {
- if (bundler.router) |router| {
- bundler.options.entry_points = try router.getEntryPoints();
- skip_normalize = true;
- load_from_routes = true;
- }
- }
-
- // 100.00 µs std.fifo.LinearFifo(resolver.Result,std.fifo.LinearFifoBufferType { .Dynamic = {}}).writeItemAssumeCapacity
- if (bundler.options.resolve_mode != .lazy) {
- try bundler.resolve_queue.ensureUnusedCapacity(3);
- }
-
+ _ = opts;
var entry_points = try allocator.alloc(_resolver.Result, bundler.options.entry_points.len);
- if (skip_normalize) {
- entry_points = entry_points[0..bundler.enqueueEntryPoints(entry_points, false)];
- } else {
- entry_points = entry_points[0..bundler.enqueueEntryPoints(entry_points, true)];
- }
+ entry_points = entry_points[0..bundler.enqueueEntryPoints(entry_points, true)];
if (log.level == .verbose) {
bundler.resolver.debug_logs = try DebugLogs.init(allocator);
@@ -1770,20 +1741,6 @@ pub const Bundler = struct {
if (bundler.options.output_dir_handle == null) {
const outstream = std.io.getStdOut();
- if (load_from_routes) {
- if (bundler.options.framework) |*framework| {
- if (framework.client.isEnabled()) {
- did_start = true;
- try switch (bundler.options.import_path_format) {
- .relative => bundler.processResolveQueue(.relative, true, @TypeOf(outstream), outstream),
- .absolute_url => bundler.processResolveQueue(.absolute_url, true, @TypeOf(outstream), outstream),
- .absolute_path => bundler.processResolveQueue(.absolute_path, true, @TypeOf(outstream), outstream),
- .package_path => bundler.processResolveQueue(.package_path, true, @TypeOf(outstream), outstream),
- };
- }
- }
- }
-
if (!did_start) {
try switch (bundler.options.import_path_format) {
.relative => bundler.processResolveQueue(.relative, false, @TypeOf(outstream), outstream),
@@ -1798,20 +1755,6 @@ pub const Bundler = struct {
Global.crash();
};
- if (load_from_routes) {
- if (bundler.options.framework) |*framework| {
- if (framework.client.isEnabled()) {
- did_start = true;
- try switch (bundler.options.import_path_format) {
- .relative => bundler.processResolveQueue(.relative, true, std.fs.Dir, output_dir),
- .absolute_url => bundler.processResolveQueue(.absolute_url, true, std.fs.Dir, output_dir),
- .absolute_path => bundler.processResolveQueue(.absolute_path, true, std.fs.Dir, output_dir),
- .package_path => bundler.processResolveQueue(.package_path, true, std.fs.Dir, output_dir),
- };
- }
- }
- }
-
if (!did_start) {
try switch (bundler.options.import_path_format) {
.relative => bundler.processResolveQueue(.relative, false, std.fs.Dir, output_dir),
diff --git a/src/bundler/bundle_v2.zig b/src/bundler/bundle_v2.zig
index f5622114a..6a1cf486c 100644
--- a/src/bundler/bundle_v2.zig
+++ b/src/bundler/bundle_v2.zig
@@ -6878,6 +6878,12 @@ const LinkerContext = struct {
}
const prev_import_ref = tracker.import_ref;
+
+ if (tracker.source_index.isInvalid()) {
+ // External
+ break;
+ }
+
const prev_source_index = tracker.source_index.get();
c.cycle_detector.append(tracker.*) catch unreachable;
@@ -6894,7 +6900,7 @@ const LinkerContext = struct {
if (status == .external and c.options.output_format.keepES6ImportExportSyntax()) {
// Imports from external modules should not be converted to CommonJS
// if the output format preserves the original ES6 import statements
- continue;
+ break;
}
// If it's a CommonJS or external file, rewrite the import to a
diff --git a/src/cli.zig b/src/cli.zig
index f9c3f403f..674aeac02 100644
--- a/src/cli.zig
+++ b/src/cli.zig
@@ -69,7 +69,7 @@ pub const Cli = struct {
log.printForLogLevelWithEnableAnsiColors(Output.errorWriter(), false) catch {};
}
- Reporter.globalError(err);
+ Reporter.globalError(err, @errorReturnTrace());
},
}
};
@@ -198,6 +198,7 @@ pub const Arguments = struct {
clap.parseParam("--outfile <STR> Write to a file") catch unreachable,
clap.parseParam("--server-components Enable React Server Components (experimental)") catch unreachable,
clap.parseParam("--splitting Split up code!") catch unreachable,
+ clap.parseParam("--transform Do not bundle") catch unreachable,
};
// TODO: update test completions
@@ -497,6 +498,7 @@ pub const Arguments = struct {
var output_file: ?string = null;
if (cmd == .BuildCommand) {
+ ctx.bundler_options.transform_only = args.flag("--transform");
if (args.option("--outdir")) |outdir| {
if (outdir.len > 0) {
ctx.bundler_options.outdir = outdir;
@@ -909,6 +911,7 @@ pub const Command = struct {
entry_names: []const u8 = "./[name].[ext]",
react_server_components: bool = false,
code_splitting: bool = false,
+ transform_only: bool = false,
};
const _ctx = Command.Context{
diff --git a/src/cli/build_command.zig b/src/cli/build_command.zig
index 1b8e5c632..825ab4d2a 100644
--- a/src/cli/build_command.zig
+++ b/src/cli/build_command.zig
@@ -90,33 +90,23 @@ pub const BuildCommand = struct {
return;
}
- // var generated_server = false;
- // if (this_bundler.options.framework) |*framework| {
- // if (framework.toAPI(allocator, this_bundler.fs.top_level_dir) catch null) |_server_conf| {
- // ServerBundleGeneratorThread.generate(
- // log,
- // env_loader,
- // ctx,
- // server_bundle_filepath,
- // _server_conf,
- // loaded_route_config,
- // this_bundler.router,
- // );
- // generated_server = true;
-
- // if (log.msgs.items.len > 0) {
- // try log.printForLogLevel(Output.errorWriter());
- // log.* = logger.Log.init(allocator);
- // Output.flush();
- // }
- // }
- // }
-
- {
+ const output_files: []options.OutputFile = brk: {
+ if (ctx.bundler_options.transform_only) {
+ this_bundler.linker.options.resolve_mode = .lazy;
+ this_bundler.options.import_path_format = .relative;
+
+ // TODO: refactor this .transform function
+ const result = try this_bundler.transform(
+ ctx.allocator,
+ ctx.log,
+ ctx.args,
+ );
+ try log.msgs.appendSlice(result.errors);
+ try log.msgs.appendSlice(result.warnings);
+ break :brk result.output_files;
+ }
- // Always generate the client-only bundle
- // we can revisit this decision if people ask
- const output_files = BundleV2.generate(
+ break :brk (BundleV2.generate(
&this_bundler,
allocator,
&estimated_input_lines_of_code_,
@@ -134,34 +124,38 @@ pub const BuildCommand = struct {
Output.flush();
exitOrWatch(1, ctx.debug.hot_reload == .watch);
unreachable;
- };
+ }).items;
+ };
+ {
{
dump: {
defer Output.flush();
var writer = Output.errorWriter();
var output_dir = this_bundler.options.output_dir;
- if (ctx.bundler_options.outfile.len > 0 and output_files.items.len == 1 and output_files.items[0].value == .buffer) {
+ if (ctx.bundler_options.outfile.len > 0 and output_files.len == 1 and output_files[0].value == .buffer) {
output_dir = std.fs.path.dirname(ctx.bundler_options.outfile) orelse ".";
- output_files.items[0].input.text = std.fs.path.basename(ctx.bundler_options.outfile);
+ output_files[0].input.text = std.fs.path.basename(ctx.bundler_options.outfile);
}
- if (output_dir.len == 0 and output_files.items.len == 1 and output_files.items[0].value == .buffer) {
- try writer.writeAll(output_files.items[0].value.buffer);
+ if (output_dir.len == 0 and ctx.bundler_options.outfile.len == 0) {
+ // if --transform is passed, it won't have an output dir
+ if (output_files[0].value == .buffer)
+ try writer.writeAll(output_files[0].value.buffer);
break :dump;
}
const root_path = output_dir;
const root_dir = try std.fs.cwd().makeOpenPathIterable(root_path, .{});
- var all_paths = try ctx.allocator.alloc([]const u8, output_files.items.len);
+ var all_paths = try ctx.allocator.alloc([]const u8, output_files.len);
var max_path_len: usize = 0;
- for (all_paths, output_files.items) |*dest, src| {
+ for (all_paths, output_files) |*dest, src| {
dest.* = src.input.text;
}
var from_path = resolve_path.longestCommonPath(all_paths);
- for (output_files.items) |f| {
+ for (output_files) |f| {
max_path_len = std.math.max(
std.math.max(from_path.len, f.input.text.len) + 2 - from_path.len,
max_path_len,
@@ -171,13 +165,13 @@ pub const BuildCommand = struct {
// On posix, file handles automatically close on process exit by the OS
// Closing files shows up in profiling.
// So don't do that unless we actually need to.
- // const do_we_need_to_close = !FeatureFlags.store_file_descriptors or (@intCast(usize, root_dir.fd) + open_file_limit) < output_files.items.len;
+ // const do_we_need_to_close = !FeatureFlags.store_file_descriptors or (@intCast(usize, root_dir.fd) + open_file_limit) < output_files.len;
var filepath_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
filepath_buf[0] = '.';
filepath_buf[1] = '/';
- for (output_files.items) |f| {
+ for (output_files) |f| {
var rel_path: []const u8 = undefined;
switch (f.value) {
// easy mode: write the buffer
@@ -194,12 +188,12 @@ pub const BuildCommand = struct {
try root_dir.dir.writeFile(rel_path, value);
},
.move => |value| {
- // const primary = f.input.text[from_path.len..];
- // bun.copy(u8, filepath_buf[2..], primary);
- // rel_path = filepath_buf[0 .. primary.len + 2];
+ const primary = f.input.text[from_path.len..];
+ bun.copy(u8, filepath_buf[2..], primary);
+ rel_path = filepath_buf[0 .. primary.len + 2];
rel_path = value.pathname;
- // try f.moveTo(result.outbase, constStrToU8(rel_path), root_dir.fd);
+ try f.moveTo(root_path, bun.constStrToU8(rel_path), root_dir.dir.fd);
},
.copy => |value| {
rel_path = value.pathname;
diff --git a/src/linker.zig b/src/linker.zig
index a62f59b8c..cccd37ae7 100644
--- a/src/linker.zig
+++ b/src/linker.zig
@@ -901,7 +901,12 @@ pub const Linker = struct {
pretty = _pretty;
relative_name = try linker.allocator.dupe(u8, relative_name);
} else {
- pretty = try linker.allocator.dupe(u8, relative_name);
+ if (relative_name.len > 1 and !(relative_name[0] == std.fs.path.sep or relative_name[0] == '.')) {
+ pretty = try strings.concat(linker.allocator, &.{ "./", relative_name });
+ } else {
+ pretty = try linker.allocator.dupe(u8, relative_name);
+ }
+
relative_name = pretty;
}
diff --git a/src/options.zig b/src/options.zig
index f7acc1c64..9d96890b9 100644
--- a/src/options.zig
+++ b/src/options.zig
@@ -1999,6 +1999,10 @@ pub const OutputFile = struct {
};
}
+ pub fn moveTo(file: *const OutputFile, _: string, rel_path: []u8, dir: FileDescriptorType) !void {
+ try bun.C.moveFileZ(file.value.move.dir, &(try std.os.toPosixPath(file.value.move.getPathname())), dir, &(try std.os.toPosixPath(rel_path)));
+ }
+
pub fn copyTo(file: *const OutputFile, _: string, rel_path: []u8, dir: FileDescriptorType) !void {
var dir_obj = std.fs.Dir{ .fd = dir };
const file_out = (try dir_obj.createFile(rel_path, .{}));