LoginSignup
85
76

More than 5 years have passed since last update.

webpackでcssとimageをバンドルする

Last updated at Posted at 2016-03-09

webpackJavascriptcssimageを一緒にまとめることができるのが、GruntやGulpといった他のタスクランナーのように設定が煩雑にならない強み、と公式サイトで見た。
実際、それがどれほど便利なのかを試してみた。
以下は、es6+babel+webpackの環境を想定しています。

cssのバンドル

css-loaderをインストール。Scssを使いたいのでsass-loaderもインストールします。

loaderのインストール
$ npm install --save-dev css-loader sass-loader

webpack.config.jsを編集します。

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;

resolveextensions.scssを指定した場合は、import './test'のように拡張子を除いてimportできます。
importの拡張子なしはJavascriptファイルのみがいいような気もする。

そしてscssファイルを作成します。

style.scss
.main-container {
  width: auto;
  height: auto;
}

#box {
  border: solid 5px;
  width: 300px;
  height: 300px;
  margin: auto;
}

Directory構造はこのようになりました。

directory構造
$ tree
.
├── index.html
├── index.js
├── style.scss
└── webpack.config.js

他のファイルはこのような感じです。

index.js
import './style.scss'
index.html
<!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-loaderurl-loaderをインストールします。

loaderのインストール
$ npm install --save-dev file-loader url-loader

上のwebpack.config.jsに追記します。

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構造はこのようにしました。

directory構造
$ tree
.
├── image.jpg
├── image.png
├── index.html
├── index.js
├── style.scss
└── webpack.config.js

index.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.htmlscriptタグを移動します。

index.html
<!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.jsurl-loaderの代わりにfile-loaderを使用します。
名前を指定しないとmd5Hashでファイル名が出力されるので注意。

webpack.config.js
// es5
...,
var config = {
  module: {
    loaders: [

      {
        // loaderを変更。名前をファイル名のままで維持する
        test: /\.(jpg|png)$/,
        loaders: 'file-loader?name=[name].[ext]'
      },
    ]
  },
  ...,
}

module.exports = config;

imageは使いどころが難しいですが、動的に使用する場合は便利な時があるかもしれませんね。

85
76
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
85
76