Spring BootのCSSをGulpで管理する
Spring BootのプロジェクトでもSASSが書きたい!という欲望から、Gulpを使ってSASSをコンパイルするようにしました。
基本Gulpでやってるので、出力先だけ変えれば、特にSpring Bootには関係ない気もしますが・・・
npmは既にインストールしてある前提で。
フォルダの構成と基本方針
フォルダ構成は以下のようなイメージ。
├── 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でインストールしていきます。
$ 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のタスクを定義します。
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出力しています。
設定したタスクを実行します。
$ gulp sass
これでCSSが出力されますので、あとはThymeleaf側から
<link rel="stylesheet" type="text/css" href="@{/css/application.css}"/>
として参照できます。
SASSを分割したい
よくあるケースとして、画面単位でSASSを分け、最終的なCSSでは1つにまとめてしまいたい、というケースがあります。 例えば、以下のようなイメージ。
assets
└── stylesheets
├── modules <- 各画面ごとのSASS
│ ├── _hoge.scss
│ └── _fuga.scss
└── application.scss <- modulesを全てimportしたい
こういった時にはgulp-sass-bulk-importが便利です。
$ npm install --save-dev gulp-sass-bulk-import
としてgulp-sass-bulk-importをインストールした後、gulpfile.jsを修正します。
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で
@import "modules/*";
とすることで、modules内のSASSを含めて、CSSがコンパイルされます。
注意点として、modules以下のSASSファイルは、プレフィックスとしてアンダーバーが付与されています。付与しない場合は、modules以下のSASSも普通にコンパイルの対象になり、そのままdestに出力されてしまうので、これを防止するため、アンダーバーを付与しています。
Bootstrapを使いたい
まずBoostrapをnpmでインストールします。
$ npm install --save-dev bootstrap@4.0.0-alpha.4
これでnode_modulesにBootstrapがインストールされたので、これをGulpから参照できるようgulpfile.jsを修正します。
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で
@import "bootstrap";
とするだけです。SASSのコンパイルを実行すると、application.cssにBootstrapのcssが含まれていることがわかります。