Webpackで Browsersync + Sassコンパイルを試す
GruntやGulpなどのタスクランナーツールでは一般的ですが、WebpackだけでBrowsersyncをベースにSassのコンパイルを試してみました。
そもそもWebpackに触れるについては、当初はやや億劫でした(汗
ローダーという仕組みについての理解不足、日本語ドキュメントの少なさ、そしてなんといっても大艦巨砲主義と揶揄されるようなオプションの多さが理由です。とにかく調べるのが大変そうなイメージでした。また本業がWebサイト制作メインなので、Gulpで十分なのでは?という気もしてます。
しかし前々からES6の導入とvue.jsを使う上でベストな環境を構築したかったのと、Rebuild.fmと例の記事に触発されて腰を上げて調べてみようと思いました。
準備
Webpackへの理解が圧倒的に足らないので自分なりに調査をするところから。大雑把なまとめとして、
- WebpackはビルドツールでBrowserifyに近い機能を提供する。Gulpなどを頼らなくてもビルドツールとして構築可能。
- 大きな特徴はloaderプラグインを使うことでJavascript以外の言語でもJavascriptに変換される。デフォルトではSassもCSSもjsファイル形式でビルドされる。後述のextract-text-webpack-pluginを使うことでcssファイルとして出力することができる。
まだ深く理解できていませんが、こんなイメージです(間違っていたらご指摘頂きたく...) この辺りの記事がわかりやすく参考になりました。
ちなみに日本語の記事だとGulpとgulp-webpackを組み合わせて、Webpackのビルド機能のみを使うという記事が圧倒的に多いようですが、あまりシンプルなやり方とも思えないので、このブログではWebpackのみを使った簡潔なビルド環境構築を目標としています。
環境
- Webpack 1.13.0
- MacOS 10
前提
Gulpで実現できていたSassのコンパイルとライブリロードを実現する。
具体的に盛り込む機能は以下。なお問題を複雑化しないために今回はSassのコンパイルのみを行います。
※JSの設定については次回検証する予定です。
ちなみに近いことをやっている方もいるようで。こちらも参考にさせてもらいました。
ディレクトリ
project/
├─ app/
│ ├─ css/ // webpackが出力するファイル
│ │ ├─ style.css
│ │ └─ style.js.map
│ └─ index.html
├─ src/
│ ├─ scss/
└─ entry.scss //ここにスタイルを書きます
└─ webpack.config.js
└─ package.json
使用モジュール・プラグイン
- webpack
- webpack-build-notifier(コンパイル・エラー時に通知させるためのプラグイン)
- extract-text-webpack-plugin(jsに組み込まないでファイルをネイティブに出力するプラグイン)
- browser-sync
- browser-sync-webpack-plugin(BrowsersyncをWebpackのplugin形式で扱うためのプラグイン)
- css-loader
- sass-loader
- style-loader
- node-sass(sass-loaderではnode-sassを使っているので設定)
Webpackの最大の特徴はローダーを使うことでどんなファイルでもjsとしてコンパイル、バンドルできる事ですが、自分の好みとしてスタイルとスクリプトは分けたいので、このプロジェクトではcssファイルを個別に出力する設定としています。Webpackでは何も指定しないとどんなファイルでもjsとしてコンパイル・バンドルされるため、extract-text-webpack-pluginでネイティブのcssファイルを出力させる必要があります。詳しくは以下ドキュメントを参照。
インストール
まとめてインストール。プロジェクトディレクトリとpackage.jsonは設置済みの前提です。
sudo npm install webpack webpack-build-notifier extract-text-webpack-plugin browser-sync browser-sync-webpack-plugin css-loader sass-loader style-loader node-sass --save-dev
webpack.config.jsの設定
gulpでいうところのgulpfile.jsと同じように、Webpackでもwebpack.config.jsをルートに置いてコンフィグを設定してあげる必要があります。 ちなみにこの段階の設定だけではsourcemapファイルを正しく出力してくれません。
var path = require('path'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var BrowserSyncPlugin = require('browser-sync-webpack-plugin'); var WebpackBuildNotifierPlugin = require('webpack-build-notifier'); module.exports = { devtool: 'source-map', entry: { style: './src/sass/entry.scss' }, output: { path: path.join(__dirname, 'app/css'), filename: '[name].css' }, module: { loaders: [ { test: /\.scss$/, loader: ExtractTextPlugin.extract('css!sass') } ] }, plugins: [ new WebpackBuildNotifierPlugin(), new ExtractTextPlugin('[name].css'), new BrowserSyncPlugin({ host: 'localhost', port: 3000, server: { baseDir: ['app'] }, files: [ 'app/*.css', 'app/*.html' ] }) ] };
WebpackでネイティブなCSSのSourcemapファイルを出力
javascriptのsourcemap出力はwebpack本体でサポートされているらしいですが、ネイティブCSSのSourcemapファイルの出力方法は、extract-text-webpack-pluginのドキュメントにも書かれておらず、このままでは正しく出力をしてくれません。いろいろ探しましたが最終的にはgithubのQuestionに解決策がありました。scssのloader部分を以下記述に書き換えることで正しいsorucemapの出力を確認できました。
module: { loaders: [ { test: /\.scss$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!sass-loader?outputStyle=expanded&sourceMap=true&sourceMapContents=true') } ] },
参考にした該当記事
webpackの実行・監視
単純にコンパイルしたい場合は以下のコマンドで。
webpack
監視したい場合は以下コマンド実行。
webpack --watch
どちらもapp/cssディレクトリにstyle.cssとstyle.css.mapファイルが出力されます。監視している場合はコンパイルされた時点でリロードが実行されます。
サンプルプロジェクト
今回の流れで作成したプロジェクトは以下にpushしています。 https://github.com/kgsi/webpack-example-sass
おわりに
SourcemapやBrowsersyncを絡めたサンプルやドキュメントがあまり無く、最初の構築には手間取りましたが、Gulpと比べて見てもかなりスッキリしたコードになりました。しかし今の実装だけではWebpackにする利点は特に感じられないです。単純にSassのコンパイルだけなら、わかりやすいタスク形式で記述するGulpに勝敗が上がる気がします。
次回はWebpackの真髄であるJSに絡んだ設定・実装を試し、さらに検証してみる予定です。
参考記事
調べる過程で読み漁ったその他の記事も載せておきます。お世話になりました。