question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Breaking changes for decaffeinate 3.0

See original GitHub issue

In response to a few requests as well as my own personal gut feelings and goals, I’m thinking of making a breaking decaffeinate 3.0 release that changes some of the default behaviors.

In addition to providing an explanation of the changes, I’m looking for feedback in case others have opinions. Some people who might have opinions on all of this: @eventualbuddha @kvz @wordofchristian @nathansobo @gr2m . And of course anyone watching the project.

High-level vision

Someone who has just learned about decaffeinate should be able to run decaffeinate (or bulk-decaffeinate convert or another wrapper) on their whole CoffeeScript codebase with no custom configuration and get a working JavaScript codebase with zero bugs introduced (even if the code isn’t pretty everywhere). The only additional task to get things working should be build system changes. As much as possible, decaffeinate should make the resulting JavaScript look nice and provide guidance on how to accurately clean it up by hand.

As a secondary goal, decaffeinate should also support the use case of converting projects incrementally, including files with thorough enough tests that the decaffeinate conversion doesn’t need to be exact.

Proposed changes

  • Change --keep-commonjs, --enable-babel-constructor-workaround, and --prefer-const to be enabled by default.
  • Add a --loose option that enables a reasonable set of --loose... options all at once.
  • Add a suggestions (a.k.a. warnings) system that lists suggested cleanup tasks of different priorities.
  • New docs to go along with the suggestions system, which attempt to explain all of the nuances in decaffeinate that people should know about when manually cleaning up code.

(Not all of these are actually breaking, but they’re all a bit related.)

Details/motivation

--keep-commonjs by default

It seems like this is commonly-used, so it seems best to make it the default behavior. Converting to import/export doesn’t work in node without Babel, and the conversion isn’t exact because decaffeinate doesn’t (and generally can’t) match named exports to named imports across files.

It’s still possible to correctly convert code to JS modules using --force-default-export and the cross-file fix-imports step of bulk-decaffeinate, which is what I do for code at my work, and there will be a bulk-decaffeinate flag/option to do this easily.

--enable-babel-constructor-workaround by default

This is probably the most controversial. You can’t use this before super in constructors in JS classes (which also means no @ params and no bound methods), so this “cheats” by inserting a code snippet that tricks Babel and TypeScript into letting you do it anyway. To clean up the code, you remove the code snippet (which is a self-contained block) and refactor the code to not use this before super.

Here’s what it looks like:

class A {}

class B extends A {
  constructor() {
    {
      // Hack: trick babel into allowing this before super.
      if (false) { super(); }
      let thisFn = (() => { this; }).toString();
      let thisName = thisFn.slice(thisFn.indexOf('{') + 1, thisFn.indexOf(';')).trim();
      eval(`${thisName} = this;`);
    }
    this.a = 1;
    super(...arguments);
  }
}

console.log(new B().a)

Some reasons why I think it’s ok to enable it by default despite the hacks:

  • To make sure people are aware of it, it will be the highest-priority suggestion/warning in the new suggestions system (this is the main reason for adding a suggestions system).
  • The flag is used for all example projects in the README, so it is very well-tested and stable.
  • The behavior when not using Babel/TypeScript is about the same as --allow-invalid-constructors (a crash when calling the constructor).

The advantage is that people can worry about the details as a follow-up step rather than before running decaffeinate, and it makes it easier to use the repl and easier to check a large codebase for decaffeinate crashes.

--prefer-const by default

decaffeinate itself uses let everywhere except for top-level constants, but I think the most common style in the JS world is to use const wherever possible. This is reasonably low-priority, but while I’m changing defaults I thought I’d throw it in.

--loose option

Given posts I’ve seen on the internet, it seems common for people to enable a number of --loose options when running decaffeinate, so this would enable a number of “suggested” ones at once. Given that every --loose... option corresponds to a bug that decaffeinate would have introduced in real-world code, I’m hesitant to encourage its use, but it seems reasonable when code has good test coverage or will be manually tested thoroughly, and avoids many of the most annoying manual cleanup steps after decaffeinate.

Suggestions system

For example, decaffeinate will write something like this to stderr after converting a file, with an option to produce a JSON format readable by wrapper scripts:

Consider these suggestions when cleaning up the JS code:
DS001: Remove Babel constructor workaround
DS005: Remove unnecessary use of Array.from
DS011: Use default parameters where possible
DS013: Avoid top-level `this`

See the docs for full explanations:
https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md

Online docs will have a description of each suggestion and why decaffeinate behaves the way it does.

Notes

All decaffeinate example projects use decaffeinate --keep-commonjs --prefer-const --enable-babel-constructor-workaround. Source (see the bulk-decaffeinate.config.js file in each project).

Args used to convert Hubot to JS: decaffeinate --keep-commonjs --prefer-const --loose-default-params --loose-for-expressions --loose-for-of --loose-includes --allow-invalid-constructors. Source (YouTube video)

@nathansobo in March suggested the following args decaffeinate --keep-commonjs --prefer-const --loose-default-params --loose-for-expressions --loose-for-of. Source.

The Invig project uses decaffeinate --loose-includes --loose-for-of --allow-invalid-constructors --keep-commonjs --prefer-const --loose-default-params. Source

Prior discussions in favor of --keep-commonjs by default: https://github.com/decaffeinate/decaffeinate/issues/403#issuecomment-310102715 and https://github.com/decaffeinate/decaffeinate/issues/904

Prior discussion around --enable-babel-constructor-workaround: https://github.com/decaffeinate/decaffeinate/issues/1100


If anyone has feedback on this, let me know!

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
gr2mcommented, Jun 25, 2017

that all sounds very reasonable. Thanks for the great project, it is tremendously helpful for us!

0reactions
nathansobocommented, Jul 3, 2017

👍

Read more comments on GitHub >

github_iconTop Results From Across the Web

Releases · decaffeinate/bulk-decaffeinate - GitHub
Run decaffeinate and related operations on a whole codebase, ... update bulk-decaffeinate for decaffeinate 3.0 (#131) (42cddf0b). Breaking Changes.
Read more >
bulk-decaffeinate - NPM Package Versions - Socket - Socket.dev
Run decaffeinate and related operations on a whole codebase, or just part of one. Version: 3.3.1 was published by alangpierce. Start using Socket...
Read more >
node-polyglot/CHANGELOG.md - UNPKG
22, ### v2.3.0: July 2, 2018 ... 45, * [Fix] revert unintentional breaking change of missing substitutions being ... 84, * [Tests] decaffeinate...
Read more >
Consumption of decaffeinated coffee with milk and sugar ...
This study aimed to compare the effect of consuming decaffeinated coffee at different times around a high glycemic index (GI) meal on postprandial...
Read more >
(PDF) Caffeine Content of Decaffeinated Coffee - ResearchGate
The caffeine content for the Starbucks espresso and the Starbucks brewed samples collected from the same outlet were 3.0-15.8 mg/shot and ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found