webpack
はJavascript
とcss
やimage
を一緒にまとめることができるのが、GruntやGulpといった他のタスクランナーのように設定が煩雑にならない強み、と公式サイトで見た。
実際、それがどれほど便利なのかを試してみた。
以下は、es6+babel+webpack
の環境を想定しています。
cssのバンドル
css-loader
をインストール。Scssを使いたいのでsass-loader
もインストールします。
$ npm install --save-dev css-loader sass-loader
webpack.config.js
を編集します。
// es5
'use strict';
var webpack = require('webpack');
var path = require('path');
var env = process.env.NODE_ENV;
var config = {
module: {
loaders: [
{
test: /\.js$/,
loaders: ['babel-loader?presets[]=react&presets[]=es2015&cacheDirectory'],
exclude: /node_modules/
},
{
// 今回はScssを使うので.scssとしています。
// cssを直接使う場合は.cssとして、loadersからsassを除きます。
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
},
]
},
entry: {
'index': 'index.js',
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js'
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env)
}),
new webpack.optimize.OccurrenceOrderPlugin(),
],
resolve: {
extensions: ['', '.json', '.js', '.jsx'],
modulesDirectories: ['node_modules', __dirname]
}
};
module.exports = config;
resolve
のextensions
で.scss
を指定した場合は、import './test'
のように拡張子を除いてimport
できます。
import
の拡張子なしはJavascriptファイルのみがいいような気もする。
そしてscssファイルを作成します。
.main-container {
width: auto;
height: auto;
}
#box {
border: solid 5px;
width: 300px;
height: 300px;
margin: auto;
}
Directory構造はこのようになりました。
$ tree
.
├── index.html
├── index.js
├── style.scss
└── webpack.config.js
他のファイルはこのような感じです。
import './style.scss'
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Load CSS Example</title>
<script src="dist/index.js"></script>
</head>
<body>
<div class="main-container">
<div id="box"></div>
</div>
</body>
</html>
imageのバンドル
file-loader
とurl-loader
をインストールします。
$ npm install --save-dev file-loader url-loader
上のwebpack.config.js
に追記します。
// es5
...,
var config = {
module: {
loaders: [
{
test: /\.js$/,
loaders: ['babel-loader?presets[]=react&presets[]=es2015&cacheDirectory'],
exclude: /node_modules/
},
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
},
{
// 追記
test: /\.(jpg|png)$/,
loaders: 'url-loader'
},
]
},
...,
}
module.exports = config;
Directory構造はこのようにしました。
$ tree
.
├── image.jpg
├── image.png
├── index.html
├── index.js
├── style.scss
└── webpack.config.js
index.js
に追記します。
import './style.scss'
import jpg from './image.jpg' // base64データがビルドされるのでそれをimportする
import png from './image.png' // base64データがビルドされるのでそれをimportする
let imgJpg = document.createElement('img')
imgJpg.src = jpg
document.getElementById('box').appendChild(imgJpg)
let imgPng = document.createElement('img')
imgPng.src = png
document.getElementById('box').appendChild(imgPng)
DOMを扱うので、index.html
のscript
タグを移動します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Load CSS Example</title>
</head>
<body>
<div class="main-container">
<div id="box"></div>
</div>
</body>
<script src="dist/index.js"></script>
</html>
余談:imageをファイル名でリンクする場合
- 元のPATHを書けば良いだけだとは思うが、一応出来るので試す。
- 出力先は
output
で指定したPATH
webpack.config.js
でurl-loader
の代わりにfile-loader
を使用します。
名前を指定しないとmd5Hashでファイル名が出力されるので注意。
// es5
...,
var config = {
module: {
loaders: [
{
// loaderを変更。名前をファイル名のままで維持する
test: /\.(jpg|png)$/,
loaders: 'file-loader?name=[name].[ext]'
},
]
},
...,
}
module.exports = config;
imageは使いどころが難しいですが、動的に使用する場合は便利な時があるかもしれませんね。