わいの日記

ありがちエンジニアブログ

vue-i18n を TypeScript で静的型付けする

最近の気づきをメモがわりに。

vue(正確にはNuxt.js) + TypeScriptのプロジェクトでvue-i18nを導入して国際化対応しました。

vue-i18nのセットアップは公式をご参照ください。
https://kazupon.github.io/vue-i18n/


内容は実際とは違いますが、
やろうとしたことの大筋はこんなです。

// テキトーに言語セットを用意しておく
const messages = {
  en: {
    message: {
      hello: 'hello world'
    }
  },
  ja: {
    message: {
      hello: 'こんにちは、世界'
    }
  }
};


// App.vue 
export default class App extends Vue {
  message!: string; // messageをstringで片付け (今回のような形だと!を付けないと別のエラーが起きるので!付けてます)
  mounted () {
    this.message = this.$t('message.hello') //  'こんにちは、世界'というstringが入ってくることを想定
  }
}

上記でError起きました
f:id:exhikkii:20190420205745p:plain

エラー見ればどうってことないのですが、型がstringじゃないんですね
以下のようにすれば大丈夫です

import { TranslateResult } from 'vue-i18n'

export default class App extends Vue {
  message!: TranslateResult;
  mounted () {
    this.message = this.$t('message.hello')
  }
}


最近、vueよりもReact + TypeScriptが楽しい

『AmazonWebServicesアプリ開発運用入門』レビュー

久しぶりにAWSの勉強をしたのでレビュー&メモ

EC2で環境を構築してCD(continuous delivery)を構築してデプロイする流れをハンズオン形式で学ぶ内容です
8章から構成されていて、各章のテーマは以下のような感じです

第1章
クラウドとはなんぞやというところからAWSの概要を説明した後に、
AWSに登録し、請求アラートを設定します

第2章
CodeCommitの設定をします
CodeCommitでもsshHTTPS認証を使えますが、ここではHTTPS認証でした
windowsユーザ向けにgitの設定やaws cliの導入フォローもあって親切な内容だなと思いました


第3章
VPCを作成し、EC2を立てます
それからセキュリティグループの設定、ElasticIPの設定、EC2へSSH接続、サンプルアプリの動作確認
ここらはよくあるawsチュートリアルって感じですね

第4章
CodeBuildでアプリのビルドをできるようにします
ここで1回詰まりました
403エラーがでてCodeCommitにpushができなくなりました
accesskeyとか確認したりいろいろ試したのですが、1時間悩んでも解決できなかったので、
ssh接続に切り替えました
そしたらすんなりうまく行きました
なんでだろう

ビルドができるようになったら、アーティファクト(ビルドの成果物)をS3に配置するように設定
更にCodeDeployを使って、そのアーティファクトをEC2にデプロイ
最後にCodeCommit、CodeBuild、CodeDeployをCodePipelineで自動化
この章が内容盛り沢山でとても参考になりました

第5章
RDS
ここもawsの書籍でよくあるやつですね
DBインスタンス立てて、EC2と接続

第6章
またまたS3
今回はファイルのアップロード先としてS3を利用


第7章
SESでメールが飛ぶようにします
更にSNSとSQSで簡易的なバウンスメール対策を設定します

第8章
ELBとWAF
負荷分散とアクセスコントールですね


いい本だと思います
親切な内容で初心者にも優しいし、awsの復習にもなるし
個人的に辛かったのはサンプルアプリがJavaなので読むのがしんどかったぐらいです

DNSのまとめメモ

先日、DNSでめっちゃ頭悩まされたので復習とメモがてら


DNS(Domain Name System)

DNSサーバは下記の2種類から構成される

  • ネームサーバー(DNSコンテンツサーバー or 権威DNSサーバー とも呼ばれる)

  -> ドメインIPアドレスを結びつける

  • フルリゾルバ(DNSキャッシュサーバ or フルサービスリゾルバ とも呼ばれる)

  -> ドメインからIPアドレスを調べてくれる(一定期間は、調べた結果をキャッシュしてくれる)


個人のPCにはスタブリゾルバってのがある
Macだと/etc/resolv.confに設定されている

cat  /etc/resolv.conf // nameserverがresolver

その中身
f:id:exhikkii:20181123153234p:plain

それぞれのIPを調べたらGoogleDNSサーバみたい

whois 8.8.8.8
whois 4.4.4.4


ここで名前解決の流れを整理しとく

ドメインでwebページを見ようとする

  • > スタブリゾルバがフルリゾルバに問い合わせ
  • > フルリゾルバがルートネームサーバに問い合わせる
  • > ルートネームサーバが返り値を元に、ネームサーバにipアドレスが取得できまで問い合わせる
  • > ipアドレスが取得できたら、webサーバーに問い合わせ

リソースレコード

ドメインIPアドレスの結びつきのこと

A

ドメインIPアドレス

// ドメインのAレコード(IPアドレス)の調べ方

dig ドメイン名 a +short

// IPアドレスの持ち主を調べる

whois IPアドレス

NS

ドメインのゾーンを管理するネームサーバ

// NSの調べ方

dig ドメイン名 ns +short

MX

ドメインのメール受信サーバ

// MXの調べ方

dig ドメイン名 mx +short

googleのメールサーバ
先頭の10とか30はプリファレンス値 といってメールサーバが複数台ある場合の優先度を表す

f:id:exhikkii:20181123201210p:plain

これでaレコードを調べれば、IPアドレスまで調べられる

MXレコードがない場合は、
AレコードのIPアドレスにメールを送ろうとする

TXT(SPF(Sender Policy Framework))

ドメインのメール送信サーバ
用途:メールの送信元が詐称されていないか調べられる
そのドメインで、メール送信が許可されているサーバのリストが書かれている

// SPFの調べ方

dig ドメイン名 txt +short

SOA

ドメインのゾーン管理情報

PTR

IPアドレスからドメインを逆びきできる

// PTRの調べ方

dig -x IPアドレス +short

CNAME

ドメインの別名のリソースレコードの参照先
ドメイン名のCNAMEレコードのドメインのAレコードを探しに行く
これをIPアドレスが見つけられるまで繰り返す、最終的に見つかったものがcanonical name(正式名)

// CNAMEの調べ方

dig ドメイン名前 cname +short

CNAMEで先日ハマったところ

CNAMEを設定すると、他のレコードを設定できない
例えば下みたいなのが無理

waichan.work IN CNAME www.waichan.work
waichan.work IN NS hoge.example.com

awsのRoute53ではそもそも設定すら無理

ZONE APEX(サブドメインを含まないドメイン)はCNAMEを使えない
そもそもZONE APEXはNSレコードとSOAレコードがあるから。。。

Route53のAliasレコードならZONE APEXでも設定可能
しかも名前解決が1回で済むという機能も!
こうじゃなく CNAME -> A-> IP
こう Alias -> IP


しっかりawsもだけど、インフラの基本勉強しないと

AdonisJS クエリパラメータの取得の仕方

タイトルまんま

以下はhttp://localhost:3333?hoge=testにアクセスするとする

start/routes.js

Route.get('/',  ({ request }) => {
  console.log('query parameter', request.input('hoge’)
});

コンソールを確認する
f:id:exhikkii:20181121215252p:plain

クエリがしっかり取れてる

AdonisJSでLaravel(5.1)のチュートリアルしてみた

AdonisJSの紹介

adonisjs.com

MVCに則ったJavaScriptフレームワークです

PHPフレームワークの1つLaravelにめっちゃそっくりです

こちらを紹介する目的:JavaScripter人口増えたらいいな
PHPerがNode.jsに入る時にexpressだと取っつきにくいと思うんです
自分はめっちゃ苦労しました
それに比べたらAdonisJSはMVCなのでめっちゃ取っつきやすいと思います
Ruby on Rails使っている人にとっても学びやすいフレームワークかなと思います

そこでLaravelにそっくりということでLaravelのチュートリアルをAdonisJSでやってみます
基本のタスクリスト 5.1 Laravel


では早速
(AdonisJSのversionは4.1です)

// validateファイルの作成

npm i --global @adonisjs/cli

// プロジェクト作成

adonis new laravel-tutorial

ディレクトリ構造です
migrationsがあったりroutes.jsがあったりでLaravel使いには馴染みのある構成ですね!
f:id:exhikkii:20181119174616p:plain


// devサーバー立ち上げ

cd laravel-tutorial
adonis serve --dev

動作確認 localhost:3333にアクセス
f:id:exhikkii:20181119174811p:plain

今回は簡単のためdatabaseにsqlite3を使います
// sqlite3を追加

yarn add sqlite3

早速tasksテーブルを作ります
// tasksテーブルのマイグレーションファイル作成

adonis make:migration tasks

// 上記のコマンドのあと、「Choose an action Create table」この選択肢を選んでください

出来上がったmigrationファイル修正
upやdownの書き方もLaravelおなじみですね

'use strict'

/** @type {import('@adonisjs/lucid/src/Schema')} */
const Schema = use('Schema')

class TasksSchema extends Schema {
  up () {
    this.create('tasks', (table) => {
      table.increments()
      table.string('name') // この1文をを追記
      table.timestamps()
    })
  }

  down () {
    this.drop('tasks')
  }
}

module.exports = TasksSchema

// migration実行

adonis migration:run

// Taskモデルの作成

adonis make:model Task

下記の内容のmdoelクラスが作られる
// app/Models/Task.js

'use strict'

/** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */
const Model = use('Model')

class Task extends Model {
}

module.exports = Task

次にルーティングの設定
// start/routes.js

'use strict';

const Route = use('Route');
const Task = use('App/Models/Task');

Route.get('/', async ({ view }) => {
  const tasks = await Task.all();
  console.log('tasks', tasks.toJSON())
  return view.render('tasks', { tasks: tasks.toJSON() });
});

Route.post('/task', async ({request, response}) => {
  await Task.create(request.only(['name']));
  return response.redirect('/');
}).validator('Task'); // 後述するvalidatorを指定する

Route.delete('/task/:id', async ({params, response}) => {
  const task = await Task.find(params.id);
  await task.delete();
  return response.redirect('/');
});

次はview
AdonisJSはedgeテンプレートを採用しています
これもまたLaravelのbladeファイルの記法とそっくり
レイアウトファイルから作ります
// view/layouts/app.edge

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Laravel Tutorial with AdonisJs</title>
  // bootstrapをcdnで読み込む
  {{ style('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u') }}  
</head>
<body>
  <div class="container">
    <nav class="navbar navbar-default">
    </nav>
  </div>
  @!section('content') // section前の! を忘れないで
</body>
</html>

さらにtask.edge
// resources/views/task.edge

@layout('layouts.app')  //レイアウトファイルを指定

@section('content') // レイアウトファイルの@!section('content')に埋め込まれる
<div class="panel-body">
  @include('common.errors') // partialファイル(resources/views/common.errors)を読み込む
  <form action="/task" method="POST" class="form-horizontal">
    {{ csrfField() }} // CSRF「トークン」を生成
    <div class="form-group">
      <label for="task" class="col-sm-3 control-label">Task</label>
      <div class="col-sm-6">
        <input type="text" name="name" id="task" class="form-control">
      </div>
    </div>

    <div class="form-group">
      <div class="col-sm-offset-3 col-sm-6">
        <button class="btn btn-default">
          <i class="fa fa-plus"></i> タスク追加
        </button>
      </div>
    </div>
  </form>
</div>
@if(tasks.length > 0)
<div class="panel panel-default">
  <div class="panle-heading">
    現在のタスク
  </div>
  <div class="panel-body">
    <div class="table table-striped task-table">
      <thead>
        <th>Task</th>
        <th>&nbsp;</th>
      </thead>
      <tbody>
        @each(task in tasks) // tasksを一覧表示するためのループ
          <tr>
            <td class="table-text">
              <div>{{ task.name }}</div> // taskの名前を表示
            </td>
            <td>
    // deleteメソッドにするときはactionの末尾に_method=DELETEをつける
              <form action="/task/{{task.id}}?_method=DELETE" method="POST">
                {{ csrfField() }}
                <button>タスク削除</button>
              </form>
            </td>
          </tr>
        @endeach
      </tbody>
    </div>
  </div>
</div>
@endif
@endsection

// resources/views/common/errors.jsの作成

@if(hasErrorFor('name')) nameをkeyにするflashメッセージがあるか確認
  <div>
    <strong>おや?何かがおかしいようです!</strong>
    <br><br>
    <p>{{ getErrorFor('name') }}</p> // あれば表示
  </div>
@endif

最後にバリデーション
バリデーションは別途設定する必要があります
// validationの追加

adonis install @adonisjs/validator

// start/app.jsの修正してバリデーションを使えるようにする

const providers = [
  '@adonisjs/framework/providers/AppProvider',
  '@adonisjs/framework/providers/ViewProvider',
  '@adonisjs/lucid/providers/LucidProvider',
  '@adonisjs/bodyparser/providers/BodyParserProvider',
  '@adonisjs/cors/providers/CorsProvider',
  '@adonisjs/shield/providers/ShieldProvider',
  '@adonisjs/session/providers/SessionProvider',
  '@adonisjs/auth/providers/AuthProvider',
  '@adonisjs/validator/providers/ValidatorProvider' // ここを追加してください
]

// validateファイルの作成

adonis make:validator Task

// app/Validators/Task.js

'use strict'

class Task {
  // バリデーションのルールを決める
  get rules () {
    return {
      name: 'required|max:30'
    }
  }

  // エラーメッセージの設定
  get messages() {
    return {
      'required': '{{ field }} is required.',
      'max': 'max 30 characters'
    }
  }

  // sessionにエラーメッセージを設定
  async fails(error) {
    this.ctx.session.withErrors(error)
      .flashAll();

    return this.ctx.response.redirect('back');
  }
}

module.exports = Task

実際のコードを下記のリポジトリに置いています
github.com

このチュートリアルではcontrollerなども利用していないのですが、
AdonisJSにもちゃんとcontrollerがあります

他にもIOCなど類似の機能はあるのでぜひ公式リファレンスをご覧ください

個人的にはAdonisJSはバックエンドのapiサーバーをして利用する際に力を発揮すると考えます
expressに比べcorsなど設定が楽だと思います(個人比)
(adonis newする際にapiモードを指定すればviewが作成されなくなります)
またapiの方も紹介しようと思います

公式ドキュメントが一番信用できる

一番に参照すべきなのはやはり公式ドキュメントだなと思いました

JavaScriptではべき乗は従来はMath.powを使います

// 2の10乗
Math.pow(2,10) // 1024

es2016から下記のように書けます

// 2の10乗
2 ** 10 // 1024

JavaScriptのべき乗演算子に関して調べいたのですが、
その時にwikibooksというサイトを参照しました

JavaScript/演算子 - Wikibooks

下記のスクショをご覧ください

べき乗(**)がない!?

f:id:exhikkii:20181114200432p:plain

(修正はしておきました)

f:id:exhikkii:20181114200742p:plain

やはりMDNが最強ですね
developer.mozilla.org

キータだったり個人ブログでもわかりやすい記事や勉強になる記事が多いのも事実だと思います
(実際、私もかなりお世話になっております)

ただ、初めはや公式ドキュメントを参照するように心がけております

なんやかんや公式が一番信用できますからね

私がメンターを務めるTECH PLAY Academyでも
公式ドキュメントをなるべく参照するように生徒さんにお伝えしています

techplay.jp

あの及川卓也さんも以前イベントでやはり参照すべきは公式だと以前仰っていました

techplay.jp


ということで、公式が最強だねって話でした

書籍としてはこちらをリファレンス代わりに使っております