Changelog: swc v1.2.60

Bugfixes#

super in decorated methods (#846)#

Previously swc emitted wrong code if a method call from super is used.

class SomeClass {
@dec
someMethod() {}
}
class OtherClass extends SomeClass {
@dec
anotherMethod() {
super.someMethod();
}
}

Codes like above now works properly.

dce: Fix for decorated classes (#1769)#

@decorator
class Class {}
function decorator(cls: any) {
console.log(cls.name);
}

Previously swc dropped a class if it's decorated and not instantiated. This is wrong because decorators can have side effects and now it's fixed.

bundler: Prevent hang (#1779)#

In certain complex import scenarios, the bundler of swc hanged while determinging cycle imports. This is now fixed and fairly complex imports are now handled by the bundler.

fixer: Binary expressions in unary operands (#1781, #1789)#

There was a regression related to parenthesis.

const n = ~~(Math.PI * 10);
const c = +(+1 / 4);
console.log(c);

These was miscompiled but it's now fixed.

Support for export * with same name (#1780)#

swc now supports code like

// constant.ts
export enum Foo {}
// File1.ts
export { Foo } from "./constant";
// file2.ts
export { Foo } from "./constant";

Fix for double imports (#1757)#

Previously swc throwed an error for double imports like

import "testlibrary";
import { aFunc } from "testlibrary";
console.log("aFunc: ", aFunc(1, 2));

It's now fixed.

Fix for async generator (#1752)#

Previously swc miscompiled await in async generators and codes like

async function* generate(): AsyncGenerator {
const results = await Promise.all([
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3),
]);
for (const result of results) {
console.log(`yield ${result}`);
yield result;
}
}
async function printValues() {
const iterator = generate();
for await (const value of iterator) {
console.log(`iterator value: ${value}`);
}
}
printValues();

was broken. It's now fixed.

Changelog: swc v1.2.59

Bugfixes#

Fix for arguments in for loops (#1462)#

Previously the helper of swc was broken by this bug. It's now fixed and new version of @swc/helpers works properly.

regnerator: var in proper level (#1718)#

Previously swc might break codes like

async function scanUser(groups: { users: number[] }[]) {
await Promise.all(
groups.map(async ({ users }) => {
for (const user of users) {
console.log("user", user);
await new Promise((resolve) => setTimeout(resolve, 30));
}
})
);
}
scanUser([{ users: [1, 2, 3, 4, 5] }, { users: [11, 12, 13, 14, 15] }]);

because the variable for iterator are recycled while it should not. It's now fixed by injecting variables at proper level.

escapes in jsx attribute values (#1661)#

The afffected code looks like

console.log(<h1 value="abc\nas">s</h1>);

regenerator: || handled properly (#1684)#

Previously swc had a bug related to await in rhs of || and code like

const cache = {};
async function getThing(key) {
const it = cache[key] || (await fetchThing(key));
return it;
}
function fetchThing(key) {
return Promise.resolve(key.toUpperCase()).then((val) => (cache[key] = val));
}

was miscompiled.

It's now fixed.

bundler: Complex circular imports (#1739)#

In a very complex cirular import scenario, the bundler may hang because of infinite recursions.

It's now fixed.

typscript: Arrow expr with class expr https://github.com/swc-project/swc/issues/1738#

The typescript type stripped of swc compiled arrow expressions with a class expression as a body wonrly.

The affected code looks like and it's now fixed.

const fn = () => class Bug {};
console.log(fn());

codegen: Unicode characters (#1744)#

Previously swc could break codes for old targets like

console.log("馃き 眉");

It's not fixed.

this in tagged template literals (#1742)#

swc, just like babel, had a bug related to this in tagged template literals. This bug could break code like

class Foo {
#tag() {
return this;
}
#tag2 = this.#tag;
constructor() {
const receiver = this.#tag`tagged template`;
console.log(receiver === this);
const receiver2 = this.#tag2`tagged template`;
console.log(receiver2 === this);
}
}
new Foo();

parser: TS1031 https://github.com/swc-project/swc/issues/1751#

Previously swc wrongly emitted an error for

class Foo {
declare a: string;
}

Fixed by @Shinyaigeek.

API type definition #1746#

The typescript type checker will not report error for keepClassNames anymore.

bundler: Support for file names ending with period. (#1748)#

Previously the bundler failed to bundler [email protected]^2 because of a bug in the resolver.

Fixed by @tmpfs.

bundler: Updated list for core modules. (#1749)#

node.js added some core modules and using them with the bundler resulted in an error because it tried to resolve it in node_modules.

Fixed by @tmpfs.

codegen: Class with minify and higher target (#1764)#

Previously swc had a codegen bug related to a class with es2016+ target and minify enabled.

Fixed by @Shinyaigeek.

New platform support#

FreeBSD (#1758)#

@Brooooooklyn, the author of a wonderful rust library for creating node modules, added supports for FreeBSD.

Changelog: swc v1.2.58

Bugfixes#

codegen: \r\n in template literals. (#1707)#

This happens only if your target is es2016 or upper. This issue is reported via a deno issue, and

const content1 = `first line\r\nsecond line\r\nthird line`;
const content2 = `first line
second line
third line`;
console.log({ content1, content2 });

now works properly.

fixer: null ?? (undefined && true). (#1709)#

This issue is reported via a deno issue. This is fixed by explicitly handling a ?? (b && c).

optimizer: Preserve optional chaining expressions. (#1688)#

({ notafunction: null }?.notafunction?.());
({ notafunction: null }?.notafunction());
({ notafunction: null }.notafunction?.());

swc preivously didn't handle optional chaining expresison propely and had break the codes above. It's now fixed.

optimizer: Side-effects of [x, y][0]. (#1674)#

Previously the optimizer of swc had a bug which breaks code like

let foo = "info";
var bar = [foo, (foo = "other")][0];
console.log(foo == "other");
console.log(bar == "info");

It's now fixed.

parser: Non-identifier names in getters. (#1671)#

const thing = {
get "a-b"() {
return "abc";
},
};
console.log(thing["a-b"]);

Due to a bug, swc previously faild to parse the code above. It's now fixed.

parser: Class member named declare (#1671)#

class A {
private declare() {}
}

The code above now works properly.

compat: async-to-generator (#1721, #1722)#

swc now compiles

async function* lol() {
yield 1;
yield 2;
}
async function main() {
for await (const x of lol()) {
console.log(x);
}
}
main();

and

(async function main() {
console.log(1);
})();

correctly.

react: Remove panic call (#1683)#

const config = {
test: /\.[jt]sx?$/i,
exclude: /[\\/]node_modules[\\/]/,
use: [
{
loader: "swc-loader",
options: {
jsc: {
target: "es5",
parser: {
tsx: true,
decorators: true,
syntax: "typescript",
dynamicImport: true,
},
transform: {
react: {
runtime: "automatic",
},
},
externalHelpers: true,
},
},
},
],
};

swc had a bug in new jsx pass which resulted in an exception thrown. It's now fixed.

parser: Type-only import equals (#1695)#

import type React = require("react");

This is valid syntax since typescript 4.2, but swc didn't support it.

Fixed by @g-plance.

compat: Private methods (#1694, #1702, #1711)#

Previously swc had a bug related to private class methods.

preset-env: Update compat data (#1704, #1719)#

The compatibility data was outdated.

typescript: Preserved module context (#1698, #1706)#

tsc emits

export {};

for

export type Foo = number;

while other tools do not preserve the information that the file is module.

Because swc prefers the bahavior of tsc over the one of babel, swc now emits export {} for type-only modules.

wasm-web: Support for bundlers (#1675)#

The @swc/wasm-web package now use correct command while publishing so it has correct data in package.json.

api: Types for react pass. (#1720)#

Fixed by @Brooooooklyn.

Changelog: swc v1.2.57

Imrpovements#

Perfoemance (#1673)#

This pr adds lots of fast path for es2015 passes, and the addition of fast-paths removes lots of useless memcpy calls. The time used for es2015 -> es5 transforms is reduced about 33%. (It's now 50% faster).

Codegen of class expressions (#1660)#

Previously swc compiled

console.log(
class {
run() {}
}
);

as

console.log(
(function () {
var _class = /*#__PURE__*/ (function () {
"use strict";
function _class() {
_classCallCheck(this, _class);
}
_createClass(_class, [
{
key: "run",
value: function run() {},
},
]);
return _class;
})();
return _class;
})()
);

which is not optimal.

Starting from swc v1.2.57, swc emits

console.log(/*#__PURE__*/ function() {
"use strict";
function _class() {
_classCallCheck(this, _class);
}
_createClass(...);
return _class;
}()
);

New features#

Pure comment for classes pass. (#1646)#

swc now emits /*#__PURE__*/ for classes to help javascript minifiers.

TypeScript: override with static (#1663)#

Implemented by @g-plane.

TypeScript: Support override in parameter properties (#1667)#

Implemented by @g-plane.

Internals#

This section contains internal improvements, which are mostly done for the new typesciprt checker I'm working on.

Function declarations in ts modules (#1665)#

Previously, swc didn't identified F2s in below code.

module M {
export class A {
name: string;
}
export function F2(x: number): string {
return x.toString();
}
}
module N {
export class A {
id: number;
}
export function F2(x: number): string {
return x.toString();
}
}

This bug resulted in a bug of stc, the typescript type checker I'm working on.

Function declarations in arrow expressions (#1666)#

Previously, the ts_resolver pass did not distinguish two bar in code below. The bug does not affect swc users because the bug only occurs when two separate arrow expressions contains a function named identically.

var f3 = <T, U extends T>(x: T, y: U) => {
function bar<V extends T, W extends U>() {
var g = <X extends W, Y extends V>(a: X, b: Y): T => {
x = y;
return y;
};
}
};
var f4 = <U extends T, T>(x: T, y: U) => {
function bar<V extends T, W extends U>() {
var g = <X extends W, Y extends V>(a: X, b: Y): T => {
x = y;
return y;
};
}
};

For of/in loops (#1672)#

Previously, the ts_resolver pass did not distinguish v in code below.

for (const v of new FooIterator()) {
const v = 0; // new scope
}

This bug is theoritically possible to affect real world codes, but it would not. So it is listed on the misc section.

Changelog: swc v1.2.55

Bugfixes#

Type definition of FunctionDeclaration (#1602)#

Fixed by @wavesheep

optimizer: Fix for do-while loops (#1518)#

Previously the optimizer of swc errornously removed some loops.

Fixed by @wbinnssmith.

Codegen of null character (#1619)#

swc now emits \x00 instead of \00 for null charcters.

preset-env: Import order of core-js modules (#1605)#

Now swc uses indexed sets for managing imports.

&nbsp; in jsx entities (#1446)#

Previously swc blindly treated &nbsp; in jsx entities as a whitespace (because it is) and it resulted in &nbsp; being removed. This is now fixed and it works as expected.

Type definition of options (#1621)#

Fixed by @Brooooooklyn.

HasDecorators.decorators: optional (#1603)#

Now Parameter allows decorators property to be skipped.

Super in sequence expressions (#1617)#

Previously swc miscompiled code like

class A extends B {
foo() {
super.foo(), bar();
}
}

TypeScript dynamic imports (#1614)#

There was a bug which occurs if the dynamic import is only import of a module.

Affected code looks like

(async () => {
const example = await import("./example");
console.log(example.foo);
})();

TypeScript common js exports (#1593)#

swc now supports

export Foo = 'example';

optimizer: Preserve x instanceof Object (#1630)#

Previously swc mis-optimized

let x = undefined;
if (x instanceof Object) {
console.log(x.obj);
}

Fixed by @mischnic.

react: Pass ordering (#1639)#

Fixed by @mischnic.

resolver: Fix setter properties (#)#

Preivously the scope analyzer of swc had a bug related to setter property. But this bug is not expected to affect any real world code because it only affects setter properties.

Type definition of JSXOpeningElement (#1608)#

Fixed by @vemoo.

Method with keyword names (#1651)#

This bug would affect code which uses a keyword as a method name.

Performance improvements#

bundler: Skip works (#1599)#

Previously swc did analysis for all modules, even if it does not have any imports. It's not necessary and it's now removed.

bundler: Rework (#1601)#

swc had a faulty design, which made the bundler slow. These legacy codes are removed, and swc becomes much faster.

bundler: Detection of circular imports (#1610)#

With the release, swc does not perform graph operations. It makes bundling modules with lots of ciruclar graph much faster.

Changelog: swc v1.2.54

Bugfixes#

typescript: async override (#1558)#

swc now supports async override in addition to override async.

class Base {
method1() {}
method2() {}
}
class Test extends Base {
public override async method1() {
return Promise.resolve(1);
}
public async override method2() {
return Promise.resolve(1);
}
}

dce bug (#1533)#

Previously swc had a bug that causes a usage of a variable in the discriminant of a switch statement not treated as a usage. It's now fixed and code like below works even if the optimizer is enabled.

var this_will_disappear; // <-- this variable declaration disappears
function a(x) {
switch (this_will_disappear) {
case x:
return;
}
}
function b() {
c();
}
function c() {
b();
d();
}
function d() {
a();
}

SIGILL (#1583)#

swc used aes feature of cpus as an optimization, but it caused SIGILL on a user's pc. So I disabled aes feature.

Logical nullish assigments (#1570)#

const a: { [a: string]: string } = {};
a.b ??= "1";
console.log(a); // expect: { b: '1' }

The code above was miscompieled by swc, but it's now fixed.

Order of statements regarding imports (#1457)#

swc now preserve order of statements even if there are some imports. This is to fix code like

import {
setGlobalOptions,
plugin,
buildSchema,
addModelToTypegoose,
deleteModel,
} from "@typegoose/typegoose";
import * as typegoose from "@typegoose/typegoose";
// typegoose.mongoose.set('debug', true);
setGlobalOptions({
options: {
allowMixed: typegoose.Severity.ALLOW,
},
schemaOptions: {
timestamps: {
createdAt: "created_at",
updatedAt: "updated_at",
},
},
});
import { schemas } from "./schemas";

Syntax context of super classes (#1586)#

swc had a bug which makes

class Foo {}
class Test extends Foo {
foo() {
console.log(Foo);
}
}
Foo = 3;
new Foo().foo();

to emit Foo instead of 3.

It's fixed by @devongovett.

Statement order of default imports. (#1568)#

To workaroudn a bug of webpack, I modified order of statements generated from export default functions.

Thankfully, @josteph explained the problem and suggested the way to fix.

Mixed import of default (#1525)#

import { Component, default as React } from "react";
class X extends Component {}
React.render(document.getElementById("root"), <X></X>);

swc previously miscompied this, because it wasn't careful enough about default as Foo-style imports. It's fixed and swc now emits

var _react = _interopRequireWildcard(require("react"));
class X extends _react.Component {}
_react.default.render(
document.getElementById("root"),
/*#__PURE__*/ _react.default.createElement(X, null)
);

which is correct.

SourceMaps (#1581)#

swc had a bug related to inline source maps and as a result it generated empty sourcemap. It's fixed.

Parameter property decorators (#1456)#

swc had a bug in logic for determining if it should work. While checking existance of decortor, swc didn't check decorators of typescript parameter properties.

As a result, decorator didn't work if all constructor parameters are parameter properties. It's now fixed and decorators are properly applied.

Fix for arguments (#1585)#

There was a bug of swc which may break some codes using arguments in arrow functions.

It could break codes like

function test() {
return () => arguments[0];
}

Fixed by @devongovett.

Fix for decorators (#1362)#

Fixed as a part of decorator fixes.

Changelog: swc v1.2.53

Bugfixes#

bundler: Complex reexports within cycles (#1576)#

Previously there was some edge cases which is not properly handled by the swc bundler. The bug ocurred only when it's reexported using export *, was in a cylcle of dependency and requires some more complex conditions. It's is now fixed.

regnerator: Fix for delegating yields (#1580)#

There was a bug related to delegating yields (yield *) and it affected codes like

function* a() {
yield 5;
return 7;
}
function* b() {
let x = yield* a();
yield x + 1;
}
expect([...b()]).toEqual([5, 8]);

It's fixed by @devongovett.

Correct helper name (#1578)#

swc used incorrect helper name in some cases. It's fixed by @grimly

fixer: Fix for yields in ternaries (#1577)#

Previously swc miscompiled (yield foo) ? "bar" : "baz" as yield foo ? "bar" : "baz".

It's fixed by @devongovett.

codegen: Fix for rest patterns (#1573)#

Affected code looks like

function myFunc({ ...data }: { field: string }) {}

bundler: Various bugfixes (#1572)#

It includes bugfixes for complexly nested export *-s and the fix for a dead-code-elimination bug.

Fix for scope of functions (#1559)#

swc compiled

var Test = (function () {
var Test = (function () {
var Test = 2;
return Test;
})();
return Test;
})();

into

var Test = (function () {
var Test = (function () {
var Test1 = 2;
return Test; // <- this is wrong
})();
return Test;
})();

which is wrong, but the bug is now fixed and it emits

var Test1 = (function () {
var Test2 = (function () {
var Test3 = 2;
return Test3;
})();
return Test2;
})();

Fixed by @devongovett.

Fix for unknown object property accesses (#1567)#

swc now does not compile {}.foo as undefined anymore. Previously swc wrongly compiled it as such if optimizer is enabled.

Fixed by @mischnic.

Fix for parens of sequence expressions in callee and params (#1566)#

Previsously swc miscompiled

let x = ({}, () => 2)();

as

let x = {
}, ()=>2
();

which is clearly wrong.

Fixed by @devongovett.

this = globalThis in imported functions (#1561)#

import foo from "foo";
foo.bar();

is now compiled with module: commonjs as

const foo = require("foo"); // This is bit different.
(0, foo).bar();

to make this in bar point the module.

Fixed by @Austaras.

Block scoping of class declarations (#1569)#

const g = 20;
function baz() {
{
class g {}
}
return g;
}

is now

const g = 20;
function baz() {
{
class g1 {}
console.log(g1);
}
return g;
}

instead of previous

const g1 = 20; // <- this is wrong
function baz() {
{
class g1 {}
}
return g; // <- this is wrong
}

Fixed by @devongovett.

Changelog: swc v1.2.52

Bugfixes#

external helper: typeof (#1557, #1458)#

Previously swc used incorrect name for typeof helpers, if extenalHelpers is true.

{
"jsc": {
"externalHelpers": true,
"target": "es2015"
}
}

This is now fixed.

helper bugs (#1555)#

Some helpers were compiled incorrectly due to a bug of the resolver pass.

The bug made swc to emit

function _setPrototypeOf(o, p) {
_setPrototypeOf =
Object.setPrototypeOf ||
function _setPrototypeOf1(o1, p1) {
o1.__proto__ = p1;
return o1;
};
return _setPrototypeOf1(o, p);
}
exports.default = _setPrototypeOf;

for

export default function _setPrototypeOf(o, p) {
_setPrototypeOf =
Object.setPrototypeOf ||
function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}

This is now fixed.

CR in template literals (#1549)#

Previously the code below resulted in a bug.

const { transform } = require("@swc/core");
transform("const a = `\r\n`;", {
jsc: {
parser: {
syntax: "typescript",
},
target: "es2015",
},
})
.then(({ code }) => code)
.then(console.log, console.error);

Input sourcemap bug (#1404)#

swc now handles input source map correctly.

Generic parsing bug (#1526)#

export const foo = function* <T>() {};
export const bar = () => {};

Prevously swc incorrectly failed emitting invalid syntax error. It was due to <T> being parsed as jsx and it's now fixed.

Dead branch remover bug (#1539)#

function test() {
return foo();
function foo() {
return 2;
}
console.log("hi");
}

is now compiled as

function test() {
function foo() {
return 2;
}
return foo();
}

Fixed by @devongovett.

TypeScript namespace bug (#1553, #1515)#

export function a() {}
export namespace a {
export function b() {}
}

When a typescript namespace is used with another declaration with identical name, swc produced an invalid code. It's now fixed by tracking names.

Sourcemap position bug (#1548)#

It's reported via deno.

swc emitted 0 for the column of indented nodes, which made the sourcemap unhelpful. swc now considers indention while emiiting sourcemap.

Visitor bug (#1543)#

There was a change to ast because previous design did not allow getting span of the template part of the template literal. But the node package was not updated and it's fixed by this pr.

Fixed by @arendjr.

Resolver bug relatead to function expressions (#1540)#

Previously swc compiled

export default function foo() {
foo = function foo(x) {
return x === 0 ? 1 : 1 + foo(x - 1);
};
return foo(10);
}

as

export default function foo() {
foo = function foo1(x) {
return x === 0 ? 1 : 1 + foo1(x - 1);
};
return foo1(10); // <- this is wrong
}

which is wrong.

The bug is fixed by @devongovett and swc now emits

test(function foo() {
foo = function foo1(x) {
return x === 0 ? 1 : 1 + foo1(x - 1);
};
return foo(10);
});

TypeScript definitions (#1542, #1535)#

Some AST type definitions are wrong, and it's now fixed by @wavesheep.

Branch simplifier bug (#1536)#

Previously the optimizer of swc broke codes like

if (Date.now() < 0) {
for (let i = 0; i < 10; i++) {
if (Date.now() < 0) {
console.log(1);
}
}
} else {
console.log(2);
}

It's now fixed by @devongovett.

TypeScript common js import bug (#1448)#

swc now supports common js import of typescript.

import F = require("yaml");
console.log(F);

Default destructuring patterns (#1477, #1449)#

swc now supports default patterns in object patterns.

async function foo() {
const { bar: {} = {} } = baz;
}

this in async object methods (#1455)#

swc previously broke codes with asynchronous method like

const SampleData = typedModel(
"SampleVideo",
VideosSchema,
undefined,
undefined,
{
byPlatform: async function (platform: string) {
const result = await this.find({ platform: { $eq: platform } });
return result;
},
}
);
SampleData.byPlatform("youtube").then((res) => {
console.info(res);
});

It's now fixed.

Type stripper bug (#1521)#

swc now allows declaring a type with name which is imported.

For example code below,

import { Test } from "test";
interface Test {}
console.log(Test);

import { Test } from "test"; is now preserved because console.log(Test); uses Test.

Fixed by @devongovett.

Comment parsing bug (#1527)#

function Bar() {
const [foo, setFoo] = useState(0);
React.useEffect(() => {
// @refresh reset
});
return <h1>{foo}</h1>;
}

swc now handles comment // @refresh reset correctly.

Abstract classes (#1454)#

export abstract class AbstractProviderDeliveryService {}

Super in class methods (#1490)#

There were some edge cases where swc emits wrong code for usages of super in class methods.

Affected code looks like

"use strict";
class Element {
getChildElements() {
return this.childElements;
}
}
class CanvasElement extends Element {
createFacets(hidden) {
const childElements = this.getChildElements();
///
}
}
class ColouredCanvasElement extends CanvasElement {
createFacets(hidden) {
hidden = super.createFacets(hidden); /// This line was buggy
///
}
}
class ColouredSquare extends ColouredCanvasElement {}
const bugExample = () => {
const colouredSquare = new ColouredSquare(),
hidden = false;
colouredSquare.createFacets(hidden);
};
export default bugExample;

Backticks in template literals (#1488)#

Previously swc handled

`\``;

in a wrong way. It's now fixed.

Declare namespace bug (#1508)#

swc preivously didn't handle declare namespace correctly. It emitted

var twttr;
(function (twttr1) {
const txt;
twttr1.txt = txt;
})(twttr || (twttr = {}));

for

declare namespace twttr {
export const txt: typeof import("twitter-text");
}

which should be an empty file. It's now fixed.

ES module interop for dynamic imports (#1480, #1509)#

Code like

const { default: ora } = await import("ora");

requires some helpers to work properly, but swc didn't use helpers.

It's now fixed and it works identically as tsc.

Parenthesis bug of class properties (#1502)#

Previously swc compiled

class A {
a = (console.log(1), 2);
}

as

class A {
a = console.log(1), 2;
}

but it's now

class A {
a = (console.log(1), 2);
}

Fixed by @nayeemrmn

Sourcemaps of multiline block comments (#1511)#

Before: Before

After: After

Fixed by @devongovett.

Generic parsing bug (#1505)#

swc has a bug related to backtracking and as a result the following code result in an exception.

type InjectedTeamsProps = {};
class Component<_T, _U> {}
class ComponentType<_T> {}
const withTeamsForUser = <P extends InjectedTeamsProps>(
_WrappedComponent: ComponentType<P>
) =>
class extends Component<
Omit<P, keyof InjectedTeamsProps> & Partial<InjectedTeamsProps>,
InjectedTeamsProps
> {
static displayName = `x`;
};

This is fixed.

Class names when keepClassNames is true (#1507)#

Previously keepClassNames didn't work for class expressions. This resulted in decorated class declarations being renamed, which breaks codes depend on relfect-metadata.

Affected code looks like:

import { Entity, BaseEntity } from "typeorm";
@Entity()
export class Location extends BaseEntity {}

Class properties named readonly (#1514)#

swc now supports

export class ClassProp {
readonly!: boolean;
}

Private declare properties (#1503)#

class Class {
private declare prop;
}

The code above now works with swc.

Assert after imports (#1512)#

import assert from "./index";
assert<123>(123);
assert<123>(123, 123);
assert<123>(123, 123, 123);

For the code above, the parser of swc tried to eat second assert to parse it as a part of an import assertion. This is fixed by checking for newlines.

New features#

TypeScript 4.3#

override (#1541)#

class SpecializedComponent extends SomeComponent {
override show() {
// ...
}
override hide() {
// ...
}
}

Implemented by @g-plane.

See: https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#override-and-the-noimplicitoverride-flag

getter / setters (#1517)#

interface X {
get foo(): string;
set foo(v: string | number);
}
type Y = {
get bar(): string;
set bar(v: string | number);
}

static index signature (#1537)#

class Foo {
static hello = "hello";
static world = 1234;
static [propName: string]: string | number | undefined;
}

Implemented by @g-plane.

See: https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#static-index-signatures

Pure annotation for react (#1564)#

swc now emits /*#__PURE__*/ for react components, which is used by various optimizers to identify side-effect-free functions.

Implemented by @devongovett.

Fast refresh (#1524)#

swc now supports react fast refresh. See docs for configurations.

Implemented by @Austaras.

UX Improvement#

Better error message for wrong configurations. (#1532)#

Previously swc sielently used default syntax for the .swcrc below.

{
"jsc": {
"parser": {
"syntax": "typescript",
"dynamicImport": true
},
"externalHelpers": true,
"target": "esnext"
},
"sourceMaps": true
}

This config is invalid because target does not allow esnext. But error message was cryptic because it was about parsing failure.

It's now fixed and swc reports proper error for such inputs.

Parser error code (#1551)#

Previously swc emiited TS1775 for the code below, but it should be TS1773.

class C implements A extends B {}

Fixed by @g-plane

Changelog: swc v1.2.51

Bugfixes#

Column position in source maps (#1470)#

Thanks to @devongovett, swc now emits correct source map regarding column offsets.

keepClassName (#1453)#

The option keepClasName was introduced in swc v1.2.50. But there was a bug at configuration merging, and it didn't work. It's now fixed.

Codegen of arrow functions (#1452)#

Arrow functions without parenthesis in arguments like async foo => 0; is now handled properly.

bundler: Stack overflow on windows (#1464)#

This was reported via deno, by #9752. Previously bunlding already-bundled file might cause stack overflow on windows, but it's now fixed.

Assignments in await argument (#1475)#

Previsouly, swc break the code like await (bar = Promise.resolve(2)); by removing parens. This is now fixed and it works properly.

Parens in nullish coalescing (#1496)#

Previously swc miscompiled

console.log(("a" ?? "b") || "");

into

console.log("a" ?? ("b" || ""));

which is wrong. swc now emits

console.log(("a" ?? "b") || "");

Jsx entities in jsx attribute values (#1501)#

swc now compiles

<div id="abc&gt;" />

as

React.createElement("div", {
id: "abc>",
});

regardless of target version.

Changelog: swc v1.2.50

Bugfixes#

TypeScript metadata for unions (#1421)#

Now swc emits proper metadata for union of string literals, like in codes like

import "reflect-metadata";
const COL_KEY = Symbol("col");
const column = () => {
return (object: any, key: string) => {
Reflect.defineMetadata(COL_KEY, "value", object, key);
};
};
class User {
@column() currency!: "usd" | "eur" | "yen";
}
console.log(Reflect.getMetadata("design:type", User.prototype, "currency"));

Previously, the code printed undefined when compiled with swc which is wrong. It is now String.

No duplicated use strict (#1423)#

For code like

"use strict";
import { arrayUtilities } from "necessary";
const { second } = arrayUtilities;
const elements = [1, 2, 3],
secondElement = second(elements);
console.log(secondElement);

swc now emits

"use strict";
var _necessary = require("necessary");
var second = _necessary.arrayUtilities.second;
var elements = [1, 2, 3],
secondElement = second(elements);
console.log(secondElement);

In previous versions, the 'use strict' directive was emitted twice.

\r\n in template literals (#1450)#

Previously swc miscompiled the code below.

import { MultipartReader } from "https://deno.land/[email protected]/mime/multipart.ts";
import { StringReader } from "https://deno.land/[email protected]/io/readers.ts";
// carriage returns added for running on POSIX, not needed if on windows
const content = `--------------------------366796e1c748a2fb\r
Content-Disposition: form-data; name="payload"\r
Content-Type: text/plain\r
\r
CONTENT\r
--------------------------366796e1c748a2fb--`;
const boundary = "------------------------366796e1c748a2fb";
const stringReader = new StringReader(content);
const multipartReader = new MultipartReader(stringReader, boundary);
const formData = await multipartReader.readForm();
for (const entry of formData.entries()) {
console.log("entry", entry);
}
console.log("formdata", formData);

\r\n in template literals was previously parsed as \n, but it's now parsed as \r\n.

bundler: Many improvements (#1427)#

The bundler of the swc can now handle much more codes. Various bugs are reported via deno and those are all fixed.

New option to prserve class name (#1279)#

To bypass restrictions of rust, swc uses a trick named span hygiene. It modifies identifier at the end to prevent conflict between identifiers. But this operation can be problematic if the name of class matters.

For example,

class MyClass {
prop = 1;
}
function Decorator(): PropertyDecorator {
return () => undefined;
}
class MyDecoratedClass {
@Decorator() prop = 1;
}
console.log(MyClass.name, MyDecoratedClass.name);

depends on the class name.

swc now has an option to preserve class name. See the documentation for .swcrc.

Fix for switch statements in loops (#1415)#

When targeting es3 or es5, swc broke some codes with switch statements in for loops like

export function test(items) {
const infoMap = new WeakMap();
for (let i = 0; i < items.length; i += 1) {
const item = items[i];
let info;
switch (item.type) {
case "branch1":
info = item.method1();
break;
case "branch2":
info = item.method2();
break;
case "branch3":
info = item.method3(
Object.fromEntries(
item.subItems.map((t) => [item.alias ?? t.name, getInfo(t)])
)
);
break;
default:
throw new Error("boom");
}
infoMap.set(item, info); // important
}
function getInfo(item) {
if (!infoMap.has(item)) {
throw new Error("no info yet");
}
return infoMap.get(item);
}
}

It is now fixed.

New features#

.swcrc option to enable sourcemps. (#1309)#

Previously generating sourcemap required calling apis with proper option. But now swc has an option to enable sourcemap. See the documentation for .swcrc.

@babel/preset-modules (#1439)#

Thanks to @devongovett, swc now has an option to enable bugfix transforms, just like preset-modules of babel.

bugfix/transform-async-arrows-in-class, bugfix/transform-edge-default-parameters and bugfix/transform-tagged-template-caching is added.