Webpack4でReactの環境構築。Create react appを使わずにReactアプリを作る。-2 -CSS, Sass, ESLint -

Tatsuya Asami
13 min readFeb 12, 2019

--

【所要時間】

7時間(2019年2月12日)

【概要】

参考リンク

【要約・学んだこと】

ReactにCSSを適用する方法

手順として

  1. CSSをJavaScriptで読み込めるようにする。
  2. CSSデータをHTMLで読み込めるようにする。

があるようだ。1はみんなcss-loaderを使っているようなのでcss-loaderを使う。

2は参考リンク含めて色々みたところ、下記の2通りのやり方があるようだ。

  • styele-loader:
    DOMにCSSを<style>タグを使って挿入する。
  • mini-css-extract-plugin:
    CSSを別のファイルに抽出する。CSSを持つJSファイルごとにCSSファイルを作成し、CSSとSourceMapsのオンデマンドローディングをサポートする。

注意点は、参考リンクではextract-text-webpack-pluginが紹介されているが、ドキュメントによるとwebpack4ではmini-css-extract-pluginに変わった点。

どちらも一長一短らしいがよくわからないが、css-loaderのドキュメントがStyle-loaderだったので、こちらを使う。

その前にcssファイルの作成と、app.jsへのcssファイルの取り込みを行う。(app.jsのcomponent名がIndexとなっていたが、Appに変更。ファイル名と一致させた。)

// src/components/app.jsimport React from 'react';
import { hot } from 'react-hot-loader'
import Test from './test';
import Counter from './counter';
import styles from './app.css';
const App = (props) => (
<div className={styles.app}>
<Counter />
<Test />
<h2>これはh2</h2>
<p>ここはIndex</p>
<p>ここはIndex</p>
<p>{props.text}</p>
</div>
);
export default hot(module)(App);

cssファイルの作成

// src/components/app.css.app {
color: blue;
}
p {
background-color: blue;
color: white;
}
.app h2 {
color: brown;
}

css-loader, style-loaderのインストールと設定

yarn add -D css-loader style-loader

webpack.config.jsの設定。まずはオプションなどをせずにcssが適用できるかを確認。このstyle-loaderとcss-loaderの順番は重要。後半にあるものから処理されるらしく、逆にするとうまくいかない。

// webpack.config.js...module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
{
loader: "style-loader"
},
{
loader: "css-loader",
}
]
}
]
},
...

最低限の設定をしたらyarn buildで確認。

ローカルに保存されているindex.htmlの画面

スタイルが適用された。しかしクラス指定した部分がうまく適用されていない。

  • css-loaderの設定

optionsの設定

  • modules: これをtrueにすることによりcss Modulesとセットアップモードを可能にする。今回はstyles.appの記述法が適用された。
  • localIndentName: 生成されるclassの名前を決める。初期だとよくわからないので、わかりやすく[name]_[local]_[hash:base64]にした。

これで狙い通りに表示された。

現在webpack.config.jsは下記のようになっている。

const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path');
const webpack = require('webpack');
const htmlPlugin = new HtmlWebpackPlugin({
template: "./public/index.html",
filename: "./index.html"
});
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
options: {
modules: true,
localIdentName: "[name]_[local]_[hash:base64]",
}

}
]
}
]
},
performance: {
hints: false
},
plugins: [
htmlPlugin,
new webpack.HotModuleReplacementPlugin(),
]
};

sass-loaderの設定

実際は.scss形式でcssを適用する事が多くあると思うので、こちらも設定する。名前的にcss-loaderの仲間っぽいsass-loaderを使う。

yarn add -D sass-loader node-sass

Node Sassか Dart Sassというものも合わせて必要らしい。ここではnode-sassを使う。

まずはwebpack.config.jsの設定

...module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.(css|scss)$/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
options: {
modules: true,
localIdentName: "[name]_[local]_[hash:base64]",
}
},
{
loader:"sass-loader",
}

]
}
]
},
...

続いてscssファイルの作成

// src/_styles.scss@mixin button {
button {
padding-left: 5px;
padding-top: 5px;
height: 30px;
width: 20%;
}
}
$brown: rgb(180, 81, 81);

もう一つ。_styles.scssで作ったmixinをインポートする。また、入れ子でスタイルを指定する。これらはcssにはない機能。

@import '../styles';.app {
color: red;
p {
background-color: yellow;
color: red;
}
h2 {
color:$brown;
}
@include button;
}

これをapp.jsにインポートする。

import React from 'react';
import { hot } from 'react-hot-loader'
import Test from './test';
import Counter from './counter';
import styles from './appScss.scss';
const App = (props) => (
<div className={styles.app}>
<Counter />
<Test />
<h2>これはh2</h2>
<p>ここはIndex</p>
<p>ここはIndex</p>
<p>{props.text}</p>
</div>
);
export default hot(module)(App);

セーブするとこれらのscssファイルが画面に適用された。

今のところオプションで指定が必要な部分もなさそうなので、特に指定しない。

ESLintの設定

思えば最初にやるべきだった。

これもdependenciesが多いからややこしい。とりあえず今回作っているReactアプリの構文チェックを行うようにする。設定はまだ自分のやり方みたいなのはないので、air-bnb-styleに従う。

※ここはハマりポイントで、./node_modules/.bin/eslint --init でuse-popular-styleを設定すると、./node_modules/.bin/eslint src を実行する際にファイルやディレクトリが見つからないというエラーになる。なんでかはわからないけど昔もなった記憶がある。

まずは必要なdependenciesをインストール

yarn add -D eslint eslint-plugin-react eslint-config-airbnb

そして実行すると

./node_modules/.bin/eslint src

色々なdependenciesが足りないとエラーが出るので、インストール。

yarn add -D eslint-plugin-import eslint-plugin-jsx-a11y

そして改めて実行すると、スタイルチェックされているのがわかる。

自動で作成された.eslintrc.jsはこのようになっている。

.eslintrc.jsmodule.exports = {
“extends”: “airbnb”
};

proptypesを入れたり今エラーを修正するのは色々面倒(本来従うべき)なので、とりあえずreactの標準の設定に戻す。

"extends": [
"eslint:recommended",
"plugin:react/recommended"
]

今はimportがreservedされているという警告が出ているので、これを消す。

yarn add -D babel-eslint

これを.eslintrc.jsのparserに追加するとimportの警告は消えるが、documentとmoduleが定義されてないと出てくるので、.eslintrc.jsのglobal変数に追加する。

module.exports = {
// "extends": "airbnb"
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"parser": "babel-eslint",
"globals": {
"module": true,
"document": true,
}

};

これでエラーが消えた。

【わからなかったこと】

  • css-loaderと同じような設定がstyle-loaderにあったが、違いがよくわからなかった。とりあえず機能しているので気にしない。

yarn buildすると

<script type=”text/javascript” src=”bundle.js”></script>

これが何度も追加されていく。これはbundleする際の設定変更で修正出来そうだが、疲れたのでまた今度確認。

【感想】

css-loader, style-loaderのインストールがなぜかうまく機能しなかった。(node_modulesとyarn.lockを消してインストールしたらうまくいった。)

今回もブラックボックスはかなりあるが、とりあえず機能するところまでいったのでよかった。

これでプロダクトを作る際に必要最低限な機能の環境構築はできたと思う。次回はprettierの設定等を追加して行きたい。

--

--

Tatsuya Asami
Tatsuya Asami

Written by Tatsuya Asami

Front end engineer. React, TypeScript, Three.js

No responses yet