| 1 | <div align="center">
|
|---|
| 2 | <h1>babel-plugin-macros π£</h1>
|
|---|
| 3 |
|
|---|
| 4 | <p>Allows you to build simple compile-time libraries</p>
|
|---|
| 5 | </div>
|
|---|
| 6 |
|
|---|
| 7 | ---
|
|---|
| 8 |
|
|---|
| 9 | <!-- prettier-ignore-start -->
|
|---|
| 10 | [![Build Status][build-badge]][build]
|
|---|
| 11 | [![Code Coverage][coverage-badge]][coverage]
|
|---|
| 12 | [![version][version-badge]][package]
|
|---|
| 13 | [![downloads][downloads-badge]][npmtrends]
|
|---|
| 14 | [![MIT License][license-badge]][license]
|
|---|
| 15 | [![All Contributors][all-contributors-badge]](#contributors-)
|
|---|
| 16 | [![PRs Welcome][prs-badge]][prs]
|
|---|
| 17 | [![Code of Conduct][coc-badge]][coc]
|
|---|
| 18 | <!-- prettier-ignore-end -->
|
|---|
| 19 |
|
|---|
| 20 | ## The problem
|
|---|
| 21 |
|
|---|
| 22 | Check out
|
|---|
| 23 | [this guest post](https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros)
|
|---|
| 24 | on the Babel.js blog for a complete write up on the problem, motivation, and
|
|---|
| 25 | solution.
|
|---|
| 26 |
|
|---|
| 27 | Currently, each babel plugin in the babel ecosystem requires that you configure
|
|---|
| 28 | it individually. This is fine for things like language features, but can be
|
|---|
| 29 | frustrating overhead for libraries that allow for compile-time code
|
|---|
| 30 | transformation as an optimization.
|
|---|
| 31 |
|
|---|
| 32 | ## This solution
|
|---|
| 33 |
|
|---|
| 34 | babel-plugin-macros defines a standard interface for libraries that want to use
|
|---|
| 35 | compile-time code transformation without requiring the user to add a babel
|
|---|
| 36 | plugin to their build system (other than `babel-plugin-macros`, which is ideally
|
|---|
| 37 | already in place).
|
|---|
| 38 |
|
|---|
| 39 | <details>
|
|---|
| 40 |
|
|---|
| 41 | <summary>Expand for more details on the motivation</summary>
|
|---|
| 42 |
|
|---|
| 43 | For instance, many css-in-js libraries have a css tagged template string
|
|---|
| 44 | function:
|
|---|
| 45 |
|
|---|
| 46 | ```js
|
|---|
| 47 | const styles = css`
|
|---|
| 48 | .red {
|
|---|
| 49 | color: red;
|
|---|
| 50 | }
|
|---|
| 51 | `
|
|---|
| 52 | ```
|
|---|
| 53 |
|
|---|
| 54 | The function compiles your css into (for example) an object with generated class
|
|---|
| 55 | names for each of the classes you defined in your css:
|
|---|
| 56 |
|
|---|
| 57 | ```js
|
|---|
| 58 | console.log(styles) // { red: "1f-d34j8rn43y587t" }
|
|---|
| 59 | ```
|
|---|
| 60 |
|
|---|
| 61 | This class name can be generated at runtime (in the browser), but this has some
|
|---|
| 62 | disadvantages:
|
|---|
| 63 |
|
|---|
| 64 | - There is cpu usage/time overhead; the client needs to run the code to generate
|
|---|
| 65 | these classes every time the page loads
|
|---|
| 66 | - There is code bundle size overhead; the client needs to receive a CSS parser
|
|---|
| 67 | in order to generate these class names, and shipping this makes the amount of
|
|---|
| 68 | js the client needs to parse larger.
|
|---|
| 69 |
|
|---|
| 70 | To help solve those issues, many css-in-js libraries write their own babel
|
|---|
| 71 | plugin that generates the class names at compile-time instead of runtime:
|
|---|
| 72 |
|
|---|
| 73 | ```js
|
|---|
| 74 | // Before running through babel:
|
|---|
| 75 | const styles = css`
|
|---|
| 76 | .red {
|
|---|
| 77 | color: red;
|
|---|
| 78 | }
|
|---|
| 79 | `
|
|---|
| 80 | // After running through babel, with the library-specific plugin:
|
|---|
| 81 | const styles = {red: '1f-d34j8rn43y587t'}
|
|---|
| 82 | ```
|
|---|
| 83 |
|
|---|
| 84 | If the css-in-js library supported babel-plugin-macros instead, then they
|
|---|
| 85 | wouldn't need their own babel plugin to compile these out; they could instead
|
|---|
| 86 | rely on babel-plugin-macros to do it for them. So if a user already had
|
|---|
| 87 | `babel-plugin-macros` installed and configured with babel, then they wouldn't
|
|---|
| 88 | need to change their babel configuration to get the compile-time benefits of the
|
|---|
| 89 | library. This would be most useful if the boilerplate they were using came with
|
|---|
| 90 | `babel-plugin-macros` out of the box, which is true for
|
|---|
| 91 | [`create-react-app`][cra].
|
|---|
| 92 |
|
|---|
| 93 | Although css-in-js is the most common example, there are lots of other things
|
|---|
| 94 | you could use `babel-plugin-macros` for, like:
|
|---|
| 95 |
|
|---|
| 96 | - Compiling GraphQL fragments into objects so that the client doesn't need a
|
|---|
| 97 | GraphQL parser
|
|---|
| 98 | - Eval-ing out code at compile time that will be baked into the runtime code,
|
|---|
| 99 | for instance to get a list of directories in the filesystem (see
|
|---|
| 100 | [preval][preval])
|
|---|
| 101 |
|
|---|
| 102 | </details>
|
|---|
| 103 |
|
|---|
| 104 | ## Table of Contents
|
|---|
| 105 |
|
|---|
| 106 | <!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|---|
| 107 | <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|---|
| 108 |
|
|---|
| 109 | - [Installation](#installation)
|
|---|
| 110 | - [Usage](#usage)
|
|---|
| 111 | - [User docs](#user-docs)
|
|---|
| 112 | - [Author docs](#author-docs)
|
|---|
| 113 | - [Caveats](#caveats)
|
|---|
| 114 | - [FAQ](#faq)
|
|---|
| 115 | - [How do I find available macros?](#how-do-i-find-available-macros)
|
|---|
| 116 | - [What's the difference between babel plugins and macros?](#whats-the-difference-between-babel-plugins-and-macros)
|
|---|
| 117 | - [In what order are macros executed?](#in-what-order-are-macros-executed)
|
|---|
| 118 | - [Does it work with function calls only?](#does-it-work-with-function-calls-only)
|
|---|
| 119 | - [How about implicit optimizations at compile time?](#how-about-implicit-optimizations-at-compile-time)
|
|---|
| 120 | - [Inspiration](#inspiration)
|
|---|
| 121 | - [Other Solutions](#other-solutions)
|
|---|
| 122 | - [Issues](#issues)
|
|---|
| 123 | - [π Bugs](#-bugs)
|
|---|
| 124 | - [π‘ Feature Requests](#-feature-requests)
|
|---|
| 125 | - [Contributors β¨](#contributors-)
|
|---|
| 126 | - [LICENSE](#license)
|
|---|
| 127 |
|
|---|
| 128 | <!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|---|
| 129 |
|
|---|
| 130 | ## Installation
|
|---|
| 131 |
|
|---|
| 132 | This module is distributed via [npm][npm] which is bundled with [node][node] and
|
|---|
| 133 | should be installed as one of your project's `devDependencies`:
|
|---|
| 134 |
|
|---|
| 135 | ```
|
|---|
| 136 | npm install --save-dev babel-plugin-macros
|
|---|
| 137 | ```
|
|---|
| 138 |
|
|---|
| 139 | ## Usage
|
|---|
| 140 |
|
|---|
| 141 | > You may like to watch
|
|---|
| 142 | > [this YouTube video](https://www.youtube.com/watch?v=1queadQ0048&list=PLV5CVI1eNcJgCrPH_e6d57KRUTiDZgs0u)
|
|---|
| 143 | > to get an idea of what macros is and how it can be used.
|
|---|
| 144 |
|
|---|
| 145 | ### User docs
|
|---|
| 146 |
|
|---|
| 147 | Are you trying to use `babel-plugin-macros`? Go to
|
|---|
| 148 | [`other/docs/user.md`](other/docs/user.md).
|
|---|
| 149 |
|
|---|
| 150 | ### Author docs
|
|---|
| 151 |
|
|---|
| 152 | Are you trying to make your own macros that works with `babel-plugin-macros`? Go
|
|---|
| 153 | to [`other/docs/author.md`](other/docs/author.md). (you should probably read the
|
|---|
| 154 | user docs too).
|
|---|
| 155 |
|
|---|
| 156 | ### Caveats
|
|---|
| 157 |
|
|---|
| 158 | #### Babel cache problem
|
|---|
| 159 |
|
|---|
| 160 | > **Note:** This issue is not present when used in Create React App.
|
|---|
| 161 |
|
|---|
| 162 | Most of the time you'll probably be using this with the babel cache enabled in
|
|---|
| 163 | webpack to rebuild faster. If your macro function is **not pure** which gets
|
|---|
| 164 | different output with same code (e.g., IO side effects) it will cause recompile
|
|---|
| 165 | mechanism fail. Unfortunately you'll also experience this problem while
|
|---|
| 166 | developing your macro as well. If there's not a change to the source code that's
|
|---|
| 167 | being transpiled, then babel will use the cache rather than running your macro
|
|---|
| 168 | again.
|
|---|
| 169 |
|
|---|
| 170 | For now, to force recompile the code you can simply add a cache busting comment
|
|---|
| 171 | in the file:
|
|---|
| 172 |
|
|---|
| 173 | ```diff
|
|---|
| 174 | import macro from 'non-pure.macro';
|
|---|
| 175 |
|
|---|
| 176 | -// Do some changes of your code or
|
|---|
| 177 | +// add a cache busting comment to force recompile.
|
|---|
| 178 | macro('parameters');
|
|---|
| 179 | ```
|
|---|
| 180 |
|
|---|
| 181 | This problem is still being worked on and is not unique to
|
|---|
| 182 | `babel-plugin-macros`. For more details and workarounds, please check related
|
|---|
| 183 | issues below:
|
|---|
| 184 |
|
|---|
| 185 | - babel-plugin-preval:
|
|---|
| 186 | [How to force recompile? #19](https://github.com/kentcdodds/babel-plugin-preval/issues/19)
|
|---|
| 187 | - graphql.macro:
|
|---|
| 188 | [Recompile problem (babel cache) #6](https://github.com/evenchange4/graphql.macro/issues/6)
|
|---|
| 189 | - twin.macro:
|
|---|
| 190 | [Can't change taliwind config #37](https://github.com/ben-rogerson/twin.macro/discussions/37)
|
|---|
| 191 |
|
|---|
| 192 | ## FAQ
|
|---|
| 193 |
|
|---|
| 194 | ### How do I find available macros?
|
|---|
| 195 |
|
|---|
| 196 | You can write your own without publishing them to `npm`, but if you'd like to
|
|---|
| 197 | see existing macros you can add to your project, then take a look at the
|
|---|
| 198 | [Awesome babel macros](https://github.com/jgierer12/awesome-babel-macros)
|
|---|
| 199 | repository.
|
|---|
| 200 |
|
|---|
| 201 | Please add any you don't see listed!
|
|---|
| 202 |
|
|---|
| 203 | ### What's the difference between babel plugins and macros?
|
|---|
| 204 |
|
|---|
| 205 | Let's use
|
|---|
| 206 | [`babel-plugin-console`](https://www.npmjs.com/package/babel-plugin-console) as
|
|---|
| 207 | an example.
|
|---|
| 208 |
|
|---|
| 209 | If we used `babel-plugin-console`, it would look like this:
|
|---|
| 210 |
|
|---|
| 211 | 1. Add `babel-plugin-console` to `.babelrc`
|
|---|
| 212 | 2. Use it in a code:
|
|---|
| 213 |
|
|---|
| 214 | ```js
|
|---|
| 215 | function add100(a) {
|
|---|
| 216 | const oneHundred = 100
|
|---|
| 217 | console.scope('Add 100 to another number')
|
|---|
| 218 | return add(a, oneHundred)
|
|---|
| 219 | }
|
|---|
| 220 |
|
|---|
| 221 | function add(a, b) {
|
|---|
| 222 | return a + b
|
|---|
| 223 | }
|
|---|
| 224 | ```
|
|---|
| 225 |
|
|---|
| 226 | When that code is run, the `scope` function does some pretty nifty things:
|
|---|
| 227 |
|
|---|
| 228 | **Browser:**
|
|---|
| 229 |
|
|---|
| 230 | 
|
|---|
| 231 |
|
|---|
| 232 | **Node:**
|
|---|
| 233 |
|
|---|
| 234 | <img alt="Node console scoping add100" src="https://github.com/mattphillips/babel-plugin-console/raw/53536cba919d5be49d4f66d957769c07ca7a4207/assets/add100-node.png" width="372" />
|
|---|
| 235 |
|
|---|
| 236 | Instead, let's use the macro it's shipped with like this:
|
|---|
| 237 |
|
|---|
| 238 | 1. Add `babel-plugin-macros` to `.babelrc` (only once for all macros)
|
|---|
| 239 | 2. Use it in a code:
|
|---|
| 240 |
|
|---|
| 241 | ```js
|
|---|
| 242 | import scope from 'babel-plugin-console/scope.macro'
|
|---|
| 243 | function add100(a) {
|
|---|
| 244 | const oneHundred = 100
|
|---|
| 245 | scope('Add 100 to another number')
|
|---|
| 246 | return add(a, oneHundred)
|
|---|
| 247 | }
|
|---|
| 248 |
|
|---|
| 249 | function add(a, b) {
|
|---|
| 250 | return a + b
|
|---|
| 251 | }
|
|---|
| 252 | ```
|
|---|
| 253 |
|
|---|
| 254 | The result is exactly the same, but this approach has a few advantages:
|
|---|
| 255 |
|
|---|
| 256 | **Advantages:**
|
|---|
| 257 |
|
|---|
| 258 | - requires only one entry in `.babelrc` for all macros used in project. Add that
|
|---|
| 259 | once and you can use all the macros you want
|
|---|
| 260 | - toolkits (like [create-react-app][cra]) may already support
|
|---|
| 261 | `babel-plugin-macros`, so no configuration is needed at all
|
|---|
| 262 | - it's explicit. With `console.scope` people may be fooled that it's just a
|
|---|
| 263 | normal `console` API when there's really a babel transpilation going on. When
|
|---|
| 264 | you import `scope`, it's obvious that it's macro and does something with the
|
|---|
| 265 | code at compile time. Some ESLint rules may also have issues with plugins that
|
|---|
| 266 | look for "global" variables
|
|---|
| 267 | - macros are safer and easier to write, because they receive exactly the AST
|
|---|
| 268 | node to process
|
|---|
| 269 | - If you misconfigure `babel-plugin-console` you wont find out until you run the
|
|---|
| 270 | code. If you misconfigure `babel-plugin-macros` you'll get a compile-time
|
|---|
| 271 | error.
|
|---|
| 272 |
|
|---|
| 273 | **Drawbacks:**
|
|---|
| 274 |
|
|---|
| 275 | - Cannot (should not) be used for implicit transpilations (like syntax plugins)
|
|---|
| 276 | - Explicitness is more verbose. Which some people might consider a drawback...
|
|---|
| 277 |
|
|---|
| 278 | ### In what order are macros executed?
|
|---|
| 279 |
|
|---|
| 280 | This is another advantage of `babel-plugin-macros` over regular plugins. The
|
|---|
| 281 | user of the macro is in control of the ordering! The order of execution is the
|
|---|
| 282 | same order as imported. The order of execution is clear, explicit and in full
|
|---|
| 283 | control of the user:
|
|---|
| 284 |
|
|---|
| 285 | ```js
|
|---|
| 286 | import preval from 'preval.macro'
|
|---|
| 287 | import idx from 'idx.macro'
|
|---|
| 288 |
|
|---|
| 289 | // preval macro is evaluated first, then idx
|
|---|
| 290 | ```
|
|---|
| 291 |
|
|---|
| 292 | This differs from the current situation with babel plugins where it's
|
|---|
| 293 | prohibitively difficult to control the order plugins run in a particular file.
|
|---|
| 294 |
|
|---|
| 295 | ### Does it work with function calls only?
|
|---|
| 296 |
|
|---|
| 297 | No! Any AST node type is supported.
|
|---|
| 298 |
|
|---|
| 299 | It can be tagged template literal:
|
|---|
| 300 |
|
|---|
| 301 | ```js
|
|---|
| 302 | import eval from 'eval.macro'
|
|---|
| 303 | const val = eval`7 * 6`
|
|---|
| 304 | ```
|
|---|
| 305 |
|
|---|
| 306 | A function:
|
|---|
| 307 |
|
|---|
| 308 | ```js
|
|---|
| 309 | import eval from 'eval.macro'
|
|---|
| 310 | const val = eval('7 * 6')
|
|---|
| 311 | ```
|
|---|
| 312 |
|
|---|
| 313 | JSX Element:
|
|---|
| 314 |
|
|---|
| 315 | ```js
|
|---|
| 316 | import Eval from 'eval.macro'
|
|---|
| 317 | const val = <Eval>7 * 6</Eval>
|
|---|
| 318 | ```
|
|---|
| 319 |
|
|---|
| 320 | Really, anything...
|
|---|
| 321 |
|
|---|
| 322 | See the [testing snapshot](src/__tests__/__snapshots__/index.js.snap) for more
|
|---|
| 323 | examples.
|
|---|
| 324 |
|
|---|
| 325 | ### How about implicit optimizations at compile time?
|
|---|
| 326 |
|
|---|
| 327 | All examples above were _explicit_ - a macro was imported and then evaluated
|
|---|
| 328 | with a specific AST node.
|
|---|
| 329 |
|
|---|
| 330 | Completely different story are _implicit_ babel plugins, like
|
|---|
| 331 | [transform-react-constant-elements](https://babeljs.io/docs/plugins/transform-react-constant-elements/),
|
|---|
| 332 | which process whole AST tree.
|
|---|
| 333 |
|
|---|
| 334 | Explicit is often a better pattern than implicit because it requires others to
|
|---|
| 335 | understand how things are globally configured. This is in this spirit are
|
|---|
| 336 | `babel-plugin-macros` designed. However, some things _do_ need to be implicit,
|
|---|
| 337 | and those kinds of babel plugins can't be turned into macros.
|
|---|
| 338 |
|
|---|
| 339 | ## Inspiration
|
|---|
| 340 |
|
|---|
| 341 | - [threepointone/babel-plugin-macros](https://github.com/threepointone/babel-plugin-macros)
|
|---|
| 342 | - [facebookincubator/create-react-app#2730][cra-issue]
|
|---|
| 343 |
|
|---|
| 344 | Thank you to [@phpnode](https://github.com/phpnode) for donating the npm package
|
|---|
| 345 | `babel-plugin-macros`.
|
|---|
| 346 |
|
|---|
| 347 | ## Other Solutions
|
|---|
| 348 |
|
|---|
| 349 | - [sweetjs](http://sweetjs.org/)
|
|---|
| 350 |
|
|---|
| 351 | ## Issues
|
|---|
| 352 |
|
|---|
| 353 | _Looking to contribute? Look for the [Good First Issue][good-first-issue]
|
|---|
| 354 | label._
|
|---|
| 355 |
|
|---|
| 356 | ### π Bugs
|
|---|
| 357 |
|
|---|
| 358 | Please file an issue for bugs, missing documentation, or unexpected behavior.
|
|---|
| 359 |
|
|---|
| 360 | [**See Bugs**][bugs]
|
|---|
| 361 |
|
|---|
| 362 | ### π‘ Feature Requests
|
|---|
| 363 |
|
|---|
| 364 | Please file an issue to suggest new features. Vote on feature requests by adding
|
|---|
| 365 | a π. This helps maintainers prioritize what to work on.
|
|---|
| 366 |
|
|---|
| 367 | [**See Feature Requests**][requests]
|
|---|
| 368 |
|
|---|
| 369 | ## Contributors β¨
|
|---|
| 370 |
|
|---|
| 371 | Thanks goes to these people ([emoji key][emojis]):
|
|---|
| 372 |
|
|---|
| 373 | <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|---|
| 374 | <!-- prettier-ignore-start -->
|
|---|
| 375 | <!-- markdownlint-disable -->
|
|---|
| 376 | <table>
|
|---|
| 377 | <tr>
|
|---|
| 378 | <td align="center"><a href="https://kentcdodds.com"><img src="https://avatars.githubusercontent.com/u/1500684?v=3?s=100" width="100px;" alt=""/><br /><sub><b>Kent C. Dodds</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=kentcdodds" title="Code">π»</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=kentcdodds" title="Documentation">π</a> <a href="#infra-kentcdodds" title="Infrastructure (Hosting, Build-Tools, etc)">π</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=kentcdodds" title="Tests">β οΈ</a></td>
|
|---|
| 379 | <td align="center"><a href="https://github.com/threepointone"><img src="https://avatars1.githubusercontent.com/u/18808?v=3?s=100" width="100px;" alt=""/><br /><sub><b>Sunil Pai</b></sub></a><br /><a href="#ideas-threepointone" title="Ideas, Planning, & Feedback">π€</a></td>
|
|---|
| 380 | <td align="center"><a href="http://suchipi.com"><img src="https://avatars0.githubusercontent.com/u/1341513?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lily Scott</b></sub></a><br /><a href="#question-suchipi" title="Answering Questions">π¬</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=suchipi" title="Documentation">π</a></td>
|
|---|
| 381 | <td align="center"><a href="http://twitter.com/dralletje"><img src="https://avatars1.githubusercontent.com/u/767261?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michiel Dral</b></sub></a><br /><a href="#ideas-dralletje" title="Ideas, Planning, & Feedback">π€</a></td>
|
|---|
| 382 | <td align="center"><a href="https://github.com/tkh44"><img src="https://avatars2.githubusercontent.com/u/662750?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kye Hohenberger</b></sub></a><br /><a href="#ideas-tkh44" title="Ideas, Planning, & Feedback">π€</a></td>
|
|---|
| 383 | <td align="center"><a href="https://hamil.town"><img src="https://avatars1.githubusercontent.com/u/11481355?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mitchell Hamilton</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=mitchellhamilton" title="Code">π»</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=mitchellhamilton" title="Tests">β οΈ</a></td>
|
|---|
| 384 | <td align="center"><a href="https://github.com/wKovacs64"><img src="https://avatars1.githubusercontent.com/u/1288694?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Justin Hall</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=wKovacs64" title="Documentation">π</a></td>
|
|---|
| 385 | </tr>
|
|---|
| 386 | <tr>
|
|---|
| 387 | <td align="center"><a href="https://github.com/PiereDome"><img src="https://avatars3.githubusercontent.com/u/1903016?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brian Pedersen</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=PiereDome" title="Code">π»</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=PiereDome" title="Documentation">π</a></td>
|
|---|
| 388 | <td align="center"><a href="https://github.com/apalm"><img src="https://avatars3.githubusercontent.com/u/4495237?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Palm</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=apalm" title="Code">π»</a></td>
|
|---|
| 389 | <td align="center"><a href="https://michaelhsu.tw/"><img src="https://avatars1.githubusercontent.com/u/1527371?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Hsu</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=evenchange4" title="Documentation">π</a> <a href="#plugin-evenchange4" title="Plugin/utility libraries">π</a></td>
|
|---|
| 390 | <td align="center"><a href="https://github.com/citycide"><img src="https://avatars2.githubusercontent.com/u/16605186?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bo Lingen</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=citycide" title="Code">π»</a></td>
|
|---|
| 391 | <td align="center"><a href="https://github.com/tylerthehaas"><img src="https://avatars1.githubusercontent.com/u/11150235?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tyler Haas</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=tylerthehaas" title="Documentation">π</a></td>
|
|---|
| 392 | <td align="center"><a href="https://github.com/FWeinb"><img src="https://avatars0.githubusercontent.com/u/1250430?v=4?s=100" width="100px;" alt=""/><br /><sub><b>FWeinb</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=FWeinb" title="Code">π»</a></td>
|
|---|
| 393 | <td align="center"><a href="http://www.tomasehrlich.cz"><img src="https://avatars2.githubusercontent.com/u/827862?v=4?s=100" width="100px;" alt=""/><br /><sub><b>TomΓ‘Ε‘ Ehrlich</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/issues?q=author%3Atricoder42" title="Bug reports">π</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=tricoder42" title="Code">π»</a></td>
|
|---|
| 394 | </tr>
|
|---|
| 395 | <tr>
|
|---|
| 396 | <td align="center"><a href="https://github.com/jgierer12"><img src="https://avatars0.githubusercontent.com/u/4331946?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonas Gierer</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=jgierer12" title="Documentation">π</a></td>
|
|---|
| 397 | <td align="center"><a href="http://loicpadier.com"><img src="https://avatars2.githubusercontent.com/u/4009640?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LoΓ―c Padier</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=lPadier" title="Code">π»</a></td>
|
|---|
| 398 | <td align="center"><a href="https://www.pshrmn.com"><img src="https://avatars0.githubusercontent.com/u/1127037?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Paul Sherman</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=pshrmn" title="Code">π»</a></td>
|
|---|
| 399 | <td align="center"><a href="http://burningpotato.com"><img src="https://avatars1.githubusercontent.com/u/540777?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Conrad Buck</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=conartist6" title="Code">π»</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=conartist6" title="Tests">β οΈ</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=conartist6" title="Documentation">π</a></td>
|
|---|
| 400 | <td align="center"><a href="https://github.com/InvictusMB"><img src="https://avatars3.githubusercontent.com/u/3091209?v=4?s=100" width="100px;" alt=""/><br /><sub><b>InvictusMB</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=InvictusMB" title="Tests">β οΈ</a></td>
|
|---|
| 401 | <td align="center"><a href="https://codefund.io"><img src="https://avatars2.githubusercontent.com/u/12481?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eric Berry</b></sub></a><br /><a href="#fundingFinding-coderberry" title="Funding Finding">π</a></td>
|
|---|
| 402 | <td align="center"><a href="http://futagoza.github.io/"><img src="https://avatars1.githubusercontent.com/u/1943570?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Futago-za Ryuu</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=futagoza" title="Code">π»</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=futagoza" title="Tests">β οΈ</a></td>
|
|---|
| 403 | </tr>
|
|---|
| 404 | <tr>
|
|---|
| 405 | <td align="center"><a href="https://luc.im"><img src="https://avatars3.githubusercontent.com/u/6616955?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Luc</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=lucleray" title="Code">π»</a></td>
|
|---|
| 406 | <td align="center"><a href="http://wintercounter.me"><img src="https://avatars2.githubusercontent.com/u/963776?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Victor Vincent</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=wintercounter" title="Code">π»</a></td>
|
|---|
| 407 | <td align="center"><a href="http://mvasilkov.ovh"><img src="https://avatars3.githubusercontent.com/u/140257?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ρ ΠΊΠΎΡΠΈΠΊ ΠΏΡΡ-ΠΏΡΡ</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=mvasilkov" title="Documentation">π</a></td>
|
|---|
| 408 | <td align="center"><a href="http://armandososa.com"><img src="https://avatars0.githubusercontent.com/u/139577?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Armando Sosa</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=soska" title="Documentation">π</a></td>
|
|---|
| 409 | <td align="center"><a href="https://github.com/matvp91"><img src="https://avatars3.githubusercontent.com/u/12699796?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthias</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=matvp91" title="Code">π»</a></td>
|
|---|
| 410 | <td align="center"><a href="https://www.jovidecroock.com/"><img src="https://avatars3.githubusercontent.com/u/17125876?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jovi De Croock</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=JoviDeCroock" title="Code">π»</a> <a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=JoviDeCroock" title="Tests">β οΈ</a></td>
|
|---|
| 411 | <td align="center"><a href="http://victorarowo.com"><img src="https://avatars0.githubusercontent.com/u/25545108?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Victor Arowo</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=VictorArowo" title="Documentation">π</a></td>
|
|---|
| 412 | </tr>
|
|---|
| 413 | <tr>
|
|---|
| 414 | <td align="center"><a href="https://twitter.com/alexandermchan"><img src="https://avatars.githubusercontent.com/u/1864372?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alex Chan</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=alexanderchan" title="Documentation">π</a></td>
|
|---|
| 415 | <td align="center"><a href="https://probablyup.com"><img src="https://avatars.githubusercontent.com/u/570070?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Evan Jacobs</b></sub></a><br /><a href="https://github.com/kentcdodds/babel-plugin-macros/commits?author=probablyup" title="Code">π»</a></td>
|
|---|
| 416 | </tr>
|
|---|
| 417 | </table>
|
|---|
| 418 |
|
|---|
| 419 | <!-- markdownlint-restore -->
|
|---|
| 420 | <!-- prettier-ignore-end -->
|
|---|
| 421 |
|
|---|
| 422 | <!-- ALL-CONTRIBUTORS-LIST:END -->
|
|---|
| 423 |
|
|---|
| 424 | This project follows the [all-contributors][all-contributors] specification.
|
|---|
| 425 | Contributions of any kind welcome!
|
|---|
| 426 |
|
|---|
| 427 | ## LICENSE
|
|---|
| 428 |
|
|---|
| 429 | MIT
|
|---|
| 430 |
|
|---|
| 431 | <!-- prettier-ignore-start -->
|
|---|
| 432 | [npm]: https://www.npmjs.com
|
|---|
| 433 | [node]: https://nodejs.org
|
|---|
| 434 | [build-badge]: https://img.shields.io/github/workflow/status/kentcdodds/babel-plugin-macros/validate?logo=github&style=flat-square
|
|---|
| 435 | [build]: https://github.com/kentcdodds/babel-plugin-macros/actions?query=workflow%3Avalidate
|
|---|
| 436 | [coverage-badge]: https://img.shields.io/codecov/c/github/kentcdodds/babel-plugin-macros.svg?style=flat-square
|
|---|
| 437 | [coverage]: https://codecov.io/github/kentcdodds/babel-plugin-macros
|
|---|
| 438 | [version-badge]: https://img.shields.io/npm/v/babel-plugin-macros.svg?style=flat-square
|
|---|
| 439 | [package]: https://www.npmjs.com/package/babel-plugin-macros
|
|---|
| 440 | [downloads-badge]: https://img.shields.io/npm/dm/babel-plugin-macros.svg?style=flat-square
|
|---|
| 441 | [npmtrends]: http://www.npmtrends.com/babel-plugin-macros
|
|---|
| 442 | [license-badge]: https://img.shields.io/npm/l/babel-plugin-macros.svg?style=flat-square
|
|---|
| 443 | [license]: https://github.com/kentcdodds/babel-plugin-macros/blob/main/LICENSE
|
|---|
| 444 | [prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
|
|---|
| 445 | [prs]: http://makeapullrequest.com
|
|---|
| 446 | [coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square
|
|---|
| 447 | [coc]: https://github.com/kentcdodds/babel-plugin-macros/blob/main/CODE_OF_CONDUCT.md
|
|---|
| 448 | [emojis]: https://github.com/all-contributors/all-contributors#emoji-key
|
|---|
| 449 | [all-contributors]: https://github.com/all-contributors/all-contributors
|
|---|
| 450 | [all-contributors-badge]: https://img.shields.io/github/all-contributors/kentcdodds/babel-plugin-macros?color=orange&style=flat-square
|
|---|
| 451 | [bugs]: https://github.com/kentcdodds/babel-plugin-macros/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+sort%3Acreated-desc+label%3Abug
|
|---|
| 452 | [requests]: https://github.com/kentcdodds/babel-plugin-macros/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3Aenhancement
|
|---|
| 453 | [good-first-issue]: https://github.com/kentcdodds/babel-plugin-macros/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3Aenhancement+label%3A%22good+first+issue%22
|
|---|
| 454 | [preval]: https://github.com/kentcdodds/babel-plugin-preval
|
|---|
| 455 | [cra]: https://github.com/facebook/create-react-app
|
|---|
| 456 | [cra-issue]: https://github.com/facebook/create-react-app/issues/2730
|
|---|
| 457 | <!-- prettier-ignore-end -->
|
|---|