dala00の100DaysOfCode

2019-01-10に作成

頑張って100日間コードを書き続けます。

所有者限定モードのためこのボードには投稿できません ボードとは?

Day37

  • 質問の編集機能を作った
  • 画像の再アップロード機能を作った

day36

OGPを1種類作成した。なんかこんな感じで長さ計りつつcanvasでの文字の折返しに対応した。もっといい方法あるんだろうか。

  const lines: string[] = []
  let line = ''
  for (let i = 0; i < str.length; i++) {
    line += str.substr(i, 1)
    const metrix = ctx.measureText(line)
    if (metrix.width > width) {
      lines.push(line.substr(0, line.length - 1))
      line = line.substr(line.length - 1, 1)
    }
  }
  if (line.length > 0) {
    lines.push(line)
  }
  return lines

Day35

Expressでの画像出力を試した。ついでにルーティング周り改めて調べてみたけど色々面白いメソッドがある。formatとか。

res.format({
  text: function(){
    res.send('hey');
  },

  html: function(){
    res.send('<p>hey</p>');
  },

  json: function(){
    res.send({ message: 'hey' });
  }
});

Day34

記事ページをCDN通すようにした。来週まで様子見る。もしかしたら一体何をやってるのかほとんど誰にも通じてないかもしれないが、まあとりあえず記事書いていく。

まあこんな感じでテンプレート直書きで認証チェックはやめて全部Storeからのチェックにしてある。

- @if ($post->user_id && Auth::id() == $post->user_id)
- <div class="text-muted">
-   {{ number_format($post->access_count) }} views
- </div>
- @endif
+ <access-count></access-count>

Day33

ログイン後に認証情報をStoreにわたすようにした。リダイレクトすると渡せないので画面を表示して渡したらjs側でリダイレクト。その間ローディングを出すのでBootstrapで中央に表示。(メンテすることもないので雑に直接書いた…)

<div style="position: relative; height:100%;">
  <div style="position:absolute; top:50%; transform: translateX(-50%)
    translateY(-50%); left:50%;">
    <div
      class="spinner-border"
      style="width: 3rem; height: 3rem;"
      role="status"
    >
      <span class="sr-only">Loading...</span>
    </div>
  </div>
</div>

Day32

Laravelのテンプレートに直でログインによる分岐を入れているところをひたすらコンポーネント化してStoreの情報で分岐するようにしている。大変…。

例えばなんかこんな感じでVueテンプレート内でisLoginが使えるようになる。

import { Vue, Component, Prop } from 'vue-property-decorator'
import { mapGetters } from 'vuex'

@Component({
  computed: {
    ...mapGetters('auth', ['isLogin'])
  }
})
export default class MuComponent extends Vue {

Day31

  • Crieitのトップにもっとたくさん記事を表示できるようにした
  • 質問サービスのメタタグを調整中

こんな感じの関数でNuxt.jsにわたすhead用のオブジェクトを作成している。

export interface CreateHeadOptions {
  title?: string
  description?: string
  image?: string
}

export function createHead(options: CreateHeadOptions) {
  const head: any = { meta: [] }

  if (options.title) {
    const title = `${options.title} - 質問サービスタイトル未定`
    head.title = title
    head.meta.push({ hid: 'og:title', property: 'og:title', content: title })
  }

Day30

質問サービスの画像アップロードを作った。Cloud Storageへ。

  async upload(filePath: string) {
    const storage = new Storage({ projectId: process.env.GCP_PROJECT_ID })
    await storage
      .bucket(<string>process.env.STORAGE_BUCKET)
      .upload(filePath, {
        destination: this.path,
        gzip: true,
        metadata: {
          cacheControl: 'public, max-age=31536000'
        }
      })
  }

Day29

質問サービスの残っているページ対応を進めて大まかにはできてきた。

TypeORMでの回答数集計のコードとか。

  async updateAnswerCount() {
    this.answerCount = await Answer.count({ question: this })
    await this.save()
  }

Day28
質問サービスの質問登録や詳細画面を作った。登録処理とか。(実際には認証チェック必要)

const question = Question.create(req.body.question)
question.uniqueId = uuidv1()
question.user = await User.findOne(req.session.passport.user.id)
await question.save()
res.json({ question: question.toJson() })

Day27

  • OGPサーバーのキューイング処理を直した
  • 質問サービス作成のログイン周りを整備した
  • Crieitのトップページにボード一覧を表示するようにした

Day26

  • 認証のセッションでエラーになってた問題を解決した。
  • TypeORMのmigrationを自分で書く場合の情報が少なすぎてひたすら調査。なんとか動くようになった。

auto increment付きのprimary keyはこんな感じになってる。マニュアルにもないけどとにかくsyncして生SQLでやれって方針?

          {
            name: 'id',
            type: 'int',
            isPrimary: true,
            isGenerated: true,
            generationStrategy: 'increment'
          },

Day25

  • OGPサーバーにキューを入れて1リクエストずつ処理するようにした
  • 質問サービスの環境を構築した。Node.js+Express+TypeORMで動かなくてハマっていたのがようやく解決

とりあえずormconfigのentitiesのパスは下記のようにして決めてる。なぜビルドフォルダ内のormconfigを見てくれないのか…。

let path = 'src';
if (process.env.NODE_ENV == 'production') {
  path = 'build/' + path
}
module.exports = {
  entities: [
    `${path}/entity/**/*{.ts,.js}`
  ],
  migrations: [
    `${path}/migration/**/*{.ts,.js}`
  ],
  subscribers: [
    `${path}/subscriber/**/*{.ts,.js}`
  ],

Day24

コードは書いていないが、Angularの周辺環境について復習がてらいろいろ調べた。Component LibraryやSSRやPWAなど。


Day23

記事に画像がない場合にOGPを自動生成するようにした。

UbuntuのOGPサーバー内でダウンロードしてきたフォントを/usr/share/fonts/opentypeにコピーし、fc-cache -f -vで有効化。fc-listでフォント一覧を見ることができるのでそこに書かれているフォント名をCSSのfont-familyに指定。