diff options
author | 2023-04-14 23:09:14 -0700 | |
---|---|---|
committer | 2023-04-14 23:09:14 -0700 | |
commit | e977bfb5a79e48b91430a8df6eff1da617ff2da6 (patch) | |
tree | 938c00a51ab070968817f60926f7743193fa8b2a | |
parent | 81e11ae58663d07b960c9da4d36f378d09bfbfdb (diff) | |
download | bun-e977bfb5a79e48b91430a8df6eff1da617ff2da6.tar.gz bun-e977bfb5a79e48b91430a8df6eff1da617ff2da6.tar.zst bun-e977bfb5a79e48b91430a8df6eff1da617ff2da6.zip |
Implement `--transform` CLI flag
-rw-r--r-- | src/bundler.zig | 73 | ||||
-rw-r--r-- | src/bundler/bundle_v2.zig | 8 | ||||
-rw-r--r-- | src/cli.zig | 5 | ||||
-rw-r--r-- | src/cli/build_command.zig | 74 | ||||
-rw-r--r-- | src/linker.zig | 7 | ||||
-rw-r--r-- | src/options.zig | 4 |
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, .{})); |