grunt-jsxを作りました。

※※ 2013-06-30 追記:add-search-pathのオプションキーはadd_search_pathに変更しました。

最近 JSXを仕事で使うことがあって、もっとjsxを便利に使いたいと思ってgrunt-jsxを作りました。

できること

gruntからjsxをコンパイルしてjsを生成する、というだけのシロモノですが、gruntのエコシステムに乗ることでjsxファイルの変更をwatchして変更がある度にjsファイルを生成する等、非常に便利になります。

事前準備

JSXコマンドを使うので事前にjsxをinstallして下さい。

$ npm install jsx -g

gruntも利用するのでインストールしましょう。

$ npm install grunt-cli -g

適当なフォルダを作成し、gruntを使用する準備をします。

$ mkdir test-jsx
$ cd test-jsx
$ npm init
// いくつか質問が表示されるので適当に回答しておく。


後はgrunt-jsxをインストールしましょう。

$ npm install grunt --save-dev
$ npm install grunt-jsx --save-dev

Gruntfile.jsを記述する。

以下の様なGruntfile.jsを記述して下さい。

module.exports = function(grunt) {
  'use strict';
  grunt.initConfig({
    jsx: {
      hello: {
        src: 'hello.jsx',
        dest: 'hello.jsx.js',
      },
    }
  });

  grunt.loadNpmTasks('grunt-jsx');
};

後はgrunt jsx:hello コマンドを実行するだけです。
hello.jsx.jsが出力されているのが分かるかと思います。

説明

以下の様なオプションが記述できます。

src: 文字列、指定必須、コンパイルするjsxファイルを指定します。
dest: 文字列、指定必須、コンパイル結果の出力先
executable: 文字列、optional、nodeかwebが入る
release: boolean、optional、リリース用に最適化するかどうか。
add_search_path: 文字列か配列、optional、コンパイル時の検索パス

watchと併用する

grunt-contrib-watchと併用すればjsxファイルが変更される度にjsにコンパイルすることができます。

npmでgrunt-contrib-watchを入れた後で、

$ npm install grunt-contrib-watch --save-dev

Gruntfile.jsを以下のように書き換えて下さい。

module.exports = function(grunt) {
  'use strict';
  grunt.initConfig({
    watch: {
      jsx: {
        files: ['*.jsx'],
        tasks: ['jsx:build']
      },
    },
    jsx: {
      build: {
        src: 'main.jsx',
        dest: 'main.jsx.js',
      },
    }
  });

  grunt.loadNpmTasks('grunt-jsx');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('default', ['jsx:build', 'watch']);
};

watchで起動しておけばjsxファイルが変更される度にコンパイルされます。

$ grunt watch

また、gruntはpackage.jsonを読み込むことができるので、複数のgruntプラグインを読み込むときは以下のように記述する方がスマートですね。

module.exports = function(grunt) {
  'use strict';
  var pkg = grunt.file.readJSON('package.json');
  grunt.initConfig({
    watch: {
      jsx: {
        files: ['*.jsx'],
        tasks: ['jsx:build']
      },
    },
    jsx: {
      build: {
        src: 'main.jsx',
        dest: 'main.jsx.js',
      },
    }
  });

  // load dev Dependencies
  for (var key in pkg.devDependencies) {
    if (/grunt-/.test(key)) {
      grunt.loadNpmTasks(key);
    }
  }
  grunt.registerTask('default', ['jsx:build', 'watch']);
};

jsxファイルが更新される度にブラウザリロードを行う

いわゆるlivereloadという奴ですね。
まずは、

Google chrome livereload extensionを入れておく必要があります。

もちろんlivereloadするためだけにextensionを入れたくない、という場合は、以下のscriptタグを表示するhtmlに記述しておく必要があります。

<script src="http://localhost:35729/livereload.js?snipver=1" type="text/javascript"></script>

後は以下のようにlivereloadオプションをGruntfile.jsを変更しておけばOK。

module.exports = function(grunt) {
  'use strict';
  var pkg = grunt.file.readJSON('package.json');
  grunt.initConfig({
    watch: {
      jsx: {
        files: ['*.jsx'],
        tasks: ['jsx:build'],
        options: {
          livereload: true, // ここに追記するだけ
        },
      },
    },
    jsx: {
      build: {
        src: 'main.jsx',
        dest: 'main.jsx.js',
      },
    }
  });

  // load dev Dependencies
  for (var key in pkg.devDependencies) {
    if (/grunt-/.test(key)) {
      grunt.loadNpmTasks(key);
    }
  }

  grunt.registerTask('default', ['jsx:build', 'watch']);
};

まとめ

という訳でgrunt-jsx作りました。gruntのエコシステムに乗れば色々組み合わせて使えるし、grunt自体にたくさんの便利APIがあるのでみんな色々作るといいよ!