やりたいこと
Vue.jsでつくっているウェブページ上で、Adobeの日本語ウェブフォント、具体的には貂明朝を使いたい。
貂明朝
- Adobe Creative Cloudの無料アカウントがあればCCの年間契約をしていなくても使える数少ない日本語フォントのうちのひとつ
- ウェブフォントとしても無料で使える
- 欧文スタイルが非常に美しい。イタリックもある(当然だが日本語はイタリックにならない)
- 可愛い貂がいくつか絵文字として登録されている
- より本文テキストに特化した貂明朝テキストはCC契約がないと使えない
どこまでは問題なくやれるか
貂明朝をAdobe Fontサイト上で「Webプロジェクトに追加」すると
 と出る。Vueに``タグなんてあるのか?と思いつつ、まずは`main.js`にscriptタグ内のコードをコピペしてみる。そして`css`で適当に`body`内のフォントを`ten-mincho`と指定すると貂明朝で表示される!
と出る。Vueに``タグなんてあるのか?と思いつつ、まずは`main.js`にscriptタグ内のコードをコピペしてみる。そして`css`で適当に`body`内のフォントを`ten-mincho`と指定すると貂明朝で表示される!
ここまではよい。
問題
問題はBootstrapVueを導入した際に発生した。適当にGetting Startedに従いmain.js上でVue.use(BootstrapVue)などとする。またstyle overrideのためにsass-loaderをいれて
$ npm install --save-dev sass-loader node-sass
src/assets/custom-vars.scssに以下のように貂明朝を指定する:
$font-family-serif: 'ten-mincho', 'Times New Roman';
$font-family-base: $font-family-serif;
そしてApp.vue内でカスタムSCSSとBootstrapデフォルトのSCSSファイルを読み込む。このあたりはBootstrapVueのthemingのページに書いてある:
<style lang="scss">
// Import custom SASS variable overrides, or alternatively
// define your variable overrides here instead
@import 'assets/custom-vars.scss';
// Import Bootstrap and BootstrapVue source SCSS files
@import '~bootstrap/scss/bootstrap.scss';
@import '~bootstrap-vue/src/index.scss';
// General style overrides and custom classes
// body {
//   background-color: black;
// }
</style>
しかしその状態でnpm run serveすると次のようなエラーが出る。さっきまでうまくいってたのに… (初学者の断末魔)
Module Warning (from ./node_modules/eslint-loader/index.js):
error: 'Typekit' is not defined (no-undef) at src/main.js:37:7:
  35 |     clearTimeout(t)
  36 |     try {
> 37 |       Typekit.load(config)
     |       ^
  38 |     } catch (e) {}
  39 |   }
  40 |   s.parentNode.insertBefore(tk, s)
error: Empty block statement (no-empty) at src/main.js:38:17:
  36 |     try {
  37 |       Typekit.load(config)
> 38 |     } catch (e) {}
     |                 ^
  39 |   }
  40 |   s.parentNode.insertBefore(tk, s)
  41 | })(document)
模索
まず埋め込み方法を忠実に守ろうとした。上の画像にもあるように、
これらのフォントを Web ページで使用するには、このコードを HTML の
タグ内にコピーします。
と指定されているが、そもそもVue.jsでやっているのでheadタグ内に入れているわけではない。headタグにぶちこめばうまくいくのでは?と思い、vue-headをnpmで入れて、main.jsのnew Vue内に
new Vue({
  router,
  store,
  head: {
    script: [
      {
        type: 'text/javascript',
        src: '@/thirdpartyjs/typekit.js',
        async: true
      }
    ]
  },
  render: h => h(App)
}).$mount('#app')
として、srcフォルダ直下に/thirdpartyjsフォルダを作り、Adobeの指定するコードをtypekit.jsとして保存した(注意:フォントによってkitIdが違うため、↓のコードではなくAdobe様からちゃんとしたものをコピペしてください)。
;(function(d) {
  var config = {
      kitId: 'utm7rry',
      scriptTimeout: 3000,
      async: true
    },
    h = d.documentElement,
    t = setTimeout(function() {
      h.className = h.className.replace(/\bwf-loading\b/g, '') + ' wf-inactive'
    }, config.scriptTimeout),
    tk = d.createElement('script'),
    f = false,
    s = d.getElementsByTagName('script')[0],
    a
  h.className += ' wf-loading'
  tk.src = 'https://use.typekit.net/' + config.kitId + '.js'
  tk.async = true
  tk.onload = tk.onreadystatechange = function() {
    a = this.readyState
    if (f || (a && a != 'complete' && a != 'loaded')) return
    f = true
    clearTimeout(t)
    try {
      Typekit.load(config)
    } catch (e) {}
  }
  s.parentNode.insertBefore(tk, s)
})(document)
しかしうまくいかない。そもそもthirdpartyjs/typekit.jsが読み込まれていないようだった(多分)。
解決策
head云々は関係なく、単にmain.js上で上記で作成したような.jsファイルをimportすればいいだけだった。なぁんだ
main.jsの冒頭は次のようになる:
import Vue from 'vue'
import App from './App.vue'
import BootstrapVue from 'bootstrap-vue'
import router from './router'
import store from './store'
import '@/thirdpartyjs/typekit.js'
参考:Adobeのウェブフォント埋め込みの説明ページ
 「<head>タグにいれろ」だけではなくimportする方法も書いてほしい…(初学者の断末魔)
disclaimer
私はまだプログラマではないしウェブデザイナーですらない。
もっと良い方法があるかもしれないし間違ったことをやっている(のにたまたま想定通りの動きをしているだけ)かもしれない。
そもそもなぜbootstrapを読み込むとうまくいかず、読み込まなければうまくいくのかすらわかっていない(変数の名前がバッティングしちゃったんですかね??)
なので何か問題点・改善点があればご指摘ください。