aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-06-29 17:47:58 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-06-29 17:47:58 -0700
commit3f197d1ce0c197864ad4c7c7b8238af4370275b4 (patch)
tree7d76dcc182e80c5b67db1568e769977229649980
parent26745bb5f300481fc242c8e81de6f252f698c863 (diff)
downloadbun-3f197d1ce0c197864ad4c7c7b8238af4370275b4.tar.gz
bun-3f197d1ce0c197864ad4c7c7b8238af4370275b4.tar.zst
bun-3f197d1ce0c197864ad4c7c7b8238af4370275b4.zip
Fix crash, fix detecting node_modules, fix undefined not being simplified
-rw-r--r--demos/css-stress-test/react-inject.js1
-rw-r--r--demos/css-stress-test/src/index.tsx27
-rw-r--r--demos/css-stress-test/src/main.tsx2
-rw-r--r--src/bundler.zig10
-rw-r--r--src/defines.zig38
-rw-r--r--src/javascript/jsc/javascript.zig192
-rw-r--r--src/js_parser/js_parser.zig18
-rw-r--r--src/linker.zig18
-rw-r--r--src/options.zig10
9 files changed, 199 insertions, 117 deletions
diff --git a/demos/css-stress-test/react-inject.js b/demos/css-stress-test/react-inject.js
new file mode 100644
index 000000000..199dbaa80
--- /dev/null
+++ b/demos/css-stress-test/react-inject.js
@@ -0,0 +1 @@
+export { default as React } from "react";
diff --git a/demos/css-stress-test/src/index.tsx b/demos/css-stress-test/src/index.tsx
index 3db53a67f..267691467 100644
--- a/demos/css-stress-test/src/index.tsx
+++ b/demos/css-stress-test/src/index.tsx
@@ -1,20 +1,33 @@
-import ReactDOM from "react-dom";
-import React from "react";
+import ReactDOMServer from "react-dom/server.browser";
+
import { Main } from "./main";
import classNames from "classnames";
-
const Base = ({}) => {
- const name = decodeURIComponent(location.search.substring(1));
+ const name =
+ typeof location !== "undefined"
+ ? decodeURIComponent(location.search.substring(1))
+ : null;
return <Main productName={name || "Bundler"} />;
};
function startReact() {
+ const ReactDOM = require("react-dom");
ReactDOM.render(<Base />, document.querySelector("#reactroot"));
}
-globalThis.addEventListener("DOMContentLoaded", () => {
+function ssr() {
+ console.log(ReactDOMServer.renderToString(<Base />));
+}
+
+if (typeof window !== "undefined") {
+ console.log("HERE!!");
+ globalThis.addEventListener("DOMContentLoaded", () => {
+ startReact();
+ });
+
startReact();
-});
-startReact();
+} else {
+ ssr();
+}
export { Base };
diff --git a/demos/css-stress-test/src/main.tsx b/demos/css-stress-test/src/main.tsx
index 1a9948fe8..c95d0f0eb 100644
--- a/demos/css-stress-test/src/main.tsx
+++ b/demos/css-stress-test/src/main.tsx
@@ -1,5 +1,3 @@
-import React from "react";
-
export const Main = ({ productName }) => {
return (
<>
diff --git a/src/bundler.zig b/src/bundler.zig
index 1d227c178..802b7cd82 100644
--- a/src/bundler.zig
+++ b/src/bundler.zig
@@ -491,7 +491,7 @@ pub fn NewBundler(cache_files: bool) type {
var resolve = _resolve;
if (resolve.is_external) return;
- resolve.is_from_node_modules = strings.contains(resolve.path_pair.primary.text, node_module_root_string);
+ const is_from_node_modules = resolve.isLikelyNodeModule();
const loader = this.bundler.options.loaders.get(resolve.path_pair.primary.name.ext) orelse .file;
var bundler = this.bundler;
defer this.scan_pass_result.reset();
@@ -500,7 +500,7 @@ pub fn NewBundler(cache_files: bool) type {
var hasher = std.hash.Wyhash.init(0);
// If we're in a node_module, build that almost normally
- if (resolve.is_from_node_modules) {
+ if (is_from_node_modules) {
switch (loader) {
.jsx,
.tsx,
@@ -971,8 +971,6 @@ pub fn NewBundler(cache_files: bool) type {
),
.input_fd = result.input_fd,
};
- // output_file.version = if (resolve_result.is_from_node_modules) resolve_result.package_json_version else null;
-
},
}
}
@@ -1158,7 +1156,7 @@ pub fn NewBundler(cache_files: bool) type {
var result = ScanResult{
.path = file_path,
.file_size = @truncate(u32, source.contents.len),
- .is_node_module = resolve_result.is_from_node_modules or strings.contains(file_path.text, "node_modules" ++ std.fs.path.sep_str),
+ .is_node_module = resolve_result.isLikelyNodeModule(),
.import_record_start = @truncate(u32, import_records.items.len),
.import_record_length = 0,
};
@@ -1290,7 +1288,7 @@ pub fn NewBundler(cache_files: bool) type {
jsx.parse = loader.isJSX();
var opts = js_parser.Parser.Options.init(jsx, loader);
opts.enable_bundling = false;
- opts.transform_require_to_import = false;
+ opts.transform_require_to_import = !bundler.options.platform.implementsRequire();
opts.force_commonjs = bundler.options.platform == .speedy;
opts.can_import_from_bundle = bundler.options.node_modules_bundle != null;
opts.features.hot_module_reloading = bundler.options.hot_module_reloading and bundler.options.platform != .speedy;
diff --git a/src/defines.zig b/src/defines.zig
index 58764c241..88665aa06 100644
--- a/src/defines.zig
+++ b/src/defines.zig
@@ -78,17 +78,33 @@ pub const DefineData = struct {
}
if (js_lexer.isIdentifier(entry.value_ptr.*) and !js_lexer.Keywords.has(entry.value_ptr.*)) {
- var ident: *js_ast.E.Identifier = try allocator.create(js_ast.E.Identifier);
- ident.ref = Ref.None;
- ident.can_be_removed_if_unused = true;
- user_defines.putAssumeCapacity(
- entry.key_ptr.*,
- DefineData{
- .value = js_ast.Expr.Data{ .e_identifier = ident },
- .original_name = entry.value_ptr.*,
- .can_be_removed_if_unused = true,
- },
- );
+
+ // Special-case undefined. it's not an identifier here
+ // https://github.com/evanw/esbuild/issues/1407
+ if (strings.eqlComptime(entry.value_ptr.*, "undefined")) {
+ user_defines.putAssumeCapacity(
+ entry.key_ptr.*,
+ DefineData{
+ .value = js_ast.Expr.Data{ .e_undefined = js_ast.E.Undefined{} },
+ .original_name = entry.value_ptr.*,
+ .can_be_removed_if_unused = true,
+ },
+ );
+ } else {
+ var ident: *js_ast.E.Identifier = try allocator.create(js_ast.E.Identifier);
+ ident.ref = Ref.None;
+ ident.can_be_removed_if_unused = true;
+
+ user_defines.putAssumeCapacity(
+ entry.key_ptr.*,
+ DefineData{
+ .value = js_ast.Expr.Data{ .e_identifier = ident },
+ .original_name = entry.value_ptr.*,
+ .can_be_removed_if_unused = true,
+ },
+ );
+ }
+
// user_defines.putAssumeCapacity(
// entry.key_ptr,
// DefineData{ .value = js_ast.Expr.Data{.e_identifier = } },
diff --git a/src/javascript/jsc/javascript.zig b/src/javascript/jsc/javascript.zig
index 7ff4070e5..338e05490 100644
--- a/src/javascript/jsc/javascript.zig
+++ b/src/javascript/jsc/javascript.zig
@@ -43,6 +43,15 @@ pub fn JSStringMap(comptime V: type) type {
return std.HashMap(js.JSStringRef, V, JSStringMapContext, 60);
}
+const DefaultSpeedyDefines = struct {
+ pub const Keys = struct {
+ const window = "window";
+ };
+ pub const Values = struct {
+ const window = "undefined";
+ };
+};
+
pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args: Api.TransformOptions) !Api.TransformOptions {
var args = _args;
@@ -63,6 +72,7 @@ pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args:
}
}
var needs_node_env = env_map.get("NODE_ENV") == null;
+ var needs_window_undefined = true;
var needs_regenerate = args.define == null and env_count > 0;
if (args.define) |def| {
@@ -72,12 +82,16 @@ pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args:
for (def.keys) |key| {
if (strings.eql(key, "process.env.NODE_ENV")) {
needs_node_env = false;
+ } else if (strings.eql(key, "window")) {
+ needs_window_undefined = false;
}
}
}
+ var extras_count = @intCast(usize, @boolToInt(needs_node_env)) + @intCast(usize, @boolToInt(needs_window_undefined));
+
if (needs_regenerate) {
- var new_list = try allocator.alloc([]const u8, env_count * 2 + @intCast(usize, @boolToInt(needs_node_env)) * 2);
+ var new_list = try allocator.alloc([]const u8, env_count * 2 + extras_count * 2);
var keys = new_list[0 .. new_list.len / 2];
var values = new_list[keys.len..];
var new_map = Api.StringMap{
@@ -119,7 +133,16 @@ pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args:
if (needs_node_env) {
keys[last] = options.DefaultUserDefines.NodeEnv.Key;
values[last] = options.DefaultUserDefines.NodeEnv.Value;
+ last += 1;
}
+
+ if (needs_window_undefined) {
+ keys[last] = DefaultSpeedyDefines.Keys.window;
+ values[last] = DefaultSpeedyDefines.Values.window;
+ last += 1;
+ }
+
+ args.define = new_map;
}
return args;
@@ -130,7 +153,7 @@ pub fn configureTransformOptionsForSpeedy(allocator: *std.mem.Allocator, _args:
// Its unavailable on Linux
pub const VirtualMachine = struct {
const RequireCacheType = std.AutoHashMap(u32, *Module);
- root: js.JSGlobalContextRef,
+ // root: js.JSGlobalContextRef,
ctx: js.JSGlobalContextRef = undefined,
group: js.JSContextGroupRef,
allocator: *std.mem.Allocator,
@@ -151,8 +174,6 @@ pub const VirtualMachine = struct {
) !*VirtualMachine {
var group = js.JSContextGroupRetain(js.JSContextGroupCreate());
- var ctx = js.JSGlobalContextRetain(js.JSGlobalContextCreateInGroup(group, null));
-
var log: *logger.Log = undefined;
if (_log) |__log| {
log = __log;
@@ -170,10 +191,10 @@ pub const VirtualMachine = struct {
try configureTransformOptionsForSpeedy(allocator, _args),
existing_bundle,
),
- .node_module_list = try allocator.create(Module.NodeModuleList),
+ .node_module_list = null,
.log = log,
.group = group,
- .root = ctx,
+
.require_cache = RequireCacheType.init(allocator),
.global = global,
};
@@ -189,7 +210,9 @@ pub const VirtualMachine = struct {
Properties.init();
if (vm.bundler.options.node_modules_bundle) |bundle| {
vm.node_modules = bundle;
+ vm.node_module_list = try allocator.create(Module.NodeModuleList);
try Module.NodeModuleList.create(vm, bundle, vm.node_module_list.?);
+ vm.global.ctx = vm.node_module_list.?.bundle_ctx;
}
return vm;
@@ -425,6 +448,7 @@ pub const Module = struct {
require_cache: []?*Module,
exports_function_call: js.JSObjectRef = null,
+ console: js.JSObjectRef = null,
const RequireBundleClassName = "requireFromBundle";
var require_bundle_class_def: js.JSClassDefinition = undefined;
@@ -650,6 +674,24 @@ pub const Module = struct {
return module.internalGetExports(js.JSContextGetGlobalContext(ctx));
}
+ pub fn getConsole(
+ ctx: js.JSContextRef,
+ thisObject: js.JSObjectRef,
+ prop: js.JSStringRef,
+ exception: js.ExceptionRef,
+ ) callconv(.C) js.JSValueRef {
+ var this = @ptrCast(
+ *NodeModuleList,
+ @alignCast(@alignOf(*NodeModuleList), js.JSObjectGetPrivate(thisObject) orelse return null),
+ );
+
+ if (this.console == null) {
+ this.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), this.vm.global.console_class, this.vm.global);
+ }
+
+ return this.console;
+ }
+
pub fn create(vm: *VirtualMachine, bundle: *const NodeModuleBundle, node_module_list: *NodeModuleList) !void {
var size: usize = 0;
var longest_size: usize = 0;
@@ -664,7 +706,13 @@ pub const Module = struct {
size += this_size;
longest_size = std.math.max(this_size, longest_size);
}
- var static_properties = try vm.allocator.alloc(js.JSStaticValue, bundle.bundle.modules.len + 1);
+ var static_properties = try vm.allocator.alloc(js.JSStaticValue, bundle.bundle.modules.len + 2);
+ static_properties[static_properties.len - 2] = js.JSStaticValue{
+ .name = Properties.UTF8.console[0.. :0],
+ .getProperty = getConsole,
+ .setProperty = null,
+ .attributes = .kJSPropertyAttributeNone,
+ };
static_properties[static_properties.len - 1] = std.mem.zeroes(js.JSStaticValue);
var utf8 = try vm.allocator.alloc(u8, size + std.math.max(longest_size, 32));
std.mem.set(u8, utf8, 0);
@@ -780,20 +828,20 @@ pub const Module = struct {
const len = js.JSStringGetLength(arguments[0]);
- // if (!require_buf_loaded) {
- // require_buf = MutableString.init(this.vm.allocator, len + 1) catch unreachable;
- // require_buf_loaded = true;
- // } else {
- // require_buf.reset();
- // require_buf.growIfNeeded(len + 1) catch {};
- // }
+ if (!require_buf_loaded) {
+ require_buf = MutableString.init(this.vm.allocator, len + 1) catch unreachable;
+ require_buf_loaded = true;
+ } else {
+ require_buf.reset();
+ require_buf.growIfNeeded(len + 1) catch {};
+ }
- // require_buf.list.resize(this.vm.allocator, len + 1) catch unreachable;
+ require_buf.list.resize(this.vm.allocator, len + 1) catch unreachable;
- var require_buf_ = this.vm.allocator.alloc(u8, len + 1) catch unreachable;
- var end = js.JSStringGetUTF8CString(arguments[0], require_buf_.ptr, require_buf_.len);
- // var end = js.JSStringGetUTF8CString(arguments[0], require_buf.list.items.ptr, require_buf.list.items.len);
- var import_path = require_buf_[0 .. end - 1];
+ // var require_buf_ = this.vm.allocator.alloc(u8, len + 1) catch unreachable;
+ // var end = js.JSStringGetUTF8CString(arguments[0], require_buf_.ptr, require_buf_.len);
+ var end = js.JSStringGetUTF8CString(arguments[0], require_buf.list.items.ptr, require_buf.list.items.len);
+ var import_path = require_buf.list.items[0 .. end - 1];
var module = this;
if (this.vm.bundler.linker.resolver.resolve(module.path.name.dirWithTrailingSlash(), import_path, .require)) |resolved| {
@@ -803,13 +851,13 @@ pub const Module = struct {
switch (load_result) {
.Module => |new_module| {
- if (isDebug) {
- Output.prettyln(
- "Input: {s}\nOutput: {s}",
- .{ import_path, load_result.Module.path.text },
- );
- Output.flush();
- }
+ // if (isDebug) {
+ // Output.prettyln(
+ // "Input: {s}\nOutput: {s}",
+ // .{ import_path, load_result.Module.path.text },
+ // );
+ // Output.flush();
+ // }
return new_module.internalGetExports(js.JSContextGetGlobalContext(ctx));
},
.Path => |path| {
@@ -862,7 +910,7 @@ pub const Module = struct {
exports_class_ref = js.JSClassRetain(js.JSClassCreate(&ExportsClass));
- module_class_def = ModuleClass.define(vm.root);
+ module_class_def = ModuleClass.define();
module_class = js.JSClassRetain(js.JSClassCreate(&module_class_def));
}
@@ -913,19 +961,18 @@ pub const Module = struct {
.vm = vm,
};
module.ref = js.JSObjectMake(global_ctx, Module.module_class, module);
-
js.JSValueProtect(global_ctx, module.ref);
-
- if (!module_wrapper_loaded) {
- module_wrapper_params[0] = js.JSStringCreateWithUTF8CString(Properties.UTF8.module[0.. :0]);
- module_wrapper_params[1] = js.JSStringCreateWithUTF8CString(Properties.UTF8.exports[0.. :0]);
- module_wrapper_loaded = true;
- }
+ // if (!module_wrapper_loaded) {
+ module_wrapper_params[0] = js.JSStringRetain(js.JSStringCreateWithUTF8CString(Properties.UTF8.module[0.. :0]));
+ module_wrapper_params[1] = js.JSStringRetain(js.JSStringCreateWithUTF8CString(Properties.UTF8.exports[0.. :0]));
+ // module_wrapper_loaded = true;
+ // }
var module_wrapper_args: [2]js.JSValueRef = undefined;
module_wrapper_args[0] = module.ref;
module_wrapper_args[1] = module.internalGetExports(global_ctx);
js.JSValueProtect(global_ctx, module_wrapper_args[1]);
+
var except: js.JSValueRef = null;
go: {
var commonjs_wrapper = js.JSObjectMakeFunction(
@@ -942,13 +989,14 @@ pub const Module = struct {
if (except != null) {
break :go;
}
+
// var module = {exports: {}}; ((module, exports) => {
_ = js.JSObjectCallAsFunction(call_ctx, commonjs_wrapper, null, 2, &module_wrapper_args, &except);
// module.exports = exports;
// })(module, module.exports);
// module.exports = module_wrapper_args[1];
- js.JSValueProtect(global_ctx, module.exports);
+
js.JSValueUnprotect(global_ctx, commonjs_wrapper);
}
if (except != null) {
@@ -1000,17 +1048,17 @@ pub const Module = struct {
.tsx,
.json,
=> {
- const package_json_ = resolved.package_json orelse brk: {
- // package_json is sometimes null when we're loading as an absolute path
- if (resolved.isLikelyNodeModule()) {
- break :brk vm.bundler.resolver.packageJSONForResolvedNodeModule(&resolved);
- }
- break :brk null;
- };
+ if (vm.node_modules) |node_modules| {
+ const package_json_ = resolved.package_json orelse brk: {
+ // package_json is sometimes null when we're loading as an absolute path
+ if (resolved.isLikelyNodeModule()) {
+ break :brk vm.bundler.resolver.packageJSONForResolvedNodeModule(&resolved);
+ }
+ break :brk null;
+ };
- if (package_json_) |package_json| {
- if (package_json.hash > 0) {
- if (vm.node_modules) |node_modules| {
+ if (package_json_) |package_json| {
+ if (package_json.hash > 0) {
if (node_modules.getPackageIDByName(package_json.name)) |possible_package_ids| {
const package_id: ?u32 = brk: {
for (possible_package_ids) |pid| {
@@ -1105,7 +1153,7 @@ pub const Module = struct {
vm.log,
source_code_printer.ctx.sentinel,
path,
- vm.global.ctx,
+ js.JSContextGetGlobalContext(ctx),
ctx,
ctx,
exception,
@@ -1287,7 +1335,6 @@ pub const GlobalObject = struct {
console_definition: js.JSClassDefinition = undefined,
global_class_def: js.JSClassDefinition = undefined,
global_class: js.JSClassRef = undefined,
- root_obj: js.JSObjectRef = undefined,
pub const ConsoleClass = NewClass(
GlobalObject,
@@ -1324,42 +1371,28 @@ pub const GlobalObject = struct {
obj: js.JSObjectRef,
exception: js.ExceptionRef,
) js.JSValueRef {
- return global.console;
- }
+ // if (global.console == null) {
+ // global.console = js.JSObjectMake(js.JSContextGetGlobalContext(ctx), global.console_class, global);
+ // js.JSValueProtect(js.JSContextGetGlobalContext(ctx), global.console);
+ // }
- pub fn onMissingProperty(
- global: *GlobalObject,
- ctx: js.JSContextRef,
- obj: js.JSObjectRef,
- prop: js.JSStringRef,
- exception: js.ExceptionRef,
- ) js.JSValueRef {
- if (js.JSObjectHasProperty(ctx, global.root_obj, prop)) {
- return js.JSObjectGetProperty(ctx, global.root_obj, prop, exception);
- } else {
- return js.JSValueMakeUndefined(ctx);
- }
+ return js.JSObjectMake(js.JSContextGetGlobalContext(ctx), global.console_class, global);
}
pub fn boot(global: *GlobalObject) !void {
- var private: ?*c_void = global;
- global.root_obj = js.JSContextGetGlobalObject(global.vm.root);
-
- global.console_definition = ConsoleClass.define(global.vm.root);
+ global.console_definition = ConsoleClass.define();
global.console_class = js.JSClassRetain(js.JSClassCreate(&global.console_definition));
- global.console = js.JSObjectMake(global.vm.root, global.console_class, private);
- global.global_class_def = GlobalClass.define(global.vm.root);
+ global.global_class_def = GlobalClass.define();
global.global_class = js.JSClassRetain(js.JSClassCreate(&global.global_class_def));
global.ctx = js.JSGlobalContextRetain(js.JSGlobalContextCreateInGroup(global.vm.group, global.global_class));
- std.debug.assert(js.JSObjectSetPrivate(js.JSContextGetGlobalObject(global.ctx), private));
- global.ref = js.JSContextGetGlobalObject(global.ctx);
+ std.debug.assert(js.JSObjectSetPrivate(js.JSContextGetGlobalObject(global.ctx), global));
if (!printer_buf_loaded) {
printer_buf_loaded = true;
- printer_buf = try MutableString.init(global.vm.allocator, 0);
+ printer_buf = try MutableString.init(global.vm.allocator, 4096);
}
}
@@ -1562,7 +1595,7 @@ pub fn NewClass(
exception: js.ExceptionRef,
) callconv(.C) js.JSValueRef {
var instance_pointer_ = js.JSObjectGetPrivate(obj);
- if (instance_pointer_ == null) return js.JSValueMakeUndefined(ctx);
+ if (instance_pointer_ == null) return null;
var instance_pointer = instance_pointer_.?;
var ptr = @ptrCast(
*ZigType,
@@ -1610,7 +1643,7 @@ pub fn NewClass(
exception: js.ExceptionRef,
) callconv(.C) js.JSValueRef {
var instance_pointer_ = js.JSObjectGetPrivate(obj);
- if (instance_pointer_ == null) return js.JSValueMakeUndefined(ctx);
+ if (instance_pointer_ == null) return null;
var this: *ZigType = @ptrCast(
*ZigType,
@alignCast(
@@ -1634,7 +1667,7 @@ pub fn NewClass(
)(
this,
ctx,
- this.ref,
+ obj,
exception,
);
},
@@ -1648,7 +1681,7 @@ pub fn NewClass(
)(
this,
ctx,
- this.ref,
+ obj,
prop,
exception,
);
@@ -1692,7 +1725,7 @@ pub fn NewClass(
)(
this,
ctx,
- this.ref,
+ obj,
prop,
value,
exception,
@@ -1704,16 +1737,14 @@ pub fn NewClass(
};
}
- pub fn define(ctx: js.JSContextRef) js.JSClassDefinition {
+ pub fn define() js.JSClassDefinition {
var def = js.kJSClassDefinitionEmpty;
if (static_functions.len > 0) {
+ std.mem.set(js.JSStaticFunction, &static_functions, std.mem.zeroes(js.JSStaticFunction));
+
inline for (function_name_literals) |function_name, i| {
var callback = To.JS.Callback(ZigType, @field(staticFunctions, function_names[i])).rfn;
- function_name_refs[i] = js.JSStringCreateWithCharactersNoCopy(
- function_name.ptr,
- function_name.len,
- );
static_functions[i] = js.JSStaticFunction{
.name = (function_names[i][0.. :0]).ptr,
@@ -1725,6 +1756,7 @@ pub fn NewClass(
// instance_functions[i] = function;
// }
}
+
def.staticFunctions = &static_functions;
}
diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig
index 63af5964d..be442728b 100644
--- a/src/js_parser/js_parser.zig
+++ b/src/js_parser/js_parser.zig
@@ -1892,8 +1892,8 @@ pub const Parser = struct {
},
loc,
);
- // Otherwise, it looks like this
- // var
+ // Otherwise, it looks like this
+ // var
} else {
jsx_part_stmts[stmt_i] = p.s(S.Import{
.namespace_ref = automatic_namespace_ref,
@@ -2196,6 +2196,7 @@ pub const Prefill = struct {
};
pub const Value = struct {
pub var EThis = E.This{};
+ pub var Zero = E.Number{ .value = 0.0 };
};
pub const String = struct {
pub var Key = E.String{ .value = &Prefill.StringLiteral.Key };
@@ -2218,6 +2219,7 @@ pub const Prefill = struct {
pub var LineNumber = Expr.Data{ .e_string = &Prefill.String.LineNumber };
pub var ColumnNumber = Expr.Data{ .e_string = &Prefill.String.ColumnNumber };
pub var This = Expr.Data{ .e_this = E.This{} };
+ pub var Zero = Expr.Data{ .e_number = &Value.Zero };
};
pub const Runtime = struct {
pub var JSXFilename = "__jsxFilename";
@@ -10781,7 +10783,19 @@ pub fn NewParser(
.e_unary => |e_| {
switch (e_.op) {
.un_typeof => {
+ const id_before = std.meta.activeTag(e_.value.data) == Expr.Tag.e_identifier;
e_.value = p.visitExprInOut(e_.value, ExprIn{ .assign_target = e_.op.unaryAssignTarget() });
+ const id_after = std.meta.activeTag(e_.value.data) == Expr.Tag.e_identifier;
+
+ // The expression "typeof (0, x)" must not become "typeof x" if "x"
+ // is unbound because that could suppress a ReferenceError from "x"
+ if (!id_before and id_after and p.symbols.items[e_.value.data.e_identifier.ref.inner_index].kind == .unbound) {
+ e_.value = Expr.joinWithComma(
+ Expr{ .loc = e_.value.loc, .data = Prefill.Data.Zero },
+ e_.value,
+ p.allocator,
+ );
+ }
if (SideEffects.toTypeof(e_.value.data)) |typeof| {
return p.e(E.String{ .utf8 = typeof }, expr.loc);
diff --git a/src/linker.zig b/src/linker.zig
index 46d2114ca..44fd140c2 100644
--- a/src/linker.zig
+++ b/src/linker.zig
@@ -204,16 +204,21 @@ pub fn NewLinker(comptime BundlerType: type) type {
continue;
}
-
if (linker.resolver.resolve(source_dir, import_record.path.text, import_record.kind)) |*_resolved_import| {
- var resolved_import: *Resolver.Result = _resolved_import;
+ const resolved_import: *const Resolver.Result = _resolved_import;
if (resolved_import.is_external) {
externals.append(record_index) catch unreachable;
continue;
}
+ if (linker.options.node_modules_bundle) |node_modules_bundle| {
+ const package_json_ = resolved_import.package_json orelse brk: {
+ if (resolved_import.isLikelyNodeModule()) {
+ break :brk linker.resolver.packageJSONForResolvedNodeModule(resolved_import);
+ }
- if (resolved_import.package_json) |package_json| {
- if (linker.options.node_modules_bundle) |node_modules_bundle| {
+ break :brk null;
+ };
+ if (package_json_) |package_json| {
if (strings.contains(package_json.source.path.name.dirWithTrailingSlash(), "node_modules")) {
if (node_modules_bundle.getPackageIDByName(package_json.name)) |possible_pkg_ids| {
const pkg_id: u32 = brk: {
@@ -537,14 +542,11 @@ pub fn NewLinker(comptime BundlerType: type) type {
linker: *ThisLinker,
loader: Options.Loader,
source_dir: string,
- resolve_result: *Resolver.Result,
+ resolve_result: *const Resolver.Result,
import_record: *ImportRecord,
comptime import_path_format: Options.BundleOptions.ImportPathFormat,
) !void {
- // extremely naive.
- resolve_result.is_from_node_modules = resolve_result.package_json != null or strings.contains(resolve_result.path_pair.primary.text, "/node_modules");
-
// lazy means:
// Run the resolver
// Don't parse/print automatically.
diff --git a/src/options.zig b/src/options.zig
index 132de8ca3..50f3efb11 100644
--- a/src/options.zig
+++ b/src/options.zig
@@ -249,6 +249,13 @@ pub const Platform = enum {
speedy,
node,
+ pub fn implementsRequire(platform: Platform) bool {
+ return switch (platform) {
+ .speedy, .node => true,
+ else => false,
+ };
+ }
+
pub const Extensions = struct {
pub const In = struct {
pub const JavaScript = [_]string{ ".js", ".ts", ".tsx", ".jsx", ".json" };
@@ -754,7 +761,7 @@ pub const BundleOptions = struct {
opts.output_dir_handle = try openOutputDir(opts.output_dir);
}
- if (opts.resolve_mode == .lazy and !(transform.generate_node_module_bundle orelse false)) {
+ if (!(transform.generate_node_module_bundle orelse false)) {
if (node_modules_bundle_existing) |node_mods| {
opts.node_modules_bundle = node_mods;
const pretty_path = fs.relativeTo(transform.node_modules_bundle_path.?);
@@ -768,6 +775,7 @@ pub const BundleOptions = struct {
const pretty_path = fs.relativeTo(bundle_path);
var bundle_file = std.fs.openFileAbsolute(bundle_path, .{ .read = true, .write = true }) catch |err| {
Output.disableBuffering();
+ defer Output.enableBuffering();
Output.prettyErrorln("<r>error opening <d>\"<r><b>{s}<r><d>\":<r> <b><red>{s}<r>", .{ pretty_path, @errorName(err) });
break :load_bundle;
};