JSXをSymfony2のAsseticで自動的にコンパイルする
2012年6月4日月曜日
JSXをSymfony2のAsseticで自動コンパイルしてみますよ。
AsseticはAssetにフィルタを適応する仕組みです。今回はJSXのコンパイル処理をAsseticで自動的にコンパイルしてみます。
まずは、JSX本体の準備
git clone http://github.com/jsx/JSX.git
node.jsが入っていなければインストール
brew install node.js
npm(node package manager)が入っていなければインストール
curl http://npmjs.org/install.sh | sudo sh
それか
brew install npm
JSXのソースをコンパイルして実行してみる
cd JSX ./bin/jsx --executable --output hello.js example/hello.jsx node hello.js Hello, world!
Symfony2側の用意
Symfony2側のAsseticフィルタクラスの追加
JSX用のフィルタクラス追加します。ここに、vendor/assetic/src/Assetic/Filter/JsxFilter.php を下記内容で追加。
namespace Assetic\Filter; use Assetic\Asset\AssetInterface; use Assetic\Util\ProcessBuilder; /** * Compiles JSX into Javascript. * */ class JsxFilter implements FilterInterface { private $jsxPath; public function __construct($jsxPath = '/usr/bin/jsx') { $this->jsxPath = $jsxPath; } public function filterLoad(AssetInterface $asset) { $input = tempnam(sys_get_temp_dir(), 'assetic_jsx'); file_put_contents($input, $asset->getContent()); $pb = new ProcessBuilder(); $pb ->inheritEnvironmentVariables() ->add($this->jsxPath) ->add($asset->getSourceRoot() . DIRECTORY_SEPARATOR . $asset->getSourcePath()) ; $proc = $pb->getProcess(); $code = $proc->run(); unlink($input); if (0 < $code) { throw new \RuntimeException($proc->getErrorOutput()); } $asset->setContent(str_replace($asset->getSourceRoot(), "", $proc->getOutput())); } public function filterDump(AssetInterface $asset) { } }
次に、DIコンテナの設定をします
/Users/morireo/Sites/fotofoo_mobile/vendor/bundles/Symfony/Bundle/AsseticBundle/Resources/config/filters/jsx.xml ファイルを編集。
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> <parameters> <parameter key="assetic.filter.jsx.class">Assetic\Filter\JsxFilter</parameter> <parameter key="assetic.filter.jsx.bin">/usr/bin/jsx</parameter> </parameters> <services> <service id="assetic.filter.jsx" class="%assetic.filter.jsx.class%"> <tag name="assetic.filter" alias="jsx" /> <argument>%assetic.filter.jsx.bin%</argument> </service> </services> </container>
app/config/config.ymlにフィルタ設定の記述
assetic: filters: jsx: jsx_path: /usr/bin/jsx
JSXクラスの記述
Resources/public/jsx/hello.jsx などに書きます
import "js/web.jsx"; class _Main { static function main(args : string[]) :void { log "Hello, world!"; } static function say() : void { var text = dom.window.document.createTextNode("Hello, world!"); dom.getElementById("hello").appendChild(text); } }
Twigに記述
<html> <head> <title></title> {% javascripts debug=true output="/js/hello.js" '@JsxTestBundle/Resources/public/jsx/hello.jsx' filter='jsx' %} <script src="{{ asset_url }}"></script> {% endjavascripts %} </head> <body> <p id="hello"></p> <script> window.addEventListener("load", function(e) { JSX.require("/Resources/public/jsx/hello.jsx")._Main.say$(); }); </script> </body> </html>
これで自動的に.jsxファイルが.jsファイルになってブラウザ上で動作するようになりました。
静的ファイルとして配置するには、./app/console assetic:dump コマンドで web/ 以下に配置されます。プロダクション環境では自動的に再生成されないので、ソースファイルを変更した場合には削除するかassetic:dumpで配置してあげる必要があります。
ラベル:
javascript,
jsx,
php,
symfony2