Babel plugins run order
Asked Answered
P

2

18

TL;DR: Is there a way how to specify the order in which the Babel plugins are supposed to be run? How does Babel determine this order? Is there any spec how this works apart from diving into Babel sources?

I'm developing my own Babel plugin. I noticed, that when I run it, my plugin is run before other es2015 plugins. For example having code such as:

const a = () => 1

and visitor such as:

visitor: {
  ArrowFunctionExpression(path) {
    console.log('ArrowFunction')
  },
  FunctionExpression(path) {
    console.log('Function')
  },
}

my plugin observes ArrowFunction (and not Function). I played with the order in which the plugins are listed in Babel configuration, but that didn't change anything:

plugins: ['path_to_myplugin', 'transform-es2015-arrow-functions'],
plugins: ['transform-es2015-arrow-functions', 'path_to_myplugin'],

OTOH, this looks like the order DOES somehow matter:

https://phabricator.babeljs.io/T6719

---- EDIT ----

I found out that if I write my visitor as follows:

  ArrowFunctionExpression: {
    enter(path) {
      console.log('ArrowFunction')
    }
  },
  FunctionExpression: {
    exit(path) {
      console.log('Function')
    }
  },

both functions are called. So it looks like the order of execution is: myplugin_enter -> other_plugin -> myplugin_exit. In other words, myplugin seems to be before other_plugin in some internal pipeline. The main question however stays the same - the order of plugins in the pipeline should be determined & configurable somehow.

Phlegethon answered 5/1, 2016 at 18:27 Comment(0)
E
19

The order of plugins is based on the order of things in your .babelrc with plugins running before presets, and each group running later plugins/presets before earlier ones.

The key thing though is that the ordering is per AST Node. Each plugin does not do a full traversal, Babel does a single traversal running all plugins in parallel, with each node processed one at a time running each handler for each plugin.

Expressionism answered 5/1, 2016 at 19:58 Comment(6)
Thanks, but even with my .babelrc disabled and my 'plugin order' such as plugins: ['transform-es2015-arrow-functions', 'path_to_myplugin'], transform-es2015-arrow-functions's enter function is obviously called AFTER myplugin's enter function. Why is this so? Is there a way to configure the plugin order in babel (apart from dealing with presets, which is not very granular kind of control)?Phlegethon
Also, you wrote '... and each group running later plugins/presets before earlier ones.'. Could you please explain, what you mean by 'group'?Phlegethon
I have a similar situation. Do you have another visitor function in a higher scope, possibly for Program that calls path.traverse with your actual visitors? I imagine this would be called first than.Lammas
@Expressionism - I see the plugins run in order. gist.github.com/jamestalmage/…Courtship
I'm getting non-deterministic errors with webpack's UglifyJs plugin sometimes failing because a lambda didn't get transformed into a function. Really wondering what's going on XDEphemera
I found this not true at least for Babel 6.26.3 and above. From babeljs.io/docs/en/6.26.3/plugins#plugin-preset-ordering, Plugin ordering is first to last., and the same for latest. This answer seems to be 2 months after Babel 6.0.0 release. I'm not sure what version this answer applied to. I didn't track whether Babel has changed this behavior.Clyve
P
8

Basically, what @loganfsmyth wrote is correct; there is (probably) no more magic in plugin ordering itself.

As for the my problem specifically, my confusion was caused by how arrow function transformation works. Even if the babel-plugin-transform-es2015-arrow-functions plugin mangles the code sooner than my plugin, it does not remove the original arrow-function ast node from the ast, so even the later plugin sees it.

Learning: when dealing with Babel, don't underestimate the amount of debug print statements needed to understand what's happening.

Phlegethon answered 28/2, 2016 at 14:29 Comment(2)
Learning: forget about having a normal social life, in your first year or two of learning(I'm being generous here), if you have little previous experience.Angelangela
Simply use AST Explorer.Funiculate

© 2022 - 2024 — McMap. All rights reserved.