TochkaというSSIサーバー作った話

前書き

今回は、gulp.jsはまだオワコンちゃうでって話の続きというか
昔、作ったgulpfile一枚物の
ソースコードぐっちゃぐちゃなSSIサーバーがあって
これをgulp-babelで整理してみました。

gulp-babelの使用の一例紹介という感じで書きます。

リポジトリこちら

依存関係

"devDependencies": {
  "@babel/cli": "^7.5.5",
  "@babel/core": "^7.5.5",
  "@babel/preset-env": "^7.5.5",
  "@babel/preset-es2017": "^7.0.0-beta.53",
  "@babel/register": "^7.5.5",
  "babel-preset-latest": "^6.24.1"
},
"dependencies": {
  "@babel/polyfill": "^7.4.4",
  "browser-sync": "^2.26.7",
  "connect-ssi": "^1.1.1",
  "gulp": "^4.0.2",
  "gulp-plumber": "^1.2.1",
  "gulp-sass": "^4.0.2",
  "gulp-sourcemaps": "^2.6.5",
  "serve-static": "^1.14.1"
}

タスクの構成

タスクの構成はこんな感じ

.
├── generate
│   ├── css.js
│   └── index.js
└── server
    └── index.js

トランスパイルなどのファイル書き出し系タスク

sassをcssにトランスパイルして
distに書き出すタスク
「generate/css.js」

import { src, dest } from 'gulp'
import sourcemaps from 'gulp-sourcemaps'
import sass from 'gulp-sass'
import plumber from 'gulp-plumber'

const path = {
  src: './src/**/*.scss',
  dist: './dist',
  reject: '!./src/**/_*.scss'
}


export default (done) => {

  src([path.src, path.reject])
  .pipe(plumber())
  .pipe(sourcemaps.init())
  .pipe(sass({ outputStyle: 'expanded' }))
  .pipe(sourcemaps.write('./.maps'))
  .pipe(dest(path.dist))

  done()
}


/srcディレクトリ以下の
トランスパイルしない、その他のファイルを
distに書き出すだけのタスク
cssのタスクもインポートして
generateパッケージとしてエクスポート
「generate/index.js」

import { src, dest } from 'gulp'
import css from './css'

const path = {
  src: './src/**/*',
  dist: './dist',
  reject: ['!./src/**/*.scss', '!./src/**/_*.scss']
}

const other = (done) => {

  src([ path.src, ...path.reject ])
  .pipe(dest(path.dist))

  done()
}

export default {
  css,
  other
}

サーバー起動、ブラウザリロード、ファイル監視タスク

サーバーの起動やブラウザのリロード、ファイルの監視などは
「server/index.js」にまとめました。
observeタスクでファイルのgenerateも行うので
generateパッケージもインポートして使っています。
そして、サーバー起動とファイル監視のタスクは
エクスポートする。とそんな感じです。

import { watch, series } from 'gulp'
import browserSync from 'browser-sync'
import serveStatic from 'serve-static'
import connectSSI from 'connect-ssi'

import generate from '../generate'

const path = {
  docRoot: './dist',
  docRootPwd: `${__dirname}/dist`
}

//サーバー起動
const start = (done) => {
  browserSync.init({
    server: {
      baseDir: path.docRoot,
      middleware: [
        connectSSI({
          baseDir: path.docRootPwd,
          ext: ".html"
        }),
        serveStatic(path.docRootPwd)
      ]
    }
  })

  done()
}

//ブラウザーリロード
const reload = (done) => {
  browserSync.reload()
  done()
}

//ファイル監視
const observe = (done) => {

  watch('./src/**/*.scss')
  .on('change', series(generate.css, reload))

  watch(['./src/**/*', '!./src/**/*.scss', '!./src/**/_*.scss'])
  .on('change', series(generate.other, reload))

  done()
}


export default {
  start,
  observe
}

gulpfile.babel.jsにタスクを読み込む

旧、gulpfile.jsに当たる
gulpfile.babel.jsは、
たったこれだけ、めちゃくちゃシンプルです。

import { task, series, parallel } from 'gulp'
import server from './tasks/server'
import generate from './tasks/generate'

task('default',
  series(
    parallel(
      generate.css,
      generate.other
    ),
    parallel(
      server.start,
      server.observe
    )
  )
)

試してみたい方は
こちらリポジトリをクローンして
使ってみてください。
ちなみにgulpはグローバルインストールしなくとも
npm startで起動できます。

まとめ

nuxt.jsとかgridsome.jsなどの
フレームワークが存在している時代に
SSIサーバーとか要らないだろうと思われるかもですが
webアプリ開発はまだしも
webサイト案件はまだまだ、htmlを量産するような案件もあります。
それが、大手ほどその傾向が強い

大手は、効率よりも人海戦術主義という感じなんでしょうかね...
このTochkaは、後々は、sitemapと言うか、サイトの仕様書を読み込んで
自動で、htmlを大量書き出しするタスクも追加する予定です。

ejsとか使いたいところなんですが
html量産するような案件ってデザイナーとかがコーディングに関わっている案件が多いので
sassぐらいがせいぜい限界...

そのため、ejsの導入は無理かなと
ちなみに、Tochkaの由来は
まるで、地獄の戦場とも言える
旧式大規模開発の現場のトーチカとなればと...
そういう悲しい由来です。
マジ、html量産開発死ぬわ