その1
https://qiita.com/DaisukeNishi/items/dae74d5dcf5ddb171b3d
その2
https://qiita.com/DaisukeNishi/items/e93a3448668f65df7a91
その3
https://qiita.com/DaisukeNishi/items/697fb3579d7dd69324b3
その4
https://qiita.com/DaisukeNishi/items/801e1b1e02487e26e905
その6
https://qiita.com/DaisukeNishi/items/c8982546c803d2c5dc99
※これは5回目にあたります。
##create-react-app+pug+stylus簡単→そんな事なかった。
最初からjsx
なんて書かない!俺はpug
で全てやるんだと意気込んだが、
pug
についての結論は、
逆にトランスパイル後のjsx
の姿を想像できてないとツライだろうと思った。
なので、ある程度jsx
の達人になってからpug
でラクに見通せるようにする方が、
学習の順序としては近道だろう。
CSS-Modules
についてすっごい調べたけど、stylus-loader
のコンフィグを
eject
しないでやろうとするとcustomize-cra
にメソッドがなくて非公式プラグイン使ったり
react-dev-utils
に書いてある処理やextensions
の書き換えの所で
ハマるので、そっち方面で進めるのは、やめたほうが良いと思う。
stylus
についてでた結論は、普通にstyled-jsx
使ったほうがラクだと思った。
Keita Ishibashi(usagi-f)さんもstyled-jsx
をオススメしてたし。
Githubのスターもそっちの方が多いし、ネットで解決案を探しやすい。
##目的
###で、この記事の目的とは?
・React
を使いたい。
・yarn eject
する選択肢はない。
・とにかくpug
とstylus
を使いたい。
それを、なんとかする記事です・・まぁ最初はなんとかなるんですよ。
「わーい、書けた書けた〜♪このまま行ける!」って思ったんですけど、
下記のやりかたを突き詰めていくと、結局hash
されたCSS
にしたいなと思ったら
むしろyarn eject
した方がラクだし、pug
のメリットを捨てなければいかんと思う。
なので今回この記事は、失敗を糧にしてもらう、というのと
CSS-Modules
...?そんなものは知らんなぁ...という感じです。
##下準備
###必要なプラグインを揃える
babel-plugin-〇〇
のいくつかのプラグインには
devDependency
にしておくと動かないものがあるので-D
を付けない事にしています(言い訳)
$ npm install -g create-react-app
$ create-react-app {yourProject}
$ cd {yourProject}
//基本セットと、「○○-loader」などを追加する
$ yarn add sass node-sass stylus pug
$ yarn add stylus-loader extract-text-webpack-plugin pug-loader json-loader
//babel系プラグインを追加する
$ yarn add babel-plugin-transform-react-pug
$ yarn add babel-plugin-transform-react-jsx
//(追記)→styled-jsxを使った方がいい。引き返すなら今ですよー!
$ yarn add styled-jsx
$ yarn add styled-jsx-plugin-stylus
//下記プラグインを使うと遠回りな気がする
$ yarn add babel-plugin-transform-jsx-css-modules
$ yarn add babel-plugin-react-pug-classnames
$ yarn add babel-plugin-react-css-modules
//eslint系プラグインを追加する
$ yarn add eslint-plugin-react-pug eslint-plugin-css-modules
//※overrideツールを追加する
$ yarn add react-app-rewired customize-cra customize-cra-add-stylus-loader
$ touch .eslintrc
$ touch .babelrc
###react-scriptsを取り出す
「いきなり何を言ってるんだ?結局直にwebpack.config.js
いじってるじゃん!」
と思うかもですが、直にいじるデメリットを軽減する方法を紹介しますのでご勘弁を。
react-script
をホームディレクトリに複製し名前を(例:react-scripts-pug-stylus
)とします。
適当で良いですが、公式パッケージや他のプロジェクトと混乱しない名前がよいです。
$ cp -r ./node_modules/react-scripts ../react-scripts-pug-stylus
$ cd ../react-scripts-pug-stylus
$ open ./config/webpack.config.js
css-loader
やsass-loader
は
create-react-app
した時にデフォで用意されますが
そのままではstylus
が読み込めないので、stylus-loader
を追加していきます。
//(50行目あたり)
const sassRegex = /\.(scss|sass)$/;
const stylRegex = /\.(styl)$/; //←追加
const sassModuleRegex = /\.module\.(scss|sass)$/;
const stylModuleRegex = /\.module\.(styl)$/; //←追加
sassの設定をコピーします。
//(500行目あたり)
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'sass-loader'
),
sideEffects: true,
},
//ここから下に追記をします。
{
test: stylRegex,
exclude: stylModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'stylus-loader'
),
sideEffects: true,
},
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
},
//下に追加
{
test: stylModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'stylus-loader'
),
},
あとは、ファイル拡張子のextensions
に.styl
を追加する。
別ファイルを参照するようになっています。
//(300行目あたり)
extensions: paths.moduleFileExtensions
path
って何?と思ったら、同じ階層に置いてあるpath.js
です。
const moduleFileExtensions = [
'web.mjs',
'mjs',
'web.js',
'js',
'web.ts',
'ts',
'web.tsx',
'tsx',
'json',
'web.jsx',
'jsx',
'styl' //←追加する
];
色々とプラグインを見てみたけど、これのスマートな代替策がない気がする。
純粋な.styl
じゃなくても.jsx
にした方が良いんじゃないかと後で思ったんですが、
それだと既存の資産を使えないので、、、このまま説明つづきます。
###.eslintrcを有効に
customize-cra
でも書き換えできるのですが、
どうせ今webpack.config.js
を書き換えてるんだし、もうここで書き換えちゃいます。
//(370行目あたり)
useEslintrc: false, //←trueにする
ちなみにcustomize-cra
でやるなら
const { override,useEslintRc,disableEsLint} = require("customize-cra");
module.exports = override(
useEslintRc(".eslintrc"),
//disableEsLint()
);
###.babelrcを有効に
customize-cra
でも書き換えできるのですが、
どうせ今webpack.config.js
を書き換えてるんだし、もうここで書き換えちゃいます。
//(2箇所ある)
babelrc: false, //←trueにする
ちなみにcustomize-cra
でやるなら
const { override,useBabelRc} = require("customize-cra");
module.exports = override(
useBabelRc(".babelrc"),
);
###Githubに上げておく
webpack.config.js
とpath.js
を編集し終わったら、
このreact-scripts-pug-stylus
を、ご自分で管理されているGithub
に上げてください。
(例):https://github.com/daisuke240000/react-scripts-pug-stylus
※他人がカスタムしたreact-scripts
を使っても動かないです。
$ cd ../yourProject
$ yarn remove react-scripts
###名前を変えて読み込む
保存する時には名前を変えたのですが、
オーバーライドツール(react-app-rewired
など)を使用する場合、
元のパッケージの名前がreact-scripts
にしておかないと動かないので、下記のようにします。
プロトコルはgit+ssh://...
と書けるのですが、
開発環境の違いなどを考慮してhttps://
の方が無難です。
(SourceTree使ってる人はsshでgitに接続しないため)
※下記の.json(.js)はシンタックスのハイライトのために付けているだけです。
"react-scripts": "^3.4.0",// yarn removeで削除される
"react-scripts": "https://github.com/daisuke240000/react-scripts-pug-stylus",
// ↑追記する。パッケージ名を同じ名前にしておかないとオーバーライドできない。
// (中略)
// ↓「npm scripts」をこのように改変します。
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test --env=jsdom",
"eject": "react-app-rewired eject"
},
変更を保存し、package.lock.json
とyarn.lock
を消して
$ yarn
パッケージを集めます。lockファイルが存在していると、書き直した時に見に行ってくれないです。
完了したらインストールされたパッケージ内容を確認。
$ open ./node_modules/react-scripts/config/webpack.config.js
成功ならばstylus-loader
やbabelrc: true
になっています。
もしも更新されていなかったら、設定に失敗してると思いますので見直してください。
該当フォルダを削除し、lockファイルも削除し、package.json
をもう一回確認して$ yarn
です。
###.babelrcを編集
react-pug
のクラス名の付け方に関してはclassName
とstyleName
があります。
CSS Modules
をやりたいので、最終的にはstyleName
を使おうと思うのですが、
「本当にstyleName
で良いんだっけ?」と思ったので、
検証用でスイッチできるよう、両方書いて片方をコメントアウトしておきます。
↓(.js)はシンタックスハイライトのために付けてるだけです。
{
"presets": [
"react-app"
],
"plugins": [
"transform-react-pug",
// ["transform-react-pug",{"classAttribute": "styleName"}], //←あとで使います。
// ["react-pug-classnames", {"classAttribute": "styleName"}],
//["transform-jsx-css-modules", {"pathToStyles": "^\\.\\/module\\.scss$"}],
"transform-react-jsx",
"transform-jsx-css-modules",
"react-css-modules"
]
}
###.eslintrcを編集
$ eslint --init
で作成したものに、
react-pug
とplugin:react-pug/all
を追加するのが無難だと思います。
$ eslint --init
できない?グローバルにインストールした方がいいかもです。
↓(.js)はシンタックスハイライトのために付けてるだけです。
{
"env": {
"es6": true,
"node": true,
"browser": true
},
"parserOptions": {
"ecmaVersion": 6,
"allowImportExportEverywhere": true
},
"plugins": [
"react-pug" //←追加
],
"extends": [
"react-app",
"plugin:react-pug/all" //←追加
],
"rules": {
"import/no-named-as-default": 0
}
}
###config-overrides.jsを編集
上書きしているのに、ダメ押しでreact-app-rewired
を使います。
customize-cra
とcustomize-cra-add-stylus-loader
を使います。
設定ファイルはプロジェクト直下にconfig-overrides.js
を作成します。
$ touch config-overrides.js
$ open config-overrides.js
####webpack設定上書き方法への考察:
#####オーバーライドツール、コレ1本で良いのでは?
babel
やeslint
に関するwebpack.config.js
のオーバーライドツールは
react-app-rewired
だけを使えば良いのでは?と思ったのですが、
.styl
やstylus-loader
を追加するメソッドが、
非公式のプラグインしか見当たらないので、補助的に使う事にしました。
#####むしろreact-app-rewired
は必要ないのでは?
むしろ逆にreact-app-rewired
は、使わなくて良いのではないか?とも思ったのですが、
disableEsLint()
でEslint
を秒でオフにできるのは、とても使い勝手が良いですし、
そもそも.styl
ファイルを読み込む事をやらないんだったら、こっちが王道です。
また、react-scripts
のバージョンが上がるたびに改変リポジトリを作るのも不自由・非効率ですし、
できる事ならreact-app-rewired
とcustomize-cra
にまとめられたらいいなと思っているので、
今回は、両方使ってみる事にしました。
このツールだけで、ほとんどオーバーライドする事が可能ですが、
独自の書き方を調べるのは若干面倒です。また、このやり方でstylus
をよませる関連ネットに例文転がってないので、
誰もやってないような気がします。
特にaddStylusLoader
っていう、個人が作ってる拡張は、ぜんぜん使ってる人いない。
#####customize-cra+add-stylus-loaderを使ってる人が・・2人?
https://github.com/kingyinliang/cra-react/blob/7bb2df8a033732ac22e4c8726da8427378d411f3/config-overrides.js
https://github.com/zhzxang/tft-help/blob/5e5d1a1638fb0797c747227b8a08843c374025d2/config-overrides.js
世界で2人だけって・・何か、別のやり方があるんだろうと思います。
const { override,
//addBabelPlugins,
//useBabelRc,
//useEslintRc,
disableEsLint
} = require("customize-cra");
const addStylusLoader = require('customize-cra-add-stylus-loader');
module.exports = override(
//...addBabelPlugins( //←使うと、babelのプラグインを追加できます。
// "babel-plugin-transform-react-pug",
// ["babel-plugin-transform-react-pug",{"classAttribute": "styleName"}],
// ["react-pug-classnames", {"classAttribute": "styleName"}],
// "babel-plugin-react-css-modules",
// "babel-plugin-transform-react-jsx"
//),
//useBabelRc(".babelrc"),
//useEslintRc(".eslintrc"), //←使うと.eslintrcが有効になります。
//addStylusLoader( //←使うとstylus-loaderの設定できるようです。※ネットに例文がない
//{
//}
//),
disableEsLint() //←.eslintをオフにします。
);
##表示される部分を編集
###css、scss、stylは正しく読み込まれているのか検証する
複製したり変換したりして、App.cssを色々な形に変換しておく。
####検証時にハイフンがめんどうになる問題
class名にハイフン使えないって、
まったく「ナンノコッチャ」だとは思いますが・・
本番で使わないけど、検証の途中でdiv(className=App-header)
という風な、ちょっとpug
らしくない書き方をした場合に、
ハイフン(-)が別の意味になってしまいます。
それで変につまづかないように、
ここでは、あらかじめハイフン(-)を何か他の書き方にしておきます。
※普通はclass名はハイフン推奨です。
※pugでハイフンを使うとバグる(引き算としての処理になる)ので
むしろdiv(className=A-B)
みたいな書き方は絶対できません。
//(※以下、抜粋です)
//<header className="App-header">
<header className="AppHeader">
//<img src={logo} className="App-logo" alt="logo" />
<img src={logo} className="AppLogo" alt="logo" />
//<a className="App-link" >
<a className="AppLink" >
/*App-logo {...}*/
.AppLogo {...}
/*App-header {...}*/
.AppHeader {...}
/*App-link {...}*/
.AppLink {...}
create-react-app
の公式のドキュメントには
「もしCSS Modules
を使うなら、ファイル名を○○.module.css
にしなさい。」
と書いてある。(もうね、いろんな人がいろんな仕様いうからこんがらがってしまう)
$ cp App.css App.scss
$ cp App.css App.styl
$ cp App.css App.module.styl
scss
もstylus
も、変換して中身を変えなくても動くはずです。
(※もしsugarss
で解析できなかったら、正しいstylus
の文法に書き換えてください)
App.js
で、一個ずつコメントアウトをはずしながら確認を行なう。
import React from 'react';
import logo from './logo.svg';
// 原型
import './App.css';
// import './App.scss';
// import './App.styl';
// import styles from App.module.styl
html
にあたる部分はpug
に置き換えますが、
pug
をトランスパイルする前に間違っているのか、
pug
にトランスパイルした後に間違っているのか、
ESLint
の設定ミスなのか、最初は分からないので、
$yarn start
でサーブしながらチェックしていきます。
あと、ここでdisableEsLint()
をしておく方が問題の切り分けはできるかもです。
###初期状態
まずは、クラス名だけ書き換えた状態で動いているのを見ておく。
import './App.css';
//(中略)
function App() {
return (
<div className="App">
<header className="AppHeader">
<img src={logo} className="AppLogo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="AppLink"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
まあコレは、当然動くでしょう。(古いブラウザじゃなかったら。。)
###名前付きで読み込みしたパターンも書いてみる。
styleName
は一旦使用せず、className
でいく場合、
import styles from './App.module.scss';
のような感じで、
外部ファイルをstyles
として読み込み、className
の頭にstyles.
をつける。
className
の値を囲んでいる""
を消し、{}
にしておく。
"{}"
でも動くけど、pug
で書いた時に全文がJS扱いになるので、""
で囲んであると動かない。
import styles from './App.module.styl';
//(中略)
function App() {
return (
<div className={styles.App}>
<header className={styles.AppHeader}>
<img src={logo} className={styles.AppLogo} alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className={styles.AppLink}
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
これも動くっぽい。pug
をjsx
にトランスパイルした後、
こんな感じになってるんだろうな、というイメージ。
###htmlタグをpugに置きかえる
pug
で書くけど、まだstyleName
は使わない。
全部JSで処理するので{}
などは不要です。-
あるとバグるって言ってたのココです。
import styles from './App.module.scss';
//(中略)
function App() {
return pug`
div(className=styles.App)
header(className=styles.AppHeader)
img(className=styles.AppLogo src=logo alt="logo")
p
| Edit
code src/App.js
| and save to reload.
a(className=styles.AppLink href="https://reactjs.org" target="_blank" rel="noOpener noReferrer")
| Learn React
`;
}
もしここでPug is not defined.
とでた場合は、
babel-plugin-transform-react-pug
が読み込まれてないか、
プラグインの順番が前後逆になっていると思います。
pug
を変換するのが先です。
###pug+styleNameの書き方
####まずはmoduleナシに戻す
pug
+styleName
を使う前に、まずstyles
を宣言してない状態に戻します。
import './App.styl';
//(中略)
function App() {
return pug`
div(className="App")
header(className="AppHeader")
img(className="AppLogo"
src=logo
alt="logo")
p
| Edit
code src/App.js
| and save to reload.
a(className="AppLink"
href="https://reactjs.org"
target="_blank"
rel="noOpener noReferrer")
| Learn React
`;
}
これは(あれ?一回説明したような気が)
ほぼ<>
が消えただけで、トランスパイル後も形はあまり変わらないので、
問題なく動くと思います。
####pugらしい書き方をする
pug
の場合、div.App
(またはdiv
も省略して.App
)というような書き方をします。
さらにpug
っぽい記述にします。
import './App.styl';
//(中略)
function App() {
return pug`
div.App
header.AppHeader
img.AppLogo(src=logo alt="logo")
p
| Edit
code src/App.js
| and save to reload.
a.AppLink(
href="https://reactjs.org"
target="_blank"
rel="noOpener noReferrer" )
| Learn React
`;
}
問題なく動いている(気がする。眠くてよう確認してないけど)
これは.App
をclassName="App"
にトランスパイルしている。
あとはモジュール化するだけなのでclassName
の設定をstyleName
に変えれば行けるはず。
###※ご注意:ここから先、だんだんと泥沼にハマっていきます。
###pugでCSS Modulesどうやる?
このプラグインの説明によるとpug
でCSS Modules
する時は、
class属性をstyleName
とするらしい。
https://github.com/pugjs/babel-plugin-transform-react-pug#css-modules
そういうズバリな変換機能がありそうだな〜。夢がひろがる。
ここ大事なので、雰囲気で英語をよまずに、ちゃんと意味を理解して翻訳してみよう。
###CSS Modules
(方法1)Babelを使用してJSX専用のCSSモジュール(例:babel-plugin-react-css-modules)をオンにするか、
(方法2)webpack-loaderを使用してスタイルをキー値オブジェクトに変換するかどうかは、pugで使用できます。
####方法1
・「Babel-plugin-react-css-modules」を使用して、
classAttributeオプションをstyleName値に設定する必要があります。
{
"plugins": [
["transform-react-pug", {
"classAttribute": "styleName"
}]
]
}
import './styles.css' // .hello{color:red}
const withCorrectStyles = pug`
div.hello I am a red text
`
実際にやってみたが、
"react-css-modules",
["transform-react-pug",{"classAttribute": "styleName"}],
Cannot use styleName attribute for style name 'App' without importing at least one stylesheet.
少なくとも1つのスタイルシートをインポートしないと、スタイル名「App」にstyleName
属性を使用できません。
→ん〜stylus
をstylesheet
だと認識してない。css
とかscss
じゃないと読み込んでくれないんだろうか。
####違うモジュールのドキュメントをよくよむ
react-css-modules
で.styl
のシンタックスを理解させるには・・・
これにオプションの設定をしておく必要がありそう。
https://www.npmjs.com/package/babel-plugin-react-css-modules
["react-css-modules", {
"filetypes" : {
".styl" : {
"syntax" : "sugarss"
}
}
}],
sugarss
というのが必要になってくる
$yarn add sugarss
あ、これでエラーが消え、ページを読み込めるようにはなった。
でも肝心のスタイルがあたらない。んがが・・
ハッシュされた名前を正しく取得するやり方がありそう。
getLocalIdent
的な関数があったと思うので、そこをちゃんと見直してみるか・・?
いや、ちょっとこのやり方で時間の消費もったいないし、他の方法をためしてみよう。
(方法1については、まだ続きを書けそうな気がする。)
####方法2
・stylesをObjectに変換するwebpack-loader、またはその他のアプローチ
import classes from './styles.css' // .hello{color:green}
const withCorrectStyles = pug`
div(className=classes.hello) I am a green text
`
ここで「classAttribute
」オプションを「styleName
」値に設定し、
「babel-plugin-transform-jsx-css-modules
」を追加することにより、開発体験を改善できます。
{
"plugins": [
["transform-react-pug", {
"classAttribute": "styleName"
}],
"transform-jsx-css-modules"
]
}
ということなので、ドキュメントに近いソースを用意しておきます。
import styles from './App.module.styl';
function App() {
return pug`
div(className=styles.App)
header(className=styles.AppHeader)
img(className=styles.AppLogo src=logo alt="logo")
p
| Edit
code src/App.js
| and save to reload.
a(className=styles.AppLink href="https://reactjs.org" target="_blank" rel="noOpener noReferrer")
| Learn React
`;
}
babelrcも上記のように書き換えておきます。(ここまでは、動く)
公式から開発体験を改善できる、と言われている
babel-plugin-transform-jsx-css-modules
の英語を、実装前によく読んでおこう。
###babel-plugin-transform-jsx-css-modules
JSXのclassName属性を変換して、css-modulesの参照を取得します。
注:プロジェクトでCSSモジュールを有効にするのではなく、
自分で作成したと仮定します(たとえば、webpackやcss-loaderを使用して)。
(※うーん、よく読もうと思ったが、途中なんのこっちゃわからん)
####Example(例)
import './styles.css'
const Component = () => (
<div styleName="root">
<h1 className="paragraph">Hello World</h1>
<p className="global" styleName="local">I'm an example!</p>
</div>
)
↓こんな感じでトランスパイルされるでしょう
import __CSSM__ from './styles.css'
const Component = () => (
<div className={__CSSM__['root']}>
<h1 className="paragraph">Hello World</h1>
<p className={["global", __CSSM__["local"]].join(" ")}>I'm an example!</p>
</div>
)
/%\.\/module\.scss$/に設定すると、。/ module.scssで開始および終了するimportを処理します。
{
"plugins": [
["transform-jsx-css-modules", {
"pathToStyles": "^\\.\\/module\\.scss$"
}]
]
}
import './module.scss'
↓こんな感じでトランスパイルされるでしょう
import __CSSM__ from './module.scss'
翻訳をおわります。
つまり・・?これで、名前付きでimportしなくても、scopedなCSSができるっつーことですかね?
もう一回ソース見直してみます。
import './App.styl';
function App() {
return pug`
div(className="App")
header(className="AppHeader")
img(className="AppLogo" src=logo alt="logo")
p
| Edit
code src/App.js
| and save to reload.
a(className="AppLink" href="https://reactjs.org" target="_blank" rel="noOpener noReferrer")
| Learn React
`;
}
↓コンパイルできてる状態。じゃあ、これはどうなんだろか?できるんじゃないか?
↓
import './App.styl';
function App() {
return pug`
div(styleName="App")
header(styleName="AppHeader")
img(styleName="AppLogo" src=logo alt="logo")
p
| Edit
code src/App.js
| and save to reload.
a(styleName="AppLink" href="https://reactjs.org" target="_blank" rel="noOpener noReferrer")
| Learn React
`;
}
・・・できませんでした。エラーを読みます。
React does not recognize the styleName prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase stylename instead.
import './App.styl';
function App() {
return pug`
.App
header.AppHeader
img.AppLogo(src=logo alt="logo")
p
| Edit
code src/App.js
| and save to reload.
a.AppLink(href="https://reactjs.org" target="_blank" rel="noOpener noReferrer")
| Learn React
`;
}
・・・トランスパイル後がエラーでてるんだから、当然トランスパイル前も同じでしょう。。。
React does not recognize the styleName prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase stylename instead.
###ご注意:ここから先は、さらに、とてもハマります
React does not recognize the styleName prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase stylename instead.
「styleNameを認識できません。もしDOMのカスタム属性として使いたいなら、stylenameにしてください。」
...もしかして、こういう事?
["transform-react-pug",{
"classAttribute": "stylename"
}],
####全然違いました。
<div stylename="App">
コレ、全然jsxとして機能しない。ただのhtmlのカスタム属性だった。この先エラーから辿れなくなって、キツイ。
####追加でReactにstyleNameを認識させるプラグインが必要かもしれない。
多分、コレかな。
https://www.npmjs.com/package/babel-plugin-react-pug-classnames
React-pug
のサブコンポーネントを呼び出す問題を解決します。
(https://github.com/ezhlobo/babel-plugin-transform-jsx-classname-componentsの改良バージョン)
ここ、英語の説明をちゃんと読むべきだと思う。
####babel-plugin-react-pug-classnames:
また、className(styleName)の配列またはオブジェクト値を自動的に解析し、
classnamesのような関数を介して変換します。
すべてのクラス名にエレメント名を自動的にプレフィックスすることにより、BEMタイプの修飾子の命名を追加します。
(ん〜〜〜〜これはどうなんだろう。BEMタイプの修飾子を追加?いやはやstyleNameを認識させたいだけなんやけど)
###まず.babelrcの設定を変更する
初期設定時にコメントアウトしていた設定を使います。
["transform-react-pug",{"classAttribute": "styleName"}],
["react-pug-classnames", {"classAttribute": "styleName"}],
これでWebpack
が認識できない属性を追加してあげれる、とおもう。
{
"presets": [
"react-app"
],
"plugins": [
//"transform-react-pug",//←コッチをコメントアウトする
["transform-react-pug",{"classAttribute": "styleName"}],
["react-pug-classnames", {"classAttribute": "styleName"}],
//"transform-react-jsx",//←いらないのかな。。
"transform-jsx-css-modules"
]
}
?エラーが出てしまう
ReferenceError: div is not defined
なんだコレは、エラー出ないどころか、重症化してしまって、
pugの中身が正しく変換してない。
###ダメだ‥何度やってもここから先の手がかりがない
stackoverflowを漁っても、流石にこれじゃ検索のしようがない。
→ハマってしまったので、次の投稿にしようかと思います。
プラグインの順番か相性かどっちかな。
CSS Modules
への道は遠い
##できたことはできたよ、オススメはせんけど
しかしコレでpug
とstylus
を使って書けるようになります。
最終的に、styleName
使わないなら、まあ動くよ、というApp.jsはこんな感じでした。
styleName
だけ切り分けてテストしてみないと原因特定できないや。まあそれは今度
import React from 'react';
import logo from './logo.svg';
import './App.styl';
function App() {
return pug`
div.App
header.AppHeader
img.AppLogo(src=logo alt="logo")
p
| Edit
code src/App.js
| and save to reload.
a.AppLink(
href="https://reactjs.org"
target="_blank"
rel="noOpener noReferrer")
| Learn React
`;
}
export default App;
最終的なstylusはこのような感じ
.App
text-align center
.AppLogo
height 40vmin
pointer-events none
@media (prefers-reduced-motion: no-preference)
.AppLogo
animation App-logo-spin infinite 20s linear
.AppHeader
background-color #282c34
min-height 100vh
display flex
flex-direction column
align-items center
justify-content center
font-size calc(10px + 2vmin)
color white
.AppLink
color #61dafb
@keyframes App-logo-spin{
from{
transform rotate(0deg)
}
to{
transform rotate(360deg)
}
}
最終的な.babelrcはこんな感じ。
{
"presets": [
"react-app"
],
"plugins": [
"transform-react-pug",
//["transform-react-pug",{"classAttribute": "styleName"}],
//["react-pug-classnames", {"classAttribute": "styleName"}],
"transform-react-jsx",
"transform-jsx-css-modules"
]
}
最終的な.eslintrc.jsはこんな感じ
{
"env": {
"es6": true,
"node": true,
"browser": true
},
"parserOptions": {
"ecmaVersion": 6,
"allowImportExportEverywhere": true
},
"plugins": [
"react-pug"
],
"extends": [
"react-app",
"plugin:react-pug/all"
],
"rules": {
"import/no-named-as-default": 0
}
}
config-overrides.jsはこんな感じ
const { override, disableEsLint } = require("customize-cra");
module.exports = override(
//useBabelRc(".babelrc"),
//useEslintRc(".eslintrc"),
disableEsLint()
);
ここに書いた方がいい設定と、.babelrc
などに書いた方が良い設定の判断はつきませんが
プラグインは.babelrc
に書いたほうが分かりやすかったです。
最終的なpackage.jsonはこちら。
{
"name": "sample",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"babel-plugin-react-css-modules": "^5.2.6",
"babel-plugin-react-pug-classnames": "^0.3.1",
"babel-plugin-transform-jsx-css-modules": "^1.0.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-plugin-transform-react-pug": "^7.0.1",
"customize-cra": "^0.9.1",
"eslint-plugin-css-modules": "^2.11.0",
"eslint-plugin-react-pug": "^0.8.4",
"node-sass": "^4.13.1",
"react": "^16.13.0",
"react-app-rewired": "^2.1.5",
"react-dom": "^16.13.0",
"react-scripts": "https://github.com/daisuke240000/react-scripts-pug-stylus",
"stylus": "^0.54.7",
"stylus-loader": "^3.0.2"
},
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test --env=jsdom",
"eject": "react-app-rewired eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
###styleName…
ネットで調べても調べてもこの問題は解決しないので、
styleName
とかもう死んだ規格なんじゃないかと思っています。
styleName
に関するリンクをココにはる予定。
↓
https://qiita.com/DaisukeNishi/items/617b7f9b4dde0bdeb3b9
(※ただの愚痴を貼っただけになってしまった)
###参考資料
https://html5beta.com/tools/css2stylus.html
https://github.com/dehimer/customize-cra-add-stylus-loader
https://github.com/arackaf/customize-cra/pull/144
adjustStyleLoadersの機能はありそうですが、使い方がわからない。
https://github.com/arackaf/customize-cra/blob/master/api.md#adjuststyleloaderscallback
https://github.com/timarney/react-app-rewired
https://github.com/gajus/babel-plugin-react-css-modules/issues/41
https://qiita.com/yikeda6616/items/0e31a920d533d70c0bd9
https://github.com/webpack-contrib/css-loader/issues/877
https://github.com/webpack/webpack/issues/8973
https://github.com/facebook/create-react-app/issues/5113
https://laracasts.com/discuss/channels/elixir/babel-plugin-react-css-modules-not-transforming-stylename-in-react
https://github.com/arackaf/customize-cra#with-webpack
https://github.com/timarney/react-app-rewired/issues/348
https://github.com/pugjs/babel-plugin-transform-react-pug#classattribute
https://github.com/timarney/react-app-rewired
http://www.beguru.work/2019/01/06/create-react-app-%E3%81%A7-babelrc%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B/
https://kic-yuuki.hatenablog.com/entry/2019/09/08/111817
https://github.com/facebook/create-react-app
https://stackoverflow.com/questions/56513346/how-to-use-pug-templating-engine-with-reactjs
https://qiita.com/TakuyaHara/items/f560d34aaa7857b32c82
https://www.npmjs.com/package/babel-plugin-transform-react-pug
https://github.com/pugjs/babel-plugin-transform-react-pug#eslint-integration
https://github.com/ezhlobo/eslint-plugin-react-pug
https://html2pug.now.sh/