Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hoge.module.scss と hoge.scss の使い分けについて #54

Closed
piro0919 opened this issue Apr 14, 2020 · 10 comments · Fixed by #57
Closed

hoge.module.scss と hoge.scss の使い分けについて #54

piro0919 opened this issue Apr 14, 2020 · 10 comments · Fixed by #57
Assignees
Labels
enhancement New feature or request question Further information is requested

Comments

@piro0919
Copy link

Is your feature request related to a problem? Please describe.
hoge.module.scsshoge.scss は、CRA的にどう扱いが異なるか書いてみてください 👍

Describe alternatives you've considered
例えば、mixin用のファイルや定数用のファイルはどこにどういった形で切ると良いでしょうか

Additional context
ヒントは、webpackでの処理の違いですね

@piro0919 piro0919 added enhancement New feature or request question Further information is requested labels Apr 14, 2020
@syunto07ka
Copy link
Owner

鍵になるのは以下の部分

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に定義しなければいけない(どこに、という問いはできるだけ高級な場所で定義する、でよい?もっと深い答えがある?)

@syunto07ka
Copy link
Owner

@piro0919
と、ざっくりこんな感じですかね。。?

@piro0919
Copy link
Author

piro0919 commented Apr 15, 2020

@syunto07ka
着眼点はいい感じです。 👍

.scssと.module.scssとで設定値が違うのはここ。

なぜそう思いましたか?

@syunto07ka
Copy link
Owner

webpack now 👀

@syunto07ka
Copy link
Owner

syunto07ka commented Apr 15, 2020

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'
              ),
            },

@syunto07ka
Copy link
Owner

@piro0919

@piro0919
Copy link
Author

@syunto07ka

なぜと言われちゃうと、useで設定している項目が、その部分以外同じだから、という答えになりそうですが。。
sassRegexはsassファイルを識別するための正規表現が代入されてて、excludeの部分はsassModuleだけ省きますよという意味。

正解です 👍

では、以下のコミットはどこが良くないかわかりますか?
7de1b37

@syunto07ka
Copy link
Owner

クラス名の付け方が異なるので、このコミット 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,
                },
              }),
            },

@piro0919
Copy link
Author

@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'
              ),
            },

正規表現を見て頂けるとわかると思いますが、上から順に以下のファイルに対する設定となります。

  1. css modulesをかまさないcssに対する設定(hoge.cssなど)
  2. css modulesをかませるcssに対する設定(hoge.modele.cssなど)
  3. css modulesをかまさないsassに対する設定(hoge.scssなど)
  4. css modulesをかませるsassに対する設定(hoge.modele.scssなど)

今回は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.の設定を触ってあげれば良いと思います。

修正方法についてはすでに把握されていると思いますが、大体こんな感じになると思います。

@syunto07ka
Copy link
Owner

babel-plugin-react-css-modulesの対象となるファイルは、当たり前ですがcss modulesを当ててやりたいファイルになるため、上記の設定のうち2.及び4.が対象となります。
そのため、1.や3.の設定を触ることは絶対になく、ましてやcss及びsassの全体の設定を触るようなことをしてはいけません。 🙅‍♂️

まさに誤解してました。。
やっと理解しましたー!babel-pluginのパッケージよく見れてないな。。もう一回読みますー

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants