htmlから勉強してNuxt.js×Firebase(Cloud Firestore)で「リンク集共有サービス」をやっと作った話

先日リンク集共有サービス「Linksh」(リンクシュ)をリリースしましたので、
いろいろと備忘録的に残しておきます。

<img width="600" alt="Linksh" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31494/75a34909-663e-8189-a364-51b6cf3c9403.png">
リンク集共有サービス Linksh - リンクシュ
https://linksh.info/

## あんた誰？
コンテンツプロバイダー系のベンチャーで5年web制作、ディレクションを、
その後10年ほど某プロバイダーで総合職としていろいろやっておりました。
ただ、数年前に身体を壊して結構長い期間充電しておりました。それはもう長い期間です。
その間に仕事に関することもすっかり忘れてしまいましたが(医者に忘れろと言われたので)、
基本的に何か作ったりするのは大好きなので、プログラミングを気持ち新たに1から学ぼうと思った次第です。
そのアウトプットがコレです。

## どんなサービス？
リンク集共有サービスです。そのままです。
似ているところにブックマークの共有サービスは既にありますが、いくつかのブックマークを目的別にまとめて
リンク集として共有できるというのはまだないみたいです。
だから他になければ日本初ということでお願いします。

自分が知ってる良いサイトを他のユーザーに推薦できたり、他のユーザーが紹介しているリンクを自分のものにできたり、サイト回遊するだけでよいリンクを集められるよう工夫しています。ただし、キュレーション的な側面が大いにあるため情報が集まらないと価値が出ないという・・・。まあ気長に運営していきます。

##目的は？
真の目的は自分の学習のためです。罷り間違って話題になってくれれば名刺代わりに。(名前を覚えられるより〜を作った人だと覚えられやすいと思うので)

## 思いついたきっかけ
1年ちょい前から学習を始めた際、例えば今、Web制作ってどんな道具を使ってどういう流れでやってるんだ？
と思った時、情報の探し方がいけなかったのかなかなか答えが見つかりませんでした。
だから、今は設計はコレ、デザインはコレ、コーディングはコレ、みたいにまとまってるといいのになぁと思った次第です。漠然としてますね。そんな中、あ、やっぱりコレ作るわ、と決定づけた出来事がコレです。

https://mainichi-kotoba.jp/shared-links

現役新聞記者が部内で使ってる便利リンク集を公開したとのこと。このリンク集は
・文章を扱う企業はどこも役立つリンクである。
・専門職である人を介しているので信用性が高い。
・実際業務で使っている。
このような性質を持っており、リンク集自体が価値のある情報コンテンツだと感じました。

昨今、検索エンジンの質がよろしくないだとかチラホラ耳にしてはいたので、役立つサイトを見つける手段の一つになればいいなぁと。で、着手しました。

## どんなサーバー、プログラミング言語やツール等使ったの？
こういう時に対処できるのもLinkshの特徴です。こちらをご覧ください。
<img width="600" alt="スクリーンショット 2019-11-10 9.44.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31494/9a36a951-8bcc-5fe4-8e7b-6a4b6fd358e5.png">
https://linksh.info/linksh/v5qFgzAcRjG54HXkSZ2H

##### 管理モードの見え方
<img width="600" alt="スクリーンショット 2019-11-10 9.41.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31494/d412b90d-a27f-1c2c-3b26-ff55a5ef5463.png">

## 躓いたところは？
ほぼ全体的に躓いてました。特に時間かかったところをピックアップします。

##### Firebaseのプランの制限に引っかからないようなドキュメント構造
無料プランではドキュメントの読み取りが5万/日となっているため、サブコレクションなどアクセスが多くなるデータ構造にできないため、第一階層のドキュメントファイルを複数使い、データをローカルに一旦溜めてからごにょごにょして表示というやり方にしました。

(参考)【Firebase】Cloud Firestoreのデータ構造の決め方をFirebaseの動画から学ぶ
https://qiita.com/shiz/items/5f4c8ae19083ccdd46b2

##### OGPがうまく動かない
これは私のミスですが、上記の通り一旦ローカルにデータを落として表示するやり方はSSRじゃなくSPAなんですね。通常Facebookなどのスクレイピングや検索エンジンのクローラーがWebページをきちんと巡回できるようにするにはサーバーサイドでレンダリングするSSRを使用します。ですので、OGPで使う情報は別で取りに行くという方式にしています。(おそらくこれはまどろっこしいやり方ですので参考にしないでね。)

```ruby:ssr.sample
  //meta用SSR
  async asyncData({ store, params, route, error }) {
    return db.collection('linksh').doc(route.params.id).get()
      .then(doc => {
        let linkshData = {}
        if(doc.exists) {
          linkshData.title = doc.data().title
          linkshData.description = doc.data().description
        } else {
          linkshData.title = ''
          linkshData.description = ''
        }
        return { linkshData }
      })
      .catch(error => {
        console.log(error)
        return 
      })
  },

  //vuexを使う場合
  async fetch({ store, params, route }) {
    if(route.params.id) {
      await store.dispatch('getMeta', route.params.id)
    }
  }

```
##### マテリアルデザイン
流行りというのもありつつ、今回デザインにあまり時間を費やしたくなかったのでvue materialというフレームワークを使用しました。便利っちゃ便利です。ただカスタマイズがし辛い！ちょっとボタンの色変えたいと思っても時間がかかることが多かったです。一応やり方はあるのですが(タグの名前がcssの名前になっている)、それでもうまくできないこともあり、よく研究してから採用した方がよかったなと。他にも同様のフレームワークはありますしね。

Vue Material - Material Design for Vue.js
https://vuematerial.io/

##### バージョン管理
Nuxt.jsを動かすためのnodeが開発環境と本番環境でバージョンが違うので動かないとかです。初歩的なミスですよね。ただこういうのもあるんだーという発見もあったんで載せておきます。

hokaccha/nodebrew: Node.js version manager
https://github.com/hokaccha/nodebrew

NodebrewでNodeをインストールする - Qiita
https://qiita.com/mame_daifuku/items/373daf5f49ee585ea498

##### Nuxtのビルド
ビルドして本番反映するには、最初sshでサーバーにつないでgit pullして本番環境でビルドしてしてました。が、ビルド時間が40分もかかり、おまけにメモリが足んねーよエラーが出たりしました。

```ruby:test
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
```
で、検索しても意外と本番公開手順て載ってないんですよね。だからこれが正解かわかりませんが、以下のようにしました。

 1. ローカル上でビルドする
 - .gitignoreファイルを編集しdistと.nuxtを外す
 - (もし公開リポジトリであればプライベートにする)
 - commit and push
 - 本番環境でpull
 - npm installでモジュールのインストール(初回、必要な時のみ)
 - npm run startで公開
 
ローカル上でビルドを行っちゃうやり方です。

##### バグとの戦い
条件分岐が複雑なので非常に時間がかかりました。完成したのに1から組み直したくなる衝動に駆られました。

### 最後に
Webアプリ処女作にしては少し重かったかも。タイトルでhtmlから勉強してと書きましたが、そこまで含めると学習構想製作期間は1年半です。なかなか長い道乗りでした・・・。コードは汚いけどなんとか作りきったぞ。

今後はちょこっとずつコードを改善しつつ使いやすくしたり、新機能を追加したりしていきたいと思います。何気に今回がQiita初投稿なんですね。これからちょくちょく投稿したいと思います。