Riot and in-browser ECMAScript 6 transpilation (and Coffeescript)
I love Riot, and to my mind itâs useful that we donât need to pre-compile tags. But you have to do that if you want work with ECMAScript 6 or Coffeescript. Thatâa pity, because, these transpilers can make in-browser transpilation.
Problem
When you make a riot custom tag like this:
<yo-bob>
<h1>{label}</h1>
<h2>{subLabel}</h2>
<script type="es6">
let firstName = "Bob";
let lastName = "Morane";
this.label = '--- Yo! ---';
this.subLabel = `Yo ${firstName} ${lastName}`;
this.on('mount', () => {
this.root.querySelector("h1").style.color = "red";
this.root.querySelector("h2").style.color = "green";
});
</script>
</yo-bob>
Then, you have to use riot executable to pre-compile the tag (see: https://muut.com/riotjs/compiler.html# pre-compilation) and use a pre-processor (for my example itâs Babel, because I want to develop with ES6), (see: https://muut.com/riotjs/compiler.html# ecmascript-6)
I would like to do that but with a in-browser âtranspilationâ. If you read the source code of compiler.js
: https://github.com/muut/riotjs/blob/master/compiler.js# L113, you can see this method which is called when âes6â (<script type="es6">
) is detected:
function es6(js) {
return require('babel').transform(js, { blacklist: ['useStrict'] }).code
}
The browser canât use es6()
because of require()
method (which is a nodejs method).
Trick
If you want in browser transpilation with Babel, first you have to include these two scripts in you html page:
browser-polyfill.js
browser.js
You can get these files when installing Babel (npm install babel
) and after take the files in this directory node_modules/babel
. Then, your page should look something like this:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<!-- babel -->
<script src="js/browser-polyfill.js"></script>
<script src="js/browser.js"></script>
<script src="js/web-components/yo-bob.html" type="riot/tag"></script>
</head>
<body>
<yo-bob></yo-bob>
<script src="js/bower_components/riot/riot.js"></script>
<script src="js/bower_components/riot/compiler.js"></script>
<script>
riot.mount("yo-bob");
</script>
</body>
</html>
And now, we have to provide a require()
method to the browser. Itâ simple, insert this code before <script src="js/bower_components/riot/riot.js"></script>
:
<script>
window.require = function (module) {
if (module=='babel') {
this.transform = function (js, param) {
return babel.transform(js, param);
}
}
return this;
}
</script>
And, it just works!
Same thing with Coffeescript
Itâs simple too. Donât forget to include the transpiler in your page (https://raw.githubusercontent.com/jashkenas/coffeescript/master/extras/coffee-script.js) and update the previous trick like that:
<script>
window.require = function (module) {
if (module=='babel') {
this.transform = function (js, param) {
return babel.transform(js, param);
}
}
if (module=='coffee-script') {
this.compile = function (js, param) {
return CoffeeScript.compile(js, param)
}
}
return this;
}
</script>
And now you can write your tag like that:
<hi-bob>
<h1>{label}</h1>
<h2>{subLabel}</h2>
<script type="text/coffeescript">
firstName = "Bob"
lastName = "Morane"
@label = '--- Yo! ---'
@subLabel = "Yo # { firstName } # { lastName }"
@on 'mount', ->
@root.querySelector('h1').style.color = 'orange'
@root.querySelector('h2').style.color = 'blue'
</script>
</hi-bob>
âEt voilĂ !â :)
Tweet