34
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IDOM EngineerAdvent Calendar 2017

Day 12

gulp+Handlebars.jsで静的htmlを作る

Last updated at Posted at 2017-12-12

※(追記) 2017年に投稿した記事なので 「当時はコレで動きました。」 という話です。
※ これからgulpの本格導入を考えてる場合は、アテにしない方が良いかもです。
※(追記) gulp4.0.2でタスクを書く場合は、こちらもご参照下さい。
https://qiita.com/DaisukeNishi/items/625419cf6ad36993a7f2

はじめに

IDOMアドベントカレンダー(12日目)に投稿しています。
https://qiita.com/advent-calendar/2017/idom-engineer
初心者向け、gulp+Handlebars.jsを使って効率的に静的なhtmlを作る方法を書きます。
序盤の初期設定などは、既にnpmをお使いの皆さんはご存知かと思いますので、
飛ばして読んだ方が良いかと思います。(また、Macでの制作前提です。)

イマドキ gulp …? WebpackVite を使わない理由は?

設定ファイルをゴリゴリかくようなタスクランナーは、需要がないかもしれないですが、
Webpack を使わない理由はエントリーポイントがJSではないためです。
静的なhtml を組み立てるだけであれば gulp で良いと思います。
WEB制作で node.js を使いはじめる瞬間に

  • 「コレ Apache じゃないから SSI 使えない。困ったな」
  • 「テキストは、 html と分けてバインディングしたい」
  • 「最終的に html で納品しなければならない」

みたいな人には、まだ使えると思います。

  • SPAで作りたい?

それはまた違う記事をご参照下さいませ。

htmlテンプレートエンジンにあえて、handlebars をあえて使う理由は?

Github の stars はpug の方が多いのですが、
npmtrends では handlebars の方が多いです。

handlebars.js で日本語サイトを検索した感じでは
マイナーなライブラリの扱いでしたが、
グラフでみるとメジャーなテンプレートエンジンのようです。
gulp だと特に追加のインストールも不要です。

http://www.npmtrends.com/handlebars-vs-jade-vs-pug-vs-ejs-vs-hogan.js-vs-mustache-vs-jsrender
ejs よりとっつきやすく pug より覚えるのが億劫でないと思います。

  • ↓しばらく初期設定が続きます。

(スキップ可)Gitリポジトリを作る。

作成方法は人それぞれですが、

  • Githubに frontend というリポジトリを作って git clone する

または

  • git init で local に frontend というリポジトリを作って $ git remote add

termminal cmd がまったく分からない場合は
SOURCETREE を使って作れば良いです
https://www.sourcetreeapp.com/

それについての説明は省略します。
(※ gitに置かない選択肢がないと思うので、記載)

  • 作成
touch .gitignore
  • 記述
.gitignore
/node_modules
/dist

.gitignoreに書いておいてください。

.gitignore の参考リンク:
https://qiita.com/inabe49/items/16ee3d9d1ce68daa9fff

これの意味:
ライブラリやコンパイル後のファイルは、commitする必要がないです。

(スキップ可)Gulpを使う前の下準備

Homebrew のインストール(Mac)

terminal
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Nodebrew(node.js:パッケージ/バージョン管理)

terminal
$ brew install nodebrew

nvmdocker が使う場合は、それでも良い。

たまにパーミッションの問題がありまして、
無いと動かない人も居るため、先に mkdir しておく。(8.3.0の箇所を打ちかえる)

terminal
$ mkdir .nodebrew/src/v8.3.0

node.jsのバージョンを指定してインストールするやり方
(8.3.0の箇所は、使いたいバージョンに打ちかえる)

※2024年現在 Node.js は v22 が最新ですが、
 gulp3〜4系全盛期の Node.jsのバージョンは、ひとケタです。
 最新で動かない場合は、あえてバージョンを下げた方が良いです。

terminal
$ nodebrew install-binary 8.3.0

最新版node.jsインストールのやり方

terminal
$ nodebrew install-binary latest

インストールされたバージョンを一覧で見る

terminal
$ nodebrew list

使うバージョンをuse〇〇で選ぶ、(8.3.0の箇所を打ちかえる)

terminal
$ nodebrew use v8.3.0

もう一度、一覧をみる。current:に使うモノが選ばれている状態

terminal
$ nodebrew list

下記「パスを通す」。

パスを通すとは、ターミナル開くたびにやらなくて良くする事。

「環境変数?パスを通す?」と思って、
bashzsh について調べ始めると、奥が深いので、つまづきポイントになります
最初は「おまじない」と覚えて、後から勉強しましょう。

touch .bashrc
.bashrc
#!/bin/bash
export PATH=$HOME/.nodebrew/current/bin:$PATH
terminal
$ source ~/.bashrc

※ 最近は bash ではなく zsh が標準的に使われています。

(スキップ可)プロジェクトに移動する

ターミナルを開いて

terminal
$ cd frontend
$ pwd

結果が

/Users/YourName/frontend

となっていれば良いです。

(スキップ可)npmの初期設定

プロジェクトを作る

次に $npm init コマンドを打ってください。
これは「このプロジェクトの初期化」の意味です。

Package.json という初期設定ファイルができていればOK。
他人のリポジトリを落としてきたりして、
既にこのファイルがある場合は npm init をしなくて良いです。
npm init は対話形式なので、聞かれたとおり素直に、適当に、答えたら大丈夫です。

terminal
$ npm init
terminal
name: (hoge) hoge
version: (0.0.0) 
description: 
entry point: (index.html) 
test command:test
git repository:frontend
keywords:fuga
author: hoge
license: (BSD) MIT

正確に答えておいた方がもちろん良いと思います。
これくらい適当でも「動かないことはない」。

(↑ここまでが初期設定でした。)

handlebars.js

htmlの元となるファイル(テンプレート)を、
handlebars.js 形式で用意します。
ファイル名は .hbs とします。

ディレクトリを作りたい構造にファイルを配置します。

下記の例では src フォルダで
pcsp のソースをウェブサーバーで表示する際の
ディレクトリ構造と一緒の構造で入れておき、

書き出した時に
/dist/pc//dist/sp/ に仕分けされて保存されるようにしたものです。
最初から /pc//sp/ に分けて作り始めると、
後で修正する際、行ったり来たり修正をしなければならず、
クライアントによってはすごく面倒です。

【ファイル&ディレクトリ構成】

frontend
 ├ .git
 ├ .gitignore
 ├ package.json
 ├ package-lock.json
 ├ gulpfile.js
 ├ gulptask
 │ ├ assemble_pc.js
 │ ├ assemble_sp.js
 │ ├ copy.js
 │ ├ watch.js
 │ └ webserver.js
 │
 ├ src
 │ ├ asset
 │ │ ├css
 │ │ ├images
 │ │ └js
 │ │ 
 │ ├ data
 │ │ └data.json
 │ │
 │ ├ doc
 │ │ ├pages1
 │ │ │├index.pc.hbs
 │ │ │└index.sp.hbs
 │ │ ├pages2
 │ │ │├index.pc.hbs
 │ │ │└index.sp.hbs
 │ │ └pages3
 │ │  ├index.pc.hbs
 │ │  └index.sp.hbs
 │ │ 
 │ ├ layouts
 │ │ ├pc.hbs
 │ │ └sp.hbs
 │ │ 
 │ └ partials
 │   ├header.hbs
 │   ├footer.hbs
 │   └common_meta.hbs
 │ 
 ├ dist
 │ ├ pc
 │ └ sp
 └ node_modules

/src/layouts/pc.hbs

まず「レイアウトファイル」を用意します。
コレは htmlで言うと、
「bodyの外側」を作る時に使います。

下記の例では pc という名前にしています。
これは最後に出来上がるファイルもPC用とSP用で分けようと思っているためです。

対応ブラウザの関係で、
スマホでしかモダンなタグを使えたり
jQuery(死語)のバージョンをスマホは最新にできるためです。

レスポンシブで作る場合は、作り分ける必要ないので、
このレイアウトファイルは default.hbs などにすれば良いです。

{% body %} が置き換わります。

pc.hbs
<!DOCTYPE html>
<html lang="ja" dir="ltr">
 <head>
  {{>common_meta}}
  <title>{{title}}</title>
  <link rel="canonical" href="https://sample.jp/{{dir}}/" />
 </head>
 <body>
  <div id="container">
   {% body %}
  </div>
 </body>
</html>

htmlに毎回使うようなパーツを読み込みたい場合は
{{>パーツ名}} と書きます。

そして /src/partials/ 以下に
パーツ名.hbs と言った感じに用意しておくと、読み込まれます。

GoogleTagManager header footerも、
このやり方で埋め込む事ができます。

これで Apache がなくても
ローカルでパーツ読み込みができるようになります。

Layoutshbs ファイルでも、
個別の hbs ファイルの中でも、
下記のような書式で読み込みできます。

partial
{{>common_meta}}
{{>gtm}}
{{>header}}
{{>footer}}

また、下記のようなデータバインディングを
<title></title>にはさみ込んでいます。

ココは ページ によって毎回異なるので、
可変部分をレイアウト側に書いて良いのかな?
と言う疑問が湧くと思いますが、

ココに書いて良いです。
レイアウト側のtitledir
どうやってページ事に変わるテキストを入れるのか?
という事は後で書きます。

pc.hbs
{{title}}
{{dir}}

/src/partials/common_〇〇.hbs

パーツの読み込みには、
Partialファイルを用意します。
common_meta.hbs の中はこんな感じ。

common_meta.hbs
{{>common_meta}}
 ↓↓↓
htmlに変換すると
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="keywords""/>

上記は include です。

何か変数を入れる場合は下記のような感じです。
例えば thymeleaf という変数を true にして gulp に処理させる場合は
if 文の上が入る感じです。

動的な処理が入る場所に関しては予めif文で分岐させておき、
distで確認する時は static に表示させ、
正式に書き出す場合に thymeleaftrue にして書き出すといいです。

true にするやり方は、色々あるので省略。

common_meta.hbs
{{#if thymeleaf}}
<meta th:substituteby="/pc/common/inc/head :: common_meta" />
{{else}}
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="keywords""/>
{{/if}}

/src/doc/sample/index.pc.hbs

各Pageのファイルを用意します。
Layoutファイル内の {% body %} の中が置き換わるイメージです。
Layoutにある {{title}}{{dir}} を置き換える場合は

hbsの先頭に、変数とその中身を書いておくと適用されます。

変数の参照ができないと思ったら : の後ろに
半角スペースが入っているかを確認してください。

: の後ろのスペースを詰めて記述すると、
テキストが上手く表示されません

index.pc.hbs
---
title: 「ここでLayoutsの変数をかきかえる」
dir: directory
---
<h1>{{obj.pagename.h1}}</h1>
<h2>{{obj.pagename.h2}}</h2>
<div>{{obj.pagename.description}}</div>

{{obj.pagename.h1}}{{obj.pagename.h2}} はどうするの?
という話ですが

/src/data/data.json を読みこんでおきます。

ちょっとしたサイトであれば、配列を手で編集できますが、
中規模以上のサイトでは手でJSONを更新するのは大変です。

そうなってきたらサーバーサイドのエンジニアの方に
json を出すURLを作ってもらうと良いです。

最初からJSONを読み込む前提で作っておけば、
後から本格的なデータバインディングに移行するのもラクですし。

全部ハードコーディングすると、
後で雪だるま式に、大変なことになります。

data.json
{
   pagename:{
    h1:"h1にこれが入ります",
    h2:"h2にこれが入ります",
    description:"descriptionにコレが入ります。"
   }
}

gulp

色々インストールしていく。「--save-dev」は必ず書くようにする。
必要なプラグインが分かるようにするため。gulp-assembleは古いので使わない。

terminal
$ npm install --save-dev gulp
$ npm install --save-dev gulp-htmlmin
$ npm install --save-dev gulp-rename
$ npm install --save-dev gulp-extname
$ npm install --save-dev assemble
$ npm install --save-dev gulp-plumber
$ npm install --save-dev path
$ npm install --save-dev gulp-webserver
$ npm install --save-dev gulp-livereload

【2018.03 追記】「fs」はNode.jsに含まれているので、要らないです。

$ npm install --save-dev fs  ← コレ不要

【2018.06 追記】Handlebars自体がインストールされてないような気がしましたので追記しました。

$ npm install --save-dev handlebars
$ npm install --save-dev gulp-handlebars
$ npm install --save-dev require-dir

【2019.02 追記】 gulp-server-livereloadが、古いっぽい。gulp-livereloadにしました。

$ npm install --save-dev gulp-server-livereload ←コレ不要

gulpfile.js

プロジェクト直下に「gulpfile.js」というファイルを作る。
中身は「/gulptask」以下に収納しようと思うので、こんな書き方にする。
(設定ファイルが長くなってくると、メンテがしづらくなってgulp疲れが発生するため)
PCとSPでhtmlを別々にしたいので、タスクを別々に書きました。
(これも中で条件分岐するより2回書いた方が設定ファイル的にラクなため。)

gulpfile.js
var gulp = require("gulp");
var requireDir = require('require-dir');

requireDir('./gulptask',{recurse: true});

gulp.task('default',
  ['assemble_pc','assemble_sp','copy','watch']
);

【追記】※あら、gulp v4.0.0だと動かないっすね。

gulpfile.js
var gulp = require("gulp");
var requireDir = require('require-dir');

requireDir('./gulptask',{recurse: true});

gulp.task('default',
  gulp.series(
    gulp.parallel(
      'assemble_pc','assemble_sp','copy','watch'
    )
  )
);
// gulp v4.0.0ではこう書く。のかな?

まず1行ずつ丁寧説明していきますと・・・
↓このファイルを実行するのには、「gulp」が必要です。

gulpfile.js
var gulp = require("gulp");

↓「require-dir」っていうプラグインを使います。

gulpfile.js
var requireDir = require('require-dir');

↓「requireDir();」を使って「/gulptask」以下にタスクを小分けにして書けるようにする。
↓「{recurse:true}」はオプションで、さらにサブディレクトリを使えるようにするヤツです。

gulpfile.js
requireDir('./gulptask',{recurse: true});

↓下記は「gulp」の「task」です。
↓タスクの名前は「default」です。
↓タスクの内容は「assemble_pc」と「assemble_sp」と「copy」と「watch」です。

gulpfile.js
gulp.task('default',['assemble_pc','assemble_sp','copy','watch']);

実行する順番を先に書きました。次に中身を書いて行きます。

/gulptask/assemble_pc.js

gulptasksの下に「assemble_pc.js」というファイルを作ります。
中身はこんな感じで書きました。

assemble_pc.js
var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin');
var rename = require('gulp-rename');
var extname = require('gulp-extname');
var assemble = require('assemble');
var plumber = require('gulp-plumber');
var webserver = require('gulp-webserver');
var livereload = require('gulp-livereload');
var path    = require('path');
var fs = require("fs");
var app = assemble();
var obj = JSON.parse(fs.readFileSync("./src/data/data.json", { encoding:"utf8" }));
gulp.task('load', function(cb) {
  app.partials('src/partials/*.hbs');
  app.layouts('src/layouts/pc.hbs');
  app.pages('src/doc/**/*.pc.hbs');
  cb();
});
gulp.task('assemble',['load'],function() {
  app.toStream('pages')
    .pipe(plumber())
    .pipe(app.renderFile({layout:'pc',obj:obj}))
    .pipe(htmlmin({collapseWhitespace: true}))
    .pipe(rename({basename:'index'}))
    .pipe(extname('.html'))
    .pipe(app.dest('dist/pc/'))
    .pipe(livereload());
});

【追記】※あら、gulp v4.0.0では動かないッスね。

assemble_pc.js
var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin');
var rename = require('gulp-rename');
var extname = require('gulp-extname');
var assemble = require('assemble');
var plumber = require('gulp-plumber');
var webserver = require('gulp-webserver');
var webserver = require('gulp-livereload');
var path    = require('path');
var fs = require("fs");
var app = assemble();
var obj = JSON.parse(fs.readFileSync("./src/data/data.json", { encoding:"utf8" }));
gulp.task('load', function(cb) {
  app.partials('src/partials/*.hbs');
  app.layouts('src/layouts/pc.hbs');
  app.pages('src/doc/**/*.pc.hbs');
  cb();
});
gulp.task('assemble', gulp.series( gulp.parallel('load'),function(){
  //明示的なreturnが必要
  return app.toStream('pages')
    .pipe(plumber())
    .pipe(app.renderFile({layout:'pc',obj:obj}))
    .pipe(htmlmin({collapseWhitespace: true}))
    .pipe(rename({basename:'index'}))
    .pipe(extname('.html'))
    .pipe(app.dest('dist/'));
}));
//gulp v4.0.0ではこう書く。のかな?

数行ずつまとめて説明します。
下記の部分は必要なプラグインを記した箇所です。(varは今風にカンマでつなげて書いても大丈夫です。)

objにはJSONをパースしたものを格納しておきます。objにJSONを格納しておけば後で呼び出せるので簡易的なデータバインディングができます。JSONファイルではなく、API叩いてJSONを返すヤツをココに組み込んでも良い、と思いますが、それはサーバーサイドのエンジニアさんに手伝ってもらって下さい。

忘れがちですが、分割されたタスクには、もう一度「gulp」を読み込む必要があります。

assemble_pc.js
var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin');
var rename = require('gulp-rename');
var extname = require('gulp-extname');
var assemble = require('assemble');
var plumber = require('gulp-plumber');
var webserver = require('gulp-webserver');
var livereload = require('gulp-livereload');
var path    = require('path');
var fs = require("fs");
var obj = JSON.parse(fs.readFileSync("./src/data/data.json", { encoding:"utf8" }));

assembleを格納しておきます。

assemble_pc.js
var app = assemble();

1つ目のタスク「load」は下処理です。色んなものを読み込ませます。
「partials」とは「パーツ」の事です。(headerとかfooterなど)
「layouts」とは「レイアウトファイル」の事です(bodyの外側)
「pages」は、今から組み立てるhtmlファイルの事です。(bodyの内側)
/**/*.pc.hbs」は、その階層以下の末尾に.pcと付いてる拡張子hbsのファイル全部、という指定の仕方です。「index.pc.hbs」的な名前の付いたファイルのみ変換されます。「index.sp.hbs」と同じフォルダに置いて作業できるので、作業する時にあちこち行き来せずに済むためラクです。
「cb」は「callback」です。「load」が次に呼び出された場所に値を返す感じです。

assemble_pc.js
gulp.task('load', function(cb) {
  app.partials('src/partials/*.hbs');
  app.layouts('src/layouts/pc.hbs');
  app.pages('src/doc/**/*.pc.hbs');
  cb();
});

下記はいよいよ組み立てるタスクです。このタスクは['load']が完了した後に実行されます。
gulpは並列でタスクを処理するので、何も意識しないと読み込みと組み立てが同時に動いてしまいます。タスクの順番がおかしくなる場合は、必ずタスクの名前の後ろに['事前に行なうタスク']を入れておくと順番がバラバラにならずに助かります。

assemble_pc.js
gulp.task('assemble_pc',['load'],function() {
  app.toStream('pages')
    .pipe(plumber())
    .pipe(app.renderFile({layout:'pc',obj:obj}))
    .pipe(htmlmin({collapseWhitespace: true}))
    .pipe(rename({basename:'index'}))
    .pipe(extname('.html'))
    .pipe(app.dest('dist/pc/'))
    .pipe(livereload());;
});

【追記】※gulp v4じゃ動かないっすね。

assemble_pc.js
gulp.task('assemble', gulp.series( gulp.parallel('load'),function(){
  //明示的なreturnが必要
  return app.toStream('pages')
    .pipe(plumber())
    .pipe(app.renderFile({layout:'pc',obj:obj}))
    .pipe(htmlmin({collapseWhitespace: true}))
    .pipe(rename({basename:'index'}))
    .pipe(extname('.html'))
    .pipe(app.dest('dist/'));
}));
//gulp v4.0.0だったらこう書く。。のかな?

1個ずつ説明していきますと・・・
コレが「assemble_pc」の外側です。名前の後ろのオプション的な箇所は['load1','load2','load3']とつなげて書く事ができます。

assemble_pc.js
gulp.task('assemble_pc',['load'],function() {○○○});

コレはstream()の新しい書き方?です。
「assemble-stream」というモジュールを使って処理するようです。pagesに格納されたファイルに対して、以下の処理を行ないます。

assemble_pc.js
app.toStream('pages')

gulpのお作法は「.pipe」でタスクを繋いでいきます。
gulp.watchしている時にエラーで処理が止まらないようにする「gulp-plumber」を使っています。watchの使い方に付いては、省略します。

assemble_pc.js
.pipe(plumber())

レイアウトは「pc」を使ってhtmlをrenderingします。「obj:obj」はパースしたJSONをrenderfile内に持って入るために利用します。

assemble_pc.js
.pipe(app.renderFile({layout:'pc',obj:obj}))

htmlをミニファイします。

assemble_pc.js
.pipe(htmlmin({collapseWhitespace: true}))

ファイル名を「index」に変更します。

assemble_pc.js
.pipe(rename({basename:'index'}))

ファイルの拡張子を「.html」に変更します。

assemble_pc.js
.pipe(extname('.html'))

ファイルを書き出す場所は「/dist/pc/」以下を指定します。

assemble_pc.js
.pipe(app.dest('dist/pc/'))

livereloadで更新するようにします。

assemble_pc.js
.pipe(livereload());

同様のファイルをspにも作成します。(省略)

###このタスクだけを実行するには?

terminal
$ gulp assemble_pc

/gulptask/copy.js

gulptasksの下に「copy.js」というファイルを作ります。

copy.js
var gulp = require('gulp');
gulp.task('copy', function() {
  gulp.src('./src/asset/**')
    .pipe(gulp.dest('./dist/'));
});

【追記】※あ、gulp v4.0.0ではこれじゃ動かないかもですね。

copy.js
var gulp = require('gulp');
gulp.task('copy',
  gulp.series(
  // gulp.parallel(
    function(){
    return gulp.src('./src/asset/**')
      .pipe(gulp.dest('./dist/'));
    }
  )
);
//gulp v4.0.0ではこう書く。のかな?

/src/asset/以下にある画像などのファイルをコピーします。
画像はdistにコピーしてあげないと表示が確認できないので、必ずセットで実行して下さい。
scssやAltJSは別のタスクで処理すると思いますが、もしもトランスパイルしない感じであれば
/src/asset/内に置いて/dist/にコピーして下さい。

###このタスクだけを実行するには?

terminal
$ gulp copy

#上記、全部のタスクを実行するには?

terminal
$ gulp

または

terminal
$ gulp default

#サーバーの立て方(gulp-webserver)
node.jsの簡易的なサーバーを立てる方法は色々ありますが、gulpなら、gulp-webserverを使います。特に「livereload」は最近のモダンなコーディング事情的には、ほぼ必須の仕組みです。(ファイルの変更を監視して自動的にブラウザが自動リロードを書けるものです。ホットリロードとも言います。)これでhtmlやCSSを書き直した時に「F5」や「Ctrl+R」をポチポチ毎回叩かなくて良いです。もっと良いやり方があるかもしれませんが、自分は「webserver」が「livereload」のイベントを拾うのと、「watch」イベントが「ファイルの更新」を監視するイベントを一つにできなかったので、「webserver」のターミナルは、「gulp default」とはターミナル別窓で開いております。(追記:「gulp-connect」はもう古いらしいので「gulp-webserver」に書き換えました。)

webserver.js
var gulp = require('gulp');
var webserver = require('gulp-webserver');

gulp.task('webserver', function() {
  gulp.src('dist')
   .pipe(webserver({
    host: 'localhost',
    port: 8888,
    livereload: true
  }));
});

【追記】※あっ、gulp v4.0.0で動かないかも・・

webserver.js
var gulp = require('gulp');
var webserver = require('gulp-webserver');

gulp.task('webserver', gulp.series( function(){
  gulp.src('dist')
   .pipe(webserver({
    host: 'localhost',
    port: 8888,
    livereload: true
  }));
}));
//gulp v4.0.0 ではこう書く。のかな。

監視の説明がなかったので、追記しました。「gulp-webserver」は「dist」を監視しているので
「src」を更新したら「dist」へ書き出し、「dist」の更新を「livereload」で拾う、という感じでできます。

watch.js
var gulp = require("gulp");
gulp.task("watch",['assemble_pc','assemble_sp','copy'], function () {
     var watcher = gulp.watch("./src/doc/**",['assemble_pc','assemble_sp','copy']);
     watcher.on('change', function(event) {
       console.log(event.path + 'が変更されました。');
     });
});

※あっ、gulp v4.0.0で動かないかも・・

watch.js
var gulp = require("gulp");
gulp.task('watch',function(){
    return gulp.watch('./src/doc/**',
      gulp.task(
        gulp.series(
          gulp.parallel(
            'assemble','copy'
          )
        )
      )
    );
});
//gulp v4.0.0 ではこう書く?のかな。。

サーバーを立てると「http://localhost:8888」をブラウザで見れるようになり、/dist/以下に書き出されたファイルを表示します。

terminal
$ gulp webserver

#npmでタスクを実行するには?
最近はタスクランナー的な抽象化をしないで「$ npm run」で何でもやることになった(らしい)ので、
「gulpをグローバルインストールしたくないよ〜」
「ターミナルに「\$ gulp」なんて打つの恥ずかしいよ〜」
「npmコマンドでやりたいよ〜」
という場合は、次のようにする。
package.json」の「scripts」に、下記のような記述をする。
(下記、webpackやらgruntやらは説明用に入ってるだけです。適宜削って下さい。)

package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "npm-run-all build:*",
    "build:webpack": "webpack",
    "build:gulp": "gulp default",
    "build:grunt": "grunt default"
  },

このモジュール(npm-run-all)をインストールしておくと
複数のbuild以下のスクリプトを実行できるようになります。

terminal
$ npm install --save-dev npm-run-all

そして

terminal
$ npm run build

とすれば良いです。(build:が付いているタスクを全部実行してくれます)

(2021.03.04追記)
ただgulpを実行したいだけなら、
package.jsonに記述を追加しなくても npx で良いんじゃないか?と思いました。
この辺はNode.jsの進化によって移り変わるので、好みでいいと思います。

$ npx gulp
$ npx gulp default
$ npx gulp assemble_pc
$ npx gulp copy
$ npx gulp watch

いかがでしたでしょうか?「非エンジニア」でも「タスクランナー」を導入することでWeb制作を効率化ができるんじゃないかなと思います。以上です。

34
32
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?