gulpの続きです。前回はwatch()
メソッドで自動コンパイルを体験しました。今回はもう一歩進んでブラウザも毎回リロードするのではなくファイルの修正→保存のたびにブラウザも自動リロードをしたく。「browser-sync」を使います。Sass(SCSS)コンパイルも同時に実行するため、
watch()やdefaultタスクを分離して書く必要がありました。それではいきましょう!
【目次】
- browser-syncのインストール
- 今回やりたいこと
- 対象ファイルの変更
- browserSyncの設定
- watch()の分離
- defaultタスクを設定
- 挙動確認
- gulpfile.js全体
- 最後に
※参考:【Gulp】watch()メソッドでSass(SCSS)を自動コンパイル - クモのようにコツコツと
※参考:メタ言語(HTMLテンプレートエンジン、AltCSS、AltJS)まとめ
qiita.com
browser-syncのインストール
ブラウザの自動リロードについて調べると「browser-sync」が一番使われているようだ。
※参考:Browsersync - Time-saving synchronised browser testing
これをインストールする。
ターミナルのcd
コマンドで、前回作業したSass(SCSS)環境のフォルダ「gulp_sass」に移動する。
cd /(フォルダ)/gulp_sass
「browser-sync」をインストール。
npm i -D browser-sync
インストール成功するとpackage.jsonに「browser-sync」が追記される。
"devDependencies": { "browser-sync": "^2.26.7", "gulp": "^4.0.2", "gulp-sass": "^4.0.2" }
今回やりたいこと
- html、css、jsのファイルを修正、保存したらブラウザが自動リロード
- Sass(SCSS)もコンパイルしたらブラウザを自動リロード
browser-syncのタスクさえ書けばこれが実現できるのかな、と思っていたが、実際に書いてみると最初の1回しか実行されなかった。。
それだけでなく、下記の処理も書く必要があった。
watch()
メソッドでbrowser-syncもSass(SCSS)も監視する- そのため前回Sass(SCSS)のタスクの中に書いた
watch()
メソッドを外に分離して、その中でbrowser-syncとSass(SCSS)を監視 - タスク名が複数になるので、それら全てを
gulp
のみで実行できるようにdefault
(タスク名が不要になる)の中で複数のタスクの実行を設定する
このやりたいことに一番近い内容を下記の記事が実現していて、とても参考になりました!
※参考:gulp4とbrowser-syncを使用したブラウザ自動更新機能作成 | Darablog
対象ファイルの変更
JSファイルを追加
今回、JSの修正による自動リロードもやってみたかったので、JSファイルを追加した。
JSコード
window.onload = () => { console.log("成功!"); }
ウィンドウがリロードされたらコンソールに「成功!」という文字を表示する。
上記のJSファイル(common.js)をHTMLにリンクして紐付ける
HTMLコード
<script src="js/common.js"></script>
別ページを追加
複数のHTMLファイルで自動リロードできるか検証したいのでページを追加した。
別ページ(other.html)を追加 HTMLコード
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>別ページ</title> <link rel="stylesheet" href="css/common.css"> <link rel="stylesheet" href="css/other.css"> <script src="js/common.js"></script> </head> <body> <section id="scss"> <h1>別ページ</h1> <p class="lede"><a href="/">Topへ</a></p> </section> </section> </body> </html>
Topページ(index.html)にも別ページへのリンクを追加する。
<p><a href="other.html">別ページへ</a></p>
browserSyncの設定
ここからはgulpの設定ファイルである「gulpfile.js」の修正になる。先程の記事を参考に進める。
※参考:gulp4とbrowser-syncを使用したブラウザ自動更新機能作成 | Darablog
browser-sync読み込み
最初にbrowser-sync
を読み込む。
const browserSync = require('browser-sync');
変数browserSync
にrequire()
でbrowser-sync
を読み込む
browserSync.init()でリロードするhtmlファイルを設定
次にbrowserSync.init()
でリロードするhtmlファイルを設定する。
// リロードするhtml gulp.task('browser-sync', (done) => { browserSync.init({ server : { baseDir : './', index : 'index.html', }, }); done(); });
gulp.task()
の第一引数はタスク名でbrowser-sync
- 第二引数は無名関数で、無名関数の引数は
done
無名関数の一つ目の処理はbrowserSync.init()
メソッドで引数は連想配列
連想配列のキーはserver
でその値も連想配列
連想配列の一つ目のキーはbaseDir
で値は./
(フォルダのパス)
二つ目のキーはindex
で値はindex.html
(Topページのファイル名) 二つ目の処理はdone()
ふむふむ。リロードを実現するためのサーバ設定だなこれは。フォルダのパスとトップページのファイル名を指定している。
コールバック関数done()
コールバック関数done()
の実行は前回までのreturn
とは別の書き方になる。
browser-syncではreturnを使っていないので、done()というコールバック関数を実行するようにしました(公式ではcb()となっています)。
これでbrowser-sync
というタスクでリロードのためのサーバが起動する。
(ちなみに、gulp 4ではgulp.task()
自体も非推奨のようだが。。今回はひとまずgulp.task()
で書く)
「コールバック関数」とは引数として渡される関数のこと。
※参考:https://wa3.i-3-i.info/word12295.html
indexキーはTopページのファイル名に
ちなみにindex
キーのファイル名をワイルドカード*.html
にしてみたところ、ページの表示が「Cannot GET」というエラーになる。
index
キーはトップページの指定らしく固有のファイル名(index.html)がいいようだ。
(index.html以外のhtmlファイルが自動リロードされるか気になったので、先程のother.htmlを追加した)
browserSync.reload()でリロード設定
上記だけだとリロードは実現できず、もう一つbrowserSync.reload()
というメソッドでリロード設定を書く
// リロード設定 gulp.task('browser-reload', (done) => { browserSync.reload(); done(); });
gulp.task()
の第一引数はタスク名でbrowser-reload
- 第二引数は無名関数で、無名関数の引数は
done
無名関数の最初の処理はbrowserSync.reload()
次の処理はdone()
これでbrowser-reload
というタスクでリロードが実行される。
watch()の分離
上記の設定だけだとファイルの修正のたびに自動リロードはされなかった。watch()
メソッドで修正の対象ファイルを監視する必要があった。
Sass(SCSS)コンパイルのwatch()メソッドを分離
前回、Sass(SCSS)コンパイルのタスクの中にwatch()
メソッドを組み入れたが、今回はSass(SCSS)コンパイルと自動リロード、二つのタスクに対してwatch()
メソッドで監視したい。そのため、watch()
メソッドをSass(SCSS)コンパイルや自動リロードの外側に書く必要があった。
前回のコード
gulp.task('sass', () => { return gulp.watch("css/*.scss", () => { return gulp .src('css/*.scss') .pipe(sass({ outputStyle: 'expanded' }) ) .on("error", sass.logError) .pipe(gulp.dest('css')); }); });
詳細は前回の記事を参照
※参考:【Gulp】watch()メソッドでSass(SCSS)を自動コンパイル - クモのようにコツコツと
ここからwatch()
メソッド部分を除外する。
// sassコンパイル gulp.task('sass', (done) => { gulp.src('./css/*.scss') .pipe(sass({ outputStyle: 'expanded' }) ) .on("error", sass.logError) .pipe(gulp.dest('./css')); done(); });
また、return
ではなくコールバック関数done()
の書き方にしてみた。
除外したのはwatch()
メソッドは下記の部分
return gulp.watch("css/*.scss", () => { // タスク処理 });
watch()メソッドを設定
watch()
メソッドは外部に別途まとめて書いた。
// 監視ファイル gulp.task('watch-files', (done) => { gulp.watch("./*.html", gulp.task('browser-reload')); gulp.watch("./css/*.css", gulp.task('browser-reload')); gulp.watch("./css/*.scss", gulp.task('sass')); gulp.watch("./js/*.js", gulp.task('browser-reload')); done(); });
gulp.task()
の第一引数はタスク名でwatch-files
- 第二引数は無名関数で引数は
done
、この中にwatch()
の設定を書く - 1つ目の
gulp.watch()
、第一引数でhtmlファイル、第二引数はgulp.task()
で引数はbrowser-reload
- 2つ目の
gulp.watch()
、第一引数でcssファイル、第二引数はgulp.task()
で引数はbrowser-reload
- 3つ目の
gulp.watch()
、第一引数でscssファイル、第二引数はgulp.task()
で引数はsass
- 4つ目の
gulp.watch()
、第一引数でjsファイル、第二引数はgulp.task()
で引数はbrowser-reload
- 最後にコールバック関数
done()
を実行
scss
ファイルはsass
タスクを実行するが、それ以外はbrowser-reload
タスクを実行する。ファイル名はワイルドカード*
で汎用的にしている。
defaultタスクを設定
今回、watch-files
、browser-sync
、sass
と複数のタスクを設定した。
これまではnpx gulp sass
などのタスク名で実行していたが、default
タスクを設定するとタスク名が不要でnpx gulp
だけでgulpが動く。
この中に複数のタスクを紐付けて実行されるようにする。
複数タスク実行の書き方(Gulp3とGulp4の違い)
ここ、今回重要だったんだけど、複数のタスクの実行をしたいときこのようなエラーが起きた。
AssertionError [ERR_ASSERTION]: Task function must be specified
gulp 3までとgulp 4で書き方が変わっていいる部分があり、gulp 3までの書き方だとエラーになった!
glup 3とgulp 4の変更点。
※参考:gulp v4.0.0がプレリリース! 移行方法と変更点まとめ | satoyan419.com
この中で今回一番関係したのは、引数の指定方法(複数のタスクを引数に入れるため)
gulp 3までの書き方
gulp.task('default', ['タスク名', 'タスク名'], () => { // タスクの処理 });
gulp.task()
の第一引数はdefault
(タスク名が不要になる)- 第二引数は配列でこの中に実行したいタスク名を入れる
- 第三引数は無名関数でその中にタスクの処理を書く
gulp 4からの書き方
gulp.task('default', gulp.series( gulp.parallel('タスク名'', 'タスク名''), () =>{ // タスクの処理 }));
gulp.task()
の第一引数はdefault
(タスク名が不要になる)- 第二引数は
gulp.series()
メソッドでその引数にさらにgulp.parallel()
メソッド。この引数の中に実行したいタスク名を入れる - 第三引数は無名関数でその中にタスクの処理を書く
配列ではなくgulp.series()
とさらにその中に入れ子になったgulp.parallel()
メソッドを書く。
gulp.series()
とgulp.parallel()
の違いは
- gulp.series:タスクを直列処理する
- gulp.parallel:タスクを並列処理する
※参考:gulp v4.0.0がプレリリース! 移行方法と変更点まとめ | satoyan419.com
defaultタスクで複数のタスクを実行
上記のgulp4の書き方でdefault
タスクに複数のタスクを設定する。
// タスク実行 gulp.task('default', gulp.series( gulp.parallel('watch-files', 'browser-sync', 'sass'), (done) => { done(); }));
gulp.task()
の第一引数はdefault
(タスク名不要)- 第二引数は
gulp.series()
で、gulp.series()
の第一引数はgulp.parallel()
gulp.parallel()
の引数にwatch-files
、browser-sync
、sass
を書く
gulp.series()
の第二引数は無名関数で、無名関数の引数はdone
無名関数の中でdone()
を実行
これでnpx gulp
を実行するとリロードとSass(SCSS)コンパイルが常に実行される。
挙動確認
gulpを実行(ブラウザが開く)
上記のコードでやりたい挙動が実現できた!
まずターミナルでgulp
を実行!
npx gulp
ブラウザでTOPページ(index.html)が立ち上がる!
URLはローカルホストのポート番号3000
http://localhost:3000/
デベロッパーツール のコンソールを開くと「成功しました!」のテキストが。 JSも動いている!
別ページに移動
一番したの「別ページへ」から別ページ(other.html)に移動
http://localhost:3000/other.html
よし!別ページも問題なく表示されている
HTMLの修正(Topページ)
Topページ(index.html)に戻って
h1タグを打ち替えてみる
<h1>SCSS事始め(with 自動リロード)</h1>
おお!h1のテキストが自動的に変わった!
HTMLの修正(別ページ)
別ページ(other.html)も打ち替えてみよう。
pタグを追加
<p>別ページもリロードされるかテストですと。</p>
おお、pタグが追加された!
Sass(SCSS)のコンパイル
sassファイルを修正してコンパイルが自動リロードで適用されるかテスト。
common.scssのh2の文字色orange
を
#oya { /*中略*/ h2 { color: orange; font-size: 1.5em; line-height: 1.2; }
blue
にしてみると…
#oya { /*中略*/ h2 { color: blue; font-size: 1.5em; line-height: 1.2; }
おお!h2タグの見出しが青くなった!
JSファイルの修正
最後にJSファイルの修正を試みる。
デベロッパーツール のコンソールは「成功しました!」だが…
コンソールのテキストを「成功したでござる!」に変えてみると…
window.onload = () => { console.log("成功したでござる!"); }
おお!コンソールの文字が変わった!
gulpfile.js全体
最後にgulpfile.js全体のコード
const gulp = require('gulp'); const sass = require('gulp-sass'); const browserSync = require('browser-sync'); // sassコンパイル gulp.task('sass', (done) => { gulp.src('./css/*.scss') .pipe(sass({ outputStyle: 'expanded' }) ) .on("error", sass.logError) .pipe(gulp.dest('./css')); done(); }); // リロードするhtml gulp.task('browser-sync', (done) => { browserSync.init({ server : { baseDir : './', index : 'index.html', }, }); done(); }); // リロード設定 gulp.task('browser-reload', (done) => { browserSync.reload(); done(); }); // 監視ファイル gulp.task('watch-files', (done) => { gulp.watch("./*.html", gulp.task('browser-reload')); gulp.watch("./css/*.css", gulp.task('browser-reload')); gulp.watch("./css/*.scss", gulp.task('sass')); gulp.watch("./js/*.js", gulp.task('browser-reload')); done(); }); // タスク実行 gulp.task('default', gulp.series( gulp.parallel('watch-files', 'browser-sync', 'sass'), (done) => { done(); }));
- 変数
browserSync
でbrowser-sync
を読み込む sass
タスクからwatch()の記述を除外browser-sync
タスクでリロードするhtmlファイルを設定browser-reload
タスクでリロード設定watch-files
タスクで監視対象のファイルと実行するタスクを設定default
タスクでgulp
コマンドで実行するタスクを設定
最後に
ということで、自動リロードを体験できましたー。成功までは結構苦戦しました。gulp3とgulp4の書き方の違いなども知ることができました。
また、今回は自動リロードだけではなく、Sass(SCSS)コンパイルも同時に実行するためにwatch()
メソッドを外側で設定する方法やdefault
タスクで複数のタスクを同時に実行する方法も知ることができました。
これまで単体で試してきたメタ言語(HTMLテンプレート、AltCSS、AltJS)を融合して、自動でコンパイル→リロード、をするための出発点になりそうです♪
それではまた!
※参考:メタ言語(HTMLテンプレートエンジン、AltCSS、AltJS)まとめ
qiita.com