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起きました
エラー見ればどうってことないのですが、型が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でもsshかHTTPS認証を使えますが、ここでは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種類から構成される
-> ドメインからIPアドレスを調べてくれる(一定期間は、調べた結果をキャッシュしてくれる)
個人のPCにはスタブリゾルバってのがある
Macだと/etc/resolv.confに設定されている
cat /etc/resolv.conf // nameserverがresolver
その中身
whois 8.8.8.8 whois 4.4.4.4
ここで名前解決の流れを整理しとく
ドメインでwebページを見ようとする- > スタブリゾルバがフルリゾルバに問い合わせ
- > フルリゾルバがルートネームサーバに問い合わせる
- > ルートネームサーバが返り値を元に、ネームサーバにipアドレスが取得できまで問い合わせる
- > ipアドレスが取得できたら、webサーバーに問い合わせ
リソースレコード
ドメインとIPアドレスの結びつきのことA
ドメインのIPアドレスdig ドメイン名 a +short
// IPアドレスの持ち主を調べる
whois IPアドレス
NS
ドメインのゾーンを管理するネームサーバ// NSの調べ方
dig ドメイン名 ns +short
MX
ドメインのメール受信サーバ// MXの調べ方
dig ドメイン名 mx +short
googleのメールサーバ
先頭の10とか30はプリファレンス値 といってメールサーバが複数台ある場合の優先度を表す
これで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’) });
コンソールを確認する
クエリがしっかり取れてる
AdonisJSでLaravel(5.1)のチュートリアルしてみた
AdonisJSの紹介
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使いには馴染みのある構成ですね!
// devサーバー立ち上げ
cd laravel-tutorial adonis serve --dev
動作確認 localhost:3333にアクセス
今回は簡単のため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> </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というサイトを参照しました
下記のスクショをご覧ください
べき乗(**)がない!?
(修正はしておきました)
やはりMDNが最強ですね
developer.mozilla.org
キータだったり個人ブログでもわかりやすい記事や勉強になる記事が多いのも事実だと思います
(実際、私もかなりお世話になっております)
ただ、初めはや公式ドキュメントを参照するように心がけております
なんやかんや公式が一番信用できますからね
私がメンターを務めるTECH PLAY Academyでも
公式ドキュメントをなるべく参照するように生徒さんにお伝えしています
あの及川卓也さんも以前イベントでやはり参照すべきは公式だと以前仰っていました
ということで、公式が最強だねって話でした
書籍としてはこちらをリファレンス代わりに使っております