前回の記事
※本記事はこちらの方法でセットアップされたことが前提となっています

前回ではyarn buildでコンテンツを書き換える仕組みがなんとなくわかった。 今回はスタイルシート回りを検証してみる。

Vue CLIでSCSSを扱う

さて、前回書き換えたApp.vueだけど、もう一度中身を見てみよう。

src/App.vue

<template>
  <div id="app">
    <p>Hello Vue.js!</p>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from './components/HelloWorld.vue';

@Component({
  components: {
    HelloWorld,
  },
})
export default class App extends Vue {}
</script>

<style lang="scss">
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

styleタグがあり、lang属性は”scss”となっている。
この中を書き換えればスタイルシートを設定できそうですね。
早速pタグにスタイルを当ててみる。
前回の記事のとおり、yarn serveしとけばブラウザで半リアルタイムに確認できるよ。

src/App.vue

<template>
  <div id="app">
    <p>Hello Vue.js!</p>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from './components/HelloWorld.vue';

@Component({
  components: {
    HelloWorld,
  },
})
export default class App extends Vue {}
</script>

<style lang="scss">
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  p {
    font-size: 4em;
  }
}
</style>

#app{}内にp{font-size: 4em}を追加しただけ。

Fig 001
Fig 001

文字が大きくなった!ちゃんとSCSSとして記述されているようだ。
トランスパイルされたCSSは「dist/css/app.ハッシュ.css」に書き出される。 yarn buildでビルドすれば確認できます。
ハッシュはビルドする度に変更されるけど、これはCDNで確実にリフレッシュされる為だろう。
index.htmlのCSS読み込み部分もちゃんと更新されるし、サーバーにデプロイされるファイルなんて今の時代、いちいち確認しないんだろうねー。
仕組みとしてはnpm_modulesのnode-sassがトランスパイルして、sass-loaderによってWebPackが処理してる感じか。

別ファイルのSCSSを読み込む

.vue内にstyleタグで書けば各ページ(Vueのテンプレート)毎にスタイルを当てられることは解った。
これはこれで使いどころはあるんだろうけど、大規模なCSSを構築するのは管理面からは向いてない。 やっぱりCSSもモジュール化して別ファイルで管理したい。
まず、さっき追記したp{font-size: 4em}を削除して、基本のスタイルとして「src/assets/css/base/_base.scss」ファイルを作ろう。

src/assets/css/base/_base.scss

#app {
  p {
    font-size: 4em;
  }
}

ファイル名の先頭がアンスコになっているのは、このファイル自体は書き出し対象に含めないようにする為。パーシャルって呼ぶみたいね。
で、このファイルをインポートするSCSSを書く。これは一個上の階層に置いておこう。
まあ、このあたりのディレクトリ階層は好きなように決めればいいんだろうけど、こうしている人が多いみたい。

src/assets/css/styles.css

@import "base/base";

普通にimport。アンスコは省略して構わない。
で、このstyles.scssをどこで呼び出すかなんだけど、これは「src/main.ts」で行う。

src/main.ts

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

これはこの記事で初めて出てきたファイルだね。
TypeScriptに不慣れな方でも、Vue.js自体のインポート、メインのテンプレートApp.vueのインポート、そしてVueの初期化が行われてるんだな、ぐらいは雰囲気がつかめると思う。
Vueの初期化が行われてるぐらいだから、ここがVueのエントリーポイントなんだな。
で、SCSSだけど、下に追記してやる。

src/main.ts

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

import "./assets/css/styles.scss"

import "./assets/css/styles.scss"を追加しただけだ。
CSSをスクリプトの中で読み込むのは若干気持ちわるい感じがするが…Vue CLIがビルドするためのスクリプト、と考えれば納得もいく。
しかしいちいちよく出来てるな。

ともあれ、これでモジュールとして公開されているリセットやノーマライズのSCSSが利用できる。 siond.comではこれを「src/css/vender」ディレクトリに置いてstyles.scssでimportしている。
記事とは関係ないけど、個人的にはスタイルをまっさらにしてしまうリセットよりノーマライズの方が好みです。

つづく