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

decorator-transforms

v2.3.0

Published

Better babel transforms for decorators

Downloads

504,685

Readme

decorator-transforms

Better babel transforms for decorators.

Why?

A transform like @babel/plugin-proposal-decorators is still often necessary because it took Decorators a long time to move through the TC39 standardization process. But we can implement the same functionality in a much simpler way now that we can rely on the presence of features like class static block, private fields, and WeakMap. This results in significantly smaller code and avoids the need to transpile other class features.

Status

This is in use in several large, legacy codebases. As far as I can tell, it implements the complete API surface of ['@babel/plugin-proposal-decorators', { legacy: true }]. Please report any differences, we aim for bug-for-bug compatibility.

Browser Support

Under our default settings, browsers will need to support

  • private fields
  • static blocks
  • WeakMap

If you use the runEarly: true option (see below) in conjunction with an appropriately-configured @babel/preset-env, browsers will only need to support

  • WeakMap

Options

runtime

The runtime option controls how the emitted code will find the (small) runtime helper module. You can set it to:

  • "globals" (default), which means the helpers must be installed in a global variable. You can install them by adding import "decorator-transform/globals" at the very beginning of your app.
  • { import: "some-module-path" }, which means the helpers will be imported as needed from the module path you specify. The module path "decorator-transforms/runtime" is available within this package for this purpose, but keep in mind that it might not always work if you're transpiling third-party dependencies that cannot necessarily resolve your app's dependencies. In that case you might want to require.resolve it to an absolute path instead.

Example Config:

{
  plugins: [
    [
      'decorator-transforms',
      {
        runtime: {
          import: require.resolve('decorator-transforms/runtime'),
        },
      },
    ],
  ];
}

runEarly

By default, decorator-transforms runs like any normal babel plugin. This works fine when you're targeting any browsers that natively support private fields and static blocks.

But if you try to transpile away private fields or static blocks, the fairly aggressive timing of those transforms in @babel/preset-env means that they will run first and

  1. Incorrectly tell you to install @babel/plugin-transform-decorators (which you don't need because you have decorator-transforms).
  2. Fail to transpile-away the private fields and static blocks emitted by decorator-transforms.

The solution to both problems is setting runEarly: true on decorator-transforms. This setting is not the default because it does incur the cost of an extra traversal in babel's pre phase.

A Note on Naming Conventions

If you try to use the string name "decorator-transforms" in a babel config file, babel will assume you mean the NPM package "babel-plugin-decorator-transforms". This is a terrible convention. The solution is to use the string "module:decorator-transforms" instead.

Trying this in an Ember App

  1. Install the decorator-transforms package.

  2. In ember-cli-build.js:

    new EmberApp(defaults, {
      'ember-cli-babel': {
         // turn off the old transform
         // (for this to work when using Embroider you need https://github.com/embroider-build/embroider/pull/1673)
         disableDecoratorTransforms: true,
       },
       babel: {
         plugins: [
           // add the new transform.
           require.resolve('decorator-transforms'),
         ],
       },
    )
  3. At the beginning of app.js, install the global runtime helpers:

    import 'decorator-transforms/globals';

    In classic builds, "globals" is the only runtime setting that works because ember-auto-import cannot see the output of this babel transform.

    In Embroider (post https://github.com/embroider-build/embroider/pull/1673), you can use runtime: { import: require.resolve("decorator-transforms/runtime") } and then you don't need to manually install the globals.