This guide explains how to convert a project using .coffee
files to
JavaScript using decaffeinate.
This guide assumes a few things:
- You have Node v4 or higher installed.
- You have a project or set of files that currently compile using the official CoffeeScript compiler.
- Your project is able to run ES2016 code. In particular, depending on what
browsers/runtimes you need to support, you may need to set up Babel,
including standard library polyfills like
Array.prototype.includes
. - You understand CoffeeScript, ES6, and the files being converted reasonably well.
- You are using Linux, Mac OS X, or a compatible OS and are comfortable using the command line. This may work on Windows with some adjustments.
Note that if you cannot or prefer not to install Node, or otherwise cannot or prefer not to run commands on the command line, you can use the decaffeinate repl to do the conversion.
First, install decaffeinate (skip if using the online repl):
$ npm install -g decaffeinate
Test it out to make sure everything is working for you:
$ echo "a = if b then c else d" | decaffeinate
let a = b ? c : d;
If you're using the online repl instead, ensure that pasting
a = if b then c else d
into the left-side editor produces
let a = b ? c : d;
in the right-side editor.
Pick a file to convert first. Ideally it should be simple, and one that you understand. If you're using the command-line, run this:
$ decaffeinate path/to/your/file.coffee
path/to/your/file.coffee → path/to/your/file.js
This will put the converted JavaScript into a .js
file alongside the
original .coffee
file.
If you're using the online repl, copy the contents of the file to be
converted and paste it into the left-side editor. You'll see the
converted output in the right-side editor. Copy the JavaScript and paste
it into a new file, ideally next to the original .coffee
file but with
a .js
extension.
It's possible your conversion will not succeed. In that case, you'll get
an error message. That message may be about an unsupported feature, or
it may indicate that the .coffee
file has invalid syntax, or it may
indicate that the JavaScript generated by decaffeinate is itself
invalid. In any case, check the issues and file a new one if
none match the message you're seeing.
If decaffeinate tells you that you're using a feature that is not yet
supported, try editing the original .coffee
file to work around that
feature and try again.
Compare your new .js
file against your .coffee
file. Does the
conversion seem correct? Is there anything that was done incorrectly? Or
perhaps there are simply a few things that worked well in CoffeeScript
but don't work as well in JavaScript. For example, watch out for:
- CoffeeScript has implicit returns in all functions. Ensure that all
the
return
statements in the generated JavaScript are intentional. - You may be using a linter that disallows the use of double-equal,
which will flag anything that looked like
a.b?
in CoffeeScript as lint in JavaScript since it converts toa.b != null
. In such cases, it may be that all you really wanted was a truthy check (i.e.a.b
) or a strict comparison tonull
. If you want the equivalent toa?.b
in a linter-friendly way, usetypeof a.b !== 'undefined' && a.b !== null
. - decaffeinate sometimes has to create temporary variables for you. Ensure that the variable names generated make sense in context, or re-write the JavaScript to avoid the use of temporary variables.
You have tests, right? The best way to ensure that the conversion went
smoothly is to run your test suite. Since decaffeinate generates code
with syntax from future versions of JavaScript, you may need to use a
tool like babel to compile the code for use in the environments
you care about (i.e. Node, browsers, etc). If so, set up your build
system to convert the new .js
file to runnable JavaScript.
Hopefully, running your tests will show that everything works as expected. If not, consider creating a new issue if you believe that decaffeinate is generating incorrect code.
While it's possible to run decaffeinate in batch mode, I recommend only doing so to get a sense of how much of your project can be automatically converted.
$ decaffeinate path/to/project
Instead, you should follow the steps outlined under "Converting one
file" for each file in your project, keeping in mind that most projects
can contain both .coffee
and .js
files. Doing it that way will allow
you to avoid regressions and spread the work over time.
Note that there is no way to convert a whole project at once using the online repl.
You're probably using a version control system like git, and you may
have noticed that if you simply delete the .coffee
file and add the
generated .js
then your version control system may not realize that
the history of the .js
version should continue to the .coffee
version. With git, you can help it along by doing this before
converting:
$ git mv path/to/file.coffee path/to/file.js
$ git add -A
$ git commit -m 'Move file to prepare for conversion to JavaScript.'
Once you've converted your file, you can run git log --follow -- path/to/file.js
and see the history of the .coffee
file too.