こんにちは、店長です。
フロントエンド入門者のためのgulp.js編も第5回となりました。第3回、第4回に引き続き、今回もgulp.jsで便利なタスクを作ってみましょう。今回はJavaScriptをより綺麗に書くために使いたい構文チェックツール「gulp-eslint」をご紹介します。
第3回から今回までの内容に関するファイルは、下記にまとめています。
Im0-3/gulp-tutorial – Github
5-1が前回の内容で、5-2と5-3が今回作る内容になっています。ファイルをダウンロードしたら、ターミナルでprojectフォルダに移動して
$ npm install gulp-eslint --save-dev
を実行しましょう。そうすると、制作に必要なライブラリをダウンロードできます。
前回までのファイルの内容は下記の通りです。ディレクトリ構成
project |--app | |--product | | |--index.html | | |--css | | | |--style.css | |--src | | |--index.html | | |--sass | | | |--style.scss |--package.json |--gulpfile.js |--.htmlhintrc
gulpfile.jsvar gulp = require('gulp'); var sass = require('gulp-sass'); var htmlhint = require('gulp-htmlhint'); var browserSync = require('browser-sync').create(); var notify = require('gulp-notify'); var plumber = require('gulp-plumber'); gulp.task('sass', function() { gulp.src('app/src/sass/*.scss') .pipe(plumber({ errorHandler: notify.onError("Error: <%= error.message %>") })) .pipe(sass()) .pipe(gulp.dest('app/product/css/')) .pipe(browserSync.stream()); }); gulp.task('html', function(){ gulp.src('app/src/**/*.html') .pipe(htmlhint()) .pipe(htmlhint.reporter()) .pipe(gulp.dest('app/product/')) .pipe(browserSync.stream()); }); gulp.task('browser-sync', function() { browserSync.init({ server: "./app/product" }); }); gulp.task('default', function() { browserSync.init({ server: "./app/product" }); gulp.watch('app/src/sass/*.scss',['sass']); gulp.watch('app/src/**/*.html',['html']); });
では、さっそく見ていきましょう。
JavaScriptの構文をチェックするgulp-eslint
デバッグ編ではHTMLの構文をチェックするHTMLHintをご紹介しました。今回はJavaScriptの構文チェックで役に立つgulp-eslintを紹介します。
gulp-eslintは、ESLintをgulpで使うことができるライブラリです。
ESLintとは
ESLintは、JavaScriptのコードの構文を検証するためのツールです。
JavaScriptの構文チェックツールは他にも、「JSHint」や「JSLint」、「JSCS」などもありますが、ESLintはチェック項目が豊富に用意されていて、すべてのルールを自由に付けたり外したりできるようになっています。加えて、ルールごとにアラートの強さを設定できるので、自分に合わせたルールを作りやすいのが特徴です。
今回はgulp-eslitでESLintを使用する方法と、簡単なチェック項目の追加をおこなってみたいと思います。
インストール
例によって、まずはgulp-eslintをインストールしましょう。
$ npm install gulp-eslint --save-dev
ESLintを使ってJavaScriptの構文をチェックしよう
まずはタスクを組んでみましょう。
srcディレクトリ内にjsディレクトリを作成して、その中のJavaScriptファイルをチェックするようにします。チェックしたら、product/jsディレクトリにJavaScriptファイルを追加します。
project |--app | |--product | | |--index.html | | |--css | | | |--style.css | | |--js | | | |--app.js | |--src | | |--index.html | | |--sass | | | |--style.scss | | |--js | | | |--app.js |--package.json |--gulpfile.js |--.htmlhintrc
今回はscriptという名前の新しいタスクを用意します。
var gulp = require('gulp'); ~ 中略 ~ var notify = require('gulp-notify'); var plumber = require('gulp-plumber'); var eslint = require('gulp-eslint'); //(*1) ~ 中略 ~ gulp.task('script', function(){ gulp.src('app/src/js/*.js') .pipe(plumber({ errorHandler: notify.onError('Error: <%= error.message %>') })) //(*2) .pipe(eslint()) //(*3) .pipe(eslint.format()) //(*4) .pipe(eslint.failAfterError()) //(*5) .pipe(gulp.dest('app/product/js/')); }); gulp.task('default', function() { browserSync.init({ server: "./app/product" }); gulp.watch('app/src/sass/*.scss',['sass']); gulp.watch('app/src/**/*.html',['html']); gulp.watch('app/src/js/*.js',['script']); //(*5) });
- (*1)まずはいつものようにgulp-eslintをrequireしましょう。
- (*2)処理の先頭で、前回使ったgulp-plumber、gulp-notifyを使って、エラー時にタスクを止めない処理と、通知を追加します。
- (*3)その後gulp-eslintを実行して、構文のチェックをおこないます。
- (*4)gulp-eslintのformatメソッドを使用すると、ターミナル内に結果の出力をおこなうことができます。
- (*5)failAfterErrorメソッドをつかうとルールに引っかかった際にはエラーを出力してくれます。
まずはこれで1回実行して、コードを書いてみましょう。
たとえば、関数のカッコを忘れている場合は、このようなエラーがでます。
では次に以下のように書いて実行してみてください。
app/src/js/app.js
var date = new Date();
var element = document.getElementById('time');
function getTime(date){
return data.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
}
element.innerHTML = getTime(date);
5行目、returnの最初のdateをわざとdataと間違えて記述してみました。
しかし、このコードではエラーは表示されないんです。ESLintは、初期の設定の場合、シンタックスエラーしかチェックをしてくれません。さらに詳細なチェックをするために、設定をカスタマイズしてみましょう。
ESLintを利用する環境にあわせよう
ESLintの設定方法はさまざまですが、今回はeslintrc.というファイルを用意して設定をおこないたいと思います。まずは、先ほどのコードを下記のように変更しましょう。
gulp.task('script', function(){
gulp.src('app/src/js/*.js')
.pipe(plumber({
errorHandler: notify.onError('Error: <%= error.message %>')
}))
.pipe(eslint({useEslintrc: true}))
.pipe(eslint.format())
.pipe(eslint.failAfterError())
.pipe(gulp.dest('app/product/js/'));
});
useEslintrcは.eslintrcを使用するかどうかを定義するためのオプションです。
次に.eslintrcというファイルをprojectディレクトリ内に用意しましょう。このファイルはESLintの細かい設定をするためのファイルです。ここに書き込むことで、環境への対応やルールの追加、変更などができるようになります。
まずは環境にあわせた設定をしてみましょう。.eslintrc内に下記の内容を記述してください。
{
"env": {
"browser": true
}
}
ここで指定した環境内にあるグローバル変数(browserで言えばwindow, documentなど)を自動で追加してくれます。他にもNode.jsや、ES6のための環境設定が存在します。
詳しくはこちらをご覧ください。
Specifying Environments - ESLint
ESLintのオススメ設定を使用してみよう
{
"extends": "eslint:recommended"
"env": {
"browser": true
}
}
先ほどのファイルに、さらに上記を追加します。
このように指定することで、「Rules - ESlint」に記載されているもののうち、チェックマークがついたものをチェックしてくれます。試しに、先ほどのコードをもう1回チェックしてみましょう。
すると、このようにエラーが出力されました。これは未定義の変数を検知したエラーです。
アラートメッセージの内容はこちらの通り。
アラートの種類はerrorとwraning(警告)の2種類あります。errorは必ず直すべきところ、warningは注意して使用する、極力使わないようにするといった意味合いです。
設定をして更に細かく設定をしてみよう
使っていくと、ルールによってはチェックしたくないものやチェックをゆるくしたいもの、逆にチェックをもっと厳しくしたいものが出てくるかと思います。
var date = new Date();
var element = document.getElementById('time');
function getTime(date){
return date.getHours(date) + ':' + date.getMinutes(date) + ':' + date.getSeconds(date);
}
element.innerHTML = getTime(date);
console.log(getTime(date));
例えば、こちらのコードを実行した場合……
このようなエラーが出力されます。これは、コンソールを使用した際に出力されるエラーです。しかし、コンソールは使うことがあるし、チェックをゆるくしたいなんて場合もあると思います。
そんなときはルールの設定を追加して、カスタマイズをしましょう!
{
"extends": "eslint:recommended"
"env": {
"browser": true
}
"rules": {
"no-console": 1 //コンソールを使用している
}
}
まずは、rulesに変更や追加をしたいルール名を指定します。
値は、0がチェックをしない、1がwarning(警告)、2がerrorとしてアラートを出すようになります。ですから、上記のようにコードを書くとコンソールを使用した際はwarning(警告)が出るようになります。
今度は、recommendedには設定されてないけど便利なルールを追加してみましょう。次に追加するルールは、クオートをシングルクオートで囲むか、ダブルクオートで囲むかをチェックする「quote」というルールです。
こちらのルールにはオプションがついています。
では実際にルールを設定してみましょう。
{
"extends": "eslint:recommended",
"env": {
"browser": true
},
"rules": {
"no-console": 1, //コンソールを使用している
"quotes": [2, "single"] //シングルクオートを使用していない
}
}
オプションが付いているルールは配列で設定値を渡します。1つ目がエラーの種類で、2つ目がルールのオプション設定です。quotesでは、ダブルクオートのみにしたい場合はdubble、シングルクオートのみにしたい場合はshigleと設定してあげます。
var date = new Date();
var element = document.getElementById("time");
function getTime(date){
return date.getHours(date) + ":" + date.getMinutes(date) + ":" + date.getSeconds(date);
}
element.innerHTML = getTime(date);
では実際に、こちらのコードをチェックしてみましょう。
すると、ダブルクオートを使っている部分でエラーが出ているのがわかるかと思います。
他にも覚えておくと便利なルールを下記にまとめてみたので、自分の環境に合わせて使用してみてください。
"rules": {
"no-console": 1, //コンソールを使用している
"no-alert": 1, //アラートを使用している
"quotes": [2, "single"], //シングルクオートを使用していない
"consistent-return": 1, //関数の戻り値に何も指定していない
"default-case": 1, //switch文でdefaultが設定されていない
"eqeqeq": 1, //「===, !==」ではなく「==,!=」を使用している
"camelcase": [2, {"properties": "always"}], //キャメルケースを使用していない
"no-unused-vars": 1 //使用していない変数がある
}
errorにするか、warningにするかは、自分の環境に合わせて調整してみてください。もちろん、まだ他にもたくさんのルールが存在します。単純な構文チェック以外にもどこにスペースを入れる入れないといった細かい指定もできます。適切に設定をして、良いルールを作っていきましょう。
ルールの内容がわからない場合やどんなルールがあるかを知りたい場合は、こちらのページをご覧ください。
Rules - ESLint
また、Web上でESLintを試してみることができるので、こちらも合わせて使ってみてください。
ESLint Demo - ESLint
errorがあるときには出力しないようにする
ルールによってチェックできるようになったので、今度はerrorが出ているときはファイルを出力しないように制御してみましょう。そのときに使用するのが、resultメソッドです。
gulp.task('script', function(){
gulp.src('app/src/js/*.js')
.pipe(plumber({
errorHandler: notify.onError('Error: <%= error.message %>')
}))
.pipe(eslint({useEslintrc: true}))
.pipe(eslint.format())
.pipe(eslint.failAfterError())
.pipe(eslint.result(function(result){
if(result.errorCount !== 0) {
return;
}
gulp.src(result.filePath)
.pipe(gulp.dest('app/product/js/'));
}))
.pipe(browserSync.stream());
});
resultメソッドはチェックした結果を確認することができるメソッド。関数の引数には、結果が返ってきます。result.errorCountではerrorの数を、result.warningCountではwarningの数を、result.filePathではファイルのパスを確認できます。
もしresult.errorCountが0でない場合は処理をせず、0の場合にはファイルをproduct内に出力します。こうすることで、errorが見つかった際には出力されず、厳密にコードを保つことができます。
まとめ
ESLintはかなり高機能で、他にもカスタムのルールが使えるなどやれることが多いです。気になる方は、ぜひいろいろと調べてみてください。
これまで3回に分けてタスクの作り方をご紹介しましたが、タスクの組み方はわかってきたでしょうか? ドキュメントを読みながら使えば、そんなに怖くはありません。
次回はgulp.js連載の最終回。gulpライブラリの探し方と便利なライブラリをまとめてご紹介します! それでは。
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。