Pugに入門してみる ~環境構築編 その2~

2020/09/03

昨日(Pugに入門してみる ~環境構築編 その1~)に引き続きPugの開発環境を整えていきたいと思います。
今日はリアルタイムプレビューできるようにします。

開発環境構築

1. 必要なパッケージのインストール

まずはパッケージのインストールから。

  • browser-sync

    $ npm install browser-sync

バージョン

browser-sync@2.26.12

### 2. gulpfile.jsを編集する
[Pugに入門してみる ~環境構築編 その1~](/2020/09//2020/09/pug-try-to-get-started/-env/)で作った**gulpfile.js**を編集していきます。  

#### 2-1. プレビュー用のローカルサーバーを起動する
下記のように**gulpfile.js**を編集します。  
```js{3,12-25}
const gulp = require('gulp');
const pug = require('gulp-pug');
const browserSync = require('browser-sync');

/**
 * `src`ディレクトリ配下のすべての`.pug`ファイルをコンパイルして`dist`へ出力する
 */
gulp.task('pug', function(done) {
  // ~ (略) ~
});

/**
 * ローカルサーバーを起動する
 */
gulp.task('browser-Sync', function(done) {
  browserSync({
    server: {
      // プレビューしたいファイルの置いてあるディレクトリを指定
      baseDir: 'dist/',
      // プレビューしたいファイルを指定
      index: "index.html"
    }
  });
  done();
});

実行してみます。

$ gulp browser-Sync

#実行結果
[Browsersync] Access URLs:
 ------------------------------------
       Local: http://localhost:3000
    External: http://192.168.X.X:3000
 ------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 ------------------------------------

実行するとブラウザが立ち上げり,index.html(指定したファイル)を表示してくれます。
image
ちなみに同一ネットワーク(Wifi)からならExternal: http://192.168.X.X:3000へアクセスすることが出来ます。
詳しくはこちらの記事(ローカル環境の開発内容を実物のスマホで確認する方法)で書いてます。

2-2. gulp.watchでファイルの変更を検出する

次に.pugファイルが変更されたのを検知して自動的にHTMLへ出力できるようにします。
引き続きgulpfile.jsを編集していきます。

const gulp = require('gulp');
const pug = require('gulp-pug');
const browserSync = require('browser-sync');

/**
 * `src`ディレクトリ配下のすべての`.pug`ファイルをコンパイルして`dist`へ出力する
 */
gulp.task('pug', function(done) {  // .pugファイルを読み込む
  gulp.src(src/**/*.pug')
    .pipe(pug({
      // pugファイルを整形するオプション
      pretty: true
    }))
    // .htmlファイルを出力する
    .pipe(gulp.dest(dist'));
    done();});

/**
 * ローカルサーバーを起動する
 */
gulp.task('browser-Sync', function() {
  // ~ (略) ~
});

/** * pugファイルの変更を検知して自動でHTMLに出力 */gulp.task('watch', function(done) {  // `./src/**/*.pug`を監視して変更を検知したらgulp.task('pug')を実行する  gulp.watch(src/**/*.pug', gulp.task('pug'));  done();});

実行してみます。

$ gulp watch

#実行結果
Starting 'watch'...
Finished 'watch' after 15 ms
Starting 'pug'...
Finished 'pug' after 16 ms
Starting 'pug'...
Finished 'pug' after 3.12 ms

.pugファイルを保存するたびにgulp.task('pug')が実行されます。

2-3. browserSyncとgulp.watchを組み合わせる

最後にリアルタイムプレビューするためにbrowserSyncとgulp.watchを組み合わせていきます。

const gulp = require('gulp');
const pug = require('gulp-pug');
const browserSync = require('browser-sync');

/**
 * `src`ディレクトリ配下のすべての`.pug`ファイルをコンパイルして`dist`へ出力する
 */
gulp.task('pug', function(done) {
  // .pugファイルを読み込む
  gulp.src(src/**/*.pug')
    .pipe(pug({
      // pugファイルを整形するオプション
      pretty: true
    }))
    // .htmlファイルを出力する
    .pipe(gulp.dest(dist'))
    .pipe(browserSync.reload({stream: true}));    done();
});

/**
 * ローカルサーバーを起動する
 */
gulp.task('browser-Sync', function(done) {
  browserSync({
    server: {
      // プレビューしたいファイルの置いてあるディレクトリを指定
      baseDir: 'dist/',
      // プレビューしたいファイルを指定
      index: "index.html"
    }
  });
  done();
});

/**
 * pugファイルの変更を検知してリアルタイムプレビューする
 */
gulp.task('watch', gulp.series(gulp.parallel('pug', 'browser-Sync'), function(done) {  gulp.watch(src/**/*.pug', gulp.task('pug'));  done();}));

若干ややこしくなりましたが,$ gulp watchが実行されると,gulp.task('pug')gulp.task('browser-Sync')が並列で実行され,その後にgulp.watchが実行されます。
そして.pugファイルが保存されるたびにgulp.task('pug')が実行されその結果がbrowserSyncに渡され,リロードされます。

3. ハマったポイント

僕自身がハマった点として,gulp3系と4系で書き方がだいぶ違うので3系の書き方をしていると思ったような挙動になりませんでした。

watchが1回しか実行されない

$ gulp watchを実行した時に,1回だけしかgulp.task('pug')が実行されず,2回目以降は変更してもHTMLが出力されませんでした。
gulp.taskにdoneコールバックを追加して,gulpにタスクが完了したのを知らせる必要が会ったようです。

gulp.seriesとgulp.parallel

4系で追加されたgulp.seriesgulp.parallelの2つのメソッドの使い方で困惑しました。
3系のままの書き方をしてるとAssertionError: Task function must be specifiedというエラーが発生します。

まとめ

リアルタイムプレビューが実装できました:tada:
思いの外ハマって時間を溶かしましたがgulp4系の書き方がだいぶわかってきた気がします。
前にチャレンジしたときは出来ずにあきらめて3系を使っていたので…
成長を感じます。積み重ねですね。

それではまた明日。

参考ページ

関連記事


書いた人: こへ
音楽と漫画と読書とアニメとスノボが好き。多趣味でいろんなことに興味有ります。 誰しもが一度は使った事があるもののIoT開発をしてます。
Twitterフォローお願いします。