npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

swc-plugin-enum-to-obj

v0.3.0

Published

An SWC plugin to convert TypeScript enums into plain objects!

Downloads

10

Readme

swc-plugin-enum-to-obj

An SWC plugin to convert TypeScript enums into plain objects!

Installation

Install with your favorite package manager as devDependency.

npm i -D swc-plugin-enum-to-obj

Add plugin to wherever you have an SWC config (e.g. .swcrc file, swc-loader config, etc).

This plugin currently has no configuration. However you have to leave an empty object to meet SWC's API schema.

{
  jsc: {
    parser: {
      syntax: 'typescript',
      tsx: true,
    },
    experimental: {
      plugins: [
        ['swc-plugin-enum-to-obj', {}],
      ],
    }
  },
}

Motivation

TypeScript enums are useful if they are used in suitable ways. However the compiled code of enums makes trouble. In order to support enum merging, TypeScript compiles them into IIFEs. I bet most of you won't use this feature, but it pollutes our compiled code.

// Before
export enum SimpleNumber {
  Bar,
  Baz,
}

// TypeScript compiles the above code to:
export var SimpleNumber;
(function(SimpleNumber) {
    SimpleNumber[SimpleNumber["Bar"] = 0] = "Bar";
    SimpleNumber[SimpleNumber["Baz"] = 1] = "Baz";
})(SimpleNumber || (SimpleNumber = {}));

This indeed works. But when you are trying to make a library containing enums, you will notice that enums are NOT tree-shakeable (e.g. rollup, SWC minify).

The compiled IIFE is a side-effect function call as the view of static code analysis. It cannot be safely removed because the analyzer don't have an idea about what it is doing.

Now that we know it is constructing enum objects, we can do this for it. This plugin picks up these compiled enum IIFEs and convert them to object literals.

After converting, bundlers and minifiers will be pleasure to remove all unused object literals for you. (e.g. rollup, SWC minify).

Why convert IIFEs instead of enums themselves? See this issue.

Examples

// Before
enum SimpleNumber {
  Bar,
  Baz,
}

// After
var SimpleNumber = {
  "Bar": 0,
  0: "Bar",
  "Baz": 1,
  1: "Baz"
};
// Before
export enum SimpleString {
  A = 'Z',
  B = 'Y',
}

// After
export var SimpleString = {
  "A": 'Z',
  "B": 'Y'
};

Caveats

  • Enum merging might not work.

    This plugin strictly looks for the "var X + IIFE" pattern. Mergings will be left unchanged.

    // Before
    enum Foo { Bar = 1 }
    enum Foo { Baz = 2 }
    
    // After
    var Foo = {
        "Bar": 1,
        1: "Bar"
    };
    (function(Foo) {
        Foo[Foo["Baz"] = 2] = "Baz";
    })(Foo || (Foo = {}));
  • You might accidently convert enums of external libraries.

    It is a problem caused by converting IIFEs.

    If you are using libraries containing enums, and you make SWC process all node_modules file at the same time, those enums will be converted too because they also match the "var X + IIFE" pattern.

    This should not cause any problems. However I think you should notice this behavior.

  • Enums containing complex caclucations are not supported.

    This plugin strictly looks for number or string literals. However in some cases, SWC left calculation expressions stay in the IIFE. This kind of enums will be left unchanged.

    // Before
    enum Foo {
      A = 3,
      B = 2,
      C = 1,
      X = A ** B ** C,
    }
    
    // After
    var Foo;
    (function(Foo) {
        Foo[Foo["A"] = 3] = "A";
        Foo[Foo["B"] = 2] = "B";
        Foo[Foo["C"] = 1] = "C";
        Foo[Foo["X"] = Foo.A ** Foo.B ** Foo.C] = "X";
    })(Foo || (Foo = {}));
  • const enums are handled by SWC, not this plugin.

    SWC currently converts const enums the same way as normal enums. There will be an enum object as a result.

License

MIT