facebook / facebook/jscodeshift

Interactive Mode

Open
#352 3 comments 4 reactions 0 assignees View on GitHub
improvement
Dominant language
JavaScript
Stars
10k
Forks
498
PR merge metrics
No merged PRs in 30d

Description

![image](https://user-images.githubusercontent.com/829827/68519584-b96b3a80-0246-11ea-99e9-87de383eb102.png)

I'd like to add a way for a human to have input on a codemod. This expands the range of what codemods can do.

For instance, consider the shift from CJS to ESM:

```js
function A() {}
function B() {}
function C() {}
module.exports = { A, B, C};

// Option 1: The three values are standalone
export function A() {}
export function B() {}
export function C() {}

// Option 2: The three values are a single unit
const _export = {A, B, C}
export default _export;
```

Determining which of the two options are preferable would be programmatically prohibitively difficult, if not impossible. But I don't want to fall back to having to handle these cases entirely by hand. If the codemod knows which of the two cases it is, it can still do the rest of the work for me.

My dream is that this is a low-friction task where the user can quickly crank through a bunch of files, when questions are easy for humans to answer but hard for machines.

My suggested API is:

```js
async function transformer(file, api) {
// ...
await api.prompt(node, {
type: 'multiselect',
name: 'namedExports',
message: 'Choose the exports that should be converted to named exports.',
choices: exportNames
});
}
```

`api.prompt` is a wrapper around [`prompts`](https://www.npmjs.com/package/prompts). It applies some codemod-specific logic, like a syntax highlighted snippet of the relevant `node`.

Longer demo:

![interactive codemod](https://user-images.githubusercontent.com/829827/68519497-3ea21f80-0246-11ea-8768-4d42c09be556.gif)

I have a [branch](https://github.com/facebook/jscodeshift/compare/master...NickHeiner:nth/async-transform?expand=1) that produces a demo for this. I created it in a single day, so it's very proof-of-concept. If this fits with your vision of jscodeshift, I'll work to get it into a mergeable state, including exhaustive tests and docs.

## Implementation Notes
1. This requires #254. I could do that as a separate PR.
1. This could become very complicated. I'd like to keep it as simple as possible and start small. Perhaps it would be labeled as an experimental API at first.
1. I have a separate PR to [`prompts`](https://github.com/terkelg/prompts/pull/234) that would make this better.
1. `prompts` relies on nothing else being written to the terminal. My branch has some work to ensure that only one part of the code writes to the terminal at once, but it only works with `--run-in-band`.
1. Features I'd like to add that are not in the demo:
* Undo: choose a different answer for a question you've already answered
* Support multiple questions per file
* Support for more than Node v13
* The demo codemod I have is both too simplistic and also produces incorrect code. :smile:

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.