コンパイラ

インブラウザ・コンパイル

ブラウザから実行可能になる前に、カスタムタグはJavaScriptに変換しておく必要があります。type="riot/tag"属性をscriptタグに設定するだけでOKです。例:

<!-- ここにマウント -->
<my-tag></my-tag>

<!-- インラインのタグ定義 -->
<script type="riot/tag">
  <my-tag>
    <h3>Tag layout</h3>
    <inner-tag />
  </my-tag>
</script>

<!-- <inner-tag/>は外部ファイルに定義されている -->
<script src="path/to/javascript/with-tags.js" type="riot/tag"></script>

<!-- riot.jsとコンパイラを読み込む -->
<script src="https://cdn.jsdelivr.net/npm/riot@3.6/riot+compiler.min.js"></script>


<!-- 通常のマウント -->
<script>
riot.mount('*')
</script>

scriptタグや外部ファイルには、複数のタグ定義と、通常のJavaScriptを含めることができます。

Riotは、riot.mount()が呼び出される前に、インラインまたは外部のタグを自動的にコンパイルします。

タグインスタンスにアクセスする

もしscript srcでタグを読み込もうとしていて、マウントされたタグにアクセスする必要があるなら、次のようにriot.compileで囲む必要があります:

<script>
riot.compile(function() {
  // here tags are compiled and riot.mount works synchronously
  var tags = riot.mount('*')
})
</script>

コンパイラのパフォーマンス

コンパイルは基本的にはまったく時間がかかりません。タイマータグを30回コンパイルするのにかかる時間は、普通のラップトップで2ミリ秒です。もし、同じくらいのサイズの1000個の異なるタグからなるクレイジーなページを作ったとしても、35msしかかからないという計算になります。

コンパイラのサイズはたかだか3.2KB(gzip圧縮で1.7KB)なので、本番環境でのクライアントサイド・コンパイルも、ダウンロード量やパフォーマンスの点で心配なく使えます。

詳しくはコンパイラAPIを見てください.

デモ

プリコンパイル

プリ(事前の)コンパイルには次のようなメリットがあります:

プリコンパイルはriotコマンドで実行します。NPMから次のようにインストールできます:

npm install riot -g

riot --helpを実行して、正しく動作することを確認します。node.jsがインストールされている必要があります。

プリコンパイル版のHTMLは次のようになるでしょう:

<!-- タグをマウントする場所 -->
<my-tag></my-tag>

<!-- riot.jsのみ読み込み -->
<script src="https://cdn.jsdelivr.net/npm/riot@3.6/riot.min.js"></script>

<!-- プリコンパイルされたタグを読み込み (通常のJavaScriptです) -->
<script src="path/to/javascript/with-tags.js"></script>

<!-- 同じようにマウント -->
<script>
riot.mount('*')
</script>

使い方

riotコマンドがどのように動くか説明します:

# ファイルを現在のフォルダにコンパイル
riot some.tag

# 指定フォルダにファイルをコンパイル
riot some.tag some_folder

# 指定パスにファイルをコンパイル
riot some.tag some_folder/some.js

# 元フォルダのすべてのファイルを、指定フォルダにコンパイル
riot some/folder path/to/dist

# 元フォルダのすべてのファイルを、結合ずみの単一ファイルとしてコンパイル
riot some/folder all-my-tags.js

ソースファイルは、ひとつあるいは複数のタグを含むことができ、通常のJavaScriptを一緒に混ぜても構いません。コンパイラはカスタムタグの部分だけを変換し、ソースファイルのほかの部分はそのままにします。

詳しい情報は、riot --helpを参照してください。

監視モード

ディレクトリを監視して、ファイルが変更されたときに自動的にファイルを変換することが可能です。

# srcフォルダを監視(watch)
riot -w src dist

カスタム拡張子

タグファイルを好きな拡張子にすることができます(デフォルトの.tagの代わりに):

riot --ext html

ES6設定ファイル

設定ファイルを使用して、すべてのriot-cliオプションを簡単に保存および設定することができ、カスタムパーサーを作成することもできます。

riot --config riot.config

riotのriot.config.jsファイル:

export default {
  from: 'tags/src',
  to: 'tags/dist',
  // files extension
  ext: 'foo',
  // html parser
  template: 'foo',
  // js parser
  type: 'baz',
  // css parser
  style: 'bar',
  parsers: {
    html: {
      foo: (html, opts, url) => require('foo').compile(html),
    },
    css: {
      bar: (tagName, css, opts, url) => require('bar').compile(css),
    },
    js: {
      baz: (js, opts, url) => require('baz').compile(js),
    },
  },
  // special options that may be used to extend
  // the default riot parsers options
  parserOptions: {
    js: {},
    template: {},
    style: {}
  }
};

Nodeモジュールとして

var riot = require('riot')

var js = riot.compile(source_string)

compile関数は文字列を受け取って、文字列を返します。

ワークフローへの組み込み

プリプロセッサ

プリコンパイルの一番美味しい部分です。カスタムタグを作るのに、好きなプリプロセッサを使うことができます。HTMLとJavaScript(訳注・CSSも)、どちらのプリプロセッサもカスタマイズが可能です。

ソースの言語は、コマンドラインの--type-t引数で指定するか、あるいは後述のようにスクリプトタグの言語を自分で定義することもできます。

<my-tag>
  <h3>My layout</h3>

  <script type="coffee">
    @hello = 'world'
  </script>
</my-tag>

CoffeeScript

# CoffeeScript プリプロセッサを使う
riot --type coffee --expr source.tag

--expr引数は、テンプレート変数(expression)の中でもプリプロセッサを使うことを指定します。”coffee”のエイリアスとして、”cs”を使うこともできます。CoffeeScriptで書かれたタグの例です:

<kids>

  <h3 each={ kids[1 .. 2] }>{ name }</h3>

  # Here are the kids
  this.kids = [
    { name: "Max" }
    { name: "Ida" }
    { name: "Joe" }
  ]

</kids>

each属性もCoffeeScriptになっていますね。なお、CoffeeScriptがあなたのマシンにインストールされていることが必要です:

npm install coffee-script -g

EcmaScript 6

ECMAScript 6(babeljs)は、”es6”を指定することで有効になります:

ES6で書かれたタグの例:

<test>

  <h3>{ test }</h3>

  var type = 'JavaScript'
  this.test = `This is ${type}`

</test>

es6コンパイラを使用する前に、以下の手順に従ってプロジェクトを適切に構成する必要があります。

  1. babel-preset-es2015-riotをインストール
    npm install babel-preset-es2015-riot --save-dev
  2. babel-coreもインストール
    npm install babel-core -g
  3. プリセットというidを含む.babelrcファイルの作成
    { "presets": ["es2015-riot"] }

環境を設定したらタグをコンパイルすることができます:

#  ES6プリプロセッサを使う
riot --type es6 source.tag

note Babelは出力にたくさんの余分なコードを生成するので、例えばbabel-plugin-external-helpers-2を使って2つの別々なステップでタグをコンパイルすることも考えられます:

# 純粋なes6のコードを使ってタグをコンパイル
riot tags/folder dist/es6.tags.js
# es6のコードを有効なes5のコードに変換
babel es6.tags.js --out-file tags.js

ここに、BabelをRiotと使った簡単なサンプルがあります。

TypeScript

TypeScriptは静的型付けをJavaScriptに追加します。--type typescriptを使って有効にします:

# TypeScriptプリプロセッサを使う
riot --type typescript source.tag

TypeScriptで書かれたタグのサンプルです:

<test>

  <h3>{ test }</h3>

  var test: string = 'JavaScript';
  this.test = test;

</test>

typescript-simpleが変換に使われます:

npm install typescript-simple

LiveScript

言語の特徴やドキュメントについては、LiveScriptを確認してください。

ソース言語は、--type-t引数で指定します:

# LiveScriptプリプロセッサを使う
riot --type livescript --expr source.tag

--expr引数はテンプレート変数についても変換することを指定します。”livescript”のエイリアスとして”ls”も使えます。LiveScriptで書かれたタグの例はこちら:

<kids>

<h3 each={ kids[1 .. 2] }>{ name }</h3>

# Here are the kids
this.kids =
* name: \Max
* name: \Ida
* name: \Joe

</kids>

each属性もLiveScriptになっています。LiveScriptがインストールされている必要があります:

npm install LiveScript -g

Pug (Jade)

HTMLレイアウトはtemplate設定オプションで、処理することができます。これは、「クリーンでホワイトスペース・センシティブなHTMLを書くための文法」pugを使った例です。

# Pug HTMLプリプロセッサを使う
riot --template pug source.tag

Pugの例:

sample
  p test { value }
  script(type='text/coffee').
    @value = 'sample'

周知の通り、テンプレートにもスクリプトの種類を定義することができます。上記はcoffeeを使っています。 pugが変換に使われます:

npm install pug -g

どんな言語でも

カスタムパーサーを用意することで、お好みのどんな言語でも設定できます (訳注:上記の定義済みのものの他に)。例:

function myParser(js, options) {
  return doYourThing(js, options)
}

このパーサーはコンパイラのparserオプションで渡されます。

var riot = require('riot')

var js = riot.compile(source_string, { parser: myParser, expr: true })

テンプレート変数も同様に処理したければ、expr: trueをセットします。

riot.parsers をブラウザとサーバで使う

Riotのカスタムパーサをriot.parsersプロパティで指定して、ブラウザとサーバで共通して使うこともできます。例:

riot.parsers.js.myJsParser = function(js, options) {
  return doYourThing(js, options)
}

riot.parsers.css.myCssParser = function(tagName, css) {
  return doYourThing(tagName, css)
}

一度、自分のriot.parsersを作ってしまえば、次の方法でタグをコンパイルすることができます。

<custom-parsers>
  <p>hi</p>
  <style type="text/myCssParser">
    @tag {color: red;}
  </style>
  <script type="text/myJsParser">
    this.version = "@version"
  </script>
</custom-parsers>

変換なし

デフォルトで、Riotは組込みのトランスパイラを使います。それによって、ES6的な短いメソッドの書き方を有効になります。この変換をすべて無効にしたい場合は、--type noneオプションをつけます:

# プリプロセッサなし
riot --type none --expr source.tag

AMDとCommonJS

Riotのタグは、AMD(Asynchronous Module Definition)やCommonJSとしてコンパイルすることができます。このオプションは、RiotをRequireJSのようなAMDローダ、あるいはBrowserifyのようなCommonJSローダと利用する場合に必要です。

いずれのケースでも、Riotライブラリ自体もriotとして、define/requireされていなければなりません。

# AMD と CommonJS を有効に
riot -m

AMDの例:


define(['riot', 'tags'], function (riot) {
  riot.mount('*')
})

CommonJSの例:

var riot = require('riot')
var tags = require('tags')

riot.mount('*')

もし、何かすごいものを作ったら、ぜひこちらでシェアしてくださいね!