Changelog: swc v1.2.50


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);

swc now emits

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

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 "[email protected]/mime/multipart.ts";
import { StringReader } from "[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
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;

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();
case "branch2":
info = item.method2();
case "branch3":
info = item.method3(
Object.fromEntries( => [item.alias ??, getInfo(t)])
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.