Showing posts with label gulp. Show all posts
Showing posts with label gulp. Show all posts

November 23, 2014

Laravel Elixirを試してみた

Laravel 5ではGulpが標準採用され、Laravel Elixirというタスクツールが併せて実装されるようです。

http://gulpjs.com/
https://github.com/laravel/elixir

ドキュメントを見てみると
* Sass,Less,CoffeeScript等のコンパイル
* CSS,JavaScriptの結合やminify
* PHPUnit,PHPSpec等の実行
* イベントやルーティングのスキャン(キャッシュ化)
といった、様々なタスクがサポートされています。

そんなLaravel Elixirを、Homesteadで試してみました。尚、Homesteadには最初からGulpがインストールされています。
http://laravel.com/docs/4.2/homestead

* Laravel 5もLaravel Elixirも現在開発中なので、今後もまだまだ変わる可能性はあるでしょう。

1. Homesteadのインストールと起動

http://madroom-project.blogspot.jp/2014/11/laravel-homesteadhomestead.html

2. Laravelプロジェクトの作成とLaravel Elixirに必要なパッケージのインストール

# Homesteadにログイン
$ homestead ssh

# Laravelプロジェクトの作成
# Laravel 5は現在開発中なので"dev-develop"を付けてインストールします
$ composer create-project laravel/laravel elixir-example dev-develop

# Laravel Elixirに必要なパッケージのインストール
$ cd elixir-example/
$ npm install
以下のコマンドは全てHomesteadの中です。

3. sassのコンパイルを試してみる

gulpfile.jsを適当に編集してみます。デフォルトではbowerと絡めてBootstrapを使用するための記述がありますが、今回は使わないので削除しています。
elixir(function(mix) {
    mix.sass('app.scss');
});
上記の'app.scss'は resources/assets/sass/app.scss を指しています。こちらも適当に編集してみます。
body {
  background: #000;
}
gulpコマンドでコンパイルしてみます。
$ gulp
[20:31:25] Using gulpfile ~/Code/elixir-example/gulpfile.js
[20:31:25] Starting 'default'...
[20:31:25] Starting 'sass'...
[20:31:27] Finished 'default' after 1.91 s
[20:31:27] gulp-notify: [Laravel Elixir]
[20:31:27] Finished 'sass' after 1.98 s
[20:31:27] gulp-notify: [Error in notifier] Error in plugin 'gulp-notify'
not found: notify-send
("gulp-notify"云々のエラーはなんだろう)

public/css/app.css としてコンパイルされました。
body {
  background: #000; }
gulp watch コマンドで、ファイル変更の度に自動でコンパイルすることもできます。
$ gulp watch

4. コンパイルするファイルにバージョン名をつける

gulpfile.jsを次のようにしてコンパイルしてみます。
elixir(function(mix) {
    mix.sass('app.scss')
        .version('css/app.css');
});
すると public/build/css/app-d8890e6e.css のように、ハッシュ付きのcssファイルが生成されました。

ビューファイルで以下のように書けば
<link rel="stylesheet" href="{{ elixir("css/app.css") }}">
public/build/rev-manifest.json を参照して
<link rel="stylesheet" href="/build/css/app-d8890e6e.css">
のようにHTMLを出力してくれます。

5. minifyする

$ gulp --production
でminifyしてくれました。

6. PHPUnitを実行する

gulpfile.jsを以下のようにすると、PHPUnitを実行して、テストが失敗すれば処理を停止、テストが成功すれば処理を継続。となりました。
elixir(function(mix) {
    mix.phpUnit()
        .sass('app.scss')
        .version('css/app.css');
}); 

7. 複数ファイルを結合してみる

scssファイルを適当に2ファイル用意してみます。
resources/assets/sass/foo.scss
.foo {
  background: #000;
}
resources/assets/sass/bar.scss
.bar {
  background: #fff;
}
gulpfile.jsを次のようにします。
elixir(function(mix) {
    mix.sass(['**/*.scss'])
        .styles('css/**/*.css')
        .version('css/all.css');
});
コンパイルすると、結合されたファイルが生成されました。
public/build/css/all-993ce219.css
.bar {
  background: #fff; }

.foo {
  background: #000; }
LessやCoffeeScriptのコンパイル、JavaScriptの結合やminify、PHPSpecの実行等も、似たような感じで実行できるはずです。(たぶん。)

以上のように、Laravel 5では、Laravel Elixirを用いて様々なタスクを簡単に実行できるようになるみたいですね。

gulpはタスクが非同期で実行されるが故に、実行順序で少しハマったことがあるのですが、その辺も吸収してくれると助かるなぁと思いました。

April 12, 2014

Chrome.fmというChrome Extensionをリリースしました。

2014/04/19 追記:
名前がダメだったらしく、現在ストアから削除されています。後日、"YouFM"という名前にして、再度公開します。

2014/04/23 追記:
YouFMに名称変更して、再公開しました。
https://chrome.google.com/webstore/detail/youfm/gbpebippikipomjijplmbepmginobjbj

--

Chrome.fmという、YouTube動画を再生できるChrome Extensionをリリースしました。音楽プレイヤーのように使えます。

Chrome.fm:
https://chrome.google.com/webstore/detail/chromefm/gbpebippikipomjijplmbepmginobjbj

以下、特徴です。
  • 無料です(きっとずっと)
  • 動画の再生に、ウインドウ(タブ)を必要としません
  • シンプルなUIです
  • (手動で)再生中の動画名をTwitterにシェアできます

以下、近々実装予定の機能です。
  • 似た曲を垂れ流すラジオモード機能 (実装済み)
  • YouTubeプレイリストのインポート機能

尚、Chrome.fm内で発生したエラー情報は、品質向上を目的として、Sentryに送信されることがあります。このエラー情報に個人情報は含まれません。

開発的な部分を少し書いておくと
  • AngularJS
  • Bower
  • gulp.js
  • Jasmine
あたりを使っています。(JSライブラリはその他色々使っていますが。)

良かったら使ってみてください。アイデア等もお気軽に :)

March 25, 2014

gulp.js + Karma + Jasmine + PhantomJS で AngularJS をテストしてみた

調べるのに少し時間がかかったので、メモがてら、書いておきます。(これが良いやり方なのかはわかりませんm(_ _)m)

gulpとkarmaをグローバルでインストールします。
$ sudo npm install -g gulp karma
どうもkarmaにパスが通っていないようなので、パスを通しておきます。
$ sudo ln -s /usr/lib/node_modules/karma/bin/karma /usr/local/bin/karma
(2014/05/23 追記: 上記、Ubuntu13.10上です。Macだと "/usr/local/lib/node_modules/karma/bin/karma" でした。)

必要なパッケージをローカルにインストールします。
$ mkdir xxx && cd xxx
$ npm install --save-dev gulp gulp-util gulp-karma karma-jasmine karma-phantomjs-launcher
package.json を自前で用意するなら、以下の様な感じになります。
{
    "name": "gulp-karma",
    "version": "0.1.0",
    "devDependencies": {
        "gulp": "~3.*",
        "gulp-util": "~2.*",
        "gulp-karma": "~0.*",
        "karma-jasmine": "~0.*",
        "karma-phantomjs-launcher": "~0.*"
    }
}
angular.js本体と、angular-mocks.js をダウンロードしておきます。
https://github.com/angular/angular.js/blob/master/src/ngMock/angular-mocks.js

今回は
  • ./vendor/angular.min.js
  • ./vendor/angular-mocks.js
として保存しました。

karmaの設定ファイルを作成します。以下、ブラウザを"Chrome"から"PhantomJS"に変えただけ(カーソルキーの上下で変えられました。)で、他はそのままです。
$ karma init

Which testing framework do you want to use ?
Press tab to list possible options. Enter to move to the next question.
> jasmine

Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no

Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next question.
> PhantomJS
>

What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
>

Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
>

Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> yes


Config file generated at "xxx/gulp-karma/karma.conf.js".
gulpfile.js を作成します。
var gulp = require('gulp');
var karma = require('gulp-karma');

gulp.task('karma', function () {
    var files = [
        'vendor/angular.min.js',
        'vendor/angular-mocks.js',
        'js/app.js',
        'spec/appSpec.js',
    ];

    gulp.src(files).pipe(karma({configFile: 'karma.conf.js'}));
});
テスト対象のjsファイルと、そのテスト(spec)のjsファイルを作成します。
$ mkdir js && mkdir spec
js/app.js
var myApp = angular.module('myApp', []);

myApp.filter('truncate', [function () {
    return function (text, length, end) {
        if (isNaN(length)) {
            length = 10;
        }

        if (end === void 0) {
            end = '...';
        }

        if (text.length <= length) {
            return text;
        }

        return text.substring(0, length - end.length) + end;
    };
}]);
spec/appSpec.js
describe('spec for popup.js', function() {
    beforeEach(function () {
        module('myApp');
    });

    it('should be truncated.', inject(function(truncateFilter) {
        expect(truncateFilter('1234567890')).toBe('1234567890');
        expect(truncateFilter('12345678901')).toBe('1234567...');
        expect(truncateFilter('1234567890', 4, '---')).toBe('1---');
        expect(truncateFilter('1234567890', 2, '---')).toBe('---');
    }));
});
テストを実行してみます。
$ gulp karma
[gulp] Using gulpfile /share/gulp-karma/gulpfile.js
[gulp] Starting 'karma'...
[gulp] Finished 'karma' after 7.23 ms
[gulp] Starting Karma server...
INFO [karma]: Karma v0.12.1 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.7 (Linux)]: Connected on socket 6KRg3iwj9PAR6jMwlCqC with id 13100382
PhantomJS 1.9.7 (Linux): Executed 1 of 1 SUCCESS (0.041 secs / 0.009 secs)
試しに、テストを適当に書き換えて失敗させてみます。
$ gulp karma
[gulp] Using gulpfile /share/gulp-karma/gulpfile.js
[gulp] Starting 'karma'...
[gulp] Finished 'karma' after 8.24 ms
[gulp] Starting Karma server...
INFO [karma]: Karma v0.12.1 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.7 (Linux)]: Connected on socket pjHN4RaPeEbzGFrtlZ35 with id 28598103
PhantomJS 1.9.7 (Linux) spec for popup.js should be truncated. FAILED
    Expected '---' to be '1--'.
PhantomJS 1.9.7 (Linux): Executed 1 of 1 (1 FAILED) ERROR (0.042 secs / 0.01 secs)
とりあえず、これでテストできるかなー。という感じにはなった気がします。