Bootstrap 4 のビルドツールは npm-scripts で決まり

Bootstrap 4 Alpha が最初に公開されたのは2015年の8月ですが、それから2年経ってやっと Beta が公開されました。[公式ブログ](https://blog.getbootstrap.com/2017/08/10/bootstrap-4-beta/)によると、今後は破壊的変更はでくるだけ避けるということなので、実際に使い始めることにしました。（Beta 2 が公開されたことに伴い変更　2017年10月22日、正式版が公開されたことに伴い変更 2018年2月6日）

Bootstrap 4 Beta では、公式のビルドツールが Grunt を使うのを止めて npm-scripts に変更されました。その npm scripts のコードをみてみると、Grunt や Gulp で書いたコードよりかなりシンプルです。もう、複雑なことをしないのであれば、npm scripts を使った方が簡単で、複雑なことをしようと思えば webpack があります。それで、Grunt や Gulp を使うのは止めようと思っています。

以下に、Bootstrap 4 の scss を npm-scripts を使ってカスタムビルドする方法を書いておきます。

## 1. Node.js をインストールする

Node.js をインストールしていなければ、[Node.js](https://nodejs.org/) のサイトからダウンロードしてインストールします。新しい物が好きな人は、v9 の方をインストールしてもいいですが、普通はLTS（推奨版）の方をインストールします。2018年1月現在の LTS（推奨版）は v8 です。

### Windows の場合
Windows では、2015年頃まではファイルシステムの最大パス長である260文字を超えてしまいうまく動作しないという問題がありましたが、この問題は解消されたようです。以前使ったときには苦労したということが頭の中に残っていたのですが、今回はすんなり動きました。

また、npm install で npm パッケージを入れようとしたときに node-gyp でエラーが出ることがあります。node-gyp のインストールに Visual C++ Build Tools や Python 2.7 が必要なためです。自分でそれらのツールをインストールしてもいいのですが、それを自動化してくれるwindows-build-toolsというものがあるそうです。以下の用に npm installするだけでC++コンパイラやPython2.7をインストールしてくれるので便利だそうです。

```
npm install --global windows-build-tools
```

### Linux の場合
Linux の場合、最新の Node.js を利用したい場合は、PPA を使用してインストールするのが便利です。Ubuntu に v8 をインストールしたい場合は、以下のコマンドでインストールできます。

```
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
```

また、node-gyp にようにビルドツールが必要になるケースがあるので、以下のコマンドでビルドツールをインストールしておきます。

```
sudo apt-get install -y build-essential
```

詳しくは、Node.js 本家 [Installing Node.js via package manager](https://nodejs.org/en/download/package-manager/) を参照してください。


## 2. npm が動作することを確認

コマンドプロンプト（ターミナル）で、npm version と入力してみてください。以下のような結果が返ってくると思います。もし、Node.js や npm のバージョンが古い場合には、新しいものをインストールします。

![b402.png](https://qiita-image-store.s3.amazonaws.com/0/103055/f3d5aa54-e6a7-2082-53ac-654293b046f9.png)

## 3. Webアプリのディレクトリに移動して npm を初期化

以下のコマンドで、package.json を作成します。npm init では、英語でいろいろ聞かれますが、全部エンターキーを押しても問題ありません。

```
cd (ディレクトリ)
npm init
```

## 4. Bootstrap を npm でインストール
以下のコマンドで npm を使って Bootstrap をインストールします。--save-dev オプションをつけることで package.json の devDependencies に追記されます。

```
npm install --save-dev bootstrap
```

この時点では、package.json は、以下のようになっていますが、実際に利用するのは "scripts" と "devDependencies" のセクションだけです。それ以外のセクションはあっても問題はありませんが削除しても構いません。

```package.json
{
  "name": "test1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "bootstrap": "^4.0.0"
  }
}
```

## 5. カスタムビルド用の scss ファイルを用意

Bootstrapの変数を変更してカスタマイズするための scss ファイル "_myvariables.scss" 及び、Bootstrapで定義済みのCSSを上書きしてデザインを変更するコードを記述する _mystyle.scss を用意して、custom.scss を次のようにします。

``` custom.scss
@import "myvariables";
@import "node_modules/bootstrap/scss/bootstrap";
@import "mystyle";
```

## 6. npm-scripts の記述

ここが、今回のポイントですが、Bootstrap の package.json の npm-scripts を見ていると npm-scripts は簡単に書けるのがわかりました。 npm-scropts は、package.json の "scripts" セクションにコマンドとスクリプトを1行で書きますが、以下は、Bootstrap の package.json の npm-scripts を見て、少し修正して作りました。以下は、scss のコンパイルの部分だけですが、同じようにして、JavaScript の方もできるし、ファイルを監視してスクリプトを実行する watch もあるので自動化も難しくありません。

```package.json
  "scripts": {
    "css": "npm-run-all css-compile css-prefix css-minify",
    "css-compile": "node-sass --output-style expanded --source-map true --source-map-contents true --precision 6 src/custom.scss dist/css/custom.css",
    "css-prefix": "postcss --config src/postcss.config.js --replace dist/css/*.css",
    "css-minify": "cleancss --level 1 --source-map --source-map-inline-sources --output dist/css/custom.min.css dist/css/custom.css"
  },
  "devDependencies": {
    "bootstrap": "^4.0.0-beta",
    "autoprefixer": "^7.2.5",
    "clean-css-cli": "^4.1.10",
    "node-sass": "^4.7.2",
    "npm-run-all": "^4.1.2",
    "postcss-cli": "^4.1.1"
  }
```
※注意 css-prefixにある「postcss.config.js」ファイルは、[GitHubのbootstrap/build](https://github.com/twbs/bootstrap/tree/v4-dev/build)から取ってきます。

この npm-scripts が、何をしているかはすぐに理解できると思います。

1行目では npm-run-all を使って、css-compile、css-prefix、css-minify の順に処理をさせます。

2行目の css-compile では、node-sass を使って sass をコンパイルします。

3行目の css-prefix では、postcss を使ってベンダープレフィックスを追加しています。なお、postcss.config.js には、autoprefixer を使用することと、対応するブラウザーの情報が記載されています。

4行目の css-minify では、clean-css を使って css を圧縮するとともに Source Maps 作成しています。

"devDependencies" には、npm-scripts を実行するときに必要となる npm モジュールを追加します。

gulp、grunt の場合には、例えば、Sass をコンパイルするためには node-sass とそれをgulp、grunt で利用するためのラッパーである gulp-sass、grunt-sass が必要になります。ラッパーは何のため必要なのか考えると、明らかに余計なことをしています。npm-scripts で直接 node.js を使った方が簡単です。

scss-lint は、公式が Ruby版を使っているので省略しました。もし必要であれば、node版のscss-lintを使って、自分の書いた scss ファイルのみをチェックしたらいいと思います。

## 7. 必要なパッケージのインストール

package.json を修正して、新しい npm モジュールを追加したので、それをローカルにインストールします。

```
npm install
```

## 8. npm run で実行

npm-scripts は、`npm run コマンド` で実行することができます。今回の場合であれば、以下のコマンドを実行すると dist/css ディレクトリーに、custom.css 等4個のファイルが作成されます。

```
npm run css
```

[GitHub](https://github.com/creativewebjp/Bootstrap4Sample) の方にサンプルを作成していますので、そちらも参考にしてください。

## 補足1 Windows の日本語フォントの指定をどうするか

Windows の場合、Windows 8.1 以降、遊ゴシック、遊明朝がバンドルされるようになりましたが、ブラウザーで游ゴシックを使用する場合に以下の問題があります。

- 薄くて読みづらい。特に、Chrome の場合はかすれて見える。
- Internet Explorerで文字の下に大きく隙間が空いてしまう

そういうことで、Windows の場合は、日本語フォントの指定をどうするかは悩ましい問題です。選択肢は、次の3つです。

1. 日本語フォントは指定せずデフォルトのままにしておく。
2. メイリオのみを指定する。
3. 対策をしたうえで遊ゴシックとメイリオを指定する。

日本語フォントを指定していなければ、ブラウザーで指定している日本語フォントで表示されます。ユーザーの意思を尊重するということではこの方法がベストです。GoogleやWikipediaは日本語フォントを指定していません。

Facebook、Line、Twitter は、メイリオのみ指定しています。もし、ブラウザーの標準フォントが MS Pゴシックがになっていると、ClearType でないのでアンチエイリアスがかからないので汚く見えます。PCに詳しくないユーザーに Facebook より文字が汚いといわれないためには、メイリオのみ指定しておくというのがもう一つの選択肢です。

この場合は、_myvariables.css で以下のように $font-family-sans-serif に`Meiro`だけを追加してやるようにすれば変更できます。

```_myvariables.css
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Meiryo, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
```

遊ゴシックを指定する場合には、游ゴシックの font-face 等を指定する必要があります。詳しくは [Bootstrap4用 游ゴシックfont-family](http://qiita.com/RinoTsuka/items/aa1ab94c10542706fdc4) をみてください。IE Hack が必要になるので、自分は好みではありません。

## 補足2 gulp-sass でコンパイルすれば簡単なのでは？

Bootstrap 4 では、postcss を使ってベンダープレフィックスを追加しています。gulp-sass でコンパイルするだけであれば、ベンダープレフィックスが付かないので十分とはいえません。