zephiransasのチラシの裏

とあるJava/Rubyプログラマのメモ代わりブログ

Spring BootのCSSをGulpで管理する

Spring BootのプロジェクトでもSASSが書きたい!という欲望から、Gulpを使ってSASSをコンパイルするようにしました。

基本Gulpでやってるので、出力先だけ変えれば、特にSpring Bootには関係ない気もしますが・・・

npmは既にインストールしてある前提で。

フォルダの構成と基本方針

フォルダ構成は以下のようなイメージ。

1
2
3
4
5
6
7
8
9
10
11
12
13
├── assets
│   └── stylesheets
│       └── application.scss
├── gulpfile.js
├── package.json
└── src
    └── main
        └── resources
            └── static
                └── css
                    ├── maps
                    │   └── application.css.map
                    └── application.css

assets/stylesheets以下にSASSを配置し、これをGulpでコンパイル。

出力先をSpring BootのCSS配備先 src/main/resources/static/css にして、これをThymeleafから参照する、という方針です。

必要なパッケージをインストールする

まずは必要なパッケージをnpmでインストールしていきます。

1
2
3
$ npm init
(以降、全てデフォルトで)
$ npm install --save-dev gulp gulp-sass gulp-sourcemaps gulp-minify-css gulp-plumber

これでpackage.jsonが作成され、node_modulesに依存ライブラリがインストールされます。node_modulesはgitignoreしておくといいでしょう。

gulpfile.jsを作成する

SASSをコンパイルできるようGulpのタスクを定義します。

gulpfile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var gulp = require('gulp'),
    sass = require('gulp-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    minifyCss = require('gulp-minify-css'),
    plumber = require('gulp-plumber');

gulp.task('sass', function(){
  gulp.src('assets/stylesheets/*.scss')
    .pipe(plumber())
    .pipe(sourcemaps.init())
    .pipe(sass())
    .pipe(minifyCss())
    .pipe(sourcemaps.write('./maps'))
    .pipe(gulp.dest('src/main/resources/static/css'))
});

まずscssファイルの置き場所を gulp.src('assets/stylesheets/*.scss') としてassets/stylesheetsディレクトリに設定します。

.pipe(sass())でSASSのコンパイル、.pipe(minifyCss())でCSSの圧縮をしています。

圧縮したCSSだと、元のSASSでの場所がわからなくなるので .pipe(sourcemaps.write('./maps'))でmapファイルを作成します。

sourcemaps.write()はデフォルトだとコンパイルされたcss内部にインラインでmapを書き込むので、別途mapsディレクトリにmapファイルを書き込むよう設定しておきます。こうしておくことでChromeなどのDeveloper toolで見たときにSASSの場所が分かるようになります。

最後に .pipe(gulp.dest('src/main/resources/static/css'))でCSS出力しています。

設定したタスクを実行します。

1
$ gulp sass

これでCSSが出力されますので、あとはThymeleaf側から

1
<link rel="stylesheet" type="text/css" href="@{/css/application.css}"/>

として参照できます。

SASSを分割したい

よくあるケースとして、画面単位でSASSを分け、最終的なCSSでは1つにまとめてしまいたい、というケースがあります。 例えば、以下のようなイメージ。

1
2
3
4
5
6
assets
└── stylesheets
    ├── modules <- 各画面ごとのSASS
    │   ├── _hoge.scss
    │   └── _fuga.scss
    └── application.scss <- modulesを全てimportしたい

こういった時にはgulp-sass-bulk-importが便利です。

1
$ npm install --save-dev gulp-sass-bulk-import

としてgulp-sass-bulk-importをインストールした後、gulpfile.jsを修正します。

gulpfile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var sassBulk = require('gulp-sass-bulk-import');

...

gulp.task('sass', function(){
  gulp.src('assets/stylesheets/*.scss')
    .pipe(plumber())
    .pipe(sourcemaps.init())
    .pipe(sassBulk()) # 追加
    .pipe(sass())
    .pipe(minifyCss())
    .pipe(sourcemaps.write('./maps'))
    .pipe(gulp.dest('src/main/resources/static/css'))
});

あとはapplication.scssで

application.scss
1
@import "modules/*";

とすることで、modules内のSASSを含めて、CSSがコンパイルされます。

注意点として、modules以下のSASSファイルは、プレフィックスとしてアンダーバーが付与されています。付与しない場合は、modules以下のSASSも普通にコンパイルの対象になり、そのままdestに出力されてしまうので、これを防止するため、アンダーバーを付与しています。

Bootstrapを使いたい

まずBoostrapをnpmでインストールします。

1
$ npm install --save-dev bootstrap@4.0.0-alpha.4

これでnode_modulesにBootstrapがインストールされたので、これをGulpから参照できるようgulpfile.jsを修正します。

gulpfile.js
1
2
3
4
5
6
7
8
9
10
11
12
gulp.task('sass', function(){
  gulp.src('assets/stylesheets/*.scss')
    .pipe(plumber())
    .pipe(sourcemaps.init())
    .pipe(sassBulk()) # 追加
    .pipe(sass({
      includePaths: ['./node_modules/bootstrap/scss']   # 追加
    }))
    .pipe(minifyCss())
    .pipe(sourcemaps.write('./maps'))
    .pipe(gulp.dest('src/main/resources/static/css'))
});

あとはapplication.scssで

application.scss
1
@import "bootstrap";

とするだけです。SASSのコンパイルを実行すると、application.cssにBootstrapのcssが含まれていることがわかります。

参考など