dfreeman / ember-cli-babel-plugin-helpers

Utilities for managing Babel plugins in Ember CLI apps and addons
4 stars 1 forks source link

Ability to search for duplicate given a custom name? #5

Open rwjblue opened 5 years ago

rwjblue commented 5 years ago

Consider the following babel plugin config:

babel: {
  plugins: [
    [require.resolve('some-thing-here'), { option: true }, 'something-here:true'],
  ]
}

We cannot use the utilities in this library to decide if we want to add:

[require.resolve('some-thing-here'), { option: false }, 'something-here:false']

Which is a perfectly valid babel configuration. A prime example here is in ember-cli-babel where we add babel-plugin-debug-macros twice with different config (the module to use for replacements).

I'm not sure what the prime API here is, but I'd suspect that we allow the plugin option to be the array we may want to add and search for both the plugin name (the require.resolve bits in my example above) and the third argument in the array (the customized name).

Thoughts?

dfreeman commented 5 years ago

This shortcoming was at the back of my mind when I originally implemented these utilities, but I couldn't decide what would feel best from an API perspective so I decided to punt until someone actually needed it 🙂

Allowing the full array to be passed in would definitely work; my only worry is that might feel to callers like it should also be checking equality on the configuration object in the middle. We could go with something like one of these options:

hasPlugin(target, 'some-thing-here', 'something-here:true');
hasPlugin(target, 'some-thing-here', { name: 'something-here:true' })

But the downside there is it's more API surface area to manage and it's a sort of impedance mismatch with the regular Babel plugin config format.

The very simplest approach on this side that would avoid committing to much of anything would be to add findPlugins(target, plugin) that returns all configuration found for that plugin instead of just the first one. Then you could write something like this:

let existing = findPlugins(target, 'some-thing-here');
if (!existing.some(plugin => plugin[2] === 'something-here:false')) {
  addPlugin(target, [require.resolve('some-thing-here'), config, 'something-here:false');
}

In the end I don't feel super strongly and would be happy to accept a PR adding either your original suggestion or one of the options here.

rwjblue commented 5 years ago

Ya, in https://github.com/pzuraq/ember-compatibility-helpers/pull/36 I decided to only check for the name (because that worked well for the specific use case), but I totally agree that in the general case the problem is quite a bit harder.