sassの環境構築とhtmlの共通化をなるべく簡単にやる

Thu Dec 5, 2019 - sass
Thu Dec 5, 2019

サーバーレスなアプリケーションをフレームワークなしで作成するとに一番困ったのが、sassとhtmlの共通化でした。

フロントエンドはwebpackgulp.jsなどの便利なツールがいろいろありますが、メンテがしてないとか多機能すぎるなどの問題がありました。まぁ、読めばいいでしょうけど、面倒くさい。

まず第一条件としてあるのは、フレームワークより簡単で、なるべく簡単にsassとかの環境構築ができて尚且つツールアップデートとかに振り回されないこと。 ページ数で言うと50ページ未満で単純な機能のみのサーバーレスで実装。メンテナンスをなるべくしなくてもいいようにフレームワークは使わない。 なるべく簡単に簡単に。

最初は、webpackgulp.jsを使っていこうかなぁと思ってましたが、以下の理由でやめました。

  • gulp.js → メンテがあまりなされていない, 凝ったことをやろうとするとgulp.jsの仕様を覚える必要がある

  • Grunt → gulp.jsと同じ理由でやめた

  • webpack → 恐らくこれが主流になると思いましたが、多機能すぎるのと覚えること多いのでやめた。まぁ、多くのフレームワークでも採用されているので使うならこれかなぁ。

  • parcel → この中では一番簡単だったが、ツールに依存したくないのでやめた

  • なんかイケてるフロントエンジニアを真似してスクリプトを自前で実装する → ここまでするくらいならnuxt.jsなどの静的ジェネレータを使うよと思ったのでやめた

使うもの

  • pug → htmlの共通化で使う

  • node-sass → sassのコンパイルで使う

  • npm scripts → sassのコンパイルを自動化するために使う

  • bash → pugのビルドの半自動化で使う

  • Live Server → vscodeの拡張子 htmlやcssの変更があったら自動でリロードしてくれる

pugのインストール

nodeが必要なのでインストールしてない人はインストールしてください。

公式にインストール方法がのってます。

pugのインストール

1
$ npm install -D pug

僕の場合はグローバルにインストールするのはイヤなので、ローカルにしてます。

1
$ npm install -D pug-cli

正しく、インストールされたか確認。

1
$ npx pug --help

共通レイアウトを作る

部分テンプレートにしたい部分の名前に_ をいれる。ベーシックなものだとこんな感じになると思います。

htmlで共通レイアウトをつくる

_layoutというフォルダの中にheadmetaとかの共通部分を_baseof.pugに記述。

_partialsフォルダにfooterheaderを入れてます。

footerheaderbaseof.pugにincludeするので、baseof.pugを組み立てます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
//- ページの設定
block pagedata

doctype html
html(lang="ja")
    head
        meta(charset="utf-8")
        meta(http-equiv="X-UA-Compatible" content="IE=edge")
        meta(name="viewport" content="width=device-width, initial-scale=1.0")
        link(href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet")
        title #{pageTitle} | Sampleホームページ

        block pagecss

    body.page
        div.container
            include ./_partials/_nav
            div.main-box
                include ./_partials/_header
                block main
            include ./_partials/_footer
    block pagejs

これで共通レイアウトの部分は完成。

個々のページを作成

ここのページはどこにでも作っていいのですが、今回はテストなのでディレクトリ直下にサンプルフォルダを作成し、その中にindex.pugを作成し、先ほど作ったbaseof.pugをincludeします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
//- テンプレート読み込み
extend ../_layout/_baseof

//-ページ独自の設定
append pagedata
    - var pageTitle= "トップページ";

//- ページ独自のcss
append pagecss
    link(rel="stylesheet" href="../assets/css/style.css")

//- ページ独自のjs
append pagejs
    script(src="../assets/js/index.js")

//- ページのコンテンツ
block main
    div.content
        div.page-item
            h1 トップページのコンテンツ

コードを見たらわかると思いますが、単純にbaseof.pugをincludeしてあとは個別のコンテンツやjscssを書いてるだけです。

buildする

pugファイルはbuildすると素のhtmlを書き出してくれます。ただし、一つ一つbuildコマンドを叩くのは面倒なので、shファイルを作って、まとめて、buildする形にします。ここでは、build_pug.sh を作成します。

1
2
3
4
5
#!/bin/sh
#
# Sample
#
npx pug sample/index.pug --pretty --out public/sample

僕の場合は、ローカルにpug cliをインストールしてないので、npxコマンドを付けてます。このコマンドの場合はディレクトリ直下のsampleフォルダの中のindex.pugをbuildして、publicフォルダのsampleフォルダに書き出すという意味です。気をつけて欲しいのはpublicやsampleフォルダは予め作成しておいてください。

出来たら、これをbuildします。

1
$ sh build_pug.sh

先ほどのをbuildするとpublic/sampleにこんな感じで書き出されます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
    <title>トップページ | Sampleホームページ</title>
    <link rel="stylesheet" href="../assets/css/style.css">
  </head>
  <body class="page">
    <div class="container">
      <nav class="nav"><span>ここはnav</span></nav>
      <div class="main-box">
        <header class="header"><span>ここヘッダー</span></header>
        <div class="content">
          <div class="page-item">
            <h1>トップページのコンテンツ</h1>
          </div>
        </div>
      </div>
      <footer class="footer"><span>ここはフッター</span></footer>
    </div>
  </body>
  <script src="../assets/js/index.js"></script>
</html>

.gitignoreファイル作成

node_modulesやbuildされるたびに変更されるものはgitに含めないようにします。

1
2
/node_modules/ 
/public/top/

node-sassを使ってsassをコンパイル

node-sassはsassを自動コンパイルするのに使うのでインストールしときます。

1
$ npm i node-sass -D

フォルダ構成はなんでもいいですけど、僕の場合は以下のようにしています。publicフォルダにassets/cssにコンパイルしたsassが格納されるようにしてあります。

htmlで共通レイアウトをつくる

試しにnode-sassのコマンドを実行してみます。ターミナルで以下のコマンドを実行してみてください。

1
$ npx node-sass sass/_src/style.scss --output public/assets/css/ --output-style compressed

public/assets/css/配下にsassをコンパイルして圧縮したcssが格納されていると思います。

今度はこれをsassが変更された時に自動でコンパイルされるようにnpm scriptsを使います。

package.jsonscriptsに先ほどのコマンドを追記します。

1
2
3
4
5
{
    "scripts": {
        "sass": "npx node-sass sass/_src/style.scss --output public/assets/css/ --output-style compressed"
    }
}

ただ、このままでは本番のコンパイルは問題ないですが、開発中はちょっと面倒なので、開発用のsass-devを追加します。

1
2
3
4
5
6
{
    "scripts": {
        "sass-dev": "npx node-sass sass/_src/style.scss --output public/assets/css/ --output-style compressed --watch --source-map true",
        "sass": "npx node-sass sass/_src/style.scss --output public/assets/css/ --output-style compressed"
    }
}

sassの変更を検知できるようにwatchやcssのデバックが簡単になるようにsource-mapを使っています。これでコマンドを実行します。ターミナルで以下のコマンド実行してください。

1
$ npm run sass-dev

sassが変更されたときにきちんと検知してコンパイルされていると思います。

開発中はsass-devを使って本番にdeployするときにsassを使うといった具合に切り分けすればいい思います。

まとめ

多少、htmlのbuildを何回もやらなきゃいけないのはちょっと面倒ですが、サーバーレスでのことなのでhtmlよりjsの実装が多いのでさほど問題にならないです。頑張ればbashで自動コンパイルもできますし。

もし、htmlの方が多いなら静的サイトジェネレーターを考えた方がいいかも。少量のページ数ですと1人で担当することが多いので、余計なツールを使わずに雛形を作ってgit管理しておけばいつでも使いまわせるので便利だと思います。

See Also