From 3378f8cf785aafda3a9a577e08c7360a290f5fbd Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 21 Sep 2017 21:18:12 -0700 Subject: [PATCH 1/8] =?UTF-8?q?Show=20an=20appropriate=20error=20if=20the?= =?UTF-8?q?=20user=20tries=20to=20use=20--transpile=20via=20the=20CLI=20an?= =?UTF-8?q?d=20babel-core=20isn=E2=80=99t=20installed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/coffeescript/command.js | 15 ++++++++++++--- src/command.coffee | 27 +++++++++++++++++++++------ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 85063c7ff4..96aeab5ff5 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -609,11 +609,20 @@ if (opts.transpile) { try { // The user has requested that the CoffeeScript compiler also transpile - // via Babel. We use Babel as an `optionalDependency`; see - // https://docs.npmjs.com/files/package.json#optionaldependencies. + // via Babel. We don’t include Babel as a dependency because we want to + // avoid dependencies in general, and most users probably won’t be relying + // on us to transpile for them; we assume most users will probably either + // run CoffeeScript’s output without transpilation (modern Node or evergreen + // browsers) or use a proper build chain like Gulp or Webpack. require('babel-core'); } catch (error) { - console.error('To use --transpile, you must have Babel installed and configured.\nSee http://coffeescript.org/#transpilation'); + // Give appropriate instructions depending on whether `coffee` was run + // locally or globally. + if (require.resolve('.').indexOf(process.cwd()) === 0) { + console.error('To use --transpile, you must have babel-core installed:\n npm install --save-dev babel-core\nAnd you must save options to configure Babel in one of the places it looks to find its options.\nSee http://coffeescript.org/#transpilation'); + } else { + console.error('To use --transpile with globally-installed CoffeeScript, you must have babel-core installed globally:\n npm install --global babel-core\nAnd you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.\nSee http://coffeescript.org/#transpilation'); + } process.exit(1); } // We’re giving Babel only a string, not a filename or path to a file, so diff --git a/src/command.coffee b/src/command.coffee index ca003efc30..be43f0ad65 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -444,15 +444,30 @@ parseOptions = -> compileOptions = (filename, base) -> if opts.transpile # The user has requested that the CoffeeScript compiler also transpile - # via Babel. We use Babel as an `optionalDependency`; see - # https://docs.npmjs.com/files/package.json#optionaldependencies. + # via Babel. We don’t include Babel as a dependency because we want to + # avoid dependencies in general, and most users probably won’t be relying + # on us to transpile for them; we assume most users will probably either + # run CoffeeScript’s output without transpilation (modern Node or evergreen + # browsers) or use a proper build chain like Gulp or Webpack. try require 'babel-core' catch - console.error ''' - To use --transpile, you must have Babel installed and configured. - See http://coffeescript.org/#transpilation - ''' + # Give appropriate instructions depending on whether `coffee` was run + # locally or globally. + if require.resolve('.').indexOf(process.cwd()) is 0 + console.error ''' + To use --transpile, you must have babel-core installed: + npm install --save-dev babel-core + And you must save options to configure Babel in one of the places it looks to find its options. + See http://coffeescript.org/#transpilation + ''' + else + console.error ''' + To use --transpile with globally-installed CoffeeScript, you must have babel-core installed globally: + npm install --global babel-core + And you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder. + See http://coffeescript.org/#transpilation + ''' process.exit 1 # We’re giving Babel only a string, not a filename or path to a file, so From b6b536eff0fddbe671c5180eade00b402f26aa99 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 21 Sep 2017 21:58:42 -0700 Subject: [PATCH 2/8] Update documentation around global/local --- docs/v2/index.html | 13 +++++++++---- documentation/sections/installation.md | 6 ++++-- documentation/sections/introduction.md | 6 +++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/docs/v2/index.html b/docs/v2/index.html index 1486fae464..e4cef1cf92 100644 --- a/docs/v2/index.html +++ b/docs/v2/index.html @@ -646,7 +646,11 @@

CoffeeScript is a little language that compiles into JavaScript. Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.

The golden rule of CoffeeScript is: “It’s just JavaScript.” The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable, pretty-printed, and tends to run as fast or faster than the equivalent handwritten JavaScript.

Latest Version: 2.0.0

-
npm install -g coffeescript
+
# Install locally for a project
+npm install --save-dev coffeescript
+
+# Install globally to execute .coffee files anywhere
+npm install --global coffeescript
 

Overview

@@ -847,15 +851,16 @@

Compatibility

Installation

-

The command-line version of coffee is available as a Node.js utility. The core compiler however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see Try CoffeeScript).

+

The command-line version of coffee is available as a Node.js utility, requiring Node 6 or later. The core compiler however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see Try CoffeeScript).

To install, first make sure you have a working copy of the latest stable version of Node.js. You can then install CoffeeScript globally with npm:

npm install --global coffeescript
 

This will make the coffee and cake commands available globally.

-

When you need CoffeeScript as a dependency of a project, within that project’s folder you can install it locally:

+

If you are using CoffeeScript in a project, you should install it locally for that project so that the version of CoffeeScript is tracked as one of your project’s dependencies. Within that project’s folder:

npm install --save-dev coffeescript
 

The coffee and cake commands will first look in the current folder to see if CoffeeScript is installed locally, and use that version if so. This allows different versions of CoffeeScript to be installed globally and locally.

+

If you plan to use the --transpile option (see Transpilation) you will need to also install babel-core either globally or locally, depending on whether you are running a globally or locally installed version of CoffeeScript.

@@ -4743,7 +4748,7 @@

Resources

Perhaps your CoffeeScript-related question has been asked before. Check the FAQ first.
  • JS2Coffee
    Is a very well done reverse JavaScript-to-CoffeeScript compiler. It’s not going to be perfect (infer what your JavaScript classes are, when you need bound functions, and so on…) — but it’s a great starting point for converting simple scripts.
  • -
  • High-Rez Logo
    +
  • High-Rez Logo
    The CoffeeScript logo is available in SVG for use in presentations.
  • diff --git a/documentation/sections/installation.md b/documentation/sections/installation.md index 7a5b62ec42..1f8887df7c 100644 --- a/documentation/sections/installation.md +++ b/documentation/sections/installation.md @@ -1,6 +1,6 @@ ## Installation -The command-line version of `coffee` is available as a [Node.js](https://nodejs.org/) utility. The [core compiler](/v<%= majorVersion %>/browser-compiler/coffeescript.js) however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see [Try CoffeeScript](#try)). +The command-line version of `coffee` is available as a [Node.js](https://nodejs.org/) utility, requiring Node 6 or later. The [core compiler](/v<%= majorVersion %>/browser-compiler/coffeescript.js) however, does not depend on Node, and can be run in any JavaScript environment, or in the browser (see [Try CoffeeScript](#try)). To install, first make sure you have a working copy of the latest stable version of [Node.js](https://nodejs.org/). You can then install CoffeeScript globally with [npm](https://www.npmjs.com/): @@ -10,10 +10,12 @@ npm install --global coffeescript This will make the `coffee` and `cake` commands available globally. -When you need CoffeeScript as a dependency of a project, within that project’s folder you can install it locally: +If you are using CoffeeScript in a project, you should install it locally for that project so that the version of CoffeeScript is tracked as one of your project’s dependencies. Within that project’s folder: ```bash npm install --save-dev coffeescript ``` The `coffee` and `cake` commands will first look in the current folder to see if CoffeeScript is installed locally, and use that version if so. This allows different versions of CoffeeScript to be installed globally and locally. + +If you plan to use the `--transpile` option (see [Transpilation](#transpilation)) you will need to also install `babel-core` either globally or locally, depending on whether you are running a globally or locally installed version of CoffeeScript. \ No newline at end of file diff --git a/documentation/sections/introduction.md b/documentation/sections/introduction.md index 14b5c9f36c..f9ea4ad039 100644 --- a/documentation/sections/introduction.md +++ b/documentation/sections/introduction.md @@ -5,5 +5,9 @@ The golden rule of CoffeeScript is: _“It’s just JavaScript.”_ The code com **Latest Version:** [<%= fullVersion %>](https://github.com/jashkenas/coffeescript/tarball/<%= fullVersion %>) ```bash -npm install -g coffeescript +# Install locally for a project +npm install --save-dev coffeescript + +# Install globally to execute .coffee files anywhere +npm install --global coffeescript ``` From b56eb8d2952edc62184558b7dde400d6810f7de5 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sat, 23 Sep 2017 12:50:16 -0700 Subject: [PATCH 3/8] =?UTF-8?q?Fix=20#4713:=20Use=20Babel=E2=80=99s=20buil?= =?UTF-8?q?t-in=20`filename`=20option=20to=20let=20Babel=20search=20for=20?= =?UTF-8?q?its=20options,=20rather=20than=20us=20doing=20so?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/coffeescript/command.js | 49 ++++++++++++------------------- src/command.coffee | 57 ++++++++++--------------------------- 2 files changed, 33 insertions(+), 73 deletions(-) diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 96aeab5ff5..819079394b 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -605,7 +605,7 @@ // The compile-time options to pass to the CoffeeScript compiler. compileOptions = function(filename, base) { - var answer, cantFindOptions, checkPath, cwd, jsDir, jsPath, packageJson; + var answer, cwd, jsDir, jsPath; if (opts.transpile) { try { // The user has requested that the CoffeeScript compiler also transpile @@ -625,43 +625,30 @@ } process.exit(1); } - // We’re giving Babel only a string, not a filename or path to a file, so - // it doesn’t know where to search to find a `.babelrc` file or a `babel` - // key in a `package.json`. So if `opts.transpile` is an object, use that - // as Babel’s options; otherwise figure out what the options should be. if (typeof opts.transpile !== 'object') { - // Find the options based on the path to the file being compiled. - cantFindOptions = function() { - console.error('To use the transpile option, there must be a .babelrc file\n(or a package.json file with a "babel" key) in the path of the file\nto be compiled, or in the path of the current working directory.\nIf you are compiling a string via the Node API, the transpile option\nmust be an object with the options to pass to Babel.\nSee http://coffeescript.org/#transpilation'); - return process.exit(1); - }; - checkPath = filename ? path.dirname(filename) : base ? base : typeof process !== "undefined" && process !== null ? process.cwd() : cantFindOptions(); - while (true) { - try { - opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, '.babelrc'), 'utf-8')); - break; - } catch (error) { - try { - packageJson = JSON.parse(fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8')); - if (packageJson.babel != null) { - opts.transpile = packageJson.babel; - break; - } - } catch (error) {} - } - if (checkPath === path.dirname(checkPath)) { // We’ve reached the root. - cantFindOptions(); - break; - } else { - checkPath = path.dirname(checkPath); - } - } + opts.transpile = {}; } // Pass a reference to Babel into the compiler, so that the transpile option // is available for the CLI. We need to do this so that tools like Webpack // can `require('coffeescript')` and build correctly, without trying to // require Babel. opts.transpile.transpile = CoffeeScript.transpile; + // Babel searches for its options (a `.babelrc` file, a `.babelrc.js` file, + // a `package.json` file with a `babel` key, etc.) relative to the path + // given to it in its `filename` option. Make sure we have a path to pass + // along. + if (!opts.transpile.filename) { + if (filename) { + opts.transpile.filename = filename; + } else { + opts.transpile.filename = base || process.cwd(); + if (opts.transpile.filename.endsWith(path.sep)) { + opts.transpile.filename += '.'; + } else { + opts.transpile.filename += path.sep + '.'; + } + } + } } else { opts.transpile = false; } diff --git a/src/command.coffee b/src/command.coffee index be43f0ad65..c6a8ea2983 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -470,54 +470,27 @@ compileOptions = (filename, base) -> ''' process.exit 1 - # We’re giving Babel only a string, not a filename or path to a file, so - # it doesn’t know where to search to find a `.babelrc` file or a `babel` - # key in a `package.json`. So if `opts.transpile` is an object, use that - # as Babel’s options; otherwise figure out what the options should be. - unless typeof opts.transpile is 'object' - # Find the options based on the path to the file being compiled. - cantFindOptions = -> - console.error ''' - To use the transpile option, there must be a .babelrc file - (or a package.json file with a "babel" key) in the path of the file - to be compiled, or in the path of the current working directory. - If you are compiling a string via the Node API, the transpile option - must be an object with the options to pass to Babel. - See http://coffeescript.org/#transpilation - ''' - process.exit 1 - - checkPath = if filename - path.dirname filename - else if base - base - else if process? - process.cwd() - else - cantFindOptions() - - loop - try - opts.transpile = JSON.parse fs.readFileSync path.join(checkPath, '.babelrc'), 'utf-8' - break - catch - try - packageJson = JSON.parse fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8') - if packageJson.babel? - opts.transpile = packageJson.babel - break - - if checkPath is path.dirname checkPath # We’ve reached the root. - cantFindOptions() - break - else - checkPath = path.dirname checkPath + opts.transpile = {} unless typeof opts.transpile is 'object' # Pass a reference to Babel into the compiler, so that the transpile option # is available for the CLI. We need to do this so that tools like Webpack # can `require('coffeescript')` and build correctly, without trying to # require Babel. opts.transpile.transpile = CoffeeScript.transpile + + # Babel searches for its options (a `.babelrc` file, a `.babelrc.js` file, + # a `package.json` file with a `babel` key, etc.) relative to the path + # given to it in its `filename` option. Make sure we have a path to pass + # along. + unless opts.transpile.filename + if filename + opts.transpile.filename = filename + else + opts.transpile.filename = base or process.cwd() + if opts.transpile.filename.endsWith(path.sep) + opts.transpile.filename += '.' + else + opts.transpile.filename += path.sep + '.' else opts.transpile = no From e949062beb0f780b90b42dc04606112004a043d3 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sat, 23 Sep 2017 13:06:41 -0700 Subject: [PATCH 4/8] Improve transpilation docs --- docs/v2/index.html | 9 ++++++--- documentation/sections/transpilation.md | 12 +++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/v2/index.html b/docs/v2/index.html index e4cef1cf92..c2aaea2ef0 100644 --- a/docs/v2/index.html +++ b/docs/v2/index.html @@ -1002,13 +1002,16 @@

    Quickstart

    CoffeeScript includes a --transpile option when used via the coffee command, or a transpile option when used via Node. To use either, Babel must be installed in your project:

    npm install --save-dev babel-core
     
    +

    Or if you’re running the coffee command outside of a project folder, using a globally-installed coffeescript module, babel-core also needs to be installed globally:

    +
    npm install --global babel-core
    +

    By default, Babel doesn’t do anything—it doesn’t make assumptions about what you want to transpile to. You might know that your code will run in Node 8, and so you want Babel to transpile modules and JSX and nothing else. Or you might want to support Internet Explorer 8, in which case Babel will transpile every feature introduced in ES2015 and later specs.

    If you’re not sure what you need, a good starting point is babel-preset-env:

    -
    npm install --save-dev babel-preset-env
    +
    npm install --save-dev babel-preset-env  # Or --global for non-project-based usage
     

    See Babel’s website to learn about presets and plugins and the multitude of options you have.

    -

    Simply installing babel-preset-env isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a .babelrc file in the folder containing the files you’re compiling, or in any parent folder up the path above those files. So if your project is in ~/app and your files are in ~/app/src, you can put .babelrc in either ~/app or in ~/app/src. You can also define the Babel options via a babel key in the package.json file for your project. A minimal .babelrc file (or package.json babel key) for use with babel-preset-env would be just { "presets": ["env"] }.

    -

    Once you have babel-core and babel-preset-env (or other presets or plugins) installed, and a .babelrc file (or package.json babel key) in place, you can use coffee --transpile to pipe CoffeeScript’s output through Babel using the options you’ve saved.

    +

    Simply installing babel-preset-env isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a .babelrc file in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports other ways to specify its options; any of them will work, though for the sake of simplicity in these docs we’ll assume you’re creating a .babelrc file.) So if your project is in ~/app and your files are in ~/app/src, you can put .babelrc in either ~/app or in ~/app/src. A minimal .babelrc file (or package.json babel key) for use with babel-preset-env would be just { "presets": ["env"] }.

    +

    Once you have babel-core and babel-preset-env (or other presets or plugins) installed, and a .babelrc file (or other equivalent file) in place, you can use coffee --transpile to pipe CoffeeScript’s output through Babel using the options you’ve saved.

    If you’re using CoffeeScript via the Node API, where you call CoffeeScript.compile with a string to be compiled and an options object, the transpile key of the options object should be the Babel options:

    CoffeeScript.compile(code, {transpile: {presets: ['env']}})
     
    diff --git a/documentation/sections/transpilation.md b/documentation/sections/transpilation.md index 29446a9c45..5a2f498286 100644 --- a/documentation/sections/transpilation.md +++ b/documentation/sections/transpilation.md @@ -22,19 +22,25 @@ CoffeeScript includes a `--transpile` option when used via the `coffee` command, npm install --save-dev babel-core ``` +Or if you’re running the `coffee` command outside of a project folder, using a globally-installed `coffeescript` module, `babel-core` also needs to be installed globally: + +```bash +npm install --global babel-core +``` + By default, Babel doesn’t do anything—it doesn’t make assumptions about what you want to transpile to. You might know that your code will run in Node 8, and so you want Babel to transpile modules and JSX and nothing else. Or you might want to support Internet Explorer 8, in which case Babel will transpile every feature introduced in ES2015 and later specs. If you’re not sure what you need, a good starting point is [`babel-preset-env`](https://babeljs.io/docs/plugins/preset-env/): ```bash -npm install --save-dev babel-preset-env +npm install --save-dev babel-preset-env # Or --global for non-project-based usage ``` See [Babel’s website to learn about presets and plugins](https://babeljs.io/docs/plugins/) and the multitude of options you have. -Simply installing `babel-preset-env` isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a [`.babelrc` file](https://babeljs.io/docs/usage/babelrc/) in the folder containing the files you’re compiling, or in any parent folder up the path above those files. So if your project is in `~/app` and your files are in `~/app/src`, you can put `.babelrc` in either `~/app` or in `~/app/src`. You can also define the Babel options via a `babel` key in the `package.json` file for your project. A minimal `.babelrc` file (or `package.json` `babel` key) for use with `babel-preset-env` would be just `{ "presets": ["env"] }`. +Simply installing `babel-preset-env` isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a [`.babelrc` file](https://babeljs.io/docs/usage/babelrc/) in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports [other ways](https://babeljs.io/docs/usage/babelrc/) to specify its options; any of them will work, though for the sake of simplicity in these docs we’ll assume you’re creating a `.babelrc` file.) So if your project is in `~/app` and your files are in `~/app/src`, you can put `.babelrc` in either `~/app` or in `~/app/src`. A minimal `.babelrc` file (or `package.json` `babel` key) for use with `babel-preset-env` would be just `{ "presets": ["env"] }`. -Once you have `babel-core` and `babel-preset-env` (or other presets or plugins) installed, and a `.babelrc` file (or `package.json` `babel` key) in place, you can use `coffee --transpile` to pipe CoffeeScript’s output through Babel using the options you’ve saved. +Once you have `babel-core` and `babel-preset-env` (or other presets or plugins) installed, and a `.babelrc` file (or other equivalent file) in place, you can use `coffee --transpile` to pipe CoffeeScript’s output through Babel using the options you’ve saved. If you’re using CoffeeScript via the [Node API](nodejs_usage), where you call `CoffeeScript.compile` with a string to be compiled and an `options` object, the `transpile` key of the `options` object should be the Babel options: From bb5ccc1075bf6cd07c28f5c5f5529360755a6b3d Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sat, 23 Sep 2017 13:14:12 -0700 Subject: [PATCH 5/8] Colons are good --- docs/v2/index.html | 4 ++-- documentation/sections/introduction.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/v2/index.html b/docs/v2/index.html index c2aaea2ef0..6602e11a00 100644 --- a/docs/v2/index.html +++ b/docs/v2/index.html @@ -646,10 +646,10 @@

    CoffeeScript is a little language that compiles into JavaScript. Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.

    The golden rule of CoffeeScript is: “It’s just JavaScript.” The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable, pretty-printed, and tends to run as fast or faster than the equivalent handwritten JavaScript.

    Latest Version: 2.0.0

    -
    # Install locally for a project
    +
    # Install locally for a project:
     npm install --save-dev coffeescript
     
    -# Install globally to execute .coffee files anywhere
    +# Install globally to execute .coffee files anywhere:
     npm install --global coffeescript
     
    diff --git a/documentation/sections/introduction.md b/documentation/sections/introduction.md index f9ea4ad039..d25d9e7274 100644 --- a/documentation/sections/introduction.md +++ b/documentation/sections/introduction.md @@ -5,9 +5,9 @@ The golden rule of CoffeeScript is: _“It’s just JavaScript.”_ The code com **Latest Version:** [<%= fullVersion %>](https://github.com/jashkenas/coffeescript/tarball/<%= fullVersion %>) ```bash -# Install locally for a project +# Install locally for a project: npm install --save-dev coffeescript -# Install globally to execute .coffee files anywhere +# Install globally to execute .coffee files anywhere: npm install --global coffeescript ``` From 72592659e87a2b1afb223aa883640963fdd865c2 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sat, 23 Sep 2017 13:16:56 -0700 Subject: [PATCH 6/8] Docs cleanup --- docs/v2/index.html | 4 ++-- documentation/sections/transpilation.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/v2/index.html b/docs/v2/index.html index 6602e11a00..eafc3d4559 100644 --- a/docs/v2/index.html +++ b/docs/v2/index.html @@ -1010,8 +1010,8 @@

    Quickstart

    npm install --save-dev babel-preset-env  # Or --global for non-project-based usage
     

    See Babel’s website to learn about presets and plugins and the multitude of options you have.

    -

    Simply installing babel-preset-env isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a .babelrc file in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports other ways to specify its options; any of them will work, though for the sake of simplicity in these docs we’ll assume you’re creating a .babelrc file.) So if your project is in ~/app and your files are in ~/app/src, you can put .babelrc in either ~/app or in ~/app/src. A minimal .babelrc file (or package.json babel key) for use with babel-preset-env would be just { "presets": ["env"] }.

    -

    Once you have babel-core and babel-preset-env (or other presets or plugins) installed, and a .babelrc file (or other equivalent file) in place, you can use coffee --transpile to pipe CoffeeScript’s output through Babel using the options you’ve saved.

    +

    Simply installing babel-preset-env isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a .babelrc file in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports other ways to specify its options; any of them will work, though for the sake of simplicity in these docs we’ll assume you’re creating a .babelrc file.) So if your project is in ~/app and your files are in ~/app/src, you can put .babelrc in either ~/app or in ~/app/src. A minimal .babelrc file for use with babel-preset-env would be just { "presets": ["env"] }.

    +

    Once you have babel-core and babel-preset-env (or other presets or plugins) installed, and a .babelrc file (or other equivalent) in place, you can use coffee --transpile to pipe CoffeeScript’s output through Babel using the options you’ve saved.

    If you’re using CoffeeScript via the Node API, where you call CoffeeScript.compile with a string to be compiled and an options object, the transpile key of the options object should be the Babel options:

    CoffeeScript.compile(code, {transpile: {presets: ['env']}})
     
    diff --git a/documentation/sections/transpilation.md b/documentation/sections/transpilation.md index 5a2f498286..c6a8c3e2be 100644 --- a/documentation/sections/transpilation.md +++ b/documentation/sections/transpilation.md @@ -38,9 +38,9 @@ npm install --save-dev babel-preset-env # Or --global for non-project-based usa See [Babel’s website to learn about presets and plugins](https://babeljs.io/docs/plugins/) and the multitude of options you have. -Simply installing `babel-preset-env` isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a [`.babelrc` file](https://babeljs.io/docs/usage/babelrc/) in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports [other ways](https://babeljs.io/docs/usage/babelrc/) to specify its options; any of them will work, though for the sake of simplicity in these docs we’ll assume you’re creating a `.babelrc` file.) So if your project is in `~/app` and your files are in `~/app/src`, you can put `.babelrc` in either `~/app` or in `~/app/src`. A minimal `.babelrc` file (or `package.json` `babel` key) for use with `babel-preset-env` would be just `{ "presets": ["env"] }`. +Simply installing `babel-preset-env` isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a [`.babelrc` file](https://babeljs.io/docs/usage/babelrc/) in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports [other ways](https://babeljs.io/docs/usage/babelrc/) to specify its options; any of them will work, though for the sake of simplicity in these docs we’ll assume you’re creating a `.babelrc` file.) So if your project is in `~/app` and your files are in `~/app/src`, you can put `.babelrc` in either `~/app` or in `~/app/src`. A minimal `.babelrc` file for use with `babel-preset-env` would be just `{ "presets": ["env"] }`. -Once you have `babel-core` and `babel-preset-env` (or other presets or plugins) installed, and a `.babelrc` file (or other equivalent file) in place, you can use `coffee --transpile` to pipe CoffeeScript’s output through Babel using the options you’ve saved. +Once you have `babel-core` and `babel-preset-env` (or other presets or plugins) installed, and a `.babelrc` file (or other equivalent) in place, you can use `coffee --transpile` to pipe CoffeeScript’s output through Babel using the options you’ve saved. If you’re using CoffeeScript via the [Node API](nodejs_usage), where you call `CoffeeScript.compile` with a string to be compiled and an `options` object, the `transpile` key of the `options` object should be the Babel options: From 071b4e30a763b121209dd83b29b1f8279c8972f3 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 25 Sep 2017 18:54:38 -0700 Subject: [PATCH 7/8] Rewrite transpilation docs --- docs/v2/index.html | 22 ++++++++++------------ documentation/sections/transpilation.md | 22 +++++++++------------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/docs/v2/index.html b/docs/v2/index.html index 359ec94be5..e402ea09b7 100644 --- a/docs/v2/index.html +++ b/docs/v2/index.html @@ -990,33 +990,31 @@

    Node.js

    Transpilation

    -

    CoffeeScript 2 generates JavaScript that uses the latest, modern syntax. Your runtime might not support all of that syntax. If so, you need to transpile the JavaScript. To make things a little easier, CoffeeScript has built-in support for the popular Babel transpiler.

    +

    CoffeeScript 2 generates JavaScript that uses the latest, modern syntax. The runtime or browsers where you want your code to run might not support all of that syntax. In that case, we want to convert modern JavaScript into older JavaScript that will run in older versions of Node or older browsers; for example, { a } = obj into a = obj.a. This is done via transpilers like Babel, Bublé or Traceur Compiler.

    Quickstart

    From the root of your project:

    npm install --save-dev babel-core babel-preset-env
     echo '{ "presets": ["env"] }' > .babelrc
     coffee --compile --transpile --inline-map some-file.coffee
     
    -

    About Transpilation

    -

    Transpilation is the conversion of source code into equivalent but different source code. In our case, we want to convert modern JavaScript into older JavaScript that will run in older versions of Node or older browsers; for example, { a } = obj into a = obj.a. This is done via transpilers like Babel, Bublé or Traceur Compiler.

    -

    CoffeeScript includes a --transpile option when used via the coffee command, or a transpile option when used via Node. To use either, Babel must be installed in your project:

    +

    Transpiling with the CoffeeScript compiler

    +

    To make things easy, CoffeeScript has built-in support for the popular Babel transpiler. You can use it via the --transpile command-line option or the transpile Node API option. To use either, babel-core must be installed in your project:

    npm install --save-dev babel-core
     
    -

    Or if you’re running the coffee command outside of a project folder, using a globally-installed coffeescript module, babel-core also needs to be installed globally:

    +

    Or if you’re running the coffee command outside of a project folder, using a globally-installed coffeescript module, babel-core needs to be installed globally:

    npm install --global babel-core
     
    -

    By default, Babel doesn’t do anything—it doesn’t make assumptions about what you want to transpile to. You might know that your code will run in Node 8, and so you want Babel to transpile modules and JSX and nothing else. Or you might want to support Internet Explorer 8, in which case Babel will transpile every feature introduced in ES2015 and later specs.

    -

    If you’re not sure what you need, a good starting point is babel-preset-env:

    +

    By default, Babel doesn’t do anything—it doesn’t make assumptions about what you want to transpile to. You need to provide it with a configuration so that it knows what to do. One way to do this is by creating a .babelrc file in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports other ways, too.) A minimal .babelrc file would be just { "presets": ["env"] }. This implies that you have installed babel-preset-env:

    npm install --save-dev babel-preset-env  # Or --global for non-project-based usage
     
    -

    See Babel’s website to learn about presets and plugins and the multitude of options you have.

    -

    Simply installing babel-preset-env isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a .babelrc file in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports other ways to specify its options; any of them will work, though for the sake of simplicity in these docs we’ll assume you’re creating a .babelrc file.) So if your project is in ~/app and your files are in ~/app/src, you can put .babelrc in either ~/app or in ~/app/src. A minimal .babelrc file for use with babel-preset-env would be just { "presets": ["env"] }.

    +

    See Babel’s website to learn about presets and plugins and the multitude of options you have. Another preset you might need is transform-react-jsx if you’re using JSX with React (JSX can also be used with other frameworks).

    Once you have babel-core and babel-preset-env (or other presets or plugins) installed, and a .babelrc file (or other equivalent) in place, you can use coffee --transpile to pipe CoffeeScript’s output through Babel using the options you’ve saved.

    If you’re using CoffeeScript via the Node API, where you call CoffeeScript.compile with a string to be compiled and an options object, the transpile key of the options object should be the Babel options:

    CoffeeScript.compile(code, {transpile: {presets: ['env']}})
     

    You can also transpile CoffeeScript’s output without using the transpile option, for example as part of a build chain. This lets you use transpilers other than Babel, and it gives you greater control over the process. There are many great task runners for setting up JavaScript build chains, such as Gulp, Webpack, Grunt and Broccoli.

    -

    Note that babel-preset-env doesn’t automatically supply polyfills for your code. CoffeeScript itself will output Array.indexOf if you use the in operator, or destructuring or spread/rest syntax; and Function.bind if you use a bound (=>) method in a class. Both are supported in Internet Explorer 9+ and all more recent browsers, but you will need to supply polyfills if you need to support Internet Explorer 8 or below and are using features that would cause these methods to be output. You’ll also need to supply polyfills if your own code uses these methods or another method added in recent versions of JavaScript. One polyfill option is babel-polyfill, though there are many other strategies.

    +

    Polyfills

    +

    Note that transpiling doesn’t automatically supply polyfills for your code. CoffeeScript itself will output Array.indexOf if you use the in operator, or destructuring or spread/rest syntax; and Function.bind if you use a bound (=>) method in a class. Both are supported in Internet Explorer 9+ and all more recent browsers, but you will need to supply polyfills if you need to support Internet Explorer 8 or below and are using features that would cause these methods to be output. You’ll also need to supply polyfills if your own code uses these methods or another method added in recent versions of JavaScript. One polyfill option is babel-polyfill, though there are many other strategies.

    @@ -2490,7 +2488,7 @@

    Everything is an Expression (at least, as much as possible)

    alert((function() { try { - return nonexistent / void 0; + return nonexistent / void 0; } catch (error1) { error = error1; return `And the error is ... ${error}`; @@ -2854,7 +2852,7 @@

    The Existential Operator

    var ref, zip;
     
    -zip = typeof lottery.drawWinner === "function" ? (ref = lottery.drawWinner().address) != null ? ref.zipcode : void 0 : void 0;
    +zip = typeof lottery.drawWinner === "function" ? (ref = lottery.drawWinner().address) != null ? ref.zipcode : void 0 : void 0;
     
    diff --git a/documentation/sections/transpilation.md b/documentation/sections/transpilation.md index c6a8c3e2be..c7a2d53db1 100644 --- a/documentation/sections/transpilation.md +++ b/documentation/sections/transpilation.md @@ -1,6 +1,6 @@ ### Transpilation -CoffeeScript 2 generates JavaScript that uses the latest, modern syntax. Your runtime [might not support all of that syntax](#compatibility). If so, you need to _transpile_ the JavaScript. To make things a little easier, CoffeeScript has built-in support for the popular [Babel](http://babeljs.io/) transpiler. +CoffeeScript 2 generates JavaScript that uses the latest, modern syntax. The runtime or browsers where you want your code to run [might not support all of that syntax](#compatibility). In that case, we want to convert modern JavaScript into older JavaScript that will run in older versions of Node or older browsers; for example, `{ a } = obj` into `a = obj.a`. This is done via transpilers like [Babel](http://babeljs.io/), [Bublé](https://buble.surge.sh/) or [Traceur Compiler](https://github.com/google/traceur-compiler). #### Quickstart @@ -12,33 +12,27 @@ echo '{ "presets": ["env"] }' > .babelrc coffee --compile --transpile --inline-map some-file.coffee ``` -#### About Transpilation +#### Transpiling with the CoffeeScript compiler -Transpilation is the conversion of source code into equivalent but different source code. In our case, we want to convert modern JavaScript into older JavaScript that will run in older versions of Node or older browsers; for example, `{ a } = obj` into `a = obj.a`. This is done via transpilers like [Babel](http://babeljs.io/), [Bublé](https://buble.surge.sh/) or [Traceur Compiler](https://github.com/google/traceur-compiler). - -CoffeeScript includes a `--transpile` option when used via the `coffee` command, or a `transpile` option when used via Node. To use either, [Babel](http://babeljs.io/) must be installed in your project: +To make things easy, CoffeeScript has built-in support for the popular [Babel](http://babeljs.io/) transpiler. You can use it via the `--transpile` command-line option or the `transpile` Node API option. To use either, `babel-core` must be installed in your project: ```bash npm install --save-dev babel-core ``` -Or if you’re running the `coffee` command outside of a project folder, using a globally-installed `coffeescript` module, `babel-core` also needs to be installed globally: +Or if you’re running the `coffee` command outside of a project folder, using a globally-installed `coffeescript` module, `babel-core` needs to be installed globally: ```bash npm install --global babel-core ``` -By default, Babel doesn’t do anything—it doesn’t make assumptions about what you want to transpile to. You might know that your code will run in Node 8, and so you want Babel to transpile modules and JSX and nothing else. Or you might want to support Internet Explorer 8, in which case Babel will transpile every feature introduced in ES2015 and later specs. - -If you’re not sure what you need, a good starting point is [`babel-preset-env`](https://babeljs.io/docs/plugins/preset-env/): +By default, Babel doesn’t do anything—it doesn’t make assumptions about what you want to transpile to. You need to provide it with a configuration so that it knows what to do. One way to do this is by creating a [`.babelrc` file](https://babeljs.io/docs/usage/babelrc/) in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports [other ways](https://babeljs.io/docs/usage/babelrc/), too.) A minimal `.babelrc` file would be just `{ "presets": ["env"] }`. This implies that you have installed [`babel-preset-env`](https://babeljs.io/docs/plugins/preset-env/): ```bash npm install --save-dev babel-preset-env # Or --global for non-project-based usage ``` -See [Babel’s website to learn about presets and plugins](https://babeljs.io/docs/plugins/) and the multitude of options you have. - -Simply installing `babel-preset-env` isn’t enough. You also need to define the configuration options that you want Babel to use. You can do this by creating a [`.babelrc` file](https://babeljs.io/docs/usage/babelrc/) in the folder containing the files you’re compiling, or in any parent folder up the path above those files. (Babel supports [other ways](https://babeljs.io/docs/usage/babelrc/) to specify its options; any of them will work, though for the sake of simplicity in these docs we’ll assume you’re creating a `.babelrc` file.) So if your project is in `~/app` and your files are in `~/app/src`, you can put `.babelrc` in either `~/app` or in `~/app/src`. A minimal `.babelrc` file for use with `babel-preset-env` would be just `{ "presets": ["env"] }`. +See [Babel’s website to learn about presets and plugins](https://babeljs.io/docs/plugins/) and the multitude of options you have. Another preset you might need is [`transform-react-jsx`](https://babeljs.io/docs/plugins/transform-react-jsx/) if you’re using JSX with React (JSX can also be used with other frameworks). Once you have `babel-core` and `babel-preset-env` (or other presets or plugins) installed, and a `.babelrc` file (or other equivalent) in place, you can use `coffee --transpile` to pipe CoffeeScript’s output through Babel using the options you’ve saved. @@ -50,4 +44,6 @@ CoffeeScript.compile(code, {transpile: {presets: ['env']}}) You can also transpile CoffeeScript’s output without using the `transpile` option, for example as part of a build chain. This lets you use transpilers other than Babel, and it gives you greater control over the process. There are many great task runners for setting up JavaScript build chains, such as [Gulp](http://gulpjs.com/), [Webpack](https://webpack.github.io/), [Grunt](https://gruntjs.com/) and [Broccoli](http://broccolijs.com/). -Note that [babel-preset-env](https://babeljs.io/docs/plugins/preset-env/) doesn’t automatically supply [polyfills](https://developer.mozilla.org/en-US/docs/Glossary/Polyfill) for your code. CoffeeScript itself will output [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) if you use the `in` operator, or destructuring or spread/rest syntax; and [`Function.bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) if you use a bound (`=>`) method in a class. Both are supported in Internet Explorer 9+ and all more recent browsers, but you will need to supply polyfills if you need to support Internet Explorer 8 or below and are using features that would cause these methods to be output. You’ll also need to supply polyfills if your own code uses these methods or another method added in recent versions of JavaScript. One polyfill option is [`babel-polyfill`](https://babeljs.io/docs/usage/polyfill/), though there are many [other](https://hackernoon.com/polyfills-everything-you-ever-wanted-to-know-or-maybe-a-bit-less-7c8de164e423) [strategies](https://philipwalton.com/articles/loading-polyfills-only-when-needed/). +#### Polyfills + +Note that transpiling doesn’t automatically supply [polyfills](https://developer.mozilla.org/en-US/docs/Glossary/Polyfill) for your code. CoffeeScript itself will output [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) if you use the `in` operator, or destructuring or spread/rest syntax; and [`Function.bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) if you use a bound (`=>`) method in a class. Both are supported in Internet Explorer 9+ and all more recent browsers, but you will need to supply polyfills if you need to support Internet Explorer 8 or below and are using features that would cause these methods to be output. You’ll also need to supply polyfills if your own code uses these methods or another method added in recent versions of JavaScript. One polyfill option is [`babel-polyfill`](https://babeljs.io/docs/usage/polyfill/), though there are many [other](https://hackernoon.com/polyfills-everything-you-ever-wanted-to-know-or-maybe-a-bit-less-7c8de164e423) [strategies](https://philipwalton.com/articles/loading-polyfills-only-when-needed/). From a5cdb30ffdcaea46e9bdca95c90261641cc3eb40 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 25 Sep 2017 22:45:45 -0700 Subject: [PATCH 8/8] =?UTF-8?q?Better=20identifier=20for=20compiled=20scri?= =?UTF-8?q?pts=20that=20didn=E2=80=99t=20come=20from=20files;=20better=20r?= =?UTF-8?q?esolving=20of=20paths?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/coffeescript/command.js | 11 +---------- src/command.coffee | 9 +-------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 819079394b..bf64200baa 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -638,16 +638,7 @@ // given to it in its `filename` option. Make sure we have a path to pass // along. if (!opts.transpile.filename) { - if (filename) { - opts.transpile.filename = filename; - } else { - opts.transpile.filename = base || process.cwd(); - if (opts.transpile.filename.endsWith(path.sep)) { - opts.transpile.filename += '.'; - } else { - opts.transpile.filename += path.sep + '.'; - } - } + opts.transpile.filename = filename || path.resolve(base || process.cwd(), ''); } } else { opts.transpile = false; diff --git a/src/command.coffee b/src/command.coffee index c6a8ea2983..c34dae5467 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -483,14 +483,7 @@ compileOptions = (filename, base) -> # given to it in its `filename` option. Make sure we have a path to pass # along. unless opts.transpile.filename - if filename - opts.transpile.filename = filename - else - opts.transpile.filename = base or process.cwd() - if opts.transpile.filename.endsWith(path.sep) - opts.transpile.filename += '.' - else - opts.transpile.filename += path.sep + '.' + opts.transpile.filename = filename or path.resolve(base or process.cwd(), '') else opts.transpile = no