LoginSignup
18
16

More than 3 years have passed since last update.

PostCSSをwebpackでサクッと動かせるサンプル

Last updated at Posted at 2019-02-24

間違っているなどありましたらご指摘お願いいたします:bow:

参考

確認バージョン

  • webpack 4

最小限で動かす

参考:michael-ciniawsky/postcss-load-config: Autoload Config for PostCSS

サンプルはこちら

bash
npm init -y
npm i -D webpack webpack-cli style-loader css-loader postcss-loader postcss-nested
./webpack.config.js
module.exports = {
    mode: 'development',
    module: {
        rules: [{
            test: /\.pcss/,
            use: [
                'style-loader',
                'css-loader',
                {
                    loader: 'postcss-loader',
                    options: { plugins: [ require('postcss-nested') ] },
                },
            ],
        }]
    }
};

loaderはuse: []の配列の下から順に適用されていきます。

今回の例では、.pcss ファイルに対して、

  1. postcss-loader がプラグインを使用して、cssでネストした書き方をプレーンなcssに変換
  2. css-loader でcssをjsにバンドルする機能
  3. style-loader<head> の最後尾に <style> を追加する機能

という順で適用されていきます

./src/index.js
import './style.pcss';
./src/style.pcss
p {
    color: seagreen;
    span {
        color: deepskyblue;
    }
}
./index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="dist/main.js"></script>
</head>
<body>
    <p>Heloo <span>World!</span></p>
</body>
</html>
bash
npx webpack

PostCSSを使ってcssをネストして書くことができました

image.png

PostCSSの設定を別ファイルにする

サンプルはこちら

bash
npm init -y
npm i -D webpack webpack-cli style-loader css-loader postcss-loader postcss-nested

.postcssrc.json

./webpack.config.js
module.exports = {
    mode: 'development',
    module: {
        rules: [{
            test: /\.pcss/,
            use: ['style-loader', 'css-loader', 'postcss-loader'],
        }]
    }
};
./.postcssrc.json
{
    "plugins": {
        "postcss-nested": {}
    }
}
bash
npx webpack

先ほどと同じように実行されることが確認できました。

image.png

.postcssrc.yml

yamlで記述することもできます

.postcssrc.yml
plugins:
  postcss-nested: {}

.postcssrc.js or postcss.config.js

設定ファイル内にロジックが必要な場合はこちらで記述する

この例ではロジックはないですが、以下のようにするとjsonやyamlの設定ファイルと同じように動かすことができました

.postcssrc.js
module.exports = {
    plugins: {
        'postcss-nested': {}
    }
};
postcss.config.js
module.exports = {
    plugins: {
        'postcss-nested': {}
    }
};

cssファイルにする

サンプルはこちら

jsにcssをバンドルするという方法でやってきましたが、
最終的にcssファイルを出力し、htmlからlinkタグでcssを取得する方法でやってみます

参考

bash
npm init -y
npm i -D webpack webpack-cli css-loader postcss-loader postcss-nested extract-text-webpack-plugin@next

↑ webpack 4だと、extract-text-webpack-plugin だとうまく動かないため、 extract-text-webpack-plugin@next をインストールするようにしましょう ※2019/02/23現在

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

module.exports = {
    mode: 'development',
    entry: './src/style.pcss',
    output: {
        path: `${__dirname}/dist`,
        filename: '[name].css', // 生成するjsファイル名
    },
    module: {
        rules: [{
            test: /\.pcss/,
            use: ExtractTextPlugin.extract({
                use: [
                    'css-loader',
                    {
                        loader: 'postcss-loader',
                        options: { plugins: [ require('postcss-nested') ] },
                    },
                ]
            }),
        }]
    },
    plugins: [
        new ExtractTextPlugin('[name].css'), // cssファイルを生成されたjsファイルと同じ名前にし上書きする -> cssファイルのみ出力という結果になる
    ],
};
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="dist/main.css">
</head>
<body>
    <p>Heloo <span>World!</span> from css file</p>
</body>
</html>

cssファイルを出力しhtmlから読み込むことができました

image.png

ソースマップを有効にする

サンプルはこちら

bash
npm init -y
npm i -D webpack webpack-cli style-loader css-loader postcss-loader postcss-nested
./webpack.config.js
module.exports = {
    mode: 'development',
    module: {
        rules: [{
            test: /\.pcss/,
            use: [
                'style-loader',
                {
                    loader: 'css-loader',
                    options: {
                        sourceMap: true,
                    }
                },
                {
                    loader: 'postcss-loader',
                    options: { 
                        sourceMap: true,
                        plugins: [ require('postcss-nested') ] 
                    },
                },
            ],
        }]
    }
};

ソースマップが有効になりました

image.png

sassと併用する

サンプルはこちら

bash
npm init -y
npm i -D webpack webpack-cli style-loader css-loader postcss-loader autoprefixer sass-loader node-sass 
./webpack.config.js
module.exports = {
    mode: 'development',
    module: {
        rules: [{
            test: /\.scss/,
            use: [
                'style-loader',
                'css-loader',
                {
                    loader: 'postcss-loader',
                    options: { plugins: [ require('autoprefixer') ] },
                },
                'sass-loader',
            ],
        }]
    }
};
./src/style.scss
body {
    background: yellowgreen;
    div {
        transform: scale(.7);
    }
}
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="dist/main.js"></script>
</head>
<body>
    <div>BOX</div>
</body>
</html>

scssとpostcssからのautoprefixerを併用できました

image.png

css-loader@import を使う際の注意点

@importの動作を確認

  • まずcss-loaderなどを使わない状態の@importの動作を確認
sample.css
@import "import.css";

p {
    font-weight: bold;
}
import.css
body {
    background: yellowgreen;
}

sample.cssとimport.cssで2回通信が発生しています

image.png

  • 次にcss-loaderを使った場合の@importの動作を確認
bash
npm init -y
npm i -D webpack webpack-cli style-loader css-loader postcss-loader postcss-nested
./webpack.config.js
module.exports = {
    mode: 'development',
    module: {
        rules: [{
            test: /\.css/,
            use: ['style-loader', 'css-loader'],
        }]
    }
};
./src/index.js
import './sample.css';
./src/sample.css
@import "import.css";

p {
    font-weight: bold;
}
./src/import.css
body {
    background: yellowgreen;
}
bash
npx webpack

通信は、./dist/main.jsを取得する1回だけとなり、<style>タグが2つ追加されるという動きになります

image.png

  • この@importをpostcssと使うときにデフォルトだとうまくいきません
./webpack.config.js
module.exports = {
    mode: 'development',
    module: {
        rules: [{
            test: /\.pcss/,
            use: [
                'style-loader',
                'css-loader',
                {
                    loader: 'postcss-loader',
                    options: { plugins: [require('postcss-nested')] },
                },
            ],
        }]
    }
};
./src/index.js
import './sample.pcss';
./src/sample.pcss
@import "import.pcss";

div {
    h1 {
        color: green;
    }
}
./src/import.pcss
div {
    h2 {
        color: red;
    }
}
bash
npx webpack

image.png

このように、postcss-nestedsample.pcssには適用されますが、import.pcssには適用されていません。
プレーンなcssの構文としては間違っているため、h2のcolor:red;も反映されていません。


importLoadersを設定するとうまくいく

./webpack.config.js
module.exports = {
    mode: 'development',
    module: {
        rules: [{
            test: /\.pcss/,
            use: [
                'style-loader',
                {
                    loader: 'css-loader',
                    options: {
                        importLoaders: 1, // importするときに適用するloaderの数を設定、sassとpostcssを使っていた場合は「2」と設定する
                    },
                },
                {
                    loader: 'postcss-loader',
                    options: { plugins: [require('postcss-nested')] },
                },
            ],
        }]
    }
};
bash
npx webpack

image.png

@importで取得した内容にも、postcss-loaderが適用されたことが確認できました。

サンプルはこちら

参考:Clarify importLoaders documentation? · Issue #228 · webpack-contrib/css-loader

postcss-importを使っても良い

postcss-importを使ってimportすることでも、↑の問題を回避することができるようでした

bash
npm init -y
npm i -D webpack webpack-cli style-loader css-loader postcss-loader postcss-nested postcss-import
./webpack.config.js
module.exports = {
    mode: 'development',
    module: {
        rules: [{
            test: /\.pcss/,
            use: [
                'style-loader',
                'css-loader',
                {
                    loader: 'postcss-loader',
                    options: { plugins: [
                        require('postcss-import'),
                        require('postcss-nested'), 
                    ]},
                },
            ],
        }]
    }
};

image.png

サンプルはこちら


最後まで読んでいただいてありがとうございましたm(_ _)m

18
16
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
18
16