create-react-appを使わないReact+PCSS

create-react-appを使うと内部でWebpackやらが勝手に設定されているので、 SASS(scss)やpostcss等のCSS用のフレームワークが適用しづらくなります。

Material-UI等のReact用に構築されたCSSライブラリを使うのがデファクトスタンダードです。

導入できなくはないのですが、構築しているところを書き換えないといけないので 初心者にはハードルが高く、弄ってしまうと他が動かなくなる可能性があるのでむやみにいじることができません。

CSSぐらい自由にいじらせてくれ!

それなら脱create-react-appをして好きなように組めるようにした方が、 余計な機能も無く知識も増えて独自のCSSも実装しやすくなるので今すぐcreate-react-appを捨てましょう!

もちろん、簡易なものを作って見た目はそこそこでいいというのであれば 使った方が効率が良いのですが、CSSのオリジナリティを出したい場合はやっぱり捨てましょう。

第二回目はPOSTCSSの導入です。

yarnコマンドでコンパイルしてcssに変換するところまでやってみましょう。

post-cssのインストール

早速postcss関連をインストールしてきましょう。

yarn add -D postcss-cli postcss-import postcss-nested postcss-mixins postcss-url
yarn add -D postcss-cssnext postcss-simple-vars postcss-color-function postcss-calc

長いので2回に分けました。

1回でまとめてインストールしても大丈夫です。

インストールしたライブラリそれぞれの役割を軽く見ていきましょう。

postcss-cli

postcssの本体。

これが無いと始まりませんので必須です。

postcss-import

postcssにimport機能を付けるプラグイン

無くても動きますが、無いと1つのcssにまとめないといけないので必須。

postcss-nested

postcssにネスト(入れ子記述)機能を付けるプラグイン

無くても動きますが、無いとSASS(scss)の方が良いわってなるのでこれも必須。

postcss-mixins

postcssにmixin(記述したCSS一覧を1つにして呼び出す機能)機能を付けるプラグイン

無くても動きますが、無いとこれもSASS(scss)の方が良いわってなるのでこれも必須。

postcss-url

postcssにurlを解決する機能を付けるプラグイン

無いと画像を呼び出したりできないのでやっぱり必須

postcss-cssnext

次世代cssを扱えるようにするプラグイン

これは無くても大丈夫ですが策定中の機能が使えたりするのでお好みでどうぞ。

css版babelですね。

postcss-simple-vars

postcssに変数機能を追加するプラグイン

無くても変数は使えたはずですが、SASSから乗り換えるときに困惑するので あった方が名前通りシンプルに扱えるので個人的には必須

postcss-color-function

postcssにカラーを登録して呼び出せる機能を追加するプラグイン

SASSだとデフォルトでついているので無いと不便なので導入。

postcss-calc

postcssに数値計算機能を入れるプラグイン

無くても大丈夫ですがあると便利。

他にもいろいろなプラグインがあるので「postcss プラグイン」でググってみて 自分の好みのpostcssを構築してみてください。

……これらを見ると特別な機能を使うことってあまりないのでSASS(scss)で良くない?ってなりますよね。

私もなりました。

ですが脳死で使っていては成長しないですし、みんながやってることをやってもつまらなく無いですか?

仕事であれば効率優先だとは思いますが個人でやるなら色々挑戦してみてはどうでしょうか。

postcssはcssの進化に合わせて作られているそうです。

SASSの開発者が開発をやめる確率が0ではないので、なるべくいろんなことができるようになっている方が望ましいです。

postcssの設定

インストールが終わったらpostcssの設定をしていきましょう。

これもwebpackやtypescriptみたいにコンフィグファイルが必要になります。

postcss.config.jsをルートに作成して以下を記述してください。

module.exports = {
  map: {
    inline: false
  },
  plugins: {
    "postcss-import": {},
    "postcss-nested": {},
    "postcss-mixins": {},
    "postcss-url": {},
    "postcss-cssnext": {},
    "postcss-simple-vars": {},
    "postcss-color-function": {},
    "postcss-calc": {},
  }
};

先程入れたプラグインの設定ですね。

プラグインを読み込む順番に気を付けてください。

恐らくこれで問題ないと思うのですが、mixinを先に読み込むとnestedが扱えず 吐き出されるcssがnestされたままになって実際に使うcssが動かなくなります。

もしプラグインが正常に働いてないと感じたらプラグインの並び順を変えたりすると解決します。

postcss自体の設定はこれだけです。

そこまで難しくはないですね。

post-cssのコンパイル

postcssはいわゆるコンパイル前のものになります。

そのままではcssとして使えないのでコンパイルする必要がありますね。

コンパイルというよりもトランスパイルになるのですかねこの場合……

webpack側で動かせるようにしてみます。

以下のローダーをインストールしてください。

yarn add -D style-loader css-loader postcss-loader

webpackで何かを扱うときはこの何とかloader系が必要になります。

前回TypeScriptを扱うときにts-loaderをインストールしたと思うので、あれもwecpack用でしたね。

それではwebpack.config.jsをに追記しましょう。

// pathモジュールの読み込み
const path = require("path");

module.exports = {
  // モードを開発モードにする
  mode: "development",
  // 入力ファイル設定
  entry: [path.resolve(__dirname, "./src/index.tsx")],
  // 出力ファイル設定
  output: {
    // 出力されるファイル名
    filename: "bundle.js",
    // 出力先ディレクトリ
    path: path.resolve(__dirname, "dist")
  },

  // モジュール設定
  module: {
    rules: [
      {
        // ts-loaderの設定
        test: /\.(js|ts|tsx)?$/,
        use: "ts-loader",
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader'
        ]
      }
    ]
  },
  // モジュール解決
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".json"]
  },

  // 開発モード設定
  devtool: "source-map",
  devServer: {
    contentBase: "./dist"
  }
};

webpackにpostcssを解決する処理を記述したら、package.jsonにコンパイルコマンドを記述します。

{
  "name": "pure_react",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "webpack-dev-server --open",
    "build": "webpack",
    "build-prod": "webpack --mode=production",
    "compile-pcss": "postcss src/pcss/style.css --base --map --output dist/css/style.min.css"
  },
  "dependencies": {
    "react": "^16.12.0",
    "react-dom": "^16.12.0"
  },
  "devDependencies": {
    "@types/node": "^13.1.4",
    "@types/react": "^16.9.17",
    "@types/react-dom": "^16.9.4",
    "css-loader": "^3.4.1",
    "postcss-calc": "^7.0.1",
    "postcss-cli": "^7.0.0",
    "postcss-color-function": "^4.1.0",
    "postcss-cssnext": "^3.1.0",
    "postcss-import": "^12.0.1",
    "postcss-loader": "^3.0.0",
    "postcss-mixins": "^6.2.3",
    "postcss-nested": "^4.2.1",
    "postcss-simple-vars": "^5.0.2",
    "postcss-url": "^8.0.0",
    "style-loader": "^1.1.2",
    "ts-loader": "^6.2.1",
    "typescript": "^3.7.4",
    "webpack": "^4.41.5",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.10.1"
  }
}

現時点での最新package.jsonです。

次にコンパイル対象となるCSSを作りましょう。

package.jsonでは

入力:src/pcss/style.css

出力:dist/css/style.min.css

としました。

入力の元となるファイルを作りましょう。

:root {
  --main_color: #186689;
  --accent_color: #00bcd4;
}

h1 {
  color: var(--main_color);
}

「:root」はカラーをまとめて変数に格納して宣言しています。

使用方法は「var(変数名)」となります。

SASS(scss)では「$~」とやってたと思いますがpostcssではこのように記述するので気を付けましょう。

プラグイン次第では同じように「$~」と書けるようになるものもありますが、 それだとSASSでいいわってなるのであえて使いません。

とりあえずh1のカラーを変えました。

これで以下のコマンドを実行してください。

yarn run compile-pcss

コンソールにDone in ~~s.と出たらコンパイル完了です。

エラーの場合は該当のエラーを解決してください。

出力後のcssはこんな感じになっています。

h1 {
  color: #186689;
}

/*# sourceMappingURL=style.min.css.map */

ちゃんと変数が置き換わってますね。

これを読み込むためにhtmlにcss読み込みの追記をしましょう。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/style.min.css.map">
    <title>pure-react</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="bundle.js"></script>
  </body>
</html>

linkタグを導入しました。

これで読み込めるようになっているはずです。

仮想サーバーを立ち上げてみましょう。

yarn start

良い感じに文字の色が変わってくれました!

後は仮想サーバー起動時にpostcssファイル保存時にpcssを自動コンパイルさせて リロードするといった形を取れれば完璧ですね。

postcssの不満点

次世代cssを使えるし今後SASSから乗り換える人が増えてくると思うので これといった不満点はないのですがやはりSASSと比べると少し面倒くさい感はあります。

他にも拡張子がcssのままなので(.pcssでも動くことは動く)エディタ側をちゃんと設定しないと混乱して cssとして認識するため使用できない記述をエラー扱いしてしまいます。

vscodeであればpostcssのプラグインを入れると解決してくれますが、 出来れば.pcss拡張子統一にしといて欲しかったですね。

現状はpostcss単体でコンパイルしていて自動コンパイルをしてくれないので、 監視するためにタスクランナーが必要になります。

通常ならpostcssにも対応しているGulpを使うかと思うのですが、 そろそろ脱Gulpしたいと思いませんか?思ってください。

Gulpもいつ更新が停止するかもわかりませんし、バージョンが上がったらまた覚えなおしで プラグインのバージョンアップを待たないといけないとなったら面倒なので脱Gulpをします。

npm-scriptsであればよほどのことが無い限り使えなくなるということはないので、 タスクランナーを使わずnpm-scriptsで対応していきます。

それでは!