LoginSignup
17
21

More than 3 years have passed since last update.

Gulp4設定まとめ(Pug/Sass)

Last updated at Posted at 2019-07-16

1. はじめに

Gulp+Pug+SassでWebサイトの開発環境を作りました。
何度か作っているのですが、毎回忘れてしまうのでまとめです。

※ gulp自体のインストール(グローバルインストールとローカルインストール)はされている前提です。
※ npmを使っています。

2. ディレクトリ構造

dest/
  ├css/
  ├images/
  └javascripts/
  index.html
src/
  ├images/
  ├javascripts/
  ├pages/
  ├pug/
  └sass/
gulpfile.js
package.json

3. 環境

Gulp 4.0.2

4. インストールしたパッケージ

パッケージ 概要
gulp-pug Pugをコンパイル
gulp-sass Sassをコンパイル
gulp-autoprefixer CSSプロパティにベンダープレフィックスを付与
gulp-cssmin CSSを圧縮
gulp-uglify JSを圧縮
browser-sync ブラウザのリロード, ローカルサーバーの立ち上げ
gulp-plumber エラーを検出
gulp-notify デスクトップに通知
del フォルダやファイルを削除

インストールコマンドの一覧です。

$ npm i -D gulp-pug
$ npm i -D gulp-sass
$ npm i -D gulp-autoprefixer
$ npm i -D gulp-cssmin
$ npm i -D gulp-uglify
$ npm i -D browser-sync
$ npm i -D gulp-plumber
$ npm i -D gulp-notify
$ npm i -D del

5. gulpfile.js

gulpを実行したら以下のような処理になるようにしました。

1. destディレクトリ配下のコンテンツを丸ごと削除
srcディレクトリとdestディレクトリにあるコンテンツに差分がない状態を保ちたいので、gulpを実行したらdestディレクトリ配下のコンテンツを丸ごと削除します。

2. 他タスクを並列で実行
1の処理が終わったら、コンパイル、ローカルサーバー起動、ファイル監視を並列で実行します。

各処理のポイント

destディレクトリ配下のコンテンツ削除

コンテンツを削除するために使用しているdelパッケージですが、paths.dest + '/**'としか書いていない場合、タスクの実行が成功してもコンテンツが削除されないので気をつけましょう。

公式ドキュメントを読むと、paths.dest + '/**', '!' + paths.dest のように明示的に「親ディレクトリを削除しない」と書かないと親ディレクトリも削除対象になるということが書かれているのですが、私の環境では削除自体が実行されませんでした。

gulpfile.js
//Clean
gulp.task('clean', function(done) {
  del.sync(paths.dest + '/**', '' + paths.dest);
  done();
});

Sass -> CSS

SassからCSSにコンパイルする処理では、コンパイルエラーの検知・通知、ベンダープレフィックスの自動付与、CSS圧縮が行われます。

gulpfile.js
//Sass
gulp.task('css', function() {
  return gulp.src([
    paths.src + '/sass/**/*.scss',
    '!' + paths.src + '/sass/**/_*.scss'
  ])
  .pipe(plumber({ //エラーを検知しデスクトップ通知
    errorHandler: notify.onError("Error: <%= error.message %>")
  }))
  .pipe(sass()) //Sass -> CSS
  .pipe(autoprefixer({ //ベンダープレフィックスを付与
      overrideBrowserslist: 'last 2 versions'
  }))
  .pipe(cssmin()) //圧縮
  .pipe(gulp.dest(paths.dest + '/css'))
});

Pug -> HTML

PugからHTMLにコンパイルする処理では、コンパイルエラーの検知・通知、読みやすいコードへの整形が行われます。

gulpfile.js
//Pug
gulp.task('html', function() {
  return gulp.src([
    paths.src + '/pages/**/*.pug',
    '!' + paths.src + '/pages/**/_*.pug'
  ])
  .pipe(plumber({ //エラーを検知しデスクトップ通知
    errorHandler: notify.onError("Error: <%= error.message %>")
  }))
  .pipe(pug({pretty: true})) // 読みやすいコードに整形
  .pipe(gulp.dest(paths.dest))
});

JavaScript

JavaScriptは圧縮します。

gulpfile.js
//JavaScript
gulp.task('js', function() {
  return gulp.src(
    paths.src + '/javascripts/**/*'
  )
  .pipe(uglify())//圧縮
  .pipe(gulp.dest(paths.dest + '/javascripts'))
});

監視

srcディレクトリ配下の各種ファイルを監視し、変更を検知したら各種ファイル形式にあわせたコンパイルタスクを実行しリロードします。

gulpfile.js
//Watch
gulp.task('watch', function () {
  const reload = () => {
    browserSync.reload(); //リロード
  };
  gulp.watch(paths.src + '/sass/**/*.scss').on('change', gulp.series('css', reload));
  gulp.watch(paths.src + '/pages/**/*.pug').on('change', gulp.series('html', reload));
  gulp.watch(paths.src + '/javascripts/**/*').on('change', gulp.series('js', reload));
  gulp.watch(paths.src + '/images/**/*').on('change', gulp.series('image', reload));
});

サンプルコード

gulpfile.jsの全文です。

gulpfile.js
const gulp = require('gulp');
const pug = require('gulp-pug');
const sass = require('gulp-sass');
const autoprefixer =require('gulp-autoprefixer'); 
const cssmin = require('gulp-cssmin');
const uglify = require('gulp-uglify');
const browsersync = require('browser-sync');
const notify = require('gulp-notify');
const plumber = require('gulp-plumber');
const del = require('del');

const paths = {
  src: 'src',
  dest: 'dest'
};

//Pug
gulp.task('html', function() {
  return gulp.src([
    paths.src + '/pages/**/*.pug',
    '!' + paths.src + '/pages/**/_*.pug'
  ])
  .pipe(plumber({
    errorHandler: notify.onError("Error: <%= error.message %>")
  }))
  .pipe(pug({pretty: true}))
  .pipe(gulp.dest(paths.dest))
});

//Sass
gulp.task('css', function() {
  return gulp.src([
    paths.src + '/sass/**/*.scss',
    '!' + paths.src + '/sass/**/_*.scss'
  ])
  .pipe(plumber({
    errorHandler: notify.onError("Error: <%= error.message %>")
  }))
  .pipe(sass({
    outputStyle: 'expanded'
  }))
  .pipe(autoprefixer({
      overrideBrowserslist: 'last 2 versions'
  }))
  .pipe(cssmin())
  .pipe(gulp.dest(paths.dest + '/css'))
});

//JavaScript
gulp.task('js', function() {
  return gulp.src(
    paths.src + '/javascripts/**/*'
  )
  .pipe(uglify())
  .pipe(gulp.dest(paths.dest + '/javascripts'))
});

//Image File
gulp.task('image', function() {
  return gulp.src(
    paths.src + '/images/**/*'
  )
  .pipe(gulp.dest(paths.dest + '/images'))
});

//Browser Sync
gulp.task('browser-sync', function (done) {
  browsersync({
    server: { //ローカルサーバー起動
        baseDir: paths.dest
  }});
  done();
});

//Watch
gulp.task('watch', function () {
  const reload = () => {
    browsersync.reload(); //リロード
  };
  gulp.watch(paths.src + '/sass/**/*').on('change', gulp.series('css', reload));
  gulp.watch(paths.src + '/pages/**/*').on('change', gulp.series('html', reload));
  gulp.watch(paths.src + '/javascripts/**/*').on('change', gulp.series('js', reload));
  gulp.watch(paths.src + '/images/**/*').on('change', gulp.series('image', reload));
});

//Clean
gulp.task('clean', function(done) {
  del.sync(paths.dest + '/**', '' + paths.dest);
  done();
});

//Default
gulp.task('default',
  gulp.series(
  'clean',
    gulp.parallel(
      'html',
      'css',
      'js',
      'image',
      'watch',
      'browser-sync'
)));

6. さいごに

毎回Gulpの設定を忘れてしまうので、今後はこの記事を更新するようにしたいと思います。

17
21
0

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
17
21