NickHeiner / jscodemod

Codemod runner
MIT License
41 stars 4 forks source link

Support complete babel options #28

Open tquetano-netflix opened 3 years ago

tquetano-netflix commented 3 years ago

Currently, you can pass in presets to help parse the code to transform, but this is inherently limiting. babelCore.transformSync supports a well-documented set of options, and ideally all would be supported.

A couple of ideas:

  1. Instead of presets, provide a babelTransformOptions option, which is a static object that is merged internally with the native options.
  2. Provide a getBabelOptions option, which accepts a callback which receives the default parameters and returns the merged options to use.

Of the two, I prefer (1) because it is approachable (for most people, just copy-and-paste their .babelrc / babel.config.js) and clear (an object with presets as the only property instead of just presets provides parity with current implementation, and is still easy to grok). It also maintains complete control over how those options are merged. The only reason I offered (2) is because it allows conditional options building on a per-file basis, which may be something desirable for large-scale codebases that want to build a central utility for disparate codemods.

If you like the idea, I can put together a PR.

NickHeiner commented 3 years ago

Hmmm, yeah, I think it would be better to provide full babelTransformOptions support. I would like jscodemod to be as decoupled from Babel as possible. Right now, knowing about presets in particular is more coupled; if the API were just "the codemod defines the second arg to babelTransformOptions and jscodemod passes it through", that's less coupled.

Are there any particular use-cases you have in mind?

What would the new codemod API look like? (e.g. would getPlugin be replaced with something else?) Maybe it looks something like:

codemod = {
  getBabelTransformOptions({filePath, fileContents}) {
  }
}

The thing I can think of as being a little tricky is where jscodemod is coupled to the babel transform options, which I think comes entirely from the necessity of configuring the options a certain way to use Recast:

https://github.com/NickHeiner/jscodemod/blob/719257870efb8a387d646aa694d8e07bb89ff5f5/src/run-codemod-on-file.ts#L139-L159

I would want to avoid any surprising API behavior there, like "the codemod can pass ast but it'll be ignored".

tquetano-netflix commented 3 years ago

Honestly, going the babelTransformOptions direction, I wouldn't expect much in the API to change. Basically just a replacement for the existing presets. Internally the merge behavior would need to be a bit more bespoke, but that is about it.

I wouldn't worry about things being "overly-coupled"; the primary benefit of this software is the ability to use Babel, so embracing it while also trying to avoid appearances of being coupled to it seem a bit contradictory. I would instead lean into transparency.