aboutsummaryrefslogtreecommitdiff
path: root/src/main_javascript.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main_javascript.zig')
-rw-r--r--src/main_javascript.zig422
1 files changed, 0 insertions, 422 deletions
diff --git a/src/main_javascript.zig b/src/main_javascript.zig
deleted file mode 100644
index 8cf3e959f..000000000
--- a/src/main_javascript.zig
+++ /dev/null
@@ -1,422 +0,0 @@
-const std = @import("std");
-const lex = @import("js_lexer.zig");
-const logger = @import("logger.zig");
-const options = @import("options.zig");
-const js_parser = @import("js_parser.zig");
-const json_parser = @import("json_parser.zig");
-const js_printer = @import("js_printer.zig");
-const js_ast = @import("js_ast.zig");
-const linker = @import("linker.zig");
-usingnamespace @import("ast/base.zig");
-usingnamespace @import("defines.zig");
-usingnamespace @import("global.zig");
-const panicky = @import("panic_handler.zig");
-pub const MainPanicHandler = panicky.NewPanicHandler(panicky.default_panic);
-const Api = @import("api/schema.zig").Api;
-const resolve_path = @import("./resolver/resolve_path.zig");
-const clap = @import("clap");
-const bundler = @import("bundler.zig");
-const fs = @import("fs.zig");
-const NodeModuleBundle = @import("./node_module_bundle.zig").NodeModuleBundle;
-const js = @import("javascript/jsc/bindings/bindings.zig");
-usingnamespace @import("javascript/jsc/javascript.zig");
-const allocators = @import("allocators.zig");
-pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn {
- if (MainPanicHandler.Singleton) |singleton| {
- MainPanicHandler.handle_panic(msg, error_return_trace);
- } else {
- panicky.default_panic(msg, error_return_trace);
- }
-}
-
-const constStrToU8 = allocators.constStrToU8;
-pub fn main() anyerror!void {
- // The memory allocator makes a massive difference.
- // std.heap.raw_c_allocator and default_allocator perform similarly.
- // std.heap.GeneralPurposeAllocator makes this about 3x _slower_ than esbuild.
- // var root_alloc = std.heap.ArenaAllocator.init(std.heap.raw_c_allocator);
- // var root_alloc_ = &root_alloc.allocator;
-
- var stdout = std.io.getStdOut();
- // var stdout = std.io.bufferedWriter(stdout_file.writer());
- var stderr = std.io.getStdErr();
- // var stderr = std.io.bufferedWriter(stderr_file.writer());
- var output_source = Output.Source.init(stdout, stderr);
- // defer stdout.flush() catch {};
- // defer stderr.flush() catch {};
- Output.Source.set(&output_source);
-
- defer Output.flush();
- try Cli.start(
- default_allocator,
- stdout,
- stderr,
- );
-}
-
-pub const Cli = struct {
- const LoaderMatcher = strings.ExactSizeMatcher(4);
- pub fn ColonListType(comptime t: type, value_resolver: anytype) type {
- return struct {
- pub fn init(allocator: *std.mem.Allocator, count: usize) !@This() {
- var keys = try allocator.alloc(string, count);
- var values = try allocator.alloc(t, count);
-
- return @This(){ .keys = keys, .values = values };
- }
- keys: []string,
- values: []t,
-
- pub fn load(self: *@This(), input: []const string) !void {
- for (input) |str, i| {
- // Support either ":" or "=" as the separator, preferring whichever is first.
- // ":" is less confusing IMO because that syntax is used with flags
- // but "=" is what esbuild uses and I want this to be somewhat familiar for people using esbuild
- const midpoint = std.math.min(strings.indexOfChar(str, ':') orelse std.math.maxInt(usize), strings.indexOfChar(str, '=') orelse std.math.maxInt(usize));
- if (midpoint == std.math.maxInt(usize)) {
- return error.InvalidSeparator;
- }
-
- self.keys[i] = str[0..midpoint];
- self.values[i] = try value_resolver(str[midpoint + 1 .. str.len]);
- }
- }
-
- pub fn resolve(allocator: *std.mem.Allocator, input: []const string) !@This() {
- var list = try init(allocator, input.len);
- try list.load(input);
- return list;
- }
- };
- }
- pub const LoaderColonList = ColonListType(Api.Loader, Arguments.loader_resolver);
- pub const DefineColonList = ColonListType(string, Arguments.noop_resolver);
-
- pub const Arguments = struct {
- pub fn loader_resolver(in: string) !Api.Loader {
- const Matcher = strings.ExactSizeMatcher(4);
- switch (Matcher.match(in)) {
- Matcher.case("jsx") => return Api.Loader.jsx,
- Matcher.case("js") => return Api.Loader.js,
- Matcher.case("ts") => return Api.Loader.ts,
- Matcher.case("tsx") => return Api.Loader.tsx,
- Matcher.case("css") => return Api.Loader.css,
- Matcher.case("file") => return Api.Loader.file,
- Matcher.case("json") => return Api.Loader.json,
- else => {
- return error.InvalidLoader;
- },
- }
- }
-
- pub fn noop_resolver(in: string) !string {
- return in;
- }
-
- pub fn fileReadError(err: anyerror, stderr: anytype, filename: string, kind: string) noreturn {
- stderr.writer().print("Error reading file \"{s}\" for {s}: {s}", .{ filename, kind, @errorName(err) }) catch {};
- std.process.exit(1);
- }
-
- pub fn readFile(
- allocator: *std.mem.Allocator,
- cwd: string,
- filename: string,
- ) ![]u8 {
- var paths = [_]string{ cwd, filename };
- const outpath = try std.fs.path.resolve(allocator, &paths);
- defer allocator.free(outpath);
- var file = try std.fs.openFileAbsolute(outpath, std.fs.File.OpenFlags{ .read = true, .write = false });
- defer file.close();
- const stats = try file.stat();
- return try file.readToEndAlloc(allocator, stats.size);
- }
-
- pub fn parse(allocator: *std.mem.Allocator, stdout: anytype, stderr: anytype) !Api.TransformOptions {
- @setEvalBranchQuota(9999);
- const params = comptime [_]clap.Param(clap.Help){
- clap.parseParam("-h, --help Display this help and exit. ") catch unreachable,
- clap.parseParam("-r, --resolve <STR> Determine import/require behavior. \"disable\" ignores. \"dev\" bundles node_modules and builds everything else as independent entry points") catch unreachable,
- clap.parseParam("-d, --define <STR>... Substitute K:V while parsing, e.g. --define process.env.NODE_ENV:development") catch unreachable,
- clap.parseParam("-l, --loader <STR>... Parse files with .ext:loader, e.g. --loader .js:jsx. Valid loaders: jsx, js, json, tsx (not implemented yet), ts (not implemented yet), css (not implemented yet)") catch unreachable,
- clap.parseParam("-o, --outdir <STR> Save output to directory (default: \"out\" if none provided and multiple entry points passed)") catch unreachable,
- clap.parseParam("-e, --external <STR>... Exclude module from transpilation (can use * wildcards). ex: -e react") catch unreachable,
- clap.parseParam("-i, --inject <STR>... Inject module at the top of every file") catch unreachable,
- clap.parseParam("--cwd <STR> Absolute path to resolve entry points from. Defaults to cwd") catch unreachable,
- clap.parseParam("--origin <STR> Rewrite import paths to start with --origin. Useful for web browsers.") catch unreachable,
- clap.parseParam("--serve Start a local dev server. This also sets resolve to \"lazy\".") catch unreachable,
- clap.parseParam("--public-dir <STR> Top-level directory for .html files, fonts, images, or anything external. Only relevant with --serve. Defaults to \"<cwd>/public\", to match create-react-app and Next.js") catch unreachable,
- clap.parseParam("--jsx-factory <STR> Changes the function called when compiling JSX elements using the classic JSX runtime") catch unreachable,
- clap.parseParam("--jsx-fragment <STR> Changes the function called when compiling JSX fragments using the classic JSX runtime") catch unreachable,
- clap.parseParam("--jsx-import-source <STR> Declares the module specifier to be used for importing the jsx and jsxs factory functions. Default: \"react\"") catch unreachable,
- clap.parseParam("--jsx-runtime <STR> \"automatic\" (default) or \"classic\"") catch unreachable,
- clap.parseParam("--jsx-production Use jsx instead of jsxDEV (default) for the automatic runtime") catch unreachable,
- clap.parseParam("--extension-order <STR>... defaults to: .tsx,.ts,.jsx,.js,.json ") catch unreachable,
- clap.parseParam("--disable-react-fast-refresh Disable React Fast Refresh. Enabled if --serve is set and --jsx-production is not set. Otherwise, it's a noop.") catch unreachable,
- clap.parseParam("--tsconfig-override <STR> Load tsconfig from path instead of cwd/tsconfig.json") catch unreachable,
- clap.parseParam("--platform <STR> \"browser\" or \"node\". Defaults to \"browser\"") catch unreachable,
- clap.parseParam("--main-fields <STR>... Main fields to lookup in package.json. Defaults to --platform dependent") catch unreachable,
- clap.parseParam("--scan Instead of bundling or transpiling, print a list of every file imported by an entry point, recursively") catch unreachable,
- clap.parseParam("--new-jsb Generate a new node_modules.jsb file from node_modules and entry point(s)") catch unreachable,
- clap.parseParam("--jsb <STR> Use a Bun JavaScript Bundle (default: \"./node_modules.jsb\" if exists)") catch unreachable,
- // clap.parseParam("--no-jsb Use a Bun JavaScript Bundle (default: \"./node_modules.jsb\" if exists)") catch unreachable,
- clap.parseParam("<POS>... Entry points to use") catch unreachable,
- };
-
- var diag = clap.Diagnostic{};
-
- var args = clap.parse(clap.Help, &params, .{ .diagnostic = &diag, .allocator = allocator }) catch |err| {
- // Report useful error and exit
- diag.report(stderr.writer(), err) catch {};
- return err;
- };
-
- if (args.flag("--help")) {
- try clap.help(stderr.writer(), &params);
- std.process.exit(1);
- }
-
- var cwd_paths = [_]string{args.option("--cwd") orelse try std.process.getCwdAlloc(allocator)};
- var cwd = try std.fs.path.resolve(allocator, &cwd_paths);
- var tsconfig_override = if (args.option("--tsconfig-override")) |ts| (Arguments.readFile(allocator, cwd, ts) catch |err| fileReadError(err, stderr, ts, "tsconfig.json")) else null;
- var origin = args.option("--origin");
- var defines_tuple = try DefineColonList.resolve(allocator, args.options("--define"));
- var loader_tuple = try LoaderColonList.resolve(allocator, args.options("--define"));
-
- var define_keys = defines_tuple.keys;
- var define_values = defines_tuple.values;
- var loader_keys = loader_tuple.keys;
- var loader_values = loader_tuple.values;
- var entry_points = args.positionals();
- var inject = args.options("--inject");
- var output_dir = args.option("--outdir");
- const serve = false;
-
- var write = entry_points.len > 1 or output_dir != null;
- if (write and output_dir == null) {
- var _paths = [_]string{ cwd, "out" };
- output_dir = try std.fs.path.resolve(allocator, &_paths);
- }
- var externals = std.mem.zeroes([][]u8);
- if (args.options("--external").len > 0) {
- externals = try allocator.alloc([]u8, args.options("--external").len);
- for (args.options("--external")) |external, i| {
- externals[i] = constStrToU8(external);
- }
- }
-
- var jsx_factory = args.option("--jsx-factory");
- var jsx_fragment = args.option("--jsx-fragment");
- var jsx_import_source = args.option("--jsx-import-source");
- var jsx_runtime = args.option("--jsx-runtime");
- var jsx_production = args.flag("--jsx-production");
- var react_fast_refresh = false;
-
- if (serve or args.flag("--new-bun")) {
- react_fast_refresh = true;
- if (args.flag("--disable-react-fast-refresh") or jsx_production) {
- react_fast_refresh = false;
- }
- }
-
- var main_fields = args.options("--main-fields");
-
- var node_modules_bundle_path = args.option("--bun") orelse brk: {
- if (args.flag("--new-bun")) {
- break :brk null;
- }
-
- const node_modules_bundle_path_absolute = resolve_path.joinAbs(cwd, .auto, "node_modules.bun");
- std.fs.accessAbsolute(node_modules_bundle_path_absolute, .{}) catch |err| {
- break :brk null;
- };
-
- break :brk node_modules_bundle_path_absolute;
- };
-
- if (node_modules_bundle_path != null) {
- node_modules_bundle_path = try std.fs.realpathAlloc(allocator, node_modules_bundle_path.?);
- }
-
- if (args.flag("--new-bun")) {
- node_modules_bundle_path = null;
- }
-
- const PlatformMatcher = strings.ExactSizeMatcher(8);
- const ResoveMatcher = strings.ExactSizeMatcher(8);
-
- var resolve = Api.ResolveMode.lazy;
- if (args.option("--resolve")) |_resolve| {
- switch (PlatformMatcher.match(_resolve)) {
- PlatformMatcher.case("disable") => {
- resolve = Api.ResolveMode.disable;
- },
- PlatformMatcher.case("bundle") => {
- resolve = Api.ResolveMode.bundle;
- },
- PlatformMatcher.case("dev") => {
- resolve = Api.ResolveMode.dev;
- },
- PlatformMatcher.case("lazy") => {
- resolve = Api.ResolveMode.lazy;
- },
- else => {
- diag.name.long = "--resolve";
- diag.arg = _resolve;
- try diag.report(stderr.writer(), error.InvalidResolveOption);
- std.process.exit(1);
- },
- }
- }
-
- var platform: ?Api.Platform = null;
-
- if (args.option("--platform")) |_platform| {
- switch (PlatformMatcher.match(_platform)) {
- PlatformMatcher.case("browser") => {
- platform = Api.Platform.browser;
- },
- PlatformMatcher.case("node") => {
- platform = Api.Platform.node;
- },
- else => {
- diag.name.long = "--platform";
- diag.arg = _platform;
- try diag.report(stderr.writer(), error.InvalidPlatform);
- std.process.exit(1);
- },
- }
- }
-
- var jsx: ?Api.Jsx = null;
- if (jsx_factory != null or
- jsx_fragment != null or
- jsx_import_source != null or
- jsx_runtime != null or
- jsx_production or react_fast_refresh)
- {
- var default_factory = "".*;
- var default_fragment = "".*;
- var default_import_source = "".*;
- jsx = Api.Jsx{
- .factory = constStrToU8(jsx_factory orelse &default_factory),
- .fragment = constStrToU8(jsx_fragment orelse &default_fragment),
- .import_source = constStrToU8(jsx_import_source orelse &default_import_source),
- .runtime = if (jsx_runtime != null) try resolve_jsx_runtime(jsx_runtime.?) else Api.JsxRuntime.automatic,
- .development = !jsx_production,
- .react_fast_refresh = react_fast_refresh,
- };
- }
-
- if (entry_points.len == 0) {
- try clap.help(stderr.writer(), &params);
- try diag.report(stderr.writer(), error.MissingEntryPoint);
- std.process.exit(1);
- }
-
- return Api.TransformOptions{
- .jsx = jsx,
- .output_dir = output_dir,
- .resolve = resolve,
- .external = externals,
- .absolute_working_dir = cwd,
- .tsconfig_override = tsconfig_override,
- .origin = origin,
- .define = .{
- .keys = define_keys,
- .values = define_values,
- },
- .loaders = .{
- .extensions = loader_keys,
- .loaders = loader_values,
- },
- .node_modules_bundle_path = node_modules_bundle_path,
- .public_dir = if (args.option("--public-dir")) |public_dir| allocator.dupe(u8, public_dir) catch unreachable else null,
- .write = write,
- .platform = .bun,
- .serve = serve,
- .inject = inject,
- .entry_points = entry_points,
- .extension_order = args.options("--extension-order"),
- .main_fields = args.options("--main-fields"),
- .generate_node_module_bundle = if (args.flag("--new-bun")) true else false,
- };
- }
- };
- pub fn resolve_jsx_runtime(str: string) !Api.JsxRuntime {
- if (strings.eql(str, "automatic")) {
- return Api.JsxRuntime.automatic;
- } else if (strings.eql(str, "fallback")) {
- return Api.JsxRuntime.classic;
- } else {
- return error.InvalidJSXRuntime;
- }
- }
- pub fn printScanResults(scan_results: bundler.ScanResult.Summary, allocator: *std.mem.Allocator) !void {
- var stdout = std.io.getStdOut();
- const print_start = std.time.nanoTimestamp();
- try std.json.stringify(scan_results.list(), .{}, stdout.writer());
- Output.printError("\nJSON printing took: {d}\n", .{std.time.nanoTimestamp() - print_start});
- }
- pub fn startTransform(allocator: *std.mem.Allocator, args: Api.TransformOptions, log: *logger.Log) anyerror!void {}
- const StringS = struct {
- pub const src = "var headers = new Headers(); headers.set(\"hey\", \"hi\"); console.log(headers.get(\"hey\")); \"HELLO\";";
- };
-
- pub fn Threader(comptime Stdout: type, comptime Stderr: type) type {
- return struct {
- allocator: *std.mem.Allocator,
- stdout: Stdout,
- stderr: Stderr,
- args: Api.TransformOptions,
- pub fn spawn(this: @This()) !void {
- var stdout = std.io.getStdOut();
- // var stdout = std.io.bufferedWriter(stdout_file.writer());
- var stderr = std.io.getStdErr();
- // var stderr = std.io.bufferedWriter(stderr_file.writer());
- var output_source = Output.Source.init(stdout, stderr);
- // defer stdout.flush() catch {};
- // defer stderr.flush() catch {};
- Output.Source.set(&output_source);
-
- var log = logger.Log.init(this.allocator);
-
- var vm = try VirtualMachine.init(this.allocator, this.args, null, &log);
- var promise = try vm.loadEntryPoint(
- vm.bundler.options.entry_points[0],
- );
- if (promise.status(vm.global.vm()) == js.JSPromise.Status.Rejected) {
- vm.defaultErrorHandler(promise.result(vm.global.vm()));
- }
- }
- };
- }
-
- pub fn start(allocator: *std.mem.Allocator, stdout: anytype, stderr: anytype) anyerror!void {
- const start_time = std.time.nanoTimestamp();
- var log = logger.Log.init(allocator);
- var panicker = MainPanicHandler.init(&log);
- MainPanicHandler.Singleton = &panicker;
-
- var args = try Arguments.parse(default_allocator, stdout, stderr);
- // var serve_bundler = try bundler.ServeBundler.init(allocator, &log, args);
- // var res = try serve_bundler.buildFile(&log, allocator, args.entry_points[0], std.fs.path.extension(args.entry_points[0]));
-
- // var results = try bundler.Bundler.bundle(allocator, &log, args);
- // var file = results.output_files[0];
-
- // var resolved_entry_point = try vm.bundler.resolver.resolve(
- // vm.bundler.fs.top_level_dir,
- // vm.bundler.normalizeEntryPointPath(vm.bundler.options.entry_points[0]),
- // .entry_point,
- // );
- const Threadable = Threader(@TypeOf(stdout), @TypeOf(stderr));
- const runner = Threadable{ .allocator = allocator, .stdout = stdout, .stderr = stderr, .args = args };
- var thread = try std.Thread.spawn(.{}, Threadable.spawn, .{runner});
- thread.join();
- }
-};
-
-pub const JavaScript = struct {};
-
-pub const JavaScriptVirtualMachine = VirtualMachine;