たくさんの自由帳

これ作るのに大変だったこと

投稿日 : | 0 日前

文字数(だいたい) : 8406

TypeScript(nuxt/content)化に伴いこの記事は古くなり、ここに書いてある内容も(ほぼ)関係なくなっています

Hexoってすごいんだなって。
なお完成はいつになるかわかりません。いつ出来上がるんだこれ?
完成までに思ったことを書いていくと思う。

あとドメインが欲しい。買ったこと無いけどどうなんですかね?

取りました

これ作るのに大変だったこと

書く。

Vuetifyが<code>に色つける。

Vuetifyくんが勝手に色を付けてくれます。が、なんかいまいちなので頑張ってCSS書いて直したいんですが、
Vuetifyくんが許してくれません。?
しかたないので!importantで黙らせました。

assets/css/styles.css

/* VuetifyのせいでCodeタグに勝手にCSS適用されるので強制上書き */

.v-application code {
    box-shadow: initial !important;
    border: 1px solid gray;
    border-radius: 5px !important;
    font-family: 'Koruri Regular';
    margin: 10px;
}

.v-application code, .v-application kbd {
    font-weight: initial !important;
}

ついでにhighlight.jsのCSS、vs2015.cssを入れてコードにシンタックスハイライトをつけようとしたんですけど、これもうまく動かなかったのでvs2015.css!important付けて対応しました。

CSS

CSSよくわがんね。

/* ほばー */
.titleHover:hover {
    color: #5870cb;
    transition: color 0.5s;
}

これは記事一覧のタイトルをマウスオーバーするとジワーッと色が変わるCSSです。

Processmdくんが時系列順に並べてくれない

これはおま環境かもしれないけど、時系列順に並んでくれません。
流石に時系列順にならないのはきついので、JavaScriptで時系列に並び替えるコードを書きました。sort関数あったし。

// なんかしらんけど並び順が新しい順とは限らないらしい?
const sortedKeyList = Object.keys(fileMap);
sortedKeyList.sort(function(a, b) {
  const aDate = new Date(fileMap[a].created_at).getTime();
  const bDate = new Date(fileMap[b].created_at).getTime();
  if (aDate > bDate) return -1;
  if (aDate < bDate) return 1;
  return 0;
});

KotlinのsortBy{}とは使い方が違っててちょっと迷った。

あとprocessmdくん、/posts/jsonに消した記事が残ってるんですがそれは、、

ページネーション

追記(2020/06/27):もしかしたらこれ書く必要ないと思う(_id.vueファイルは必要だと思う)
詳細→ Nuxt.jsを2.13に上げた時の話

次のページ、前のページを付けることを、ページネーションって言うそうですよ。
これ付けないと記事が増えたときのスクロールがとんでもないことになる。

記事一覧はこんな感じに静的に出してほしいので(postsに置くとタイトル被りそうなのでpageフォルダがある。)

/posts/page/1

特に需要はなさそうですが一応必要なページ数に合わせてposts/pageの配列を返す関数置いときますね。

/** 次のページ機能をつける。そうしないと記事一覧にどばーってなってスクロール大変になる */
const generatePagenationRoutesList = () => {
  // 何ページ必要か計算する(10で割ればいいっしょ)。ただ1ページ目は最低限必要なので1足す
  const calc = Math.floor(postsJSON.sourceFileArray.length / PAGE_LIMIT) + 1
  // ページ分だけ動的ルーティングの配列出す?
  const dynamicRouterPathList = []
  // console.log(`ページ数:${calc} / 記事数:${postsJSON.sourceFileArray.length}`)
  // ページ生成。1ページ目から作るので1からスタート
  for (let i = 1; i <= calc; i++) {
    dynamicRouterPathList.push(`/posts/page/${i}`)
  }
  return dynamicRouterPathList
}

// 省略

/** 静的サイトジェネレート関数。配列(pages/とposts/)くっつける */
const generateRoutes = callback => {
  callback(null, [generatePagenationRoutesList()].flat())
}

これ動かすにはpostsフォルダpageフォルダを作って中に、_id.vueを置いておく必要があります。

これでposts/page/1などが生成されるようになります(多分)

この記事書いてる途中でなんでこれ動いてんのかよくわからなくなったのは内緒←やっぱり生成できてなかったので直しました。(2020/06/03)

<v-card>が遅い?→いつの間にか直った?

何故か知りませんが、VuetiryのCardコンポーネントがおそい。というかページ遷移がこいつのせいで遅くなる。

せっかくの静的サイトで遅いのは辛いので直したい。(しかも記事一覧に戻った時にワンテンポ遅れるとか見てられない)

で、なぜか<v-card><v-sheet>に置き換えることで解決しました。

なんで?

記事一覧を再読み込みした後記事を開くと404

なんかしらんけどF5するとURLの後ろに/が入ります。
最後に/が入っていないのが前提で作っているので、最後に入ると ../(一個前に戻る) がおかしな場所を指すようになります。

---追記---

別に../使わなくても良いことに気付いたのでこの問題は解決しました。
to='/posts/first'みたいな感じで別に戻る必要ありませんでした。

---追記おわり---

というかこれは私の作り方(ファイル構成)が悪いですね、なんで戻ったりしないといけないんだ。

  • pages
    • pages(固定ページ。今回は省略)
    • posts(ブログ)
      • page
        • _id.vue(記事一覧)
      • tag
        • _id.vue(タグ検索結果)
      • index.vue(本来ここに記事一覧が有るべき?)
      • _slug.vue(記事。ここに居るので一覧から来たら戻らないといけない。)

今回はnuxt.config.jsを開き、URLの最後に/を入れる設定を付けました。おかげて修正が必要になりましたが。

export.default {
  // 省略
  router: {
    base: '/Ziyuutyou/',
    trailingSlash: true // ←これ
  }
}

sw.jsがよくわからんけどバージョン管理対象外になっててホーム画面に追加が消えてた

GitHubのリポジトリ開いて/docs開いたら見事にServiceWorkerだけ抜けてました。なんで?

Hexoと違ってリアルタイムで記事の内容が反映されない

Hexoって書いてる途中でも、リロードすれば記事の内容が更新されてどんな感じに見れてるか確認できるんですけど、processmdくんデフォルトだとできないっぽい?
processmd見る感じ、ファイルの中身を監視する--watchオプションが存在するのでそれ使えばよさそうです、
それで適当にpackage.jsonscriptsの中に実行とprocessmdの監視オプション付きを同時に実行する様に書いたんですけど、
nuxt起動から先に進みません!そりゃnuxtもファイルを監視してるからそこで止まりますよね。

それでどうすれば同時に(並列に)起動できるかって話ですが、npm-run-allってのを使えば並列実行ができそうです。
ただ、これ使っても更新できるのは記事の中身だけで記事一覧(summary.json)は更新できないっぽいです。(nuxt起動時にsummary.jsonが空っぽだぞって怒られる。どうやら一度消えるらしい?)

でも記事の中身がリアルタイムで反映されるようになったので満足です。VSCode半分にしなくて済むし。
参考程度のpackage.jsonのscript

{
  "scripts": {
    "dev": "nuxt --port 11451",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "markdown": "npm run post && npm run page",
    "page": "processmd contents/pages/**/*.md --stdout --outputDir contents/pages/json > contents/pages/summary.json --markdownOptions.linkify",
    "post": "processmd contents/posts/**/*.md --stdout --outputDir contents/posts/json > contents/posts/summary.json --markdownOptions.linkify",
    "pagewatch": "processmd contents/pages/**/*.md --outputDir contents/pages/json --markdownOptions.linkify --watch",
    "postwatch": "processmd contents/posts/**/*.md --outputDir contents/posts/json --markdownOptions.linkify --watch",
    "all": "npm-run-all markdown --parallel dev postwatch"
  },
}

npm run allを実行すると

  • markdownファイルがJSON形式に変換される
  • nuxt起動
  • nuxt起動と同時にprocessmdの監視を始める
    • --stdoutオプションは外してあるので、記事一覧は更新されない。

--parallelのあとに指定したスクリプトが並列で実行され、その前に書いてあるスクリプトは直列で実行されます。

ちなみにprocessmdくんがJSONファイルを書き換えるとnuxtのファイル変更監視に引っかかるので自動で更新されるようになります。すげえ

たまにundefinedになるけどしゃーない

マークダウンに書いたURLがリンクにならない

processmdくんのオプションに--markdownOptions.linkifyをくっつけて実行すればいいです。

{
  "scripts": {
    "post": "processmd contents/posts/**/*.md --stdout --outputDir contents/posts/json > contents/posts/summary.json --markdownOptions.linkify"
  }
}

しれっとNetlifyにお引越ししたりした。

GitHubPagesより良いのかはしらんけどお試しで引っ越してみた。これ勝手にメアド公開したりしないよな?
Netlify へデプロイするには?ってのが有るのでそれに沿ってやればできると思います。

じゃあなんで大変だったことに書いてんだよって話ですが、っぱコケるんですね。

あーJSだからしゃーないのかなーなんて思ってとりあえず検索すると、Chromeのバージョン的に対応していないとか出てきたのでワンちゃんNode.jsくんのバージョンがおかしいのではないかと考えました。

NetlifyにNode.jsのバージョンを指定する方法ですが、検索したらありました。 参考元

.nvmrcというファイルを置いて、中にNode.jsのバージョンを書くだけで解決しました。

v12.14.1

これだけ。これで成功しました。

ちなみサイト作成時のステップ3で、ビルドコマンドにnpm run generate、ディレクトリをdocs(GitHubPagesの名残)すれば、コミット+プッシュ時に勝手にnpm run genreateして公開してくれます。らく

実は静的サイト書き出しできてなかった

これは別に記事に書いた→ Nuxtの静的サイトジェネレートはモードをuniversalにしよう

読みたくない方向け→nuxt.config.jsmode:universalにすればHTMLに書き出してくれます。
spaだとHTMLのbody見てもscriptタグが何個か有るだけで、内容はJS実行されるまで表示されませんでした。
universalならHTMLに書き出してくれるのでJS切っても見れます。

(本当かわからんけど)開発時(localhost)の時は別のタブで開けない?

記事を別のタブで開くと永遠に読み込んでたりするんだけどもしかして別のタブで開くことできない?

特に大変じゃなかったこと

PWA

PWAってめんどいんですよ。アイコン画像を用意するのがね!!!。
192x192だったり512x512だったりいっぱい要求してくるんですけど、
@nuxt/pwaは指定がない場合、static/icon.pngを使ってくれるので、512x512のpngを置いておくだけで終わりました。PWA RTA行けそう(は?)

一応nuxt.config.jsmanifest置いておきますね。

/** 
 * PWA manifest.json
 */
manifest: {
  name: 'たくさんの自由帳',
  title: 'たくさんの自由帳',
  'og:title': 'たくさんの自由帳',
  lang: 'ja',
  theme_color: '#8c9eff',
  background_color: '#5870cb',
  display: 'standalone',
}

ダークモード

Vuetifyなら

$vuetify.theme.dark = true

で終わります。Vuetifyすげー

ダークモード切り替えスイッチの例置いときますね。

<!-- ダークモードスイッチ -->
<v-switch
  class="text-center ma-2"
  :append-icon="`${$vuetify.theme.dark ? 'mdi-weather-night' : 'mdi-weather-sunny'}`"
  v-model="$vuetify.theme.dark"
  label="テーマ切り替え"
></v-switch>

三項演算子使うの初めてかもしれない(まずKotlinにはないし)

ところで$←これなに?

端末がダークモードかどうか

以下のJSでダークモードかどうかを監視して、Vuetifyのモードを変更するようにできます。
参考:StackOverflow

window
      .matchMedia("(prefers-color-scheme: dark)")
      .addEventListener("change", e => {
        const isDeviceDarkModeEnabled = e.matches;
        // Vuetify切り替える
        this.$vuetify.theme.dark = isDeviceDarkModeEnabled
      });

StackOverflow先生の回答ではe.matchesdarkかlightが入ってるっぽいんですが、私のChromeくんではtrueかfalseでした。先生の回答ちょっと古かったのかな。

まあダークモードなんてあんま使わないんですけどね(は?)

おわりに

学校始まるわ。早起きつっら
あと画像貼る方法確立してない。imgur使うか?