はじめに
はじめまして。
9月の中旬にエンジニアとして株式会社アンティー・ファクトリーに入社しました。
今回はタイトルにもある通り、gulpについて理解を深めたいと思います。
まず、弊社では開発する際に使用するテンプレートがあり、gulpなどの便利なツールが内蔵されています。
先輩から教わったとおりにスクリプトを打ち込み、gulpを動かして制作するのですが、度々
「何がどう動いてどうなっているのか分からない」「変なとこいじっちゃってやばいことになったらやばい」
と不安になることがあるので、この記事ではgulpについての理解を深めていきたいです。
やること
まず今回やることはこれです。
- Sass、ejsのコンパイルの自動化
- ローカルサーバーの立ち上げ
- タスクの同時実行
の3点です。
バージョン
node.js 16.17.0
npm 8.15.0
フォルダ構成
今回はgulpをタスクごとにファイル分けするため、gulpfile.jsというフォルダーを作成し、その中にファイルをどんどん入れていこうと思います。
下準備
今回使用するディレクトリに移動します。
$ cd file
package.jsonの作成
下記のコマンドを入力すると質問攻めに遭います。質問に答えると、package.jsonが作成されます。
質問攻めを回避したい場合はnpm init -y
と入力。
$ npm init
{
"name": "file",
"version": "1.0.0",
"description": "gulpの練習",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
gulpのインストール
続いてgulpをインストールします。
--save-dev
をつけるとpackage.jsonのdevDependencies
の部分にインストールされたモジュールが記述されます。
$ npm install gulp --save-dev
このようになっていたらOK。
{
"name": "file",
"version": "1.0.0",
"description": "gulpの練習",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"gulp": "^4.0.2"
}
}
Sass、ejsのコンパイル自動化
gulpの設定
本来はgulpfile.jsというファイルの中にタスクを記述するのが一般的かと思いますが、タスクごとにファイル分けすることで、コードの可読性やファイル構造の理解しやすさが上がるのではないかと思ったのでそのように進めていきます。
では、gulpfile.jsの中に移動し、index.jsを作成します。
$ cd gulpfile.js
$ touch index.js
続いてindex.jsに
const gulp = require('gulp');
と記述します。これでgulpを使えるようになりました。
Sassのコンパイル
次に、Sassをコンパイルするタスクを記述するファイルを作成します。ファイル名はsass.jsとします。
$ touch sass.js
さらに、Sassをコンパイルするためのモジュールをインストールします。
$ npm install gulp-sass --save-dev
$ npm install sass --save-dev
$ npm install gulp-source-maps --save-dev
gulp-sass
、sass
はSassをコンパイルするためのモジュールでgulp-sourcemaps
はソースマップを作成するためのモジュールです。
インストールが完了したら、作成したsass.jsに下記のように記述していきます。
const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const sourcemaps = require('gulp-sourcemaps');
const style = (done) => {
gulp.src("src/scss/**/*.scss")
.pipe(sass({outputStyle: 'expanded'}))
.pipe(sourcemaps.init())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest("dest/css/"));
done();
};
exports.style = style;
style
という関数では
-
gulp.src()
というメソッドでコンパイルしたいファイルの読み込み -
.pipe(sass({outputStyle: 'expanded'}))
で、コンパイルされたファイルの記法を指定 -
.pipe(sourcemaps.init())
でソースマップの作成 -
.pipe(sourcemaps.write('./'))
でソースマップを作成するパスの指定 -
.pipe(gulp.dest("dest/css/"))
でコンパイルされたファイルを設置するパスの指定
をしています。
今回はdest
というフォルダの中にcss
というフォルダを作成し、その中にコンパイルされたファイルを置くように指定しています。
続いて、index.jsに
const gulp = require("gulp");
const { style } = require('./sass'); //追加
exports.style = style; //追加
exports.default = gulp.series(
style
); //追加
コメントアウトされている部分を追加します。
記述できたら試運転です。
ターミナルやコマンドプロンプトに
$ gulp style
と入力します。
上記の画像のようになり、dest
フォルダ内にcss
フォルダが設置され、コンパイルされたcssとcssのソースマップが作成されていれば成功です。
ejsのコンパイル
次に、ejsのコンパイルをしていきます。
手順としては、先ほどのSassと大体同じです。
$ touch ejs.js
ejsをコンパイルするタスクを記述するファイルを作成。
$ npm install gulp-ejs --save-dev
$ npm install gulp-rename --save-dev
使用するモジュールをインストールします。
インストールできたら、作成したejs.jsに
const gulp = require('gulp');
const ejs = require('gulp-ejs');
const rename = require('gulp-rename');
const markup = (done) => {
gulp.src("src/ejs/**/*.ejs","!src/ejs/**/_*.ejs")
.pipe(ejs())
.pipe(rename( { extname: ".html"} ))
.pipe(gulp.dest('dest/html/'));
done();
};
exports.markup = markup;
と記述します。
markup
という関数では、
-
gulp.src("src/ejs/**/*.ejs","!src/ejs/**/_*.ejs")
でコンパイルするフォルダの読み込み
(第二引数では、_.ejs
とあるように_
がついているファイルをコンパイルしないように指定) -
.pipe(ejs())
でejsのコンパイル実行 -
.pipe(rename( { extname: ".html"} ))
で拡張子を.ejs
から.html
に書き換え -
.pipe(gulp.dest('dest/html/'));
でコンパイルされたファイルを設置するパスの指定
をしています。
そして、index.jsに
const gulp = require("gulp");
const { style } = require('./sass');
const { markup } = require('./ejs'); //追加
exports.style = style;
exports.markup = markup; //追加
exports.default = gulp.series(
style,markup //追加
);
コメントアウトされている部分を追加します。
記述できたら、試運転です。
ターミナルやコマンドプロンプトに
$ gulp markup
と入力します。
上記の画像のようになり、dest
フォルダ内にhtml
フォルダが設置され、コンパイルされたhtmlファイルが作成されていれば成功です。
ローカルサーバーの立ち上げ
次にローカルサーバーを立ち上げるタスクを記述していきます。
$ touch server.js
ファイルを作成します。
$ npm install browser-sync --save-dev
使用するモジュールをインストールします。
server.js内に下記のように記述します。
const { series,watch } = require('gulp');
const browserSync = require('browser-sync').create();
const { markup } = require('./ejs');
const { style } = require('./scss');
const browserReload = callback => {
browserSync.reload();
callback();
};
const serve = () => {
browserSync.init({
open:false,
startPath:'',
reloadDelay:1000,
once:true,
notify:true,
ghostMode:false,
server: {
baseDir:"dest/",
},
});
watch('src/ejs/**/*.ejs', { usePolling: true }).on('change', series(markup, browserReload));
watch('src/scss/**/*.scss', { usePolling: true }).on('change', series(style, browserReload));
};
exports.serve = serve;
ターミナルに下記のように入力します。
$ gulp serve
同時実行
ここまでさまざまなタスクを作成してきましたが、最後に今までの処理を同時に実行したいと思います。
理想としては、
- 一旦
dest
フォルダのhtml
フォルダ、css
フォルダを削除 -
src
フォルダのejs
フォルダ、scss
フォルダ内のファイルをコンパイル - ローカルサーバーの立ち上げ
- 監視状態に移行
という処理を一度に実行できるようにしたいです。
手順
まずは必要なモジュールをインストールします。
$ npm install rimraf --save-dev
インストールできたら、package.json
の"scripts"
の部分に記述していきます。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"clean": "rimraf dest/html/ & rimraf dest/css/",
"compile": "gulp markup && gulp style",
"dev" : "npm run clean && npm run compile && gulp serve"
}
clean
というコマンドでdest
フォルダ内のhtml
フォルダ、css
フォルダを削除し、
compile
というコマンドでejsとSassのコンパイルを行なっています。
dev
というコマンドでは先ほどのclean
とcompile
を順に行い、最後にローカルサーバーを立ち上げています。
記述できたらコマンドプロンプトやターミナルに下記のコマンドを入力します。
$ npm run dev
上記の画像のようにmarkup
タスク、style
タスク、serve
タスクが順に実行され、ローカルサーバーが立ち上がり、監視状態に移行していれば成功です。
感想
実際に自分で環境を構築してみて、gulpについて未だ分からない部分はありますが、理解度は上がったのかなと思います。本当は、ファイル名が変更されたら出力先のファイル名も変更されるタスクも作成したかったのですが、自分の実力不足で完成には至りませんでした。他にも、足りない部分や実装すべきタスクや機能はまだまだあると思いますので、もっと知識を吸収してどんどん機能を足していけたらいいなと思いました。予想以上に長くなりましたが、ここまで読んでいただきありがとうございます。