aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build-id2
-rw-r--r--src/bundler.zig21
-rw-r--r--src/js_parser/js_parser.zig388
-rw-r--r--src/js_printer.zig48
-rw-r--r--src/linker.zig2
-rw-r--r--src/options.zig6
-rw-r--r--src/runtime/hmr.ts14
7 files changed, 334 insertions, 147 deletions
diff --git a/build-id b/build-id
index b6a7d89c6..98d9bcb75 100644
--- a/build-id
+++ b/build-id
@@ -1 +1 @@
-16
+17
diff --git a/src/bundler.zig b/src/bundler.zig
index 8486e64e9..d832c01fe 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -1902,12 +1902,21 @@ pub fn NewBundler(cache_files: bool) type {
try bundler.linker.link(file_path, &result, import_path_format, false);
return BuildResolveResultPair{
- .written = try bundler.print(
- result,
- Writer,
- writer,
- .esm,
- ),
+ .written = switch (result.ast.exports_kind) {
+ .esm => try bundler.print(
+ result,
+ Writer,
+ writer,
+ .esm,
+ ),
+ .cjs => try bundler.print(
+ result,
+ Writer,
+ writer,
+ .cjs,
+ ),
+ else => unreachable,
+ },
.input_fd = result.input_fd,
};
},
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 1fa9f3491..24ead5013 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -1957,7 +1957,7 @@ pub const Parser = struct {
var wrapper_expr: ?Expr = null;
- if (p.es6_export_keyword.len > 0 or p.top_level_await_keyword.len > 0) {
+ if ((p.es6_export_keyword.len > 0 or p.top_level_await_keyword.len > 0) and !uses_module_ref and !uses_exports_ref) {
exports_kind = .esm;
} else if (uses_exports_ref or uses_module_ref or p.has_top_level_return) {
exports_kind = .cjs;
@@ -2022,13 +2022,16 @@ pub const Parser = struct {
const automatic_namespace_ref = p.jsx_automatic.ref;
const decls_count: u32 =
- @intCast(u32, @boolToInt(jsx_symbol.use_count_estimate > 0)) * 2 + @intCast(u32, @boolToInt(jsx_static_symbol.use_count_estimate > 0)) * 2 +
+ @intCast(u32, @boolToInt(jsx_symbol.use_count_estimate > 0)) * 2 +
+ @intCast(u32, @boolToInt(jsx_static_symbol.use_count_estimate > 0)) * 2 +
@intCast(u32, @boolToInt(jsx_factory_symbol.use_count_estimate > 0)) +
@intCast(u32, @boolToInt(jsx_fragment_symbol.use_count_estimate > 0)) +
@intCast(u32, @boolToInt(jsx_filename_symbol.use_count_estimate > 0));
const imports_count =
- @intCast(u32, @boolToInt(std.math.max(jsx_symbol.use_count_estimate, jsx_static_symbol.use_count_estimate) > 0)) + @intCast(u32, std.math.max(jsx_factory_symbol.use_count_estimate, jsx_fragment_symbol.use_count_estimate)) + @intCast(u32, @boolToInt(p.options.features.react_fast_refresh));
+ @intCast(u32, @boolToInt(std.math.max(jsx_symbol.use_count_estimate, jsx_static_symbol.use_count_estimate) > 0)) +
+ @intCast(u32, std.math.max(jsx_factory_symbol.use_count_estimate, jsx_fragment_symbol.use_count_estimate)) +
+ @intCast(u32, @boolToInt(p.options.features.react_fast_refresh));
const stmts_count = imports_count + 1;
const symbols_count: u32 = imports_count + decls_count;
const loc = logger.Loc{ .start = 0 };
@@ -2048,19 +2051,6 @@ pub const Parser = struct {
var stmt_i: usize = 0;
if (jsx_symbol.use_count_estimate > 0 or jsx_static_symbol.use_count_estimate > 0) {
- if (jsx_automatic_symbol.use_count_estimate > 0) {
- if (jsx_automatic_symbol.link != null) {
- p.symbols.items[p.jsx_automatic.ref.inner_index].link = null;
- p.symbols.items[p.jsx_automatic.ref.inner_index].original_name = try std.fmt.allocPrint(
- p.allocator,
- "jsxImport{x}",
- .{
- @truncate(u16, std.hash.Wyhash.hash(0, p.options.jsx.import_source)),
- },
- );
- }
- }
-
declared_symbols[declared_symbols_i] = .{ .ref = automatic_namespace_ref, .is_top_level = true };
declared_symbols_i += 1;
@@ -3543,8 +3533,8 @@ pub fn NewParser(
try p.module_scope.generated.ensureUnusedCapacity(generated_symbols_count * 3);
try p.module_scope.members.ensureCapacity(generated_symbols_count * 3 + p.module_scope.members.count());
- p.exports_ref = try p.declareCommonJSSymbol(.unbound, "exports");
- p.module_ref = try p.declareCommonJSSymbol(.unbound, "module");
+ p.exports_ref = try p.declareCommonJSSymbol(.hoisted, "exports");
+ p.module_ref = try p.declareCommonJSSymbol(.hoisted, "module");
p.require_ref = try p.declareCommonJSSymbol(.unbound, "require");
if (FeatureFlags.auto_import_buffer) {
@@ -3575,8 +3565,6 @@ pub fn NewParser(
p.runtime_imports.__HMRClient = try p.declareGeneratedSymbol(.other, "__HMRClient");
p.recordUsage(p.hmr_module.ref);
p.recordUsage(p.runtime_imports.__HMRClient.?.ref);
- } else {
- p.runtime_imports.__export = GeneratedSymbol{ .ref = p.exports_ref, .primary = Ref.None, .backup = Ref.None };
}
if (is_jsx_enabled) {
@@ -12256,76 +12244,27 @@ pub fn NewParser(
name_loc: logger.Loc,
is_call_target: bool,
) ?Expr {
- if (@as(Expr.Tag, target.data) == .e_identifier) {
- const id = target.data.e_identifier;
-
- // Rewrite property accesses on explicit namespace imports as an identifier.
- // This lets us replace them easily in the printer to rebind them to
- // something else without paying the cost of a whole-tree traversal during
- // module linking just to rewrite these EDot expressions.
- // if (p.import_items_for_namespace.getPtr(id.ref)) |import_items| {
- // const item: LocRef = import_items.get(name) orelse brk: {
- // const _item = LocRef{ .loc = name_loc, .ref = p.newSymbol(.import, name) catch unreachable };
- // p.module_scope.generated.append(_item.ref orelse unreachable) catch unreachable;
-
- // import_items.put(name, _item) catch unreachable;
- // p.is_import_item.put(_item.ref orelse unreachable, true) catch unreachable;
-
- // var symbol: *js_ast.Symbol = &p.symbols.items[_item.ref.?.inner_index];
- // // Mark this as generated in case it's missing. We don't want to
- // // generate errors for missing import items that are automatically
- // // generated.
- // symbol.import_item_status = .generated;
-
- // // Make sure the printer prints this as a property access
- // symbol.namespace_alias = G.NamespaceAlias{ .namespace_ref = id.ref, .alias = name };
- // break :brk _item;
- // };
-
- // // Undo the usage count for the namespace itself. This is used later
- // // to detect whether the namespace symbol has ever been "captured"
- // // or whether it has just been used to read properties off of.
- // //
- // // The benefit of doing this is that if both this module and the
- // // imported module end up in the same module group and the namespace
- // // symbol has never been captured, then we don't need to generate
- // // any code for the namespace at all.
- // p.ignoreUsage(id.ref);
-
- // // Track how many times we've referenced this symbol
- // p.recordUsage(item.ref.?);
- // var ident_expr = p.e(
- // E.Identifier{
- // .ref = item.ref.?,
- // },
- // target.loc,
- // );
-
- // return p.handleIdentifier(name_loc, ident_expr.data.e_identifier, name, IdentifierOpts{
- // .assign_target = assign_target,
- // .is_delete_target = is_delete_target,
- // // If this expression is used as the target of a call expression, make
- // // sure the value of "this" is preserved.
- // .was_originally_identifier = false,
- // });
- // }
-
- if (is_call_target and id.ref.eql(p.module_ref) and strings.eqlComptime(name, "require")) {
- p.ignoreUsage(p.module_ref);
- p.recordUsage(p.require_ref);
- return p.e(E.Identifier{ .ref = p.require_ref }, name_loc);
- }
+ switch (target.data) {
+ .e_identifier => |id| {
+ // Rewrite "module.require()" to "require()" for Webpack compatibility.
+ // See https://github.com/webpack/webpack/pull/7750 for more info.
+ // This also makes correctness a little easier.
+ if (is_call_target and id.ref.eql(p.module_ref) and strings.eqlComptime(name, "require")) {
+ p.ignoreUsage(p.module_ref);
+ p.recordUsage(p.require_ref);
+ return p.e(E.Identifier{ .ref = p.require_ref }, name_loc);
+ }
- // If this is a known enum value, inline the value of the enum
- if (is_typescript_enabled) {
- if (p.known_enum_values.get(id.ref)) |enum_value_map| {
- if (enum_value_map.get(name)) |enum_value| {
- return p.e(E.Number{ .value = enum_value }, loc);
+ // If this is a known enum value, inline the value of the enum
+ if (is_typescript_enabled) {
+ if (p.known_enum_values.get(id.ref)) |enum_value_map| {
+ if (enum_value_map.get(name)) |enum_value| {
+ return p.e(E.Number{ .value = enum_value }, loc);
+ }
}
}
- }
-
- if (p.options.features.hot_module_reloading) {}
+ },
+ else => {},
}
return null;
@@ -14233,13 +14172,223 @@ pub fn NewParser(
}
if (commonjs_wrapper_expr) |commonjs_wrapper| {
+ var part = &parts[parts.len - 1];
+
var require_function_args = p.allocator.alloc(Arg, 2) catch unreachable;
+ var imports_count: u32 = 0;
+ // We have to also move export from, since we will preserve those
+ var exports_from_count: u32 = 0;
+
+ var additional_stmts_because_of_exports: u32 = 0;
+
+ // Two passes. First pass just counts.
+ for (parts[parts.len - 1].stmts) |stmt, i| {
+ imports_count += switch (stmt.data) {
+ .s_import => @as(u32, 1),
+ else => @as(u32, 0),
+ };
+
+ exports_from_count += switch (stmt.data) {
+ .s_export_star, .s_export_from => @as(u32, 1),
+ else => @as(u32, 0),
+ };
+ }
+
+ var new_stmts_list = p.allocator.alloc(Stmt, exports_from_count + imports_count + 1) catch unreachable;
+ var imports_list = new_stmts_list[0..imports_count];
+
+ var exports_list = if (exports_from_count > 0) new_stmts_list[imports_list.len + 1 ..] else &[_]Stmt{};
+
const name_ref = null;
require_function_args[0] = G.Arg{ .binding = p.b(B.Identifier{ .ref = p.module_ref }, logger.Loc.Empty) };
require_function_args[1] = G.Arg{ .binding = p.b(B.Identifier{ .ref = p.exports_ref }, logger.Loc.Empty) };
+ var exports_identifier: ExprNodeIndex = undefined;
+ var exports_identifier_set = false;
const default_name_loc_ref = LocRef{ .ref = name_ref, .loc = logger.Loc.Empty };
+ var imports_list_i: u32 = 0;
+ var exports_list_i: u32 = 0;
+
+ for (part.stmts) |_, i| {
+ switch (part.stmts[i].data) {
+ .s_import => {
+ imports_list[imports_list_i] = part.stmts[i];
+ part.stmts[i] = Stmt.empty();
+ part.stmts[i].loc = imports_list[imports_list_i].loc;
+ imports_list_i += 1;
+ },
+
+ // .s_export_default => |s_export| {
+ // if (!exports_identifier_set) {
+ // exports_identifier = p.e(E.Identifier{ .ref = p.exports_ref }, logger.Loc.Empty);
+ // exports_identifier_set = true;
+ // }
+
+ // switch (s_export.value) {
+ // .expr => |default_expr| {
+ // part.stmts[i] = Expr.assignStmt(p.e(
+ // E.Dot{ .name = "default", .name_loc = part.stmts[i].loc, .target = exports_identifier },
+ // part.stmts[i].loc,
+ // ), default_expr, p.allocator);
+ // },
+ // .stmt => |default_stmt| {
+ // switch (default_stmt.data) {
+ // .s_function => |func| {
+ // part.stmts[i] = Expr.assignStmt(p.e(
+ // E.Dot{ .name = "default", .name_loc = part.stmts[i].loc, .target = exports_identifier },
+ // part.stmts[i].loc,
+ // ), p.e(
+ // E.Function{ .func = func.func },
+ // default_stmt.loc,
+ // ), p.allocator);
+ // },
+ // .s_class => |class| {
+ // part.stmts[i] = Expr.assignStmt(
+ // p.e(
+ // E.Dot{ .name = "default", .name_loc = part.stmts[i].loc, .target = exports_identifier },
+ // part.stmts[i].loc,
+ // ),
+ // p.e(
+ // default_stmt.data.s_class.class,
+ // default_stmt.loc,
+ // ),
+ // p.allocator,
+ // );
+ // },
+ // else => unreachable,
+ // }
+ // },
+ // }
+ // },
+
+ // .s_function => |func| {
+ // if (!exports_identifier_set) {
+ // exports_identifier = p.e(E.Identifier{ .ref = p.exports_ref }, logger.Loc.Empty);
+ // exports_identifier_set = true;
+ // }
+
+ // part.stmts[i] = Expr.assignStmt(p.e(
+ // E.Dot{ .name = "default", .name_loc = part.stmts[i].loc, .target = exports_identifier },
+ // part.stmts[i].loc,
+ // ), default_expr, p.allocator);
+ // },
+ // .s_local => |local| {
+ // if (!exports_identifier_set) {
+ // exports_identifier = p.e(E.Identifier{ .ref = p.exports_ref }, logger.Loc.Empty);
+ // exports_identifier_set = true;
+ // }
+
+ // const items = local.decls;
+
+ // for (items[1..]) |item| {
+ // assignment = Expr.joinWithComma(assignment, Expr.assign(
+ // p.e(E.Dot{
+ // .name = item.alias,
+ // .target = exports_identifier,
+ // .name_loc = item.alias_loc,
+ // }, item.alias_loc),
+ // p.e(
+ // E.Identifier{
+ // .ref = item.name.ref.?,
+ // },
+ // item.name.loc,
+ // ),
+ // p.allocator,
+ // ), p.allocator);
+ // }
+
+ // const original_loc = part.stmts[i].loc;
+ // part.stmts[i] = p.s(S.SExpr{
+ // .value = assignment,
+ // }, original_loc);
+
+ // },
+ // .s_class => |class| {
+ // if (!exports_identifier_set) {
+ // exports_identifier = p.e(E.Identifier{ .ref = p.exports_ref }, logger.Loc.Empty);
+ // exports_identifier_set = true;
+ // }
+
+ // part.stmts[i] = Expr.assignStmt(
+ // },
+
+ // .s_export_clause => |s_export| {
+ // const items = s_export.items;
+ // switch (items.len) {
+ // 0 => {
+ // part.stmts[i] = Stmt.empty();
+ // },
+ // 1 => {
+ // if (!exports_identifier_set) {
+ // exports_identifier = p.e(E.Identifier{ .ref = p.exports_ref }, logger.Loc.Empty);
+ // exports_identifier_set = true;
+ // }
+
+ // part.stmts[i] = Expr.assignStmt(p.e(
+ // E.Dot{
+ // .name = items[0].alias,
+ // .target = exports_identifier,
+ // .name_loc = items[0].alias_loc,
+ // },
+ // items[0].alias_loc,
+ // ), p.e(
+ // E.Identifier{
+ // .ref = items[0].name.ref.?,
+ // },
+ // items[0].name.loc,
+ // ), p.allocator);
+ // },
+ // else => {
+ // if (!exports_identifier_set) {
+ // exports_identifier = p.e(E.Identifier{ .ref = p.exports_ref }, logger.Loc.Empty);
+ // exports_identifier_set = true;
+ // }
+ // var assignment = Expr.assign(p.e(
+ // E.Dot{
+ // .name = items[0].alias,
+ // .target = exports_identifier,
+ // .name_loc = items[0].alias_loc,
+ // },
+ // items[0].alias_loc,
+ // ), p.e(E.Identifier{
+ // .ref = items[0].name.ref.?,
+ // }, items[0].name.loc), p.allocator);
+
+ // for (items[1..]) |item| {
+ // assignment = Expr.joinWithComma(assignment, Expr.assign(
+ // p.e(E.Dot{
+ // .name = item.alias,
+ // .target = exports_identifier,
+ // .name_loc = item.alias_loc,
+ // }, item.alias_loc),
+ // p.e(
+ // E.Identifier{
+ // .ref = item.name.ref.?,
+ // },
+ // item.name.loc,
+ // ),
+ // p.allocator,
+ // ), p.allocator);
+ // }
+
+ // const original_loc = part.stmts[i].loc;
+ // part.stmts[i] = p.s(S.SExpr{
+ // .value = assignment,
+ // }, original_loc);
+ // },
+ // }
+ // },
+ .s_export_star, .s_export_from => {
+ exports_list[exports_list_i] = part.stmts[i];
+ part.stmts[i] = Stmt.empty();
+ part.stmts[i].loc = exports_list[exports_list_i].loc;
+ exports_list_i += 1;
+ },
+ else => {},
+ }
+ }
+
commonjs_wrapper.data.e_call.args[0] = p.e(
E.Function{ .func = G.Fn{
.name = null,
@@ -14260,8 +14409,8 @@ pub fn NewParser(
}
}
commonjs_wrapper.data.e_call.args[1] = p.e(E.String{ .utf8 = sourcefile_name }, logger.Loc.Empty);
- parts[parts.len - 1].stmts = p.allocator.alloc(Stmt, 1) catch unreachable;
- parts[parts.len - 1].stmts[0] = p.s(
+
+ new_stmts_list[imports_list.len] = p.s(
S.ExportDefault{
.value = .{
.expr = commonjs_wrapper,
@@ -14270,6 +14419,7 @@ pub fn NewParser(
},
logger.Loc.Empty,
);
+ part.stmts = new_stmts_list;
} else if (p.options.features.hot_module_reloading) {
var named_exports_count: usize = p.named_exports.count();
const named_imports: js_ast.Ast.NamedImports = p.named_imports;
@@ -14611,21 +14761,23 @@ pub fn NewParser(
toplevel_stmts_i += 1;
- if (named_export_i > 0) {
- toplevel_stmts[toplevel_stmts_i] = p.s(
- S.Local{
- .decls = exports_decls[0..named_export_i],
- },
- logger.Loc.Empty,
- );
- } else {
- toplevel_stmts[toplevel_stmts_i] = p.s(
- S.Empty{},
- logger.Loc.Empty,
- );
- }
+ if (has_any_exports) {
+ if (named_export_i > 0) {
+ toplevel_stmts[toplevel_stmts_i] = p.s(
+ S.Local{
+ .decls = exports_decls[0..named_export_i],
+ },
+ logger.Loc.Empty,
+ );
+ } else {
+ toplevel_stmts[toplevel_stmts_i] = p.s(
+ S.Empty{},
+ logger.Loc.Empty,
+ );
+ }
- toplevel_stmts_i += 1;
+ toplevel_stmts_i += 1;
+ }
toplevel_stmts[toplevel_stmts_i] = p.s(
S.SExpr{
@@ -14641,7 +14793,7 @@ pub fn NewParser(
p.e(
E.Function{
.func = .{
- .body = .{ .loc = logger.Loc.Empty, .stmts = update_function_stmts[0..named_export_i] },
+ .body = .{ .loc = logger.Loc.Empty, .stmts = if (named_export_i > 0) update_function_stmts[0..named_export_i] else &.{} },
.name = null,
.args = update_function_args,
.open_parens_loc = logger.Loc.Empty,
@@ -14655,22 +14807,22 @@ pub fn NewParser(
logger.Loc.Empty,
);
toplevel_stmts_i += 1;
- if (named_export_i > 0) {
- toplevel_stmts[toplevel_stmts_i] = p.s(
- S.ExportClause{
- .items = export_clauses[0..named_export_i],
- },
- logger.Loc.Empty,
- );
- } else {
- toplevel_stmts[toplevel_stmts_i] = p.s(
- S.Empty{},
- logger.Loc.Empty,
- );
+ if (has_any_exports) {
+ if (named_export_i > 0) {
+ toplevel_stmts[toplevel_stmts_i] = p.s(
+ S.ExportClause{
+ .items = export_clauses[0..named_export_i],
+ },
+ logger.Loc.Empty,
+ );
+ } else {
+ toplevel_stmts[toplevel_stmts_i] = p.s(
+ S.Empty{},
+ logger.Loc.Empty,
+ );
+ }
}
- toplevel_stmts_i += 1;
-
part.stmts = _stmts[0 .. imports_list.len + toplevel_stmts.len + exports_from.len];
}
diff --git a/src/js_printer.zig b/src/js_printer.zig
index 706b52503..12c92f9fc 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -213,6 +213,7 @@ pub fn NewPrinter(
comptime Linker: type,
comptime rewrite_esm_to_cjs: bool,
comptime bun: bool,
+ comptime is_inside_bundle: bool,
) type {
return struct {
symbols: Symbol.Map,
@@ -2315,7 +2316,7 @@ pub fn NewPrinter(
p.printIndent();
p.printSpaceBeforeIdentifier();
- if (!rewrite_esm_to_cjs) {
+ if (!is_inside_bundle) {
p.print("export default");
}
@@ -2323,7 +2324,7 @@ pub fn NewPrinter(
switch (s.value) {
.expr => |expr| {
- if (rewrite_esm_to_cjs) {
+ if (is_inside_bundle) {
p.printModuleExportSymbol();
p.print(".default = ");
}
@@ -2339,7 +2340,7 @@ pub fn NewPrinter(
switch (s2.data) {
.s_function => |func| {
p.printSpaceBeforeIdentifier();
- if (rewrite_esm_to_cjs) {
+ if (is_inside_bundle) {
if (func.func.name) |name| {
// p.print("var ");
// p.printSymbol(name.ref.?);
@@ -2368,15 +2369,13 @@ pub fn NewPrinter(
p.printFunc(func.func);
- if (rewrite_esm_to_cjs) {
+ if (is_inside_bundle) {
p.printSemicolonAfterStatement();
- if (rewrite_esm_to_cjs) {
- if (func.func.name) |name| {
- p.printIndent();
- p.printBundledExport("default", p.renamer.nameForSymbol(name.ref.?));
- p.printSemicolonAfterStatement();
- }
+ if (func.func.name) |name| {
+ p.printIndent();
+ p.printBundledExport("default", p.renamer.nameForSymbol(name.ref.?));
+ p.printSemicolonAfterStatement();
}
} else {
p.printNewline();
@@ -2385,7 +2384,7 @@ pub fn NewPrinter(
.s_class => |class| {
p.printSpaceBeforeIdentifier();
- if (rewrite_esm_to_cjs) {
+ if (is_inside_bundle) {
if (class.class.class_name) |name| {
// p.print("var ");
// p.printSymbol(name.ref.?);
@@ -2405,7 +2404,7 @@ pub fn NewPrinter(
p.printClass(class.class);
- if (rewrite_esm_to_cjs) {
+ if (is_inside_bundle) {
p.printSemicolonAfterStatement();
if (class.class.class_name) |name| {
@@ -2425,7 +2424,7 @@ pub fn NewPrinter(
}
},
.s_export_star => |s| {
- if (rewrite_esm_to_cjs) {
+ if (is_inside_bundle) {
p.printIndent();
p.printSpaceBeforeIdentifier();
@@ -2566,7 +2565,7 @@ pub fn NewPrinter(
p.printSemicolonAfterStatement();
},
.s_export_from => |s| {
- if (rewrite_esm_to_cjs) {
+ if (is_inside_bundle) {
const record = p.import_records[s.import_record_index];
// $$lz(export, $React(), {default: "React"});
@@ -2935,7 +2934,7 @@ pub fn NewPrinter(
p.printIndent();
p.printSpaceBeforeIdentifier();
- if (rewrite_esm_to_cjs) {
+ if (is_inside_bundle) {
return p.printBundledImport(record, s, stmt);
}
@@ -3646,7 +3645,7 @@ pub fn NewPrinter(
}
pub fn printDeclStmt(p: *Printer, is_export: bool, comptime keyword: string, decls: []G.Decl) void {
- if (rewrite_esm_to_cjs and keyword[0] == 'v' and is_export) {
+ if (rewrite_esm_to_cjs and keyword[0] == 'v' and is_export and is_inside_bundle) {
// this is a top-level export
if (decls.len == 1 and
std.meta.activeTag(decls[0].binding.data) == .b_identifier and
@@ -3680,9 +3679,16 @@ pub fn NewPrinter(
for (decls) |decl, i| {
p.print("'");
p.printBinding(decl.binding);
- p.print("': {get: () => (");
+ p.print("': {get: () => ");
p.printBinding(decl.binding);
- p.print("), enumerable: true, configurable: true}");
+
+ if (comptime !strings.eqlComptime(keyword, "const")) {
+ p.print(", set: ($_newValue) => {");
+ p.printBinding(decl.binding);
+ p.print(" = $_newValue;}");
+ }
+
+ p.print(", enumerable: true, configurable: true}");
if (i < decls.len - 1) {
p.print(",\n");
@@ -4040,7 +4046,7 @@ pub fn printAst(
comptime LinkerType: type,
linker: ?*LinkerType,
) !usize {
- const PrinterType = NewPrinter(false, Writer, LinkerType, false, false);
+ const PrinterType = NewPrinter(false, Writer, LinkerType, false, false, false);
var writer = _writer;
var printer = try PrinterType.init(
@@ -4086,7 +4092,7 @@ pub fn printCommonJS(
comptime LinkerType: type,
linker: ?*LinkerType,
) !usize {
- const PrinterType = NewPrinter(false, Writer, LinkerType, true, false);
+ const PrinterType = NewPrinter(false, Writer, LinkerType, true, false, false);
var writer = _writer;
var printer = try PrinterType.init(
writer,
@@ -4144,7 +4150,7 @@ pub fn printCommonJSThreaded(
comptime getPos: fn (ctx: GetPosType) anyerror!u64,
end_off_ptr: *u32,
) !WriteResult {
- const PrinterType = NewPrinter(false, Writer, LinkerType, true, false);
+ const PrinterType = NewPrinter(false, Writer, LinkerType, true, false, true);
var writer = _writer;
var printer = try PrinterType.init(
writer,
diff --git a/src/linker.zig b/src/linker.zig
index efcde5a24..182fe3b3c 100644
--- a/src/linker.zig
+++ b/src/linker.zig
@@ -365,6 +365,8 @@ pub fn NewLinker(comptime BundlerType: type) type {
result.ast.needs_runtime = true;
needs_require = true;
+ } else if (result.ast.exports_kind == .cjs) {
+ import_record.module_id = @truncate(u32, std.hash.Wyhash.hash(0, path.pretty));
}
} else |err| {
had_resolve_errors = true;
diff --git a/src/options.zig b/src/options.zig
index ab248da1d..02d44fa08 100644
--- a/src/options.zig
+++ b/src/options.zig
@@ -1181,7 +1181,11 @@ pub const BundleOptions = struct {
if (isWindows and opts.routes.static_dir_handle != null) {
opts.routes.static_dir_handle.?.close();
}
- opts.hot_module_reloading = opts.platform.isWebLike() and !(transform.disable_hmr orelse false);
+ opts.hot_module_reloading = opts.platform.isWebLike();
+
+ if (transform.disable_hmr orelse false)
+ opts.hot_module_reloading = false;
+
opts.serve = true;
}
diff --git a/src/runtime/hmr.ts b/src/runtime/hmr.ts
index 213192c4f..4a8ccca43 100644
--- a/src/runtime/hmr.ts
+++ b/src/runtime/hmr.ts
@@ -66,6 +66,11 @@ if (typeof window !== "undefined") {
cancel: false,
lastError: null,
render(error, cwd) {
+ if ("__BunRenderBuildError" in globalThis) {
+ globalThis.__BunRenderBuildError(error, cwd);
+ return;
+ }
+
BunError.lastError = [error, cwd];
BunError.cancel = false;
@@ -1076,6 +1081,15 @@ if (typeof window !== "undefined") {
URL.revokeObjectURL(blobURL);
// Ensure we don't keep the bytes around longer than necessary
this.bytes = null;
+
+ if ("__BunRenderHMRError" in globalThis) {
+ globalThis.__BunRenderHMRError(
+ exception,
+ oldModule.file_path,
+ oldModule.id
+ );
+ }
+
oldModule = null;
throw exception;
}