Changelog: swc v1.2.23

New features#

jsx pragma (#1015)#

swc finally suports jsx pragma, which is required to use some libraries like emotion.sh.

// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */
import { css, jsx } from "@emotion/core";
const color = "white";
render(
<div
css={css`
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
&:hover {
color: ${color};
}
`}
>
Hover to change color.
</div>
);

BingInt literal type (#1020)#

I didn't know that it is valid syntax, but the code below is validl, and swc now supports it.

const a: 1000n = 1000n;

Dynamic imports in non-es6 modules (#1028)#

Dynamic imports are not widely supported, so it should be transcompiled.

describe("foo", () => {
it("should import", async () => {
expect.assertions(1);
const { FOO } = await import("./foo");
expect(FOO).toBe(true);
});
});

is now compiled as

describe("foo", () => {
it("should import", async () => {
expect.assertions(1);
const { FOO } = await Promise.resolve().then(function () {
return require("./foo");
});
expect(FOO).toBe(true);
});
});

if the module config is common js.

Block scoping (#1029)#

this is now correctly handled in the loops.

class C {
m() {
for (let x = 0; x < 10; x++) console.log(this, (y) => y != x);
}
}

Also, you can now mutate the index variable while iterating.

e.g.

for (let i = 0; i < 5; i++) {
console.log(
i++,
[2].every((x) => x != i)
);
}

fixer: binary expression in callee of new (#1030)#

Previously swc miscompiled

return new (P || (P = Promise))(function (resolve, reject) {
// ....
});

into

return (
new P() ||
(P = Promise)(function (resolve, reject) {
// ....
})
);

which is wrong. Now it's fixed and swc emits correct output.

Support for large binary expressions (#1032)#

I fixed the code generator, parser, typescript stripper, fixer pass, resolver pass and hygiene pass to handle very large binary expressions.

As a result, swc can now compile very large binary expressions like those in seedlings

Correct this in optional chaining (#1035)#

Previously, swc miscompiled

a.focus?.();

into

"use strict";
var ref;
(ref = a.focus) === null || ref === void 0 ? void 0 : ref.call(ref);

which is wrong. It should be

"use strict";
var ref;
(ref = a.focus) === null || ref === void 0 ? void 0 : ref.call(a);

and swc now emits correct code.

spack (#1016, #1031, #1034)#

I did very hard work on it, and many edge cases are fixed. I don't think it's production ready yet, but it will be in a near future.

As a side note, #1016 is about ecmascript imports and #1031 and #0134 are about complex reexports and common js support, respectively.

Performance improvement#

swc becomes faster and it will be much faster with the next version. Its performance is similar to it of esbuild, even though there are so many low-hanging fruits.


Full change log