RequireJS + babel-standalone + JSX


概要

JSXの変換ができるbrowser.js(babel-browser)が廃止されたみたいですが、babel-standaloneで代わりのことができるので備忘録に残しました。
Node.jsを使わず、ブラウザのみでJSXのコードをランタイムに変換します。
RequireJSを使用する前提で書いています。

サンプル

  • JSXに限らず、es2015も書けるとは思いますがパフォーマンスの面からあくまでもSandbox環境での確認に留めたほうが良さそうです。
index.html
<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.min.js"></script>

    <script type="text/babel">
      // JSXをtext/babel内に書く
      define('main', ['react', 'react_dom'], function(React, ReactDOM) {
        var Main = function() {};
        Main.prototype.load = function() {
          ReactDOM.render(<span>Hello World</span>, document.getElementById('container'));
        };
        return Main;
      });
    </script>

    <script>
      requirejs.config({
        paths: {
          babel: 'https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.7.7/babel.min',
          react: 'https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min',
          react_dom: 'https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min',
        }
      });

      // まずbabelをロードする
      require(['babel'], function(Babel) {

        // text/babel部分を取得(複数あればその分だけ)
        var babel_scripts = document.querySelectorAll('script[type="text/babel"]');
        Array.prototype.forEach.call(babel_scripts, function(script) {

          // JSXを変換してロードする
          new Function(Babel.transform(script.textContent, {
            presets: ['es2015', 'react'],
            filename: 'embedded',
            sourceMaps: 'inline'
          }).code)();
        });

        // Babelでロードしたdefineの呼び出し
        require(['main'], function(Main) {

          // ロードする
          var main = new Main();
          main.load();
        });
      });
    </script>
  </head>

  <body>
    <div id="container"></div>
  </body>
</html>