From 80a456f7583c5a79a44cfed896250ae6df55c3cf Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sun, 10 Sep 2017 21:21:33 -0700 Subject: [PATCH 01/13] Upgrade Babeli (now babel-minify) which fixes the bug that was forcing us to run Babel twice for transpilation --- Cakefile | 11 +- package-lock.json | 368 +++++++++++++++++++++++++++++----------------- package.json | 2 +- 3 files changed, 237 insertions(+), 144 deletions(-) diff --git a/Cakefile b/Cakefile index f7145f2188..5315e588db 100644 --- a/Cakefile +++ b/Cakefile @@ -70,16 +70,9 @@ transpile = (code) -> babel = require 'babel-core' presets = [] # Exclude the `modules` plugin in order to not break the `}(this));` - # at the end of the above code block. + # at the end of the `build:browser` code block. presets.push ['env', {modules: no}] unless process.env.TRANSFORM is 'false' - babelOptions = - presets: presets - sourceType: 'script' - { code } = babel.transform code, babelOptions unless presets.length is 0 - # Running Babel twice due to https://github.com/babel/babili/issues/614. - # Once that issue is fixed, move the `babili` preset back up into the - # `presets` array and run Babel once with both presets together. - presets = if process.env.MINIFY is 'false' then [] else ['babili'] + presets.push 'minify' unless process.env.MINIFY is 'false' babelOptions = compact: process.env.MINIFY isnt 'false' presets: presets diff --git a/package-lock.json b/package-lock.json index 7fad923d4a..3d5ea72cbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -168,29 +168,6 @@ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", "dev": true }, - "babel-cli": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.24.1.tgz", - "integrity": "sha1-IHzXBbumFImy6kG1MSNBz2rKIoM=", - "dev": true, - "requires": { - "babel-core": "6.26.0", - "babel-polyfill": "6.23.0", - "babel-register": "6.24.1", - "babel-runtime": "6.23.0", - "chokidar": "1.7.0", - "commander": "2.11.0", - "convert-source-map": "1.5.0", - "fs-readdir-recursive": "1.0.0", - "glob": "7.1.2", - "lodash": "4.17.4", - "output-file-sync": "1.1.2", - "path-is-absolute": "1.0.1", - "slash": "1.0.0", - "source-map": "0.5.6", - "v8flags": "2.1.1" - } - }, "babel-code-frame": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", @@ -1026,17 +1003,6 @@ "integrity": "sha1-/isdKU6wXodSTrk3JN6m4sPWb6E=", "dev": true }, - "babel-polyfill": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", - "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "core-js": "2.4.1", - "regenerator-runtime": "0.10.5" - } - }, "babel-preset-babili": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/babel-preset-babili/-/babel-preset-babili-0.1.4.tgz", @@ -1106,19 +1072,240 @@ "semver": "5.3.0" } }, - "babel-register": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", - "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", - "dev": true, - "requires": { - "babel-core": "6.26.0", - "babel-runtime": "6.23.0", - "core-js": "2.4.1", - "home-or-tmp": "2.0.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "source-map-support": "0.4.15" + "babel-preset-minify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.2.0.tgz", + "integrity": "sha512-mR8Q44RmMzm18bM2Lqd9uiPopzk5GDCtVuquNbLFmX6lOKnqWoenaNBxnWW0UhBFC75lEHTIgNGCbnsRI0pJVw==", + "dev": true, + "requires": { + "babel-plugin-minify-builtins": "0.2.0", + "babel-plugin-minify-constant-folding": "0.2.0", + "babel-plugin-minify-dead-code-elimination": "0.2.0", + "babel-plugin-minify-flip-comparisons": "0.2.0", + "babel-plugin-minify-guarded-expressions": "0.2.0", + "babel-plugin-minify-infinity": "0.2.0", + "babel-plugin-minify-mangle-names": "0.2.0", + "babel-plugin-minify-numeric-literals": "0.2.0", + "babel-plugin-minify-replace": "0.2.0", + "babel-plugin-minify-simplify": "0.2.0", + "babel-plugin-minify-type-constructors": "0.2.0", + "babel-plugin-transform-inline-consecutive-adds": "0.2.0", + "babel-plugin-transform-member-expression-literals": "6.8.5", + "babel-plugin-transform-merge-sibling-variables": "6.8.6", + "babel-plugin-transform-minify-booleans": "6.8.3", + "babel-plugin-transform-property-literals": "6.8.5", + "babel-plugin-transform-regexp-constructors": "0.2.0", + "babel-plugin-transform-remove-console": "6.8.5", + "babel-plugin-transform-remove-debugger": "6.8.5", + "babel-plugin-transform-remove-undefined": "0.2.0", + "babel-plugin-transform-simplify-comparison-operators": "6.8.5", + "babel-plugin-transform-undefined-to-void": "6.8.3", + "lodash.isplainobject": "4.0.6" + }, + "dependencies": { + "babel-helper-evaluate-path": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.2.0.tgz", + "integrity": "sha512-0EK9TUKMxHL549hWDPkQoS7R0Ozg1CDLheVBHYds2B2qoAvmr9ejY3zOXFsrICK73TN7bPhU14PBeKc8jcBTwg==", + "dev": true + }, + "babel-helper-flip-expressions": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.2.0.tgz", + "integrity": "sha512-rAsPA1pWBc7e2E6HepkP2e1sXugT+Oq/VCqhyuHJ8aJ2d/ifwnJfd4Qxjm21qlW43AN8tqaeByagKK6wECFMSw==", + "dev": true + }, + "babel-helper-is-void-0": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.2.0.tgz", + "integrity": "sha512-Axj1AYuD0E3Dl7nT3KxROP7VekEofz3XtEljzURf3fABalLpr8PamtgLFt+zuxtaCxRf9iuZmbAMMYWri5Bazw==", + "dev": true + }, + "babel-helper-mark-eval-scopes": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.2.0.tgz", + "integrity": "sha512-KJuwrOUcHbvbh6he4xRXZFLaivK9DF9o3CrvpWnK1Wp0B+1ANYABXBMgwrnNFIDK/AvicxQ9CNr8wsgivlp4Aw==", + "dev": true + }, + "babel-helper-remove-or-void": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.2.0.tgz", + "integrity": "sha512-1Z41upf/XR+PwY7Nd+F15Jo5BiQi5205ZXUuKed3yoyQgDkMyoM7vAdjEJS/T+M6jy32sXjskMUgms4zeiVtRA==", + "dev": true + }, + "babel-helper-to-multiple-sequence-expressions": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.2.0.tgz", + "integrity": "sha512-ij9lpfdP3+Zc/7kNwa+NXbTrUlsYEWPwt/ugmQO0qflzLrveTIkbfOqQztvitk81aG5NblYDQXDlRohzu3oa8Q==", + "dev": true + }, + "babel-plugin-minify-builtins": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.2.0.tgz", + "integrity": "sha512-4i+8ntaS8gwVUcOz5y+zE+55OVOl2nTbmHV51D4wAIiKcRI8U5K//ip1GHfhsgk/NJrrHK7h97Oy5jpqt0Iixg==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "0.2.0" + } + }, + "babel-plugin-minify-constant-folding": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.2.0.tgz", + "integrity": "sha512-B3ffQBEUQ8ydlIkYv2MkZtTCbV7FAkWAV7NkyhcXlGpD10PaCxNGQ/B9oguXGowR1m16Q5nGhvNn8Pkn1MO6Hw==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "0.2.0" + } + }, + "babel-plugin-minify-dead-code-elimination": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.2.0.tgz", + "integrity": "sha512-zE7y3pRyzA4zK5nBou0kTcwUTSQ/AiFrynt1cIEYN7vcO2gS9ZFZoI0aO9JYLUdct5fsC1vfB35408yrzTyVfg==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "0.2.0", + "babel-helper-mark-eval-scopes": "0.2.0", + "babel-helper-remove-or-void": "0.2.0", + "lodash.some": "4.6.0" + } + }, + "babel-plugin-minify-flip-comparisons": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.2.0.tgz", + "integrity": "sha512-QOqXSEmD/LhT3LpM1WCyzAGcQZYYKJF7oOHvS6QbpomHenydrV53DMdPX2mK01icBExKZcJAHF209wvDBa+CSg==", + "dev": true, + "requires": { + "babel-helper-is-void-0": "0.2.0" + } + }, + "babel-plugin-minify-guarded-expressions": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.2.0.tgz", + "integrity": "sha512-5+NSPdRQ9mnrHaA+zFj+D5OzmSiv90EX5zGH6cWQgR/OUqmCHSDqgTRPFvOctgpo8MJyO7Rt7ajs2UfLnlAwYg==", + "dev": true, + "requires": { + "babel-helper-flip-expressions": "0.2.0" + } + }, + "babel-plugin-minify-infinity": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.2.0.tgz", + "integrity": "sha512-U694vrla1lN6vDHWGrR832t3a/A2eh+kyl019LxEE2+sS4VTydyOPRsAOIYAdJegWRA4cMX1lm9azAN0cLIr8g==", + "dev": true + }, + "babel-plugin-minify-mangle-names": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.2.0.tgz", + "integrity": "sha512-Gixuak1/CO7VCdjn15/8Bxe/QsAtDG4zPbnsNoe1mIJGCIH/kcmSjFhMlGJtXDQZd6EKzeMfA5WmX9+jvGRefw==", + "dev": true, + "requires": { + "babel-helper-mark-eval-scopes": "0.2.0" + } + }, + "babel-plugin-minify-numeric-literals": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.2.0.tgz", + "integrity": "sha512-VcLpb+r1YS7+RIOXdRsFVLLqoh22177USpHf+JM/g1nZbzdqENmfd5v534MLAbRErhbz6SyK+NQViVzVtBxu8g==", + "dev": true + }, + "babel-plugin-minify-replace": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.2.0.tgz", + "integrity": "sha512-SEW6zoSVxh3OH6E1LCgyhhTWMnCv+JIRu5h5IlJDA11tU4ZeSF7uPQcO4vN/o52+FssRB26dmzJ/8D+z0QPg5Q==", + "dev": true + }, + "babel-plugin-minify-simplify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.2.0.tgz", + "integrity": "sha512-Mj3Mwy2zVosMfXDWXZrQH5/uMAyfJdmDQ1NVqit+ArbHC3LlXVzptuyC1JxTyai/wgFvjLaichm/7vSUshkWqw==", + "dev": true, + "requires": { + "babel-helper-flip-expressions": "0.2.0", + "babel-helper-is-nodes-equiv": "0.0.1", + "babel-helper-to-multiple-sequence-expressions": "0.2.0" + } + }, + "babel-plugin-minify-type-constructors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.2.0.tgz", + "integrity": "sha512-NiOvvA9Pq6bki6nP4BayXwT5GZadw7DJFDDzHmkpnOQpENWe8RtHtKZM44MG1R6EQ5XxgbLdsdhswIzTkFlO5g==", + "dev": true, + "requires": { + "babel-helper-is-void-0": "0.2.0" + } + }, + "babel-plugin-transform-inline-consecutive-adds": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.2.0.tgz", + "integrity": "sha512-GlhOuLOQ28ua9prg0hT33HslCrEmz9xWXy9ZNZSACppCyRxxRW+haYtRgm7uYXCcd0q8ggCWD2pfWEJp5iiZfQ==", + "dev": true + }, + "babel-plugin-transform-member-expression-literals": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.5.tgz", + "integrity": "sha512-Ux3ligf+ukzWaCbBYOstDuFBhRgMiJHlpJBKV4P47qtzVkd0lg1ddPj9fqIJqAM0n+CvxipyrZrnNnw3CdtQCg==", + "dev": true + }, + "babel-plugin-transform-merge-sibling-variables": { + "version": "6.8.6", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.6.tgz", + "integrity": "sha512-o5Jioq553HtEAUN5uty7ELJMenXIxHI3PIs1yLqYWYQwP6mg6IPVAJ+U7i4zr9XGF/kb2RGsdehglGTV+vngqA==", + "dev": true + }, + "babel-plugin-transform-minify-booleans": { + "version": "6.8.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.3.tgz", + "integrity": "sha512-bPbUhkeN2Nc0KH0/A19GwQGj8w+CvdJzyu8t59VoEDgsNMQ9Bopzi5DrVkrSsVjbYUaZpzq/DYLrH+wD5K2Tig==", + "dev": true + }, + "babel-plugin-transform-property-literals": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.5.tgz", + "integrity": "sha512-MmiQsQ5AcIaRZMJD0zY5C4H3xuHm06/nWgtOsz7AXV44VEIXIlPiJ39IFYJ4Qx67/fEm8zJAedzR8t+B7d10Bg==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "babel-plugin-transform-regexp-constructors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.2.0.tgz", + "integrity": "sha512-7IsQ6aQx6LAaOqy97/PthTf+5Nx9grZww3r6E62IdWe76Yr8KsuwVjxzqSPQvESJqTE3EMADQ9S0RtwWDGNG9Q==", + "dev": true + }, + "babel-plugin-transform-remove-console": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.5.tgz", + "integrity": "sha512-uuCKvtweCyIvvC8fi92EcWRtO2Kt5KMNMRK6BhpDXdeb3sxvGM7453RSmgeu4DlKns3OlvY9Ep5Q9m5a7RQAgg==", + "dev": true + }, + "babel-plugin-transform-remove-debugger": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.5.tgz", + "integrity": "sha512-InDQDdHPOLJKM+G6oXrEesf+P29QFBmcTXID+TAvZziVz+38xe2VO/Bn3FcRcRtnOOycbgsJkUNp9jIK+ist6g==", + "dev": true + }, + "babel-plugin-transform-remove-undefined": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.2.0.tgz", + "integrity": "sha512-O8v57tPMHkp89kA4ZfQEYds/pzgvz/QYerBJjIuL5/Jc7RnvMVRA5gJY9zFKP7WayW8WOSBV4vh8Y8FJRio+ow==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "0.2.0" + } + }, + "babel-plugin-transform-simplify-comparison-operators": { + "version": "6.8.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.5.tgz", + "integrity": "sha512-B3HlBZb+Uq86nRj5yNPO6pJ3noEdqHvzYkEYoUWtrsWTv48ZIRatYlumoOiif/v8llF13YjYjx9zhyznDx+N9g==", + "dev": true + }, + "babel-plugin-transform-undefined-to-void": { + "version": "6.8.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.3.tgz", + "integrity": "sha512-goYwp8dMrzHD6x9GjZ2M85Mk2vxf1h85CnUgAjfftUnlJvzF4uj5MrbReHBTbjQ96C8CuRzvhYZ3tv8H3Sc1ZA==", + "dev": true + } } }, "babel-runtime": { @@ -1173,16 +1360,6 @@ "to-fast-properties": "1.0.3" } }, - "babili": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/babili/-/babili-0.1.4.tgz", - "integrity": "sha1-Q7t2hmTTd96oS6l3q8WwG9WWbxE=", - "dev": true, - "requires": { - "babel-cli": "6.24.1", - "babel-preset-babili": "0.1.4" - } - }, "babylon": { "version": "6.17.4", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", @@ -2009,18 +2186,6 @@ "universalify": "0.1.0" } }, - "fs-readdir-recursive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz", - "integrity": "sha1-jNF0XItPiinIyuw5JHaSG6GV9WA=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, "fsevents": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz", @@ -3045,20 +3210,6 @@ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, "glob-base": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", @@ -3175,16 +3326,6 @@ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", "dev": true }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -3816,15 +3957,6 @@ "is-extendable": "0.1.1" } }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, "os-browserify": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", @@ -3854,17 +3986,6 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "output-file-sync": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", - "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "mkdirp": "0.5.1", - "object-assign": "4.1.1" - } - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -4592,12 +4713,6 @@ } } }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", @@ -4621,15 +4736,6 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "1.1.1" - } - }, "validate-npm-package-license": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", @@ -4761,12 +4867,6 @@ } } }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index 70a1ab42a7..7b7fa2fedb 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "babel-core": "~6.26.0", "babel-preset-babili": "~0.1.4", "babel-preset-env": "~1.6.0", - "babili": "^0.1.4", + "babel-preset-minify": "^0.2.0", "codemirror": "^5.29.0", "docco": "~0.7.0", "highlight.js": "~9.12.0", From 582d4881fe53d1147b1d15ade6c9b4f2fc9867d1 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 11 Sep 2017 00:32:03 -0700 Subject: [PATCH 02/13] Add --transpile option (WIP) --- .babelrc | 3 ++ lib/coffeescript/coffeescript.js | 16 +++++- lib/coffeescript/command.js | 87 ++++++++++++++++++++++++++++++-- package.json | 3 ++ src/coffeescript.coffee | 12 +++++ src/command.coffee | 85 +++++++++++++++++++++++++++++-- test/argument_parsing.coffee | 3 +- 7 files changed, 200 insertions(+), 9 deletions(-) create mode 100644 .babelrc diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000000..002b4aa0d5 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["env"] +} diff --git a/lib/coffeescript/coffeescript.js b/lib/coffeescript/coffeescript.js index 491b16e7d4..82d11fd84f 100644 --- a/lib/coffeescript/coffeescript.js +++ b/lib/coffeescript/coffeescript.js @@ -85,7 +85,7 @@ // object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for // doing programmatic lookups. exports.compile = compile = withPrettyErrors(function(code, options) { - var currentColumn, currentLine, encoded, extend, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, merge, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, v3SourceMap; + var babel, babelOutput, currentColumn, currentLine, encoded, extend, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, merge, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, v3SourceMap; ({merge, extend} = helpers); options = extend({}, options); // Always generate a source map if no filename is passed in, since without a @@ -167,6 +167,20 @@ } sourceMaps[filename].push(map); } + if (options.transpile) { + // See https://github.com/babel/babel/issues/827#issuecomment-77573107: + // Babel can take a v3 source map object as input in `inputSourceMap` + // and it will return an *updated* v3 source map object in its output. + if (generateSourceMap && (options.transpile.inputSourceMap == null)) { + options.transpile.inputSourceMap = v3SourceMap; + } + babel = require('babel-core'); + babelOutput = babel.transform(js, options.transpile); + js = babelOutput.code; + if (options.sourceMap && babelOutput.map) { + v3SourceMap = babelOutput.map; + } + } if (options.inlineMap) { encoded = base64encode(JSON.stringify(v3SourceMap)); sourceMapDataURI = `//# sourceMappingURL=data:application/json;base64,${encoded}`; diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index c72af0e476..68ccb43d8c 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -45,7 +45,7 @@ BANNER = 'Usage: coffee [options] path/to/script.coffee [args]\n\nIf called without options, `coffee` will run your script.'; // The list of all the valid option flags that `coffee` knows how to handle. - SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-m', '--map', 'generate source map and save as .js.map files'], ['-M', '--inline-map', 'generate source map and include it directly in output'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [PATH]', 'set the output path or path/filename for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [MODULE*]', 'require the given module before eval or REPL'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffeescript'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']]; + SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-m', '--map', 'generate source map and save as .js.map files'], ['-M', '--inline-map', 'generate source map and include it directly in output'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [PATH]', 'set the output path or path/filename for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-r', '--require [MODULE*]', 'require the given module before eval or REPL'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffeescript'], ['-t', '--transpile', 'pipe generated JavaScript through Babel'], ['--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']]; // Top-level objects shared by all the functions. opts = {}; @@ -605,12 +605,93 @@ // The compile-time options to pass to the CoffeeScript compiler. compileOptions = function(filename, base) { - var answer, cwd, jsDir, jsPath; + var answer, babel, babelOptions, checkPath, cwd, exception, jsDir, jsPath, ref; + if (opts.transpile && ((ref = opts.transpile) !== false && ref !== 0 && ref !== 'false' && ref !== 'off' && ref !== 'no' && ref !== '0')) { + 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. + babel = require('babel-core'); + } catch (error) { + exception = error; + console.error('To use --transpile, you must have Babel installed and configured\nSee http://coffeescript.org/#usage'); + 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') { + // Only possible via the Node API. + babelOptions = opts.transpile; + } else { + if (typeof opts.transpile === 'string') { + try { + // This is only possible via the Node API; did that API pass us a path + // to a `.babelrc` or `package.json` file? + opts.transpile = JSON.parse(fs.readFileSync(opts.transpile, 'utf-8')); + } catch (error) { + try { + opts.transpile = JSON.parse(fs.readFileSync(path.join(process.cwd(), opts.transpile), 'utf-8')); + } catch (error) { + console.error(`Babel options could not be loaded from ${opts.transpile}`); + process.exit(1); + } + } + if (opts.transpile.babel) { + opts.transpile = opts.transpile.babel; + } + } else { + // This is the code path from the CLI `--transpile`, or from the Node + // API if `transpile` is set to `true`. Find the options based on the + // path to the file being compiled; or if we aren’t given a path, die. + // When calling `compile` via the Node API, if `transpile` is + // specified it must be a resolvable path (see above) or an object + // that can be passed to Babel as its options. + if (filename) { + checkPath = path.dirname(filename); + while (true) { + try { + opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, '.babelrc'), 'utf-8')); + break; + } catch (error) { + try { + opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8')).babel; + break; + } catch (error) {} + } + if (checkPath === path.dirname(checkPath)) { // We’ve reached the root. + break; + } + checkPath = path.dirname(checkPath); + } + } else { + console.error('To use the transpile option without giving the compiler a filename,\nthe transpile option must be either:\n- a string path to a .babelrc file or package.json file with a babel key\n- an object to pass to Babel as its options (if compiling via the API)'); + process.exit(1); + } + } + } + // Whew! By now we’ve populated `opts.transpile` with the options to pass + // to Babel, if at all possible. Fill in a few more options unless the user + // has explicitly defined them. + if (opts.transpile.sourceMaps == null) { + if (opts.map && opts['inline-map']) { + opts.transpile.sourceMaps = 'both'; + } else if (opts.map) { + opts.transpile.sourceMaps = true; + } else if (opts['inline-map']) { + opts.transpile.sourceMaps = 'inline'; + } + } + } else { + opts.transpile = false; + } answer = { - filename, + filename: filename, literate: opts.literate || helpers.isLiterate(filename), bare: opts.bare, header: opts.compile && !opts['no-header'], + transpile: opts.transpile, sourceMap: opts.map, inlineMap: opts['inline-map'] }; diff --git a/package.json b/package.json index 7b7fa2fedb..adaa7cb750 100644 --- a/package.json +++ b/package.json @@ -51,5 +51,8 @@ "underscore": "~1.8.3", "webpack": "~3.5.6" }, + "optionalDependencies": { + "babel-core": "^6" + }, "dependencies": {} } diff --git a/src/coffeescript.coffee b/src/coffeescript.coffee index b7eae3ac34..fc91438b6e 100644 --- a/src/coffeescript.coffee +++ b/src/coffeescript.coffee @@ -129,6 +129,18 @@ exports.compile = compile = withPrettyErrors (code, options) -> sourceMaps[filename] ?= [] sourceMaps[filename].push map + if options.transpile + # See https://github.com/babel/babel/issues/827#issuecomment-77573107: + # Babel can take a v3 source map object as input in `inputSourceMap` + # and it will return an *updated* v3 source map object in its output. + if generateSourceMap and not options.transpile.inputSourceMap? + options.transpile.inputSourceMap = v3SourceMap + babel = require 'babel-core' + babelOutput = babel.transform js, options.transpile + js = babelOutput.code + if options.sourceMap and babelOutput.map + v3SourceMap = babelOutput.map + if options.inlineMap encoded = base64encode JSON.stringify v3SourceMap sourceMapDataURI = "//# sourceMappingURL=data:application/json;base64,#{encoded}" diff --git a/src/command.coffee b/src/command.coffee index d9e62627e5..a023592c80 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -48,7 +48,8 @@ SWITCHES = [ ['-r', '--require [MODULE*]', 'require the given module before eval or REPL'] ['-s', '--stdio', 'listen for and compile scripts over stdio'] ['-l', '--literate', 'treat stdio as literate style coffeescript'] - ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'] + ['-t', '--transpile', 'pipe generated JavaScript through Babel'] + [ '--tokens', 'print out the tokens that the lexer/rewriter produce'] ['-v', '--version', 'display the version number'] ['-w', '--watch', 'watch scripts for changes and rerun commands'] ] @@ -441,14 +442,90 @@ parseOptions = -> # The compile-time options to pass to the CoffeeScript compiler. compileOptions = (filename, base) -> - answer = { - filename + if opts.transpile and opts.transpile not in [no, 0, 'false', 'off', 'no', '0'] + # 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. + try + babel = require 'babel-core' + catch exception + console.error ''' + To use --transpile, you must have Babel installed and configured + See http://coffeescript.org/#usage + ''' + 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 is 'object' + # Only possible via the Node API. + babelOptions = opts.transpile + else + if typeof opts.transpile is 'string' + # This is only possible via the Node API; did that API pass us a path + # to a `.babelrc` or `package.json` file? + try + opts.transpile = JSON.parse fs.readFileSync opts.transpile, 'utf-8' + catch + try + opts.transpile = JSON.parse fs.readFileSync path.join(process.cwd(), opts.transpile), 'utf-8' + catch + console.error "Babel options could not be loaded from #{opts.transpile}" + process.exit 1 + opts.transpile = opts.transpile.babel if opts.transpile.babel + else + # This is the code path from the CLI `--transpile`, or from the Node + # API if `transpile` is set to `true`. Find the options based on the + # path to the file being compiled; or if we aren’t given a path, die. + # When calling `compile` via the Node API, if `transpile` is + # specified it must be a resolvable path (see above) or an object + # that can be passed to Babel as its options. + if filename + checkPath = path.dirname filename + loop + try + opts.transpile = JSON.parse fs.readFileSync path.join(checkPath, '.babelrc'), 'utf-8' + break + catch + try + opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8')).babel + break + + break if checkPath is path.dirname checkPath # We’ve reached the root. + checkPath = path.dirname checkPath + else + console.error ''' + To use the transpile option without giving the compiler a filename, + the transpile option must be either: + - a string path to a .babelrc file or package.json file with a babel key + - an object to pass to Babel as its options (if compiling via the API) + ''' + process.exit 1 + + # Whew! By now we’ve populated `opts.transpile` with the options to pass + # to Babel, if at all possible. Fill in a few more options unless the user + # has explicitly defined them. + unless opts.transpile.sourceMaps? + if opts.map and opts['inline-map'] + opts.transpile.sourceMaps = 'both' + else if opts.map + opts.transpile.sourceMaps = yes + else if opts['inline-map'] + opts.transpile.sourceMaps = 'inline' + else + opts.transpile = no + + answer = + filename: filename literate: opts.literate or helpers.isLiterate(filename) bare: opts.bare header: opts.compile and not opts['no-header'] + transpile: opts.transpile sourceMap: opts.map inlineMap: opts['inline-map'] - } + if filename if base cwd = process.cwd() diff --git a/test/argument_parsing.coffee b/test/argument_parsing.coffee index 2ed4fdb8c7..6c613956e8 100644 --- a/test/argument_parsing.coffee +++ b/test/argument_parsing.coffee @@ -135,7 +135,8 @@ If called without options, `coffee` will run your script. -r, --require require the given module before eval or REPL -s, --stdio listen for and compile scripts over stdio -l, --literate treat stdio as literate style coffeescript - -t, --tokens print out the tokens that the lexer/rewriter produce + -t, --transpile pipe generated JavaScript through Babel + --tokens print out the tokens that the lexer/rewriter produce -v, --version display the version number -w, --watch watch scripts for changes and rerun commands From f826bf16c9dead7409c1af05a6a641ffb8528a0e Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 11 Sep 2017 01:02:49 -0700 Subject: [PATCH 03/13] =?UTF-8?q?Node=20API=20always=20compiles=20a=20stri?= =?UTF-8?q?ng,=20so=20it=20doesn=E2=80=99t=20need=20the=20option=20to=20pa?= =?UTF-8?q?ss=20a=20path=20to=20an=20options=20file,=20it=20can=20always?= =?UTF-8?q?=20just=20pass=20an=20object=20to=20`transpile`;=20get=20`trans?= =?UTF-8?q?pile`=20working=20with=20`eval`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/coffeescript/command.js | 63 ++++++++++--------------------- src/command.coffee | 74 +++++++++++++++++-------------------- 2 files changed, 52 insertions(+), 85 deletions(-) diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 68ccb43d8c..ac4422c399 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -605,13 +605,13 @@ // The compile-time options to pass to the CoffeeScript compiler. compileOptions = function(filename, base) { - var answer, babel, babelOptions, checkPath, cwd, exception, jsDir, jsPath, ref; + var answer, cantFindOptions, checkPath, cwd, exception, jsDir, jsPath, ref; if (opts.transpile && ((ref = opts.transpile) !== false && ref !== 0 && ref !== 'false' && ref !== 'off' && ref !== 'no' && ref !== '0')) { 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. - babel = require('babel-core'); + require('babel-core'); } catch (error) { exception = error; console.error('To use --transpile, you must have Babel installed and configured\nSee http://coffeescript.org/#usage'); @@ -621,53 +621,28 @@ // 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') { - // Only possible via the Node API. - babelOptions = opts.transpile; - } else { - if (typeof opts.transpile === 'string') { + 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/#usage'); + return process.exit(1); + }; + checkPath = filename ? path.dirname(filename) : base ? base : typeof process !== "undefined" && process !== null ? process.cwd() : cantFindOptions(); + while (true) { try { - // This is only possible via the Node API; did that API pass us a path - // to a `.babelrc` or `package.json` file? - opts.transpile = JSON.parse(fs.readFileSync(opts.transpile, 'utf-8')); + opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, '.babelrc'), 'utf-8')); + break; } catch (error) { try { - opts.transpile = JSON.parse(fs.readFileSync(path.join(process.cwd(), opts.transpile), 'utf-8')); - } catch (error) { - console.error(`Babel options could not be loaded from ${opts.transpile}`); - process.exit(1); - } - } - if (opts.transpile.babel) { - opts.transpile = opts.transpile.babel; + opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8')).babel; + break; + } catch (error) {} } - } else { - // This is the code path from the CLI `--transpile`, or from the Node - // API if `transpile` is set to `true`. Find the options based on the - // path to the file being compiled; or if we aren’t given a path, die. - // When calling `compile` via the Node API, if `transpile` is - // specified it must be a resolvable path (see above) or an object - // that can be passed to Babel as its options. - if (filename) { - checkPath = path.dirname(filename); - while (true) { - try { - opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, '.babelrc'), 'utf-8')); - break; - } catch (error) { - try { - opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8')).babel; - break; - } catch (error) {} - } - if (checkPath === path.dirname(checkPath)) { // We’ve reached the root. - break; - } - checkPath = path.dirname(checkPath); - } + if (checkPath === path.dirname(checkPath)) { // We’ve reached the root. + cantFindOptions(); + break; } else { - console.error('To use the transpile option without giving the compiler a filename,\nthe transpile option must be either:\n- a string path to a .babelrc file or package.json file with a babel key\n- an object to pass to Babel as its options (if compiling via the API)'); - process.exit(1); + checkPath = path.dirname(checkPath); } } } diff --git a/src/command.coffee b/src/command.coffee index a023592c80..fc39761627 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -447,7 +447,7 @@ compileOptions = (filename, base) -> # via Babel. We use Babel as an `optionalDependency`; see # https://docs.npmjs.com/files/package.json#optionaldependencies. try - babel = require 'babel-core' + require 'babel-core' catch exception console.error ''' To use --transpile, you must have Babel installed and configured @@ -459,50 +459,42 @@ compileOptions = (filename, base) -> # 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 is 'object' - # Only possible via the Node API. - babelOptions = opts.transpile - else - if typeof opts.transpile is 'string' - # This is only possible via the Node API; did that API pass us a path - # to a `.babelrc` or `package.json` file? + 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/#usage + ''' + 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 opts.transpile, 'utf-8' + opts.transpile = JSON.parse fs.readFileSync path.join(checkPath, '.babelrc'), 'utf-8' + break catch try - opts.transpile = JSON.parse fs.readFileSync path.join(process.cwd(), opts.transpile), 'utf-8' - catch - console.error "Babel options could not be loaded from #{opts.transpile}" - process.exit 1 - opts.transpile = opts.transpile.babel if opts.transpile.babel - else - # This is the code path from the CLI `--transpile`, or from the Node - # API if `transpile` is set to `true`. Find the options based on the - # path to the file being compiled; or if we aren’t given a path, die. - # When calling `compile` via the Node API, if `transpile` is - # specified it must be a resolvable path (see above) or an object - # that can be passed to Babel as its options. - if filename - checkPath = path.dirname filename - loop - try - opts.transpile = JSON.parse fs.readFileSync path.join(checkPath, '.babelrc'), 'utf-8' - break - catch - try - opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8')).babel - break - - break if checkPath is path.dirname checkPath # We’ve reached the root. - checkPath = path.dirname checkPath + opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8')).babel + break + + if checkPath is path.dirname checkPath # We’ve reached the root. + cantFindOptions() + break else - console.error ''' - To use the transpile option without giving the compiler a filename, - the transpile option must be either: - - a string path to a .babelrc file or package.json file with a babel key - - an object to pass to Babel as its options (if compiling via the API) - ''' - process.exit 1 + checkPath = path.dirname checkPath # Whew! By now we’ve populated `opts.transpile` with the options to pass # to Babel, if at all possible. Fill in a few more options unless the user From e6a042f622e282b2d48fe681d598ccab1b35a8d5 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 11 Sep 2017 01:10:59 -0700 Subject: [PATCH 04/13] =?UTF-8?q?Not=20allowing=20argument=20to=20`--trans?= =?UTF-8?q?pile`=20so=20don=E2=80=99t=20need=20to=20cover=20so=20many=20ca?= =?UTF-8?q?ses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/coffeescript/command.js | 4 ++-- src/command.coffee | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index ac4422c399..59962087af 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -605,8 +605,8 @@ // The compile-time options to pass to the CoffeeScript compiler. compileOptions = function(filename, base) { - var answer, cantFindOptions, checkPath, cwd, exception, jsDir, jsPath, ref; - if (opts.transpile && ((ref = opts.transpile) !== false && ref !== 0 && ref !== 'false' && ref !== 'off' && ref !== 'no' && ref !== '0')) { + var answer, cantFindOptions, checkPath, cwd, exception, jsDir, jsPath; + if (opts.transpile) { try { // The user has requested that the CoffeeScript compiler also transpile // via Babel. We use Babel as an `optionalDependency`; see diff --git a/src/command.coffee b/src/command.coffee index fc39761627..6119645afb 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -442,7 +442,7 @@ parseOptions = -> # The compile-time options to pass to the CoffeeScript compiler. compileOptions = (filename, base) -> - if opts.transpile and opts.transpile not in [no, 0, 'false', 'off', 'no', '0'] + 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. From 9eaad641226dc9c244f652c024175fe45df92861 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 11 Sep 2017 01:13:58 -0700 Subject: [PATCH 05/13] =?UTF-8?q?Don=E2=80=99t=20need=20to=20worry=20about?= =?UTF-8?q?=20`sourceMaps`=20option=20to=20pass=20to=20Babel,=20`inputSour?= =?UTF-8?q?ceMap`=20overrides=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/coffeescript/command.js | 17 ++--------------- src/command.coffee | 15 ++------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 59962087af..412b440a17 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, exception, jsDir, jsPath; + var answer, cantFindOptions, checkPath, cwd, jsDir, jsPath; if (opts.transpile) { try { // The user has requested that the CoffeeScript compiler also transpile @@ -613,8 +613,7 @@ // https://docs.npmjs.com/files/package.json#optionaldependencies. require('babel-core'); } catch (error) { - exception = error; - console.error('To use --transpile, you must have Babel installed and configured\nSee http://coffeescript.org/#usage'); + console.error('To use --transpile, you must have Babel installed and configured.\nSee http://coffeescript.org/#usage'); process.exit(1); } // We’re giving Babel only a string, not a filename or path to a file, so @@ -646,18 +645,6 @@ } } } - // Whew! By now we’ve populated `opts.transpile` with the options to pass - // to Babel, if at all possible. Fill in a few more options unless the user - // has explicitly defined them. - if (opts.transpile.sourceMaps == null) { - if (opts.map && opts['inline-map']) { - opts.transpile.sourceMaps = 'both'; - } else if (opts.map) { - opts.transpile.sourceMaps = true; - } else if (opts['inline-map']) { - opts.transpile.sourceMaps = 'inline'; - } - } } else { opts.transpile = false; } diff --git a/src/command.coffee b/src/command.coffee index 6119645afb..d9a6b3fe88 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -448,9 +448,9 @@ compileOptions = (filename, base) -> # https://docs.npmjs.com/files/package.json#optionaldependencies. try require 'babel-core' - catch exception + catch console.error ''' - To use --transpile, you must have Babel installed and configured + To use --transpile, you must have Babel installed and configured. See http://coffeescript.org/#usage ''' process.exit 1 @@ -495,17 +495,6 @@ compileOptions = (filename, base) -> break else checkPath = path.dirname checkPath - - # Whew! By now we’ve populated `opts.transpile` with the options to pass - # to Babel, if at all possible. Fill in a few more options unless the user - # has explicitly defined them. - unless opts.transpile.sourceMaps? - if opts.map and opts['inline-map'] - opts.transpile.sourceMaps = 'both' - else if opts.map - opts.transpile.sourceMaps = yes - else if opts['inline-map'] - opts.transpile.sourceMaps = 'inline' else opts.transpile = no From 9206a2639218352a17d9475a73adba9e8267b05a Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Tue, 12 Sep 2017 23:42:28 -0700 Subject: [PATCH 06/13] Rewrite Webpack test to use Node API --- Cakefile | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/Cakefile b/Cakefile index 5315e588db..e8629054e8 100644 --- a/Cakefile +++ b/Cakefile @@ -93,7 +93,7 @@ testBuiltCode = (watch = no) -> buildAndTest = (includingParser = yes, harmony = no) -> process.stdout.write '\x1Bc' # Clear terminal screen. - execSync 'git checkout lib/*', stdio: [0,1,2] # Reset the generated compiler. + execSync 'git checkout lib/*', stdio: 'inherit' # Reset the generated compiler. buildArgs = ['bin/cake'] buildArgs.push if includingParser then 'build' else 'build:except-parser' @@ -487,20 +487,28 @@ task 'test:integrations', 'test the module integrated with other libraries and e # Node modules are required as part of the compiler (as opposed to the tests) # and that therefore the compiler will run in a browser environment. tmpdir = os.tmpdir() - try - buildLog = execSync "./node_modules/webpack/bin/webpack.js - --entry=./ - --output-library=CoffeeScript - --output-library-target=commonjs2 - --output-path=#{tmpdir} - --output-filename=coffeescript.js" - catch exception - console.error buildLog.toString() - throw exception - - builtCompiler = path.join tmpdir, 'coffeescript.js' - CoffeeScript = require builtCompiler - global.testingBrowser = yes - testResults = runTests CoffeeScript - fs.unlinkSync builtCompiler - process.exit 1 unless testResults + webpack = require 'webpack' + webpack { + entry: './' + output: + path: tmpdir + filename: 'coffeescript.js' + library: 'CoffeeScript' + libraryTarget: 'commonjs2' + }, (err, stats) -> + if err or stats.hasErrors() + if err + console.error err.stack or err + console.error err.details if err.details + if stats.hasErrors() + console.error error for error in stats.compilation.errors + if stats.hasWarnings() + console.warn warning for warning in stats.compilation.warnings + process.exit 1 + + builtCompiler = path.join tmpdir, 'coffeescript.js' + CoffeeScript = require builtCompiler + global.testingBrowser = yes + testResults = runTests CoffeeScript + fs.unlinkSync builtCompiler + process.exit 1 unless testResults From 790bb51d5bc8742e35c466bbaeb7e7b9e634a7f9 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Wed, 13 Sep 2017 00:28:58 -0700 Subject: [PATCH 07/13] Make the compiler safe again for browsers and Webpack/Browserify --- lib/coffeescript/coffeescript.js | 22 +++++++++++++++------- lib/coffeescript/command.js | 5 +++++ lib/coffeescript/index.js | 23 ++++++++++++++++++++++- src/coffeescript.coffee | 21 +++++++++++++++------ src/command.coffee | 6 ++++++ src/index.coffee | 19 ++++++++++++++++++- 6 files changed, 81 insertions(+), 15 deletions(-) diff --git a/lib/coffeescript/coffeescript.js b/lib/coffeescript/coffeescript.js index 82d11fd84f..9433161686 100644 --- a/lib/coffeescript/coffeescript.js +++ b/lib/coffeescript/coffeescript.js @@ -85,7 +85,7 @@ // object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for // doing programmatic lookups. exports.compile = compile = withPrettyErrors(function(code, options) { - var babel, babelOutput, currentColumn, currentLine, encoded, extend, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, merge, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, v3SourceMap; + var currentColumn, currentLine, encoded, extend, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, merge, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, transpiler, transpilerOutput, v3SourceMap; ({merge, extend} = helpers); options = extend({}, options); // Always generate a source map if no filename is passed in, since without a @@ -168,17 +168,25 @@ sourceMaps[filename].push(map); } if (options.transpile) { + if (typeof options.transpile !== 'object') { + // This only happens if run via the Node API and `transpile` is set to + // something other than an object. + throw new Error('The transpile option must be given an object with options to pass to Babel'); + } + // Get the reference to Babel that we have been passed if this compiler + // is run via the CLI or Node API. + transpiler = options.transpile.transpile; + delete options.transpile.transpile; // See https://github.com/babel/babel/issues/827#issuecomment-77573107: // Babel can take a v3 source map object as input in `inputSourceMap` // and it will return an *updated* v3 source map object in its output. - if (generateSourceMap && (options.transpile.inputSourceMap == null)) { + if (v3SourceMap && (options.transpile.inputSourceMap == null)) { options.transpile.inputSourceMap = v3SourceMap; } - babel = require('babel-core'); - babelOutput = babel.transform(js, options.transpile); - js = babelOutput.code; - if (options.sourceMap && babelOutput.map) { - v3SourceMap = babelOutput.map; + transpilerOutput = transpiler(js, options.transpile); + js = transpilerOutput.code; + if (v3SourceMap && transpilerOutput.map) { + v3SourceMap = transpilerOutput.map; } } if (options.inlineMap) { diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 412b440a17..84d7d8ba0f 100644 --- a/lib/coffeescript/command.js +++ b/lib/coffeescript/command.js @@ -645,6 +645,11 @@ } } } + // 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; } else { opts.transpile = false; } diff --git a/lib/coffeescript/index.js b/lib/coffeescript/index.js index c2b45ad2f7..d842c9934b 100644 --- a/lib/coffeescript/index.js +++ b/lib/coffeescript/index.js @@ -14,7 +14,28 @@ helpers = CoffeeScript.helpers; - compile = CoffeeScript.compile; + CoffeeScript.transpile = function(js, options) { + var babel; + try { + babel = require('babel-core'); + } catch (error) { + // This error is only for Node, as CLI users will see a different error + // earlier if they don’t have Babel installed. + throw new Error('To use the transpile option, you must have the \'babel-core\' module installed'); + } + return babel.transform(js, options); + }; + + compile = function(code, options) { + // Pass a reference to Babel into the compiler, so that the transpile option + // is available in the Node API. We need to do this so that tools like Webpack + // can `require('coffeescript')` and build correctly, without trying to + // require Babel. + if (options.transpile) { + options.transpile.transpile = CoffeeScript.transpile; + } + return CoffeeScript.compile(code, options); + }; // Compile and execute a string of CoffeeScript (on the server), correctly // setting `__filename`, `__dirname`, and relative `require()`. diff --git a/src/coffeescript.coffee b/src/coffeescript.coffee index fc91438b6e..5598569f28 100644 --- a/src/coffeescript.coffee +++ b/src/coffeescript.coffee @@ -130,16 +130,25 @@ exports.compile = compile = withPrettyErrors (code, options) -> sourceMaps[filename].push map if options.transpile + if typeof options.transpile isnt 'object' + # This only happens if run via the Node API and `transpile` is set to + # something other than an object. + throw new Error 'The transpile option must be given an object with options to pass to Babel' + + # Get the reference to Babel that we have been passed if this compiler + # is run via the CLI or Node API. + transpiler = options.transpile.transpile + delete options.transpile.transpile + # See https://github.com/babel/babel/issues/827#issuecomment-77573107: # Babel can take a v3 source map object as input in `inputSourceMap` # and it will return an *updated* v3 source map object in its output. - if generateSourceMap and not options.transpile.inputSourceMap? + if v3SourceMap and not options.transpile.inputSourceMap? options.transpile.inputSourceMap = v3SourceMap - babel = require 'babel-core' - babelOutput = babel.transform js, options.transpile - js = babelOutput.code - if options.sourceMap and babelOutput.map - v3SourceMap = babelOutput.map + transpilerOutput = transpiler js, options.transpile + js = transpilerOutput.code + if v3SourceMap and transpilerOutput.map + v3SourceMap = transpilerOutput.map if options.inlineMap encoded = base64encode JSON.stringify v3SourceMap diff --git a/src/command.coffee b/src/command.coffee index d9a6b3fe88..ab7d2f62eb 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -495,6 +495,12 @@ compileOptions = (filename, base) -> break else checkPath = path.dirname checkPath + + # 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 else opts.transpile = no diff --git a/src/index.coffee b/src/index.coffee index f2bec76eb3..e1934d82be 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -5,7 +5,24 @@ vm = require 'vm' path = require 'path' helpers = CoffeeScript.helpers -compile = CoffeeScript.compile + +CoffeeScript.transpile = (js, options) -> + try + babel = require 'babel-core' + catch + # This error is only for Node, as CLI users will see a different error + # earlier if they don’t have Babel installed. + throw new Error 'To use the transpile option, you must have the \'babel-core\' module installed' + babel.transform js, options + +compile = (code, options) -> + # Pass a reference to Babel into the compiler, so that the transpile option + # is available in the Node API. We need to do this so that tools like Webpack + # can `require('coffeescript')` and build correctly, without trying to + # require Babel. + if options.transpile + options.transpile.transpile = CoffeeScript.transpile + CoffeeScript.compile code, options # Compile and execute a string of CoffeeScript (on the server), correctly # setting `__filename`, `__dirname`, and relative `require()`. From 02c486521572585c66ea74ca9d014d84537da578 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 14 Sep 2017 01:19:59 -0700 Subject: [PATCH 08/13] Node version of CoffeeScript.compile passes reference to Babel if transpile is requested --- lib/coffeescript/coffeescript.js | 8 ++++---- lib/coffeescript/index.js | 18 +++++++++++------- src/coffeescript.coffee | 6 +++--- src/index.coffee | 15 +++++++++------ 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/lib/coffeescript/coffeescript.js b/lib/coffeescript/coffeescript.js index 9433161686..99ec22dded 100644 --- a/lib/coffeescript/coffeescript.js +++ b/lib/coffeescript/coffeescript.js @@ -84,10 +84,10 @@ // in which case this returns a `{js, v3SourceMap, sourceMap}` // object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for // doing programmatic lookups. - exports.compile = compile = withPrettyErrors(function(code, options) { - var currentColumn, currentLine, encoded, extend, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, merge, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, transpiler, transpilerOutput, v3SourceMap; - ({merge, extend} = helpers); - options = extend({}, options); + exports.compile = compile = withPrettyErrors(function(code, options = {}) { + var currentColumn, currentLine, encoded, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, transpiler, transpilerOutput, v3SourceMap; + // Clone `options`, to avoid mutating the `options` object passed in. + options = Object.assign({}, options); // Always generate a source map if no filename is passed in, since without a // a filename we have no way to retrieve this source later in the event that // we need to recompile it to get a source map for `prepareStackTrace`. diff --git a/lib/coffeescript/index.js b/lib/coffeescript/index.js index d842c9934b..7873fa8347 100644 --- a/lib/coffeescript/index.js +++ b/lib/coffeescript/index.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript 2.0.0-beta5 (function() { // Node.js Implementation - var CoffeeScript, compile, ext, fn, fs, helpers, i, len, path, ref, vm, + var CoffeeScript, ext, fn, fs, helpers, i, len, path, ref, universalCompile, vm, hasProp = {}.hasOwnProperty; CoffeeScript = require('./coffeescript'); @@ -26,15 +26,19 @@ return babel.transform(js, options); }; - compile = function(code, options) { + // The `compile` method shared by the CLI, Node and browser APIs. + universalCompile = CoffeeScript.compile; + + // The `compile` method particular to the Node API. + CoffeeScript.compile = function(code, options) { // Pass a reference to Babel into the compiler, so that the transpile option // is available in the Node API. We need to do this so that tools like Webpack // can `require('coffeescript')` and build correctly, without trying to // require Babel. - if (options.transpile) { + if (options != null ? options.transpile : void 0) { options.transpile.transpile = CoffeeScript.transpile; } - return CoffeeScript.compile(code, options); + return universalCompile.call(CoffeeScript, code, options); }; // Compile and execute a string of CoffeeScript (on the server), correctly @@ -51,7 +55,7 @@ mainModule.paths = require('module')._nodeModulePaths(dir); // Compile. if (!helpers.isCoffee(mainModule.filename) || require.extensions) { - answer = compile(code, options); + answer = CoffeeScript.compile(code, options); code = (ref = answer.js) != null ? ref : answer; } return mainModule._compile(code, mainModule.filename); @@ -116,7 +120,7 @@ o[k] = v; } o.bare = true; // ensure return value - js = compile(code, o); + js = CoffeeScript.compile(code, o); if (sandbox === global) { return vm.runInThisContext(js); } else { @@ -149,7 +153,7 @@ // Strip the Unicode byte order mark, if this file begins with one. stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw; try { - answer = compile(stripped, { + answer = CoffeeScript.compile(stripped, { filename, sourceMap, inlineMap, diff --git a/src/coffeescript.coffee b/src/coffeescript.coffee index 5598569f28..f9ab4972a4 100644 --- a/src/coffeescript.coffee +++ b/src/coffeescript.coffee @@ -64,9 +64,9 @@ sourceMaps = {} # in which case this returns a `{js, v3SourceMap, sourceMap}` # object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for # doing programmatic lookups. -exports.compile = compile = withPrettyErrors (code, options) -> - {merge, extend} = helpers - options = extend {}, options +exports.compile = compile = withPrettyErrors (code, options = {}) -> + # Clone `options`, to avoid mutating the `options` object passed in. + options = Object.assign {}, options # Always generate a source map if no filename is passed in, since without a # a filename we have no way to retrieve this source later in the event that # we need to recompile it to get a source map for `prepareStackTrace`. diff --git a/src/index.coffee b/src/index.coffee index e1934d82be..5dd025c941 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -15,14 +15,17 @@ CoffeeScript.transpile = (js, options) -> throw new Error 'To use the transpile option, you must have the \'babel-core\' module installed' babel.transform js, options -compile = (code, options) -> +# The `compile` method shared by the CLI, Node and browser APIs. +universalCompile = CoffeeScript.compile +# The `compile` method particular to the Node API. +CoffeeScript.compile = (code, options) -> # Pass a reference to Babel into the compiler, so that the transpile option # is available in the Node API. We need to do this so that tools like Webpack # can `require('coffeescript')` and build correctly, without trying to # require Babel. - if options.transpile + if options?.transpile options.transpile.transpile = CoffeeScript.transpile - CoffeeScript.compile code, options + universalCompile.call CoffeeScript, code, options # Compile and execute a string of CoffeeScript (on the server), correctly # setting `__filename`, `__dirname`, and relative `require()`. @@ -45,7 +48,7 @@ CoffeeScript.run = (code, options = {}) -> # Compile. if not helpers.isCoffee(mainModule.filename) or require.extensions - answer = compile code, options + answer = CoffeeScript.compile code, options code = answer.js ? answer mainModule._compile code, mainModule.filename @@ -85,7 +88,7 @@ CoffeeScript.eval = (code, options = {}) -> o = {} o[k] = v for own k, v of options o.bare = on # ensure return value - js = compile code, o + js = CoffeeScript.compile code, o if sandbox is global vm.runInThisContext js else @@ -107,7 +110,7 @@ CoffeeScript._compileFile = (filename, sourceMap = no, inlineMap = no) -> stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw try - answer = compile stripped, { + answer = CoffeeScript.compile stripped, { filename, sourceMap, inlineMap sourceFiles: [filename] literate: helpers.isLiterate filename From 790a787ccf9d08b10b8903dbd508363039644211 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 14 Sep 2017 01:21:02 -0700 Subject: [PATCH 09/13] Test Node API for transpile option --- test/compilation.coffee | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/compilation.coffee b/test/compilation.coffee index 55941a9a0d..b405761ea3 100644 --- a/test/compilation.coffee +++ b/test/compilation.coffee @@ -1,10 +1,18 @@ # Compilation # ----------- -# helper to assert that a string should fail compilation +# Helper to assert that a string should fail compilation. cantCompile = (code) -> throws -> CoffeeScript.compile code +# Helper to pipe the CoffeeScript compiler’s output through a transpiler. +transpile = (method, code) -> + # `method` should be 'compile' or 'eval' or 'run' + CoffeeScript[method] code, + bare: yes + transpile: + # Target Internet Explorer 6, which supports no ES2015+ features. + presets: [['env', {targets: browsers: ['ie 6']}]] test "ensure that carriage returns don't break compilation on Windows", -> doesNotThrow -> CoffeeScript.compile 'one\r\ntwo', bare: on @@ -123,3 +131,15 @@ test "#3001: `own` shouldn't be allowed in a `for`-`in` loop", -> test "#2994: single-line `if` requires `then`", -> cantCompile "if b else x" + +test "transpile option, for Node API CoffeeScript.compile", -> + return if global.testingBrowser + ok transpile('compile', "import fs from 'fs'").includes 'require' + +test "transpile option, for Node API CoffeeScript.eval", -> + return if global.testingBrowser + ok transpile 'eval', "import path from 'path'; path.sep in ['/', '\\\\']" + +test "transpile option, for Node API CoffeeScript.run", -> + return if global.testingBrowser + doesNotThrow -> transpile 'run', "import fs from 'fs'" From fa5398e5cbb6459e339060770a5ed721966c1dd7 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 14 Sep 2017 21:35:30 -0700 Subject: [PATCH 10/13] Test for merged source maps --- test/compilation.coffee | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/test/compilation.coffee b/test/compilation.coffee index b405761ea3..50e55aec57 100644 --- a/test/compilation.coffee +++ b/test/compilation.coffee @@ -6,13 +6,14 @@ cantCompile = (code) -> throws -> CoffeeScript.compile code # Helper to pipe the CoffeeScript compiler’s output through a transpiler. -transpile = (method, code) -> +transpile = (method, code, options = {}) -> # `method` should be 'compile' or 'eval' or 'run' - CoffeeScript[method] code, - bare: yes - transpile: - # Target Internet Explorer 6, which supports no ES2015+ features. - presets: [['env', {targets: browsers: ['ie 6']}]] + options.bare = yes + options.transpile = + # Target Internet Explorer 6, which supports no ES2015+ features. + presets: [['env', {targets: browsers: ['ie 6']}]] + CoffeeScript[method] code, options + test "ensure that carriage returns don't break compilation on Windows", -> doesNotThrow -> CoffeeScript.compile 'one\r\ntwo', bare: on @@ -143,3 +144,19 @@ test "transpile option, for Node API CoffeeScript.eval", -> test "transpile option, for Node API CoffeeScript.run", -> return if global.testingBrowser doesNotThrow -> transpile 'run', "import fs from 'fs'" + +test "transpile option has merged source maps", -> + return if global.testingBrowser + untranspiledOutput = CoffeeScript.compile "import path from 'path'\nconsole.log path.sep", sourceMap: yes + transpiledOutput = transpile 'compile', "import path from 'path'\nconsole.log path.sep", sourceMap: yes + untranspiledOutput.v3SourceMap = JSON.parse untranspiledOutput.v3SourceMap + transpiledOutput.v3SourceMap = JSON.parse transpiledOutput.v3SourceMap + ok untranspiledOutput.v3SourceMap.mappings isnt transpiledOutput.v3SourceMap.mappings + # Babel adds `'use strict';` to the top of files with the modules transform. + eq transpiledOutput.js.indexOf('use strict'), 1 + # The `'use strict';` followed by two newlines results in the first two lines + # of the source map mappings being two blank/skipped lines. + eq transpiledOutput.v3SourceMap.mappings.indexOf(';;'), 0 + # The number of lines in the transpiled code should match the number of lines + # in the source map. + eq transpiledOutput.js.split('\n').length, transpiledOutput.v3SourceMap.mappings.split(';').length From 77e7338589365e79edec4a5f79a4bc6fb73029f2 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Thu, 14 Sep 2017 22:13:42 -0700 Subject: [PATCH 11/13] Test for Node API error message --- test/compilation.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/compilation.coffee b/test/compilation.coffee index 50e55aec57..04bc50619a 100644 --- a/test/compilation.coffee +++ b/test/compilation.coffee @@ -160,3 +160,9 @@ test "transpile option has merged source maps", -> # The number of lines in the transpiled code should match the number of lines # in the source map. eq transpiledOutput.js.split('\n').length, transpiledOutput.v3SourceMap.mappings.split(';').length + +test "using transpile from the Node API requires an object", -> + try + CoffeeScript.compile '', transpile: yes + catch exception + eq exception.message, 'The transpile option must be given an object with options to pass to Babel' From 520c60bd9b81a6eb335f64e8845fc2143a3ae773 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Fri, 15 Sep 2017 00:07:07 -0700 Subject: [PATCH 12/13] Only stop searching for Babel options if a package.json has a truthy "babel" key --- lib/coffeescript/command.js | 9 ++++++--- src/command.coffee | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/coffeescript/command.js b/lib/coffeescript/command.js index 84d7d8ba0f..8be6c25b33 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; + var answer, cantFindOptions, checkPath, cwd, jsDir, jsPath, packageJson; if (opts.transpile) { try { // The user has requested that the CoffeeScript compiler also transpile @@ -633,8 +633,11 @@ break; } catch (error) { try { - opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8')).babel; - break; + 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. diff --git a/src/command.coffee b/src/command.coffee index ab7d2f62eb..96eeaaee0e 100644 --- a/src/command.coffee +++ b/src/command.coffee @@ -487,8 +487,10 @@ compileOptions = (filename, base) -> break catch try - opts.transpile = JSON.parse(fs.readFileSync(path.join(checkPath, 'package.json'), 'utf-8')).babel - break + 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() From fd403874f17dd5ddbc79530edd710f3ad76c42c0 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Fri, 15 Sep 2017 00:50:05 -0700 Subject: [PATCH 13/13] Update docs --- docs/v2/index.html | 78 ++++++++++++------- documentation/sections/coffeescript_2.md | 10 +-- .../sections/command_line_interface.md | 9 ++- documentation/sections/compatibility.md | 5 ++ documentation/sections/es2015plus_output.md | 15 ---- documentation/sections/nodejs_usage.md | 1 + documentation/sections/transpilation.md | 42 ++++++++++ documentation/v2/body.html | 9 ++- documentation/v2/sidebar.html | 3 +- 9 files changed, 116 insertions(+), 56 deletions(-) create mode 100644 documentation/sections/compatibility.md delete mode 100644 documentation/sections/es2015plus_output.md create mode 100644 documentation/sections/transpilation.md diff --git a/docs/v2/index.html b/docs/v2/index.html index c4ed852cc4..3df4ca49de 100644 --- a/docs/v2/index.html +++ b/docs/v2/index.html @@ -527,12 +527,13 @@ Try CoffeeScript Overview CoffeeScript 2 + Compatibility Installation Usage Language Reference