From 47e91926f1d9ed763ad11cbd39a9b9fbc1986b20 Mon Sep 17 00:00:00 2001 From: Ryan Delaney Date: Thu, 21 Dec 2017 11:29:55 -0800 Subject: [PATCH] Add Reason asset type (#342) * Add bsb-js dependency * Add ReasonAsset type * Actually add the Reason asset type * Add OCaml file type, add integration test, remote unused imports * use promisify for reading files * Fix integration tests --- package.json | 1 + src/Parser.js | 2 ++ src/assets/ReasonAsset.js | 28 ++++++++++++++++++++++++++++ test/integration/reason/index.js | 5 +++++ test/integration/reason/local.bs.js | 11 +++++++++++ test/integration/reason/local.re | 3 +++ test/reason.js | 16 ++++++++++++++++ 7 files changed, 66 insertions(+) create mode 100644 src/assets/ReasonAsset.js create mode 100644 test/integration/reason/index.js create mode 100644 test/integration/reason/local.bs.js create mode 100644 test/integration/reason/local.re create mode 100644 test/reason.js diff --git a/package.json b/package.json index a833671c5cc..2a214410871 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "babylon": "^6.17.4", "babylon-walk": "^1.0.2", "browser-resolve": "^1.11.2", + "bsb-js": "^1.0.1", "chalk": "^2.1.0", "chokidar": "^1.7.0", "commander": "^2.11.0", diff --git a/src/Parser.js b/src/Parser.js index 6bc3624caee..92365e2299f 100644 --- a/src/Parser.js +++ b/src/Parser.js @@ -12,6 +12,8 @@ class Parser { this.registerExtension('es6', './assets/JSAsset'); this.registerExtension('jsm', './assets/JSAsset'); this.registerExtension('mjs', './assets/JSAsset'); + this.registerExtension('ml', './assets/ReasonAsset'); + this.registerExtension('re', './assets/ReasonAsset'); this.registerExtension('ts', './assets/TypeScriptAsset'); this.registerExtension('tsx', './assets/TypeScriptAsset'); this.registerExtension('coffee', './assets/CoffeeScriptAsset'); diff --git a/src/assets/ReasonAsset.js b/src/assets/ReasonAsset.js new file mode 100644 index 00000000000..ed9268e01fa --- /dev/null +++ b/src/assets/ReasonAsset.js @@ -0,0 +1,28 @@ +const bsb = require('bsb-js'); +const fs = require('fs'); +const JSAsset = require('./JSAsset'); +const promisify = require('../utils/promisify'); +const readFile = promisify(fs.readFile); + +class ReasonAsset extends JSAsset { + async parse(code) { + // This runs BuckleScript - the Reason to JS compiler. + // Other Asset types use `localRequire` but the `bsb-js` package already + // does that internally. This should also take care of error handling in + // the Reason compilation process. + if (process.env.NODE_ENV !== 'test') { + await bsb.runBuild(); + } + + // This is a simplified use-case for Reason - it only loads the recommended + // BuckleScript configuration to simplify the file processing. + const outputFile = this.name.replace(/\.(re|ml)$/, '.bs.js'); + const outputContent = await readFile(outputFile); + this.contents = outputContent.toString(); + + // After loading the compiled JS source, use the normal JS behavior. + return await super.parse(this.contents); + } +} + +module.exports = ReasonAsset; diff --git a/test/integration/reason/index.js b/test/integration/reason/index.js new file mode 100644 index 00000000000..46547936019 --- /dev/null +++ b/test/integration/reason/index.js @@ -0,0 +1,5 @@ +var local = require('./local.re'); + +module.exports = function () { + return local.a + local.b; +}; diff --git a/test/integration/reason/local.bs.js b/test/integration/reason/local.bs.js new file mode 100644 index 00000000000..486e372765e --- /dev/null +++ b/test/integration/reason/local.bs.js @@ -0,0 +1,11 @@ +// Generated by BUCKLESCRIPT VERSION 1.9.2, PLEASE EDIT WITH CARE +'use strict'; + + +var a = 1; + +var b = 2; + +exports.a = a; +exports.b = b; +/* No side effect */ diff --git a/test/integration/reason/local.re b/test/integration/reason/local.re new file mode 100644 index 00000000000..8869258b8ad --- /dev/null +++ b/test/integration/reason/local.re @@ -0,0 +1,3 @@ +let a = 1; + +let b = 2; diff --git a/test/reason.js b/test/reason.js new file mode 100644 index 00000000000..dfefa3e3698 --- /dev/null +++ b/test/reason.js @@ -0,0 +1,16 @@ +const assert = require('assert'); +const fs = require('fs'); +const {bundle, run, assertBundleTree} = require('./utils'); + +describe('reason', function() { + it('should produce a bundle', async function() { + let b = await bundle(__dirname + '/integration/reason/index.js'); + + assert.equal(b.assets.size, 2); + assert.equal(b.childBundles.size, 0); + + let output = run(b); + assert.equal(typeof output, 'function'); + assert.equal(output(), 3); + }); +});