Skip to content

Latest commit

 

History

History
60 lines (53 loc) · 4.36 KB

comparison-with-jscodeshift.md

File metadata and controls

60 lines (53 loc) · 4.36 KB

Workflow & Codemod Authoring

  • Support for post-processing steps removes cases where you'd need to write a custom bash script. For example:
    const codemod = {
      transform({source}) { /* ... */ }
    
      async postProcess(modifiedFiles, {jscodemod}) {
        // Run a second codemod on the set of files we modified in the first phase.
        await jscodemod(
          require.resolve('path/to/second-codemod-phase'),
          modifiedFiles
        )
      }
    }
  • At scale, codemod authors often need to exclude some files from processing. In jscodeshift, you'd do something like:
    const IGNORED_FILES = ['path/to/a.js', 'path/to/b.js']
      // We need to convert to absolute paths, 
      // because that's what jscodeshift gives the transform.
      .map(file => path.resolve(repoRoot, file)); 
    
    function transform({source, filePath}) {
      if (IGNORED_FILES.some((f) => file.path.includes(f)) || filePath.includes('directory-to-omit')) {
        return;
      }
    }
    With jscodemod, use the built-in ignore functionality:
    const codemod = {
      ignore: [new RegExp('path/to/a.js'), 'path/to/b.js', /directory-to-omit/]
      ignoreFiles: ['path/to/.eslintignore', 'path/to/.npmignore']
      // ...
    }
  • By default, jscodeshift attempts to parse your code. In my opinion, this is brittle. jscodemod makes no attempt to parse your code – you handle it by default.

Usability

  • jscodeshift has a custom command line arg parser, which does not throw on unrecognized flags, making it easy to have a typo. JSCodemod uses yargs, which provides an interface familiar to users of many other Node tools, and does throw errors on unrecognized flags.
  • jscodemod bypasses the challenges of passing ignore patterns to jscodeshift, because it automatically will only process git-tracked files.
  • jscodeshift's documentation is lacking. I suppose that if one feels this way, one could just avoid using the undocumented parts of jscodeshift. But I feel like it's not doing users any favors to suggest that using these APIs is the primary way to use the tool, but then not document those APIs. By contrast, jscodemod fully documents everything that is available to users.

Performance

I've observed jscodemod being 30x-50x faster than jscodeshift, on a comparison that simply does a string concatenation. (This removes any difference due to using different code parsers.)

The main reason for this performance difference is jscodemod uses Node's worker pool API (via Piscina), rather than child_process.fork.

Use the included ./benchmark/index.js script to run your own benchmarks. Here's a result of mine, running against Nodejs:

$ ./benchmark/index.js ~/code/node/
┌─────────────┬───────────┬─────────────────────────┬──────────────────────────────┬──────────────┐
│ Runner      │ Transform │ Mean Duration (seconds) │ Standard Deviation (seconds) │ Sample count │
├─────────────┼───────────┼─────────────────────────┼──────────────────────────────┼──────────────┤
│ jscodemod   │ string    │ 1.92                    │ 0.0542                       │ 6            │
├─────────────┼───────────┼─────────────────────────┼──────────────────────────────┼──────────────┤
│ jscodeshift │ string    │ 47.1                    │ 1.62                         │ 5            │
└─────────────┴───────────┴─────────────────────────┴──────────────────────────────┴──────────────┘