【テンプレ有り】webpack4でSassとES6の開発環境を構築する
webpack(ウェブパック)とは、モジュールバンドラーと呼ばれる複数のファイルを1つにまとめることが出来るツールです。
webpackを使うことによって、サイト上でサーバーへのリクエストを減らして表示速度を向上出来たり、開発時に機能ごとに複数のファイルに分けて作業をすることが可能になります。
本記事では、サービスサイトなど通常のサイトを作ることを想定としており、Vue.jsなどを使いSPAを作るフロントエンドエンジニア向けでは無いので予めご了承下さい。
また、本記事で紹介しているwebpackの設定で出来ることは下記の通りになります。
- Sass(Scss)をコンパイルしてcssに出力
- cssにベンダープレフィックスを自動付与(Autoprefixer)
- ES6をES5にコンパイル(これによりアロー関数やファイル分割が可能になる)
- cssとjsでソースマップを使用可能&minify化
- 開発用、本番用で実行したい処理を分ける
本記事で紹介するコードはこちらからダウンロード出来ます。
環境構築
必要なファイルをダウンロード
本記事では、私が用意したコードを元に解説を行っていきますので、ファイル一式をこちらからダウンロードして下さい。
ディレクトリ構成は下記のようになっているかと思います。
まず、ディレクトリ構成とそれぞれのファイルを簡単に解説していきます。
_srcは、実際に作業するディレクトリになります。jsとsassのディレクトリにそれぞれファイルを追加して開発を行っていきます。
publicは、jsとsassがコンパイルされて書き出されるディレクトリになります。これを本番用のディレクトリにしても大丈夫です。
webpack.common.js、webpack.dev.js、webpack.prod.jsは、webpackの設定が記述されているファイルです。
package.jsonは、プラグインなどのバージョンを管理するファイルになります。これを利用することで、複数人でも同じ開発環境を簡単に作ることが出来ます。
node.jsをインストール
webpackを使うにはnode.jsが必須になります。
ターミナルでnode -vを実行してみて下さい。nodeのバージョンが返ってきたらインストールされているので、下記の作業は不要です。command not found: nodeのようにエラーが返ってきたらnodeがインストールされていないので、公式サイトからインストールする必要があります。
インストール手順
- 公式サイト(https://nodejs.org/ja/)にアクセス
- 任意のバージョンを選択してpkgファイルをダウンロードする(左側の推奨番をダウンロードが一番安心です)
- ダウンロードしたpkgファイルを実行してnode.jsをインストール
- ターミナルでnode -vを実行してバージョンが返ってきたら成功
webpackとプラグインをインストール
ターミナルでpackage.jsonがあるディレクトリに移動します。
その後、下記コマンドを実行して下さい。
npm i
※iはinstallの略です
環境構築はこれで終わりです。
ここから先は、さらに詳しく設定ファイルなどの解説をしていきますが、「解説は不要」「早く作業したい」という方のために、どのように開発時にSassやES6をコンパイルするかを先に次のセクションで紹介します。
使い方
開発時
Sassとjs(ES6)を編集して保存したら自動でコンパイルされるようにすることが出来ます。下記コマンドでディレクトリを監視モードにします。
npm run watch
このコマンドを実行したら_srcディレクトリが監視モードになります。試しにsassやjsを編集して保存をしてみて下さい。
publicディレクトリにコンパイルされるはずです。
この監視モードの状態でコンパイルされたファイルは開発用のファイルになり、ソースマップが使える状態です
ソースマップを使うことで、ブラウザのデベロッパーツールで「どのファイルの何行目で書いた処理」なのかが分かるようになります。
以下の画像では、pタグのスタイルがどのsassファイルで書かれたのかがひと目で分かるかと思います。このようにソースマップは開発時のデバッグなどで非常に便利な機能なのです。
本番用ファイルを作成
ソースマップは便利な機能ですが、本番環境には必要ありません。npm run watchでコンパイルしたファイルを本番で使っても問題はありませんが、せっかくwebpackを使うのでより最適なファイルを本番環境で使いましょう。
本番用のファイルを作成するには下記コマンドを実行します。
npm run build
少し時間がかかりますが、処理が終わるとpublicディレクトリのcssからはソースマップの記述が削除、jsはminify化されます。
これで本番環境に最適なファイルを作ることが出来ました。
使い方のまとめ
- 開発時にはnpm run watch
- 本番用ファイルを作成するにはnpm run build
サンプルファイルについて
初めに
webpackの設定はwebpack.common.js、webpack.dev.js、webpack.prod.jsの3ファイルに記述しています。
webpack.dev.jsには開発時の設定を記述しています。つまり、npm run watchを実行する際の設定を記述しています。
webpack.prod.jsには本番用の設定を記述しています。つまり、npm run buildを実行する際の設定を記述しています。
そしてwebpack.common.jsには、開発時と本番用どちらにも共通する設定を記述しています。
つまり、基本的な設定はwebpack.common.jsに記述して、開発用と本番用で処理を分けたいときはそれぞれwebpack.dev.jsとwebpack.prod.jsのファイルに設定を記述します。
また、設定ファイルのコードは下記に記載しています。
webpack.common.js
const path = require('path')
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')
const autoprefixer = require('autoprefixer')
module.exports = {
entry: {
'public/application.js': './_src/js/_index.js',
'public/style.css': './_src/sass/index.sass'
},
output: {
path: __dirname,
filename: '[name]'
},
module: {
rules: [
{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
presets: 'env'
}
}],
exclude: /node_modules/,
},
{
test: /\.sass$/,
use: [
ExtractTextWebpackPlugin.loader,
{
loader: 'css-loader',
options: {
url: false,
sourceMap: true,
minimize: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
plugins: [
autoprefixer({
browsers: 'last 2 versions',
grid: true
})
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
},
]
}
]
},
plugins: [
new ExtractTextWebpackPlugin('[name]'),
]
}
webpack.dev.js
const merge = require('webpack-merge')
const common = require('./webpack.common.js')
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
})
webpack.prod.js
const merge = require('webpack-merge')
const common = require('./webpack.common.js')
module.exports = merge(common, {
mode: 'production',
})
解説
まず、webpack.common.jsの中身を解説していきます。
定義
const path = require('path')
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')
const autoprefixer = require('autoprefixer')
webpackのプラグインを使うには、このように最初に定義しなくてはいけません。
上記では、パスを操作するpath、sassなどをファイルとして出力するextract-text-webpack-plugin
、ベンダープレフィックスを自動で付与するautoprefixer
を記述しています。
module.exports
module.exports = {}
entry
entry: {
'public/application.js': './_src/js/_index.js',
'public/style.css': './_src/sass/index.sass'
},
output
output: {
path: __dirname,
filename: '[name]'
},
output: {
path: __dirname,
filename: 'public/app.js'
},
output: {
path: __dirname,
filename: {
'public/style.css',
'public/app.js'
}
},
entryの'任意の名前': 'コンパイルさせたいファイルのパス'の任意の名前にコンパイル先のパス(ファイル名を含む)を記述して、
outputのfilenameに[name]を与えることでエントリーポイントが増えてもoutputを変更しなくてすむようになります。
module
moduleの中のrulesには、コンパイル対象のファイル(今回はjsとsass)についての設定を記述します。
このrulesの中を編集することはあまりないので、今回は最低限の解説のみにします。
jsの設定は下記の通りです。
{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
presets: 'env'
}
}],
exclude: /node_modules/,
},
{
test: /\.sass$/,
use: [
ExtractTextWebpackPlugin.loader,
{
loader: 'css-loader',
options: {
url: false,
sourceMap: true,
minimize: true
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
plugins: [
autoprefixer({
browsers: 'last 2 versions',
grid: true
})
]
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
},
]
}
mode
webpack.dev.jsにはmode: 'development'、webpack.prod.jsにはmode: 'production'の記述があると思います。
devtool
ソースマップをコンパイル時に作成するかどうかを設定することが出来ます。
何個かオプションがありますが、基本的に以下3パターンだけ覚えていれば問題ないかと思います。
- devtool: 'inline-source-map':ソースマップの記述がファイル内に追加される
- devtool: 'source-map':ソースマップが新規ファイルとして出力される
- 何も記述しない:ソースマップが作成されない
なので、webpack.dev.jsにはソースマップが作成されるような設定をして、webpack.prod.jsにはソースマップが作成されないように何も記述はしていません。
開発用と本番用で処理を分ける
const merge = require('webpack-merge')
そして、読み込ませたいファイルを記述します。
const common = require('./webpack.common.js')
最後に、分けたい処理内容を下記のように記述をします。
module.exports = merge(common, {
// 分けたい処理内容
})
次に、packge.jsonのscriptに下記のように記述します。
"scripts": {
"watch": "webpack --config webpack.dev.js",
"build": "webpack --config webpack.prod.js"
},
webpackを実行する時に、webpack.dev.jsの設定で実行したい場合
webpack --config webpack.dev.js
webpackを実行する時に、webpack.prod.jsの設定で実行したい場合
webpack --config webpack.prod.js
上記のように--configの後に実行したいファイル名を与えることで、そのファイルの設定でwebpackを実行することが出来ます。
※ダウンロードしたファイルのscriptsのwatchには--watchが記述されていますが、これは開発時にファイルを監視するために記述をしており、処理を分けるということには一切関係ありません。
しかし、毎回このように入力するのは手間なので、scriptsに実行したいコマンドを登録しておきます。
このようにscriptsに設定をしたら、npmコマンドで登録したコマンドを実行することが出来ます。実行コマンドは下記の通りです。
npm run 登録名
上記コマンドを実行したら"登録名": "実行したいコマンド"の「実行したいコマンド」が実行されます。
まとめ
webpackは非常に便利な機能ですが、初めて使う方からしてみたら最初は全く理解できないかと思います。
私自身これまでGulpを使っており、そこからwebpackを使ってみようとなって色々カスタマイズしようと思ったのですが、最初は全く理解出来ず、色々調べながら少しずつ理解出来るようになりました。
その時に調べて覚えた内容を今回の記事にまとめたつもりなので、少しでもwebpackを使ったりカスタマイズする際に皆様のお役に立てれば幸いです。
この記事で基本的な書き方を理解出来たら、プラグインを追加してみたり、今回はあえて紹介しなかったdev-serverを使ってみたりなど色々なことを試してみてはいかがでしょうか。