まちいろエンジニアブログ

南池袋のWebサービス開発会社、株式会社まちいろのエンジニアブログです。

webpackでPostCSSをビルドする

f:id:y_kashiwaya:20170113151951p:plain

こんにちわ!柏谷です。

今回は、webpackでPostCSSをビルドするまでの方法を紹介します。

環境

前提条件

Nodejs、npmはインストール済みであること。

PostCSSとは

PostCSS

PostCSSは、JSのプラグインCSSのスタイルを変更するためのツールです。

変数や、mixin、最新のcssの変換などを様々な機能を持ったプラグインがあり、お好みで利用することができます。

Sassは不要な機能が多いし、重い、なんて悩んでいる方にぴったりのツールです。

webpackとは

webpack

モジュールバンドラー。

loaderというプラグインを利用し元のjsをあれやこれやして、ブラウザーで使用するjsファイルを生成してくれる。

jsだけでなく、画像やcssの処理も可能。

準備

プロジェクト用にディレクトリを作成します。

$ mkdir webpack_postcss_demo
$ cd webpack_postcss_demo

npm init して、package.jsonを作成します。

$ npm init

package.jsonを編集します。

$ vim package.json

scriptの箇所を次のように編集します。

{
  "name": "webpack_postcss_demo",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "webpack": "webpack" # ←
  },
  "author": "",
  "license": "ISC",
}

PostCSSをインストールして、webpackでビルドしてみる

今回は、cssにいい感じにベンダープレフィックスをつけてくれるautoprefixerというプラグインを使用します。

また、jsからcssimport するため、babelも一緒にインストールします。

$ npm install webpack postcss-loader css-loader style-loader autoprefixer babel-core babel-preset-es2015 --save-dev

本記事記述時点では、以下のとおりインストールされました。

{
  "name": "webpack_postcss_demo",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "webpack": "webpack"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^6.6.0",
    "babel-core": "^6.21.0",
    "babel-loader": "^6.2.10",
    "babel-preset-es2015": "^6.18.0",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.26.1",
    "extract-text-webpack-plugin": "^1.0.1",
    "postcss-loader": "^1.2.1",
    "style-loader": "^0.13.1",
    "webpack": "^1.14.0"
  }
}

webpack.config.json を書く

次に、webpackの設定ファイルwebpack.config.jsonを書いていきます。

# webpack.config.json
const autoprefixer = require('autoprefixer');

module.exports = {
  entry: {
    entry: ['./js/entry.js'],
  },

  output: {
    path: './dist/',
    filename: "js/[name].js"
  },

  module: {
    loaders: [
      {
        test: /\.js?$/,
          loader: 'babel'
      }, {
        test: /\.css$/,
        loader: "style-loader!css-loader!postcss-loader"
      }
    ]
  },

  babel: {
    presets: ['es2015'],
  },

  postcss: [
    require('autoprefixer')
  ]
};

意味はそれぞれ、

  • entry

webpackで処理される対象のjsを記載します。

  • output

処理されたjsの書き出される場所、ファイル名を記載します。

  • modules

どのような処理を行うかを記載します。

  • babel、postcss

プラグインを利用する場合、プラグインの利用に必要なプラグインやプリセットなどを記載します。

postCSS処理対象のファイルと読み込むHTMLを準備する

PostCSSでCSSコンパイルするためには、jsファイルから対象のcssファイルをimportする必要があります。

htmlからコンパイルされたjsを読み込むと、ヘッダーに自動的に差し込んでくれるようになっています。

次の構成で準備します。

.
├── css
│   └── sample.css ①
├── js
│   └── entry.js ②
├── index.html ③
├── node_modules
└── webpack.config.js

① 処理対象のcssファイルを作成します。

/* ./css/sample.css */
:fullscreen a {
    display: flex
}

cssをインポートするjsファイルを作成します。

# ./js/entry.js
import '../css/sample.css'

③ 書き出されたjsを読み込むhtmlファイルを作成します。

<!— index.html —>
<!DOCTYPE html>
<html lang="ja">
  <head><title>タイトルだよ</title></head>
  <body>ボディだよ</body>
  <script src="dist/js/entry.js"></script>
</html>

webpack を実行する

必要なファイルが揃ったので、webpackを実行します。

$ npm run webpack

distディレクトリができ、中にentry.jsができます。

.
├── dist
│   └── js
│       └── entry.js  ←生成されたjs
├── css
│   └── sample.css
├── js
│   └── entry.js
├── index.html
├── node_modules
└── webpack.config.js

ブラウザで確認すると、コンパイルされたcssのコードが head に挿入されているのが確認できます。

f:id:y_kashiwaya:20170113151956p:plain

PostCSSでコンパイルしたcssファイルを別に保存する

えっ、headerに書き出されても…というあなた。

postCSSで処理したcssファイルを書き出すのには別に extract-text-webpack-plugin というプラグインが必要となります。

extract-text-webpack-plugin のインストール

npm install extract-text-webpack-plugin —save-dev

また、webpack.config.js を次の通り書き直します。

const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  entry: {
    entry: ['./js/entry.js'],
  },

  output: {
    path: './dist/',
    filename: "js/[name].js"
  },

  module: {
    loaders: [
      {
        test: /\.js?$/,
          loader: 'babel'
      }, {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader')
      }
    ]
  },

  babel: {
    presets: ['es2015'],
  },

  postcss: [
    require('autoprefixer')
  ],

  plugins: [
    new ExtractTextPlugin('./css/sample.css'),
  ]
};

再度、npm run webpackを実行すると、dist下にcssができています。

.
├── dist
│   ├── css
│   │   └── sample.css  ← 生成されたcss
│   └── js
│       └── entry.js
├── css
│   └── sample.css
├── js
│   └── entry.js
├── index.html
├── node_modules
└── webpack.config.js

書き出されたcssの中身を確認すると、ベンダープレフィックスが付与されたファイルが書き出されます。

:-webkit-full-screen a {
    display: -webkit-box;
    display: flex
}
:-moz-full-screen a {
    display: flex
}
:-ms-fullscreen a {
    display: -ms-flexbox;
    display: flex
}
:fullscreen a {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex
}

ちなみに、cssが書き出される場所は、js同様、webpack.config.jsonのoutputのpathを参照します。

この例では、pathに./dist/の指定があり、ExtractTextPluginで ./css/sample.css を指定したため、./dist/の下の css/sample.css に書き出されました。

まとめ

gulpやgruntなどのタスクランナーと違って、webpackは基本的にjsのモジュールバンドラーだということを失念しており、実装に無駄に時間がかかったのはいい思い出です。

postCSSのプラグインは公式で検索できます。

postcss.parts

カテゴリだけで17個もあります。

いろいろ試して、コーディングしやすい環境ができるといいですね!