TypeScript + RxJS + Closure Compiler setup
I'm just going to make a note of this for Future Paul, because I spent way too long trying to get this working. If anyone has a better version of this workflow let me know.
Here's the rough idea:
Because Future Paul will want it, here's the installs needed:
npm i google-closure-compiler rollup-plugin-commonjs rollup-plugin-node-resolve rxjs
# You might not want global, I usually do.
npm i -g typescript rollup
Take the following code:
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/filter';
class Sample {
static main () {
// Create a number every second, but filter to just even numbers...
const even = Observable.interval(1000)
.filter(data => data % 2 === 0);
// Now do the same again, but for odd numbers.
const odd = Observable.interval(1000)
.filter(data => data % 2 === 1)
Sample.combineNumbers(even, odd)
.subscribe(data => console.log('Number', data));
}
static combineNumbers(a:Observable<number>, b:Observable<number>):Observable<number> {
return Observable.merge(a, b);
}
}
Sample.main();
Firstly, lol at the naming of the functions etc... I'm one step away from "Enterprise" coding here, folks. Send help.
Anyway, it's a bit of TypeScript that creates a couple of Observable
s and merges them to a third, final Observable
and logs out its values.
You need a tsconfig.json
file in the root.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs"
}
}
Next up, compile the TypeScript.
tsc -p .
Which will output JavaScript that looks like this:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Observable_1 = require("rxjs/Observable");
require("rxjs/add/observable/interval");
require("rxjs/add/observable/merge");
require("rxjs/add/operator/filter");
class Sample {
static main() {
// Create a number every second, but filter to just even numbers...
const even = Observable_1.Observable.interval(1000)
.filter(data => data % 2 === 0);
// Now do the same again, but for odd numbers.
const odd = Observable_1.Observable.interval(1000)
.filter(data => data % 2 === 1);
Sample.combineNumbers(even, odd)
.subscribe(data => console.log('Number', data));
}
static combineNumbers(a, b) {
return Observable_1.Observable.merge(a, b);
}
}
Sample.main();
Those requires need to be resolved. For what it's worth I tried using Tsickle rather
than tsc
directly, and that generates similar output save that the requires are goog.require
calls instead.
But, because Closure Compiler doesn't like the goog.require
calls against non-Closure code, I had
to abandon that.
Instead we can run rollup
, for which we first need a rollup.config.js
:
import cjs from 'rollup-plugin-commonjs';
import nodeResolve from 'rollup-plugin-node-resolve';
export default {
entry: 'src/app.js',
dest: 'src/bundle.js',
format: 'iife',
moduleName: 'Sample',
plugins: [
nodeResolve({jsnext: true, main: true}),
cjs()
]
};
And now call rollup
with the config flag.
rollup -c
Now we have a bundle, but it has comments and all sorts of unnecessary gubbins in there (though functionally it should just be the stuff we need). Let's hand it off to Closure Compiler to have it squish the output:
java -jar ./node_modules/google-closure-compiler/compiler.jar --js src/bundle.js --language_in=ECMASCRIPT6 --language_out=ES5_STRICT --compilation_level SIMPLE_OPTIMIZATIONS | tee > dist/app.js
It would be nice to have ADVANCED_OPTIMIZATIONS
enabled here because huge size reductions FTW, but because the RxJS
isn't a simple match with Closure, there's no easy option here AFAICT.
With all that done, it should now at least build and spit out some JS that works.