Closed piro0919 closed 4 years ago
鍵になるのは以下の部分
modules: {
getLocalIndent: getCSSModuleLocalIdent,
}
.scssと.module.scssとで設定値が違うのはここ。(他にもあるが、今回はこの部分を見れば良いはず?)
modulesは、CssModulesを使用するかどうかや使用する場合の設定値を設定できるkeyで、defaultはfalseになっている(つまり使わない)
https://webpack.js.org/loaders/css-loader/#modules
そうなったときの.scssと.module.scss の大きな違いは、クラス名が変わること。
.scssファイルにて指定されたクラスはそのまま反映されるが、.module.scssファイルで指定されたクラスは[file]__[localname]_[hash]
のように名前が書き換わってしまう。
例えば、mixin用のファイルや定数用のファイルはどこにどういった形で切ると良いでしょうか
この部分の問でいうと、.module.scssでmixinや定数を定義してしまうと、別の名前に書き換わってしまうので.scssに定義しなければいけない(どこに、という問いはできるだけ高級な場所で定義する、でよい?もっと深い答えがある?)
@piro0919 と、ざっくりこんな感じですかね。。?
@syunto07ka 着眼点はいい感じです。 👍
.scssと.module.scssとで設定値が違うのはここ。
なぜそう思いましたか?
webpack now 👀
configファイルの中でsassとmodule.sassの設定を行っているのが以下
なぜと言われちゃうと、useで設定している項目が、その部分以外同じだから、という答えになりそうですが。。
sassRegex
はsassファイルを識別するための正規表現が代入されてて、excludeの部分はsassModule
だけ省きますよという意味。
webpack.config.js
// Opt-in support for SASS (using .scss or .sass extensions).
// By default we support SASS Modules with the
// extensions .module.scss or .module.sass
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'sass-loader'
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules, but using SASS
// using the extension .module.scss or .module.sass
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
},
@piro0919
@syunto07ka
なぜと言われちゃうと、useで設定している項目が、その部分以外同じだから、という答えになりそうですが。。 sassRegexはsassファイルを識別するための正規表現が代入されてて、excludeの部分はsassModuleだけ省きますよという意味。
正解です 👍
では、以下のコミットはどこが良くないかわかりますか? https://github.com/syunto07ka/jewelry_box/commit/7de1b37dcc6b77746b0d16ce5ccb9df7bd8e192b
クラス名の付け方が異なるので、このコミット 7de1b37 だと.module.scssを読み込んだときにスタイル情報が当たらない。のでどちらにもLocalIdentNameの指定をして上げる必要がある。もっというとcssを使う場合も考慮して、css側の設定も変更したほうがよい
ですかね? @piro0919
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
}),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
}),
},
@syunto07ka
クラス名の付け方が異なるので、このコミット 7de1b37 だと.module.scssを読み込んだときにスタイル情報が当たらない。のでどちらにもLocalIdentNameの指定をして上げる必要がある。もっというとcssを使う場合も考慮して、css側の設定も変更したほうがよい
ちょっと表現が曖昧過ぎてよくわからないです。
CRAのwebpackでは、以下の4つの設定がcssファイルやscssファイルに関する設定となっています。
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
}),
sideEffects: true,
},
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
}),
},
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'sass-loader'
),
sideEffects: true,
},
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
},
正規表現を見て頂けるとわかると思いますが、上から順に以下のファイルに対する設定となります。
今回はscssファイルに限った話をしているので、そもそも対象となる設定は3.と4.に限られます。
3.と4.の設定の違いはmodules
というオプションをgetStyleLoaders
関数に渡しているか否かの違いのみとなっています。
そもそもmodules
とは一体なんぞやという話になるのですが。
css-loader
の公式を見て頂けるとわかると思うのですが、modules
オプションを追加すると、対象となるファイルはcss modules用のファイルとして扱われるようになります。
その結果、hoge.module.scssファイルを切ってやると、クラス名が勝手に変換され、カプセル化が行われるという仕組みになっているわけです。
そこで、babel-plugin-react-css-modules
との兼ね合いの話になってくるのですが。
これ自身の説明は以前したはずなのでざっくりと書いてしまいますが、素のcss modulesを使ってしまった場合、割り当てるclassName
の変数名がlinterや規約的に良くなかったり、ロジック側かスタイル側で使用されているのかなどがわかりづらいなどの問題が発生してしまいます。
それを解決してくれるのがこのパッケージで、カプセル化を行いたいスタイリングについてはstyleName
というpropsを渡せば、このパッケージが良しなにやってくれるわけですね。
ここで1つ誤解されているかもしれないのですが。
babel-plugin-react-css-modules
の対象となるファイルは、当たり前ですがcss modulesを当ててやりたいファイルになるため、上記の設定のうち2.及び4.が対象となります。
そのため、1.や3.の設定を触ることは絶対になく、ましてやcss及びsassの全体の設定を触るようなことをしてはいけません。 🙅♂️
babel-plugin-react-css-modules
の導入については、babelの設定をいじってやればほぼ解決するのですが。
ここで1つ問題となるのが、素のcss modulesと素のbabel-plugin-react-css-modules
では、クラス名の変換のロジックが以下のように異なるのです。
css modules: [name]__[local]___[hash:base64:5]
babel-plugin-react-css-modules: [path]___[name]__[local]___[hash:base64:5]
そのため、css及びsass側のクラス名の変換に関する設定を修正してやらないといけない、ということになります。 今回のケースでは、scssファイルのみを対象としているため、上記の設定のうち4.の設定を触ってあげれば良いと思います。
修正方法についてはすでに把握されていると思いますが、大体こんな感じになると思います。
babel-plugin-react-css-modulesの対象となるファイルは、当たり前ですがcss modulesを当ててやりたいファイルになるため、上記の設定のうち2.及び4.が対象となります。 そのため、1.や3.の設定を触ることは絶対になく、ましてやcss及びsassの全体の設定を触るようなことをしてはいけません。 🙅♂️
まさに誤解してました。。 やっと理解しましたー!babel-pluginのパッケージよく見れてないな。。もう一回読みますー
Is your feature request related to a problem? Please describe.
hoge.module.scss
とhoge.scss
は、CRA的にどう扱いが異なるか書いてみてください 👍Describe alternatives you've considered 例えば、mixin用のファイルや定数用のファイルはどこにどういった形で切ると良いでしょうか
Additional context ヒントは、webpackでの処理の違いですね