インストール
まずはcomposerでプロジェクト作成。
sudo php composer.phar create-project --prefer-dist -s dev cakephp/app myApp
途中で以下のように質問されるようになった。
Set Folder Permissions ? (Default to Y) [Y,n]? Y
無事終了したら、パーミッションを変えておく(OSXのみ)
sudo chown -R mymac:staff myApp
ここで一旦 .gitignore を編集してコミットしておく。tmpとlogsをコメントアウトして、
自分の環境でよくあるやつを入れておく。
/vendor/*
/config/app.php
#/tmp/*
#/logs/*
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db
*.swp
*.un~
*~
*BAK
あとはいつものgit処理で。
git init
git add .
git commit -m "Initialize repository"
git remote add origin https://github.com/xxxxxxx/myApp.git
git push -u origin master
pushしたらtmpとlogsのコメントアウトを外しておく。
/tmp/*
/logs/*
一旦サーバー起動してみて動作確認。
cd myApp
bin/cake server
テスト
次に、test(phpunit)ができるようにしておく。
composer.jsonを編集する。
suggest に入っている phpunit と codesniffer を require-dev に移す。
"require-dev": {
"d11wtq/boris": "1.0.*",
"cakephp/debug_kit": "3.0.*-dev",
"cakephp/bake": "dev-master",
"phpunit/phpunit": "*",
"cakephp/cakephp-codesniffer": "*"
},
composerのアップデートをかける。
sudo php ../composer.phar update
無事入ったら、phpunitの動作確認。
vendor/bin/phpunit
この時点で(もっとそれより早くて構わないが)データベースを準備しておく。
開発用のDBにはテーブル(例:articles)も作っておく。
テスト用のDBは空っぽ(テーブル無し)でよい。
config/app.php を編集してDB接続情報を入れておく。
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'username' => 'root',
'password' => 'password',
'database' => 'sample_db',
'encoding' => 'utf8',
//'timezone' => 'UTC',
'cacheMetadata' => true,
],
/**
* The test connection is used during the test suite.
*/
'test' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'username' => 'root',
'password' => 'password',
'database' => 'test_sample_db',
'encoding' => 'utf8',
//'timezone' => 'UTC',
'cacheMetadata' => true,
'quoteIdentifiers' => false,
],
],
で、以下のコマンドで、テーブルのモデルをbakeコマンドで自動生成。
(するとtestsディレクトリ以下にテストケースとフィクスチャーも自動生成される)
bin/cake bake model Articles
再びテストしてみる。(以下でテスト結果が出るはず)
vendor/bin/phpunit
ついでにカバレッジも作ってみる。
vendor/bin/phpunit --coverage-html webroot/coverage
webroot/coverage 以下に index.html が生成されるのでブラウザで開いてみる。
コーディング規約
さらにコードスニッッファーの設定をする。
以下のコマンドを打つ。
sudo vendor/bin/phpcs --config-set installed_paths vendor/cakephp/cakephp-codesniffer
さっきbakeで自動生成されたソースファイルを適当にいじる。
(コードスニッッファーにひっかかるようにコーディング規約を違反する)
いじったら、以下で実行。
vendor/bin/phpcs --standard=CakePHP src/
こんな感じに出る。
FILE: ...myApp/src/Model/Table/ArticlesTable.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
24 | ERROR | Space found after object operator
----------------------------------------------------------------------
Time: 343ms; Memory: 6.75Mb
タスクランナー
まずは Grunt をグローバルにインストールする
(が、これは多分やってある人もいるはず。なのでその人は次へ。)
npm install -g grunt-cli
次に初期化する。
npm init
いろいろ質問されるが、適当にエンターして完了。(まじめに入力してもよい)
これで package.json が作られる
次に grunt と grunt-phpunit をインストールする。
npm install grunt --save-dev
npm install grunt-phpunit --save-dev
同じく直下に以下のような Gruntfile.js を作成する。
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
phpunit: {
classes: {
dir: 'tests/TestCase/'
},
options: {
bin: 'vendor/bin/phpunit',
bootstrap: 'tests/bootstrap.php',
colors: true
}
},
});
grunt.loadNpmTasks('grunt-phpunit');
// Default task(s).
grunt.registerTask('default', ['phpunit']);
};
で、gruntコマンド実行。
grunt
結果は以下。よさそうである。
Running "phpunit:classes" (phpunit) task
Starting phpunit (target: classes) in tests/TestCase/
PHPUnit 4.5.0 by Sebastian Bergmann and contributors.
Configuration read from /Users/mymac/myApp/phpunit.xml.dist
IIIII
Time: 1.79 seconds, Memory: 8.50Mb
OK, but incomplete, skipped, or risky tests!
Tests: 5, Assertions: 0, Incomplete: 5.
Done, without errors.
コーディング規約の方も同じく設定する。
npm install grunt-phpcs --save-dev
ついでなので、見た目をグラフィカルにしてみる。(以下のプラグインで実行時間の棒グラフ表示が追加になる)
npm install time-grunt --save-dev
Gruntfile.js に追加。
module.exports = function(grunt) {
require('time-grunt')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
phpunit: {
classes: {
dir: 'tests/TestCase/'
},
options: {
bin: 'vendor/bin/phpunit',
bootstrap: 'tests/bootstrap.php',
colors: true
}
},
phpcs: {
application: {
dir: ['src/**/*.php']
},
options: {
bin: 'vendor/bin/phpcs',
standard: 'CakePHP'
}
}
});
grunt.loadNpmTasks('grunt-phpunit');
grunt.loadNpmTasks('grunt-phpcs');
// Default task(s).
grunt.registerTask('default', ['phpunit', 'phpcs']);
};
最後に watch を追加して、ファイルに編集があったら自動で実行されるようにしておく。
npm install grunt-contrib-watch --save-dev
以下追加・編集部分のみ。
grunt.initConfig({
watch: {
phpunit: {
files: ['src/**/*.php', 'src/**/*.ctp', 'tests/TestCase/**/*.php'],
tasks: ['phpunit'],
options: {
spawn: false,
},
},
phpcs: {
files: ['src/**/*.php'],
tasks: ['phpcs'],
options: {
spawn: false,
},
},
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['watch']);
JavaScript設置
JavaScript は Browserify を使ってモジュール単位で開発したいので、その準備をする。
とりあえずソースファイルは、 src/assets/scripts というディレクトリに設置することにして、
mkdir -p src/assets/scripts
その中に main.js と Hello.js をひな形として設置。
(単にHelloを返すだけのHello.jsをmain.jsからrequireして実行してるだけ)
(function(){
'use strict';
var Hello = require('./components/Hello');
var hello = new Hello();
console.log(hello.message);
})();
function Hello() {
'use strict';
this.message = 'Hello!';
}
module.exports = Hello;
これを Browserify で合体して webroot/js 以下に書きだそうという狙いである。
browserifyのgruntプラグインを入れる。
npm install grunt-browserify --save-dev
だがここで jquery も使えた方が便利なので、bower でインストールしておく。
bower init
いろいろ質問されるが、適当にエンターして完了。
bower.json ができる。
引き続きjQueryをインストール
bower install jquery --save
これでjqueryが入ったので、jqueryの場所をpackage.jsonに記述しておく。
"browser": {
"jquery": "./bower_components/jquery/dist/jquery.js"
}
最後、Gruntfile.js に以下追加。
browserify : {
dist : {
src : 'src/assets/scripts/main.js',
dest : 'webroot/js/build.js' // 出力するファイル名
}
},
watch: {
browserify: {
files: ['src/assets/**/*.js'],
tasks: ['browserify'],
options: {
spawn: false,
},
},
}
grunt.loadNpmTasks('grunt-browserify');
jquery使うぞってことで main.js の上の方に以下を追加。
var $ = require('jquery');
grunt コマンドを走らせて、watch状態になったら、先ほどのHello.jsを適当に編集してみる。
結果、
Running "watch" task
Waiting...
>> File "src/assets/scripts/components/Hello.js" changed.
Running "browserify:dist" (browserify) task
となって、webroot/js/ 以下に build.js が生成されていれば成功だ。
JavaScriptテスト
qunit は今さら〜ってことなので mocha にしてみる。
まずは npmでインストールする。
npm install -g mocha
テスト用jsの設置先を tests/scripts 以下にする。(新規ディレクトリ作成)
mkdir tests/scripts
vim tests/scripts/test.js
エディターで以下のようなテストスクリプトを保存する。
var assert = require("assert");
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
});
});
});
ここで mocha の動作確認。
mocha tests/scripts/test.js
以下のように出ればOKだ。
Array
#indexOf()
✓ should return -1 when the value is not present
1 passing (10ms)
実際的なテストを追加する。
var assert = require("assert");
var Hello = require('../../src/assets/scripts/components/Hello');
var hello = new Hello();
describe('Array', function(){
describe('#hello()', function(){
it('should return Hello when we call hello.message', function(){
assert.equal('Hello!!', hello.message);
});
});
});
続いてgruntから実行するのに、 grunt-simple-mocha を入れる。
npm install grunt-simple-mocha --save-dev
Gruntfile.jsに以下を追加。
simplemocha: {
options: {
ui: 'bdd',
reporter: 'nyan'
},
all: { src: ['tests/scripts/**/*.js'] }
},
watch: {
simplemocha: {
files: ['src/assets/**/*.js', 'tests/scripts/**/*.js'],
tasks: ['simplemocha'],
options: {
spawn: false,
},
},
}
grunt.loadNpmTasks('grunt-simple-mocha');
再び、
grunt
して、watch状態になったら、テストファイルを書き換えてみる。
以下のようになれば良い。
Running "watch" task
Waiting...
>> File "tests/scripts/test.js" changed.
Running "simplemocha:all" (simplemocha) task
4 -_-_-_,------,
0 -_-_-_| /\_/\
0 -_-_-^|__( ^ .^)
-_-_- "" ""
4 passing (17ms)
この辺で、だんだんGruntfile.jsが大きくなってきて見づらくなってきたと思う。
それがgruntの弱点だとも言われているが、そもそも先人たちが作り上げた巨大化したGruntfile.jsを最初っからバーンと渡されてこれでやるんだと説明されても、もう既に中身を読む気にならない状態な訳である。
なのでここではこうやって、たらたらと一つずつ設定している。
自分で一つずつ設定していって、最後、消すなら消す、使うなら残す、追加するなら追加する、自分で考えて決めればよい。
コントローラとテンプレート
JavaScriptのテストまでやったが、まだその結合したjsが実際に動いているのかどうか、確認していない。
ということで、ここで再びbakeコマンドを使ってコントローラとテンプレートを作成し、jsファイルを埋め込んでみる。
Articlesモデルは作成済みなので、同じように、
bin/cake bake controller articles
bin/cake bake template articles
とやって、
bin/cake server
でサーバーを起動、 http://localhost:8765/ にアクセスする。
src/Template/Layout/default.ctp を開いて、ヘッダー部分に以下を追加。
<?= $this->Html->script('build') ?>
http://localhost:8765/articles を開いてみて、コンソールにHelloと出ていればOKである。
動いている。
JavaScript構文チェック
引き続きjshintで構文チェックを行う。
npm install grunt-contrib-jshint --save-dev
Gruntfile.jsに以下を追加。
jshint: {
options: {
jshintrc: true
},
files: ['src/assets/**/*.js', 'tests/scripts/**/*.js']
},
grunt.loadNpmTasks('grunt-contrib-jshint');
とりあえず実行してみると、
grunt jshint
特に mocha のテストのところでエラーが大量にでる。
.jshintrc ファイルを作成してオプションを設定。
とりあえずこんな感じにしてみた。
{
"curly": true,
"eqnull": true,
"eqeqeq": true,
"undef": true,
"expr" : true,
"globals": {
"jQuery": true,
"module": false,
"require": false,
"console": false,
"describe": false,
"it": false,
"before": false,
"beforeEach": false,
"after": false,
"afterEach": false
}
}
watch はさっきのsimplemochaのところに追加しておけばいいだろう。
simplemocha: {
files: ['src/assets/**/*.js', 'tests/scripts/**/*.js'],
tasks: ['simplemocha', 'jshint'],
options: {
spawn: false,
},
},
コードの圧縮とsourceMap
grunt-contrib-uglify のインストール。
npm install grunt-contrib-uglify --save-dev
Gruntfileの編集。圧縮して build.min.js を作る。
uglify: {
my_target: {
options: {
sourceMap: true
},
files: {
'webroot/js/build.min.js': ['webroot/js/build.js']
}
}
},
watch: {
simplemocha: {
files: ['src/assets/**/*.js', 'tests/scripts/**/*.js'],
tasks: ['simplemocha', 'jshint', 'uglify'],
options: {
spawn: false,
},
},
}
grunt.loadNpmTasks('grunt-contrib-uglify');
テンプレート(レイアウト)の書き換え。
<?= $this->Html->script('build.min') ?>
Gitリポジトリ
最後にリポジトリに登録する。
.gitignoreにいくつか追加する。
/webroot/coverage/*
/node_modules/*
/bower_components/*
add して commit して pushする。
git add .
git commit -m "Improve project file"
git push origin master
他の開発メンバーは、
git clone https://github.com/xxxxxxxxx/myApp.git
curl -sS https://getcomposer.org/installer | php
cd myApp/
sudo php ../composer.phar install
sudo vendor/bin/phpcs --config-set installed_paths vendor/cakephp/cakephp-codesniffer
npm install
bower install
サーバー起動してみて。
bin/cake server
gruntでwatch開始。
grunt
以上終了。さあ、作るぞと。