前提
既存で運用しているサイトで所々vueを使用している箇所があり、この度Nuxt化しようとなった
HTMLはpug、CSSはscssで書かれている
課題
共通のCSS(例えばボタンとかリストとかutilityとか)を読み込んでいるページと、読み込んでいないページが少数存在
なので、この共通CSSを読み込んでいるlayout(default.vue)と読み込んでいないlayout(init.vue)を作成
おのおのページでレイアウト設定したところ、共通CSSを読み込んでいないlayout(init.vue)で設定しているのに共通CSS読み込まれいていた…
★ おおよそこんなイメージ ★
assets
L common.scss ← 共通のstyle
L index.scss ← ページごとのstyle
pages
L index.vue ← init.vueのレイアウトを使用。index.scssをimport(not scoped)
layouts
L default.vue ← common.scssをimport(not scoped)
L init.vue ← common.scssは読み込んでいない
原因
Nuxtのlayouts配下で読み込まれているCSSはレイアウトごとに分ける設定にデフォルトではなっていないらしい。
つまり、layouts配下のvueで読み込まれているCSSはなんであれ一つにまとめてられてしまう。
えーーー!?!?なんためのレイアウトなのーーー???
見た目をバッチリ分けたいからこの機能あるんじゃないのーーーー!?!?
と思ってしまいました…
解決案
nuxt.config.jsのbuildに以下を設定するとレイアウトごとにファイルを分けて出してくれる
splitChunks: {
layouts: true, ←デフォルトではここがfalse
commons: true,
pages: true
},
https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-build#splitchunks
scoped属性をつけてしまうと、ボタンとかリストとか共通のモジュールのstyleが当たらなくなってしまうし……ここは後者で対応。
よっしゃー!これで行けるゼッと思ったところ新たな問題が発生
問題点
上記の設定をしたあと、再度表示を確認したところ各ページごとのCSSより共通のCSSが優先されている…!?ことが発覚
<極端な例>
default.vueで読み込んでいるdefault.css(=common.scss)ではbodyは赤だけど、TOPだけはbodyをピンクにしたい!
→index.scssでbodyをピンクに設定
結果:bodyは赤色になっている
なぜ。。。。。???????
原因
よく見ると、閉じbodyの直前にCSSの読み込みが記述されいてる。
ビルドされたhmtlファイルにはこの読み込みは存在していなかった、ので!動的に追加されているらしい。。
しかも順番が、ページ用のCSSの後にdefaultのCSS。。。
なんで!?!?!?
そういう仕様なのねッ!?!?!?
考えた対応策
1.layoutは分けず、CSS読み込み用のコンポーネントを作ってコンポーネントの読み分けをする
BaseStyle.vueみたいなコンポーネントを作成して共通cssをimport
中身はslotのみにして、layout機能のようなものを作成
このコンポーネントをdefault.vueで読み込んで、分岐したらいける??
<tempate lang="pug">
div(v-if="判定するためのフラグがtrueだったら")
BaseStyle
Nuxt
div(v-else)
Nuxt
</tempate>
結果
意味なし!
コンポーネントが表示されてるされてないに関わらず、default.vueで読み込まれてると全ページに共通CSSがきいてしまうらしい。。。
2.各ページで共通CSSをimportする
結果
まぁ、うまくいくけど面倒だよな
3.ページごとのSCSSのimportをscopedつける
結果
うまく行くページと行かないページが…
4.共通SCSSを別でビルドして動的にCSSの読み込みを追加する
結果
いやいや、共通SCSS別ビルドするの…?それはなくね…?
結論
チームで話し合った結果、今回は共通CSSを読み込んでいないページでも読み込むことによる表示崩れはほとんど発生しないから読み込んでしまおうということになりました。
共通モジュールのstyleを、ファイルの読み込み順によって上書きしよ。っていう発想はやめよ
以上