公開日: 2023年9月17日

Git 第1回: GitHub に上げるサンプルプロジェクトを作ろう

今回から 6 回にわたり、Git とその周辺について書いていこうと思います。各回はそれぞれ次のような内容になっています。第 1 回 ~ 第 5 回は流れで書いたので、途中から読むとわかりづらいところがあるかもしれません。第 6 回は他の記事から独立しているので、この回だけ読んでも支障はありません。

はじめに

第 1 回目の今回は、Git の基本のキみたいなコマンドだけを使って、次回以降の説明に用いるサンプルプロジェクトを作ります。プロジェクトの概要をざっくり説明すると、ホームページの作成を支援する Sass、EJS、Gulp といったツールを使って、図 1 のような見た目をもつ HTML と CSS を出力します。どこか見覚えのあるデザインですが、どこにでもよくあるデザインともいえます。なお、数年前に仕入れた知識で作成したため、2023 年現在では陳腐化しているかもしれません。

図 1: サンプルページの最終形
図 1: サンプルページの最終形

今回作成するサンプルプロジェクトは、すでに GitHub に上げてあります (上げ方は次回の記事でやります)。

Git のインストールと設定

Git は packages からカンタンにインストールすることができます。

# pkg install -y git

インストールが済んだら最低限の設定を行います。ユーザー名、メールアドレス、 改行コード、デフォルトエディタなどです。

% git config --global user.name "mijinco"
% git config --global user.email "0106@retrotecture.jp"
% git config --global core.autocrlf input
% git config --global core.editor 'nano -Ynone'

FreeBSD で開発するのであればcore.autocrlfinputにしておくのがよいと思います (たぶん)。エディタは GNU nano にしています。-Ynoneをつけるとシンタックスハイライトを無効にしますが、有効にする場合は削除してください。また、キーバインドは頑張れば Emacs 風にすることもできます。

上のように--globalオプションをつけると、すべてのリポジトリに共通のグローバルな設定となるのですが、場合によってはリポジトリごとに違うユーザーを名乗りたいということもあるかと思います。次の節ではそういったこともやってみます。

最後に、Git のリポジトリや作業ディレクトリをつっこんでいくことになるルートディレクトリを作っておきましょう。作らなければいけないルールはありませんが、整理整頓的な観点からは作っておいたほうがよいと思います。名前も好きなようにつければ大丈夫です。今後はこのディレクトリの中にローカルリポジトリを作っていくことにします。

% mkdir ~/gitroot/

サンプルプロジェクトを作成する

それではサンプルプロジェクトを作っていきましょう。最初にやることは、プロジェクト名を決めて、その名前で作業用のディレクトリを作って初期化することです。
% mkdir ~/gitroot/hp-example/
% cd ~/gitroot/hp-example/
% git init

ここではホームページのサンプルということで hp-example というプロジェクト名にしました。このあとの作業は、特に明示しない限りこの ~/gitroot/hp-example/ ディレクトリで行います。

ところで、プロジェクトごとに違うユーザー名を名乗りたいという場合もあると思います。フリーランスの方なら仕事用とプライベート用で使い分けたいとか、「このプロジェクト同姓同名の人が 6 人もいて困る」というようなケースです。そういうときのために、このリポジトリ内でだけ別のユーザー名を使うことができます。次のように、そのリポジトリの中で--globalオプションをつけずにgit configを実行します。

% git config user.name "mike"

そういうことができるんだということを文書として残すためだけに、以降このプロジェクトにはアメリカ人のマイクが取り組んでくれたという体で書いていこうと思います。ちなみに、リポジトリローカルな設定は、作業ディレクトリ直下の .git/config に保存されます。

箱ができたので、中身をつっこんでいきます。意味のない文字列を表示する HTML ファイルとリセット CSS です。リセット CSS は A modern CSS reset を使わせていただきました。作業ディレクトリの中が次のような構成になるように、サブディレクトリとファイルを配置します (tree コマンドは ports/packages からインストールします)。

% tree
.
├── css
│     └── reset.css
└── template.html

HTML ファイルの中身はごく簡単です。

template.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>hp-example</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="css/reset.css">
</head>
<body>

<div>
    <header>
        Header Header
    </header>

    <main>
        <p>
            メインメインメインmain main main
            メインメインメインmain main main
            メインメインメインmain main main
            メインメインメインmain main main
            メインメインメインmain main main
            メインメインメインmain main main
            メインメインメインmain main main
            メインメインメインmain main main
            メインメインメインmain main main
            メインメインメインmain main main
        </p>
    </main>

    <aside>
        <p>
            サイドバーサイドバーサイドバーsidebar sidebar sidebar
            サイドバーサイドバーサイドバーsidebar sidebar sidebar
            サイドバーサイドバーサイドバーsidebar sidebar sidebar
        </p>
    </aside>

    <footer>
        <small>footerfooter</small>
    <footer>
</div>

それでは、この 2 つのファイルをコミットしましょう (ようやく Git の記事らしくなってきた)。まず、新規作成した 2 つのファイルをステージに上げ、ステータスを確認します。「.」を指定してgit addすると、変更のあったファイルをすべてステージに上げてくれるんだったと思います (正確には違うかも)。

% git add .
% git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   css/reset.css
        new file:   template.html

この状態では、まだコミットはされていません。実際にコミットするにはgit commitです。

% git commit -m "HTML のテンプレとリセット CSS を新規登録"

ちゃんとコミットされたか確認します。

% git status
On branch master
nothing to commit, working tree clean
% git log
commit 751a808c788a1de02fba2f8a00e60497e947c35b (HEAD -> master)
Author: mike <0106@retrotecture.jp>
Date:   Wed Aug 9 09:59:44 2023 +0900

    HTML のテンプレとリセット CSS を新規登録

よさそうです。ちなみにこの HTML ファイルをブラウザで表示するとこうなります。最初のバージョンとしては上出来です…よね?

図 2: ここから出発
図 2: ここから出発

サンプルプロジェクトを発展させる

さて、実際にやってみるとわかりますが、素の HTML と CSS だけで頑張ろうとすると早晩行き詰まります (実体験)。そうならないように、ここで FLOCSS という設計手法を取り入れることにします (ただし厳密に取り入れるのは大変そうなので、ゆるくです)。そのために Sass や Gulp といったツールを新たに導入します。FLOCSS の説明はここではしませんが、気になる方はネットで調べてみてください。

開発環境の構築

まず、Node.js と NPM を ports/packages でインストールします。

# pkg install -y node npm

作業ディレクトリに移動し、NPM を初期化します。

% cd ~/gitroot/hp-example/
% npm init -y

作業ディレクトリに Gulp をインストールします。ついでにその他の必要なパッケージもインストールします。

% npm install --save-dev gulp gulp-sass gulp-sass-glob gulp-line-ending-corrector gulp-postcss css-mqpacker postcss sass gulp-ejs gulp-rename

ちなみにアンインストールしたいときは下記のようにします。

% npm uninstall --save-dev <パッケージ名>

インストールしたパッケージを確認します。

% npm ls --depth=0
hp-example@1.0.0 /usr/home/mijinco/gitroot/hp-example
├── css-mqpacker@7.0.0
├── gulp-ejs@5.1.0
├── gulp-line-ending-corrector@1.0.3
├── gulp-postcss@9.0.1
├── gulp-rename@2.0.0
├── gulp-sass-glob@1.1.0
├── gulp-sass@5.1.0
├── gulp@4.0.2
├── postcss@8.4.27
└── sass@1.64.2

ちなみに、現時点で作業ディレクトリはこういう状態になっています。

% ls
css/             package-lock.json      template.html*
node_modules/    package.json

FLOCSS 指向でディレクトリとファイルを作成していく

作業ディレクトリ直下に sass ディレクトリを作成し、その下に FLOCSS になるべく従う形でディレクトリとファイルを作成していきます。

% mkdir sass
% cd sass
% mkdir component/ foundation/ layout/ project/ utility/
% touch foundation/_foundation.scss foundation/_mixin.scss foundation/_variables.scss
% touch layout/_footer.scss layout/_header.scss layout/_main.scss layout/_page.scss layout/_sidebar.scss
% touch style.scss

ディレクトリ構造はこうなりました。foundation と layout 以外のディレクトリは今のところ空です。

% tree
.
├── component
├── foundation
│     ├── _foundation.scss
│     ├── _mixin.scss
│     └── _variables.scss
├── layout
│     ├── _footer.scss
│     ├── _header.scss
│     ├── _main.scss
│     ├── _page.scss
│     └── _sidebar.scss
├── project
├── style.scss
└── utility

各ファイルの中身を一言コメントと共に紹介していきます。まずは Foundation レイヤから。

sass/foundation/_foundation.scss
@import "_variables";
@import "_mixin";

_foundation.scss は、このレイヤにある他のすべてのファイルをインポートするためだけのファイルです。

sass/foundation/_mixin.scss
// メディアクエリ
@mixin mq-up($bp: tab) {
    @media #{map-get($breakpoints-up, $bp)} {
        @content;
    }
}

ミックスイン (関数のようなもの。というより C 言語の関数形式マクロのほうがイメージが近いかもしれません) を 1 カ所にまとめて記述しておくために設けたファイルです。今のところ、メディアクエリを書くためのミックスインが 1 個あるだけです。

sass/foundation/_variables.scss
// 大まかなレイアウトの設定
$layout-width-max: 1024px;
$layout-width-sp: 768px;

// ブレークポイント (スマホベース)
$breakpoints-up: (
    "sp": "(max-width: #{$layout-width-sp - 1px})",
    "tab": "(min-width: #{$layout-width-sp})",
    "pc": "(min-width: #{$layout-width-max})",
);

// ヘッダーの高さ
$header-height-sp: 60px;
$header-height-pc: 60px;

// 色
$site-color-bg: #FFCC00;
$site-color-fg: #000000;

プロジェクト全体に関わる変数の値を定義しているファイルです。

次は Layout レイヤです。

sass/layout/_footer.scss
.l-footer {
    grid-area: footer;
    background: #555500;
}

_footer.scss ではサイトのフッターがページの最下部に配置されるようにしているのですが、このファイルだけだと何をやっているのかわかりづらいかもしれません。同じレイヤの _page.scss と合わせて読むと理解しやすいと思います。CSS のグリッドレイアウトという機能を使っています。

また、レイアウトに関するレイヤなのに、ここで色を決めていることに違和感があるかもしれませんが、これはデバッグのために各エリアを適当な色で塗り分けているだけですので、気にしないでください。あとで消します。

sass/layout/_header.scss
.l-header {
    grid-area: header;
    height: $header-height-sp;
    background: $site-color-bg;
}

@include mq-up("pc") {
    .l-header {
        height: $header-height-pc;
    }
}

フッターと同様に、サイトのヘッダーをページの一番上に配置する処理が書かれています。PC で閲覧した場合 (mq-up("pc") {...}) とそうでない場合とで、ヘッダーの高さを少し変えています。

sass/layout/_main.scss
.l-main {
    grid-area: main;
    background: #FFCCCC;
}

記事本体の配置を行っています。

sass/layout/_page.scss
.l-page {
    max-width: 100%;
    display: grid;
    grid-gap: 15px;
    grid-template-columns: 1fr;
    grid-template-areas:
        "header"
        "main"
        "sidebar"
        "footer"
}

@include mq-up("pc") {
    .l-page {
        grid-template-columns: 3fr 1fr;
        grid-template-areas:
            "header header"
            "main sidebar"
            "footer footer"
    }
}

ページ全体のレイアウトを決めています。CSS のグリッドレイアウトでは、何をどこに配置したいかを視覚的に並べて記述します。上の例では、PC で閲覧した場合は 2 列となり、最上段は左右ともにヘッダー、最下段は左右ともにフッター、中段は左が記事本文、右がサイドバーというレイアウトになります。PC 以外で閲覧した場合は 1 列でヘッダー、本文、サイドバー、フッターの順に配置されるレイアウトになります。

sass/layout/_sidebar.scss
.l-sidebar {
    grid-area: sidebar;
    background: #FFEEAA;
}

サイドバーの配置を行っています。

最後に、すべてのレイヤのすべてのファイルをインポートするためのファイルです。

sass/style.scss
@import "foundation/_foundation";
@import "layout/**";
@import "component/**";
@import "project/**";
@import "utility/**";

FROCSS では、必ずこの順番でインポートする必要があります。@import "layout/**"のように書くと、layout ディレクトリ内のファイルをサブディレクトリまでたどってすべてインポートしてくれます。foundation ディレクトリだけそのように書かないのは、FROCSS がそれを推奨していないからです (詳しくは FLOCSS の作者による唯一の解説書『柴犬でもわかる FLOCSS』p.24 を参照してください)。

HTML ファイルのほうは次のように修正します。

% git diff template.html
diff --git a/template.html b/template.html
index 7dba85b..88f5669 100755
--- a/template.html
+++ b/template.html
@@ -6,15 +6,16 @@
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <link rel="stylesheet" href="css/reset.css">
+<link rel="stylesheet" href="css/style.css">
 </head>
 <body>

-<div>
-    <header>
+<div class="l-page">
+    <header class="l-header">
         Header Header
     </header>

-    <main>
+    <main class="l-main">
         <p>
             メインメインメインmain main main
             メインメインメインmain main main
@@ -24,7 +25,7 @@
         </p>
     </main>

-    <aside>
+    <aside class="l-sidebar">
         <p>
             サイドバーサイドバーサイドバーsidebar sidebar sidebar
             サイドバーサイドバーサイドバーsidebar sidebar sidebar
@@ -32,7 +33,7 @@
         </p>
     </aside>

-    <footer>
+    <footer class="l-footer">
         <small>footerfooter</small>
     </footer>
 </div>

作業ディレクトリのトップ (~/gitroot/hp-example/) に gulpfile.js を作成します。中身をざっくり説明すると「sass ディレクトリの下にある *.scss ファイルから css/style.css を生成せよ」ということが書かれています。

gulpfile.js
const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const glob = require('gulp-sass-glob');
const lec = require('gulp-line-ending-corrector');
const pcss = require('gulp-postcss');
const mqp = require('css-mqpacker');

const io_sass = {
    src: 'sass/**/*.scss',
    dest: 'css',
}
const opt_sass = {
    outputStyle: 'expanded',
}
const opt_lec = {
    eolc: 'CRLF',        /* CRLF|CR|LF */
    encoding: 'utf8',    /* others are not tested */
}

/* Sass task */
function sass_task() {
    return gulp.src(io_sass.src)
        .pipe(glob())
        .pipe(sass(opt_sass))
        .pipe(lec(opt_lec))
        .pipe(pcss([mqp()]))
        .pipe(gulp.dest(io_sass.dest))
        ;
}

exports.default = gulp.series(
    sass_task
);

ちなみに現時点で作業ディレクトリはこういう状態になっています。

% ls ~/gitroot/hp-example/
css/            node_modules/        package.json      template.html*
gulpfile.js     package-lock.json    sass/

コンパイルする

HTML と CSS だけでやっていたころは必要なかったのですが、Sass を導入したことによって *.scss をコンパイルするというひと手間が加わりました。次のように実行します。

% npx gulp

これにより css ディレクトリの下に style.css が生成されます。そうしたらブラウザで template.html を開いてみましょう。図 3 のようになります。ちょっとだけ最終イメージに近づきました。

図 3: ぽくなってきた
図 3: ぽくなってきた

Git の追跡対象から外したいファイルの扱い

Sass をコンパイルして得られる style.css だとか、インストールしたパッケージが収められている node_modules ディレクトリなどは Git の追跡対象から外したいですね。そのようなディレクトリやファイルは作業ディレクトリの直下に .gitignore を作成し、そこに列挙しておきます。

.gitignore
node_modules/
css/style.css

コミットしよう

ここまでの成果をコミットしておきましょう。まずgit statusで確認します。先ほど作った .gitignore が早速効力を発揮して node_modules/ と css/style.css が無視されていますね。

% git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   template.html

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    .gitignore
    gulpfile.js
    package-lock.json
    package.json
    sass/

ステージに上げてコミットします。

% git add template.html .gitignore gulpfile.js package-lock.json package.json sass/
% git commit -m "style.css を Sass からコンパイルするようにした"

ツリーが少し成長しました:)

% git log
commit 64f7174bee701f37effac9d18632ef1d6d0a0e79 (HEAD -> master)
Author: mike <0106@retrotecture.jp>
Date:   Wed Aug 9 10:19:51 2023 +0900

    style.css を Sass からコンパイルするようにした

commit 751a808c788a1de02fba2f8a00e60497e947c35b
Author: mike <0106@retrotecture.jp>
Date:   Wed Aug 9 09:59:44 2023 +0900

    HTML のテンプレとリセット CSS を新規登録

今回はここまで

こんな調子でホームページの外観や中身を充実させていきましょう。ただ、こればっかりやっていると本題を逸脱してゼロからはじめるホームページ作成講座になってしまいますので、適当なところでまとめます。最終的な姿はすでに図 1 に示したとおりです。

ここまででタグを打っておきましょう。イマイチ適切なタグ名を思いつかなかったので、安易ですが「v0.1」としました。

% git tag -a v0.1 -m "v0.1"

そして最終的なディレクトリ構造はこうなりました (Git で追跡するファイルのみ抜粋)。上のほうに書いたように、全ソースコードは GitHub から取得することができます。

% tree -al
.
├── .gitignore
├── gulpfile.js
├── package-lock.json
├── package.json
└── src
       ├── css
       │     └── reset.css
       ├── ejs
       │     ├── _category.ejs
       │     ├── _footer.ejs
       │     ├── _header.ejs
       │     ├── _newentry.ejs
       │     ├── _siteinfo.ejs
       │     └── template.ejs
       └── sass
              ├── component
              │     ├── _adbox.scss
              │     ├── _footnote.scss
              │     ├── _itembox.scss
              │     ├── _itemize.scss
              │     └── _linkblock.scss
              ├── debug
              │     ├── _footer.scss
              │     ├── _header.scss
              │     └── _main.scss
              ├── foundation
              │     ├── _base.scss
              │     ├── _foundation.scss
              │     ├── _mixin.scss
              │     └── _variables.scss
              ├── layout
              │     ├── _footer.scss
              │     ├── _header.scss
              │     ├── _main.scss
              │     ├── _page.scss
              │     └── _sidebar.scss
              ├── project
              │     ├── _adbox.scss
              │     ├── _footer.scss
              │     ├── _header.scss
              │     ├── _itembox.scss
              │     └── _main.scss
              ├── style.scss
              └── utility
                     ├── _space.scss
                     └── _text.scss

次回はこれを GitHub 等のホスティングサービスに登録してみます。