Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support complete babel options #28

Open
tquetano-netflix opened this issue Sep 18, 2021 · 2 comments
Open

Support complete babel options #28

tquetano-netflix opened this issue Sep 18, 2021 · 2 comments

Comments

@tquetano-netflix
Copy link

tquetano-netflix commented Sep 18, 2021

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
Copy link
Owner

NickHeiner commented Sep 18, 2021

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:

const babelOpts = {
...getBabelOpts(),
..._.pick(codemod, 'presets'),
// There are options that are recognized by recast but not babel. Babel errors when they're passed. To avoid
// this, we'll omit them.
..._.omit(
opts,
'jsx', 'loc', 'locations', 'range', 'comment', 'onComment', 'tolerant', 'ecmaVersion'
),
/**
* We must have babel emit tokens. Otherwise, recast will use esprima to tokenize, which won't have the
* user-provided babel config.
*
* https://github.com/benjamn/recast/issues/834
*/
parserOpts: {
tokens: true
}
};
log.trace({babelOpts});
return babelParse(source, babelOpts);

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

@tquetano-netflix
Copy link
Author

tquetano-netflix commented Sep 20, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants