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

Webpack2+sassでbundle.cssを出力する&sassで画像ファイルを扱う

More than 3 years have passed since last update.

はじめに

sass-loader を使っているものの entryoutput にjsが指定されている記事があったり、
loaderの指定方法が変わっていたりして、よくわからなかったので理解のため自分の記事を書きます。

また、SCSSで background-image を扱おうとした際に、
webpackのビルドで扱けてしまったので、その解決策も書く。

Webpack2でsassをビルドする

参考にしたページ: http://qiita.com/nicchi__1985/items/e30e73de6d8443909537

SCSSをWebpackでビルドするのに必要なパッケージたち

package.json
{
  ~略~
  "devDependencies": {
    "css-loader": "^0.26.1",
    "extract-text-webpack-plugin": "2.0.0-rc.3",
    "node-sass": "^4.5.0",
    "sass-loader": "^5.0.1",
    "style-loader": "^0.13.1",
    "webpack": "^2.2.1"
  },
  ~略~
}

extract-text-webpack-plugin は、jsではなくcssとして出力するプラグインという認識。
Webpack2でビルドしてエラーが出た際に、調べていたらRC版を使えばいいよというIssueを見つけたので使用しています。

Webpack1 と Webpack2 の記述で混乱したところ

  • module.loaders.loader ではなく module.rules.use を使う
  • loader: 'style!css!sass'loader: 'style-loader!css-loader!sass-loader'ではなく use: ['sass-loader', 'css-loader', 'sass-loader'] を使う

参考にしたページ(公式): https://webpack.js.org/guides/migrating/

ファイル構成

$ tree
.
├── index.html
├── package.json
├── scss
│   ├── app.scss
│   └── _body.scss
└── webpack.config.js

scss/app.scss

app.scss
@import '_body';

scss/_body.scss

_body.scss
body {
  color: #ffffff;
  background-color: #000000;
}

webpack.config.js

webpack.config.js
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: './scss/app.scss',
  output: {
    filename: 'bundle.css'
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract(
          {
            fallback: "style-loader",
            use: ["css-loader", "sass-loader?outputStyle=expanded"]
          }
        )
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('bundle.css')
  ]
};

エントリポイント: scss/app.scss を指定
アウトプットに: bundle.css を指定

ビルド

$ webpack

これで bundle.css が出力されます。
index.htmlbundle.css を読み込めばバンドルされたCSSがそのまま使えます。

Webpack2 + sass で画像ファイルを扱う

background-image: url(../res/background.png);

を指定したかったのだが、
Webpackがエラーになってしまって上手くいかなかったときに調べたこと

必要なパッケージ

package.json
 {
   ~略~
   "devDependencies": {
     "css-loader": "^0.26.1",
     "extract-text-webpack-plugin": "2.0.0-rc.3",
+    "file-loader": "^0.10.0",
     "node-sass": "^4.5.0",
     "sass-loader": "^5.0.1",
     "style-loader": "^0.13.1",
     "webpack": "^2.2.1"
   },
   ~略~
 }

url-loader または file-loder が必要と書かれているページがありました。
参考にしたページ: http://a0sy.hatenablog.jp/entry/2015/08/03/204933

url-loader を使用すると BASE64エンコード されてしまうという記述があったので、
file-loader を使って試してみることにしました。

ファイル構成

 $ tree
 .
 ├── index.html
 ├── package.json
+├── res
+│   └── background.png
 ├── scss
 │   ├── app.scss
 │   └── _body.scss
 └── webpack.config.js

scss/_body.scss

_body.scss
 body {
-  color: #ffffff;
-  background-color: #000000;
+  color: #000000;
+  background-image: url(../res/background.png);
 }

ここで指定するパスは、
webpack.config.js のエントリポイントになっているファイルからのパスのようです。

webpack.config.js

webpack.config.js
 var ExtractTextPlugin = require('extract-text-webpack-plugin');

 module.exports = {
   entry: './scss/app.scss',
   output: {
     filename: 'bundle.css'
   },
   module: {
     rules: [
       {
         test: /\.scss$/,
         use: ExtractTextPlugin.extract(
           {
             fallback: "style-loader",
             use: ["css-loader", "sass-loader?outputStyle=expanded"]
           }
         )
-      }
+      }, {
+        test: /\.(jpg|png)$/,
+        use: 'file-loader?name=assets/[name].[ext]'
+      }
     ]
   },
   plugins: [
     new ExtractTextPlugin('bundle.css')
   ]
 };

SCSS内で指定されたパス ../res/background.pngassets/[name].[ext] として出力されます。
※res内のファイルを直接参照するのではなく bundle.jsbundle.css のように、別のファイルとして出力されるようです。

つまり今回のケースでは assets/.gitignore に追加しておく必要がある。

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
ユーザーは見つかりませんでした