Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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は使いどころが難しいですが、動的に使用する場合は便利な時があるかもしれませんね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした