#はじめに
HyperappでもJSXが使えるらしいです。READMEを読むと"@babel/plugin-transform-react-jsx"をインストールして、.babelrcに以下を記述するように書いてあります。
{
"plugins": [["@babel/plugin-transform-react-jsx", { "pragma": "h" }]]
}
これはNode.js環境じゃないと動かないですね。嫌ですね。
#方法1. RequireJSを使う
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" id="script">
define('main', ['hyperapp'], ({h, app}) => () => {
const state = {
count: 0
}
const actions = {
down: value => state => ({ count: state.count - value }),
up: value => state => ({ count: state.count + value })
}
const view = (state, actions) =>
<div>
<h1>{state.count}</h1>
<button onclick={() => actions.down(1)}>-</button>
<button onclick={() => actions.up(1)}>+</button>
</div>
app(state, actions, view, document.body)
});
</script>
<script>
requirejs.config({
paths: {
babel: 'https://unpkg.com/@babel/standalone@7.3.4/babel.min',
hyperapp: 'https://cdnjs.cloudflare.com/ajax/libs/hyperapp/1.2.9/hyperapp'
}
});
// JSXをトランスパイルする
require(['babel'], function(Babel) {
var script = document.getElementById("script");
new Function(Babel.transform(script.textContent, {
presets: ['es2015'],
plugins: [['transform-react-jsx', { "pragma": "h" }]],
sourceMaps: 'inline'
}).code)();
require(['main'], function (Main) {
Main();
});
});
</script>
</head>
</html>
window.onload = app(state, actions, view, document.body)だと動かなかったので、直接app()を呼び出してます
#方法2. 外部ファイル読み込みを使う
Chromeで試す場合はクロスドメイン制約を回避する必要があります。
クロスドメイン制約を回避するChromeショートカットを作る
index.html
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/hyperapp"></script>
<script src=" https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.min.js"></script>
<object data="index.js" type="text/javascript" id="obj"></object>
<script>
var script = document.getElementById("obj");
script.onload = function(){
// JSXを変換してロードする
new Function(Babel.transform(script.contentDocument.documentElement.textContent, {
presets: ['es2015'],
plugins: [['transform-react-jsx', { "pragma": "h" }]],
sourceMaps: 'inline'
}).code)();
};
</script>
</head>
</html>
index.js
const { h, app } = hyperapp;
const state = {
count: 0
}
const actions = {
down: value => state => ({ count: state.count - value }),
up: value => state => ({ count: state.count + value })
}
const view = (state, actions) =>
<div>
<h1>{state.count}</h1>
<button onclick={() => actions.down(1)}>-</button>
<button onclick={() => actions.up(1)}>+</button>
</div>
window.onload = app(state, actions, view, document.body)
#参考文献
RequireJS + babel-standalone + JSX
クロスドメイン制約を回避するChromeショートカットを作る