Skip to content

Commit

Permalink
fix: jsx key after spread (#7464)
Browse files Browse the repository at this point in the history
* fix: jsx key after spread

* feat: configurable logLevel
  • Loading branch information
rhyzx authored Dec 10, 2023
1 parent 402f335 commit 7541f4c
Show file tree
Hide file tree
Showing 10 changed files with 324 additions and 284 deletions.
5 changes: 5 additions & 0 deletions packages/bun-types/bun.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1130,6 +1130,11 @@ declare module "bun" {
* it in some cases. Do your own benchmarks!
*/
inline?: boolean;

/**
* @default "warn"
*/
logLevel?: "verbose" | "debug" | "info" | "warn" | "error";
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/RuntimeTranspilerCache.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ** Update the version number when any breaking changes are made to the cache format or to the JS parser **
const expected_version = 1;
const expected_version = 2;

const bun = @import("root").bun;
const std = @import("std");
Expand Down
15 changes: 14 additions & 1 deletion src/bun.js/api/JSTranspiler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub const TransformTask = struct {
.loader = loader,
.replace_exports = transpiler.transpiler_options.runtime.replace_exports,
};
transform_task.log.level = transpiler.transpiler_options.log.level;
transform_task.bundler = transpiler.bundler;
transform_task.bundler.linker.resolver = &transform_task.bundler.resolver;

Expand Down Expand Up @@ -318,7 +319,6 @@ fn transformOptionsFromJSC(globalObject: JSC.C.JSContextRef, temp_allocator: std
.transform = default_transform_options,
.log = logger.Log.init(allocator),
};
transpiler.log.level = .warn;

if (!object.isObject()) {
JSC.throwInvalidArguments("Expected an object", .{}, globalObject, exception);
Expand Down Expand Up @@ -723,6 +723,18 @@ fn transformOptionsFromJSC(globalObject: JSC.C.JSContextRef, temp_allocator: std
transpiler.runtime.replace_exports = replacements;
}

if (object.get(globalThis, "logLevel")) |logLevel| {
const logLevelString = logLevel.toBunString(globalThis);
defer logLevelString.deref();
const key = logLevelString.toOwnedSlice(allocator) catch bun.outOfMemory();
if (logger.Log.Level.Map.get(key)) |level| {
transpiler.log.level = level;
} else {
JSC.throwInvalidArguments("logLevel must be one of \"verbose\", \"debug\", \"info\", \"warn\", or \"error\"", .{}, globalObject, exception);
return transpiler;
}
}

transpiler.tree_shaking = tree_shaking orelse false;
transpiler.trim_unused_imports = trim_unused_imports orelse transpiler.tree_shaking;

Expand Down Expand Up @@ -1125,6 +1137,7 @@ pub fn transformSync(
this.bundler.setAllocator(arena.allocator());
this.bundler.macro_context = null;
var log = logger.Log.init(arena.backingAllocator());
log.level = this.transpiler_options.log.level;
this.bundler.setLog(&log);

defer {
Expand Down
1 change: 1 addition & 0 deletions src/cache.zig
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ pub const JavaScript = struct {
source: *const logger.Source,
) anyerror!?js_ast.Result {
var temp_log = logger.Log.init(allocator);
temp_log.level = log.level;
var parser = js_parser.Parser.init(opts, &temp_log, source, defines, allocator) catch {
temp_log.appendToMaybeRecycled(log, source) catch {};
return null;
Expand Down
2 changes: 1 addition & 1 deletion src/js_ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ pub const LocRef = struct {

pub const Flags = struct {
pub const JSXElement = enum {
is_key_before_rest,
is_key_after_spread,
has_any_dynamic,
can_be_inlined,
can_be_hoisted,
Expand Down
558 changes: 280 additions & 278 deletions src/js_parser.zig

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/bundler/bun-build-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ describe("Bun.build", () => {
expect(x.success).toBe(true);
expect(x.logs).toHaveLength(1);
expect(x.logs[0].message).toBe(
'"key" prop before a {...spread} is deprecated in JSX. Falling back to classic runtime.',
'"key" prop after a {...spread} is deprecated in JSX. Falling back to classic runtime.',
);
expect(x.logs[0].name).toBe("BuildMessage");
expect(x.logs[0].position).toBeTruthy();
Expand Down
2 changes: 1 addition & 1 deletion test/bundler/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe("bun build", () => {
});
expect(exitCode).toBe(0);
expect(stderr.toString("utf8")).toContain(
'warn: "key" prop before a {...spread} is deprecated in JSX. Falling back to classic runtime.',
'warn: "key" prop after a {...spread} is deprecated in JSX. Falling back to classic runtime.',
);
});

Expand Down
2 changes: 1 addition & 1 deletion test/bundler/fixtures/jsx-warning/index.jsx
Original file line number Diff line number Diff line change
@@ -1 +1 @@
console.log(<div key={"123"} {...props} />);
console.log(<div {...props} key={"123"} />);
19 changes: 19 additions & 0 deletions test/transpiler/transpiler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,7 @@ export default <>hi</>
define: {
"process.env.NODE_ENV": JSON.stringify("development"),
},
logLevel: "error",
});

expect(bun.transformSync("console.log(<div key={() => {}} points={() => {}}></div>);")).toBe(
Expand Down Expand Up @@ -1251,6 +1252,24 @@ export default <>hi</>

expect(bun.transformSync("console.log(<div></div>);")).toBe(
`console.log(jsxDEV("div", {}, undefined, false, undefined, this));
`,
);

// key after spread props
// https://github.com/oven-sh/bun/issues/7328
expect(bun.transformSync(`console.log(<div {...obj} key="after" />, <div key="before" {...obj} />);`)).toBe(
`console.log(createElement(\"div\", {\n ...obj,\n key: \"after\"\n}), jsxDEV(\"div\", {\n ...obj\n}, \"before\", false, undefined, this));
`,
);
expect(bun.transformSync(`console.log(<div {...obj} key="after" {...obj2} />);`)).toBe(
`console.log(createElement(\"div\", {\n ...obj,\n key: \"after\",\n ...obj2\n}));
`,
);
expect(
bun.transformSync(`// @jsx foo;
console.log(<div {...obj} key="after" />);`),
).toBe(
`console.log(createElement(\"div\", {\n ...obj,\n key: \"after\"\n}));
`,
);
});
Expand Down

0 comments on commit 7541f4c

Please sign in to comment.