- 投稿日:2020-09-18T21:57:14+09:00
Amplifyのbundleサイズを5MB減らした
自分の運営しているサービス(VRCSnap!)のPageSpeed Insightsを久しぶりに測ったらモバイルのスコアが大変なことになってた
VRCSnapはこんな感じの、VRChat関連でアバターが写ってる画像ツイートを紹介するサービスです
Nuxt, Amplify(AppSync)環境で作ってます
それで肝心のスコアは・・・
に、にじゅうなな・・・(PCは87でした)
で、twitterのwiget.jsの読み込みをbodyタグ内にしたり(body: tureを入れる)
nuxt.config.jsscript: [ { src: 'https://platform.twitter.com/widgets.js', body: true } ],@nuxtjs/deviceを入れてモバイルの時だけツイートの読み込み数を減らしして48まで上げることができました
後はwebpackを小さくするくらいかなと思ってbundleサイズを見てみると
aws-sdkと@aws-amplifyがめっちゃでかい
なんとかならんもんかと思って調べてみると、Amplify公式に丁度いい記事が
これまでamplify.jsは以下のようにしていたのですが、これだと上の画像のようにaws-sdkを全部インポートするのでかなり重い
amplify.jsimport Amplify from 'aws-amplify'; import aws_exports from './aws-exports'; Amplify.configure(aws_exports);そこで、使用するカテゴリだけインポートするようにする(今回の場合は@amplify/coreの他は@amplify/apiのみ)
amplify.jsimport Amplify from '@aws-amplify/core'; import API from '@aws-amplify/api'; import aws_exports from './aws-exports'; Amplify.configure(aws_exports);個別のコンポーネントでも、aws-amplifyからではなく@aws-amplify/apiからインポートする
import API, { graphqlOperation } from '@aws-amplify/api'そうするとbundleサイズが5MBほど削減できました
PSIのスコアも63に
な、なんとか50を超えた・・・!
後はvue-awesome-swiper(カルーセル)が結構重かったりするので、色々整理します
こんな感じで、Amplifyが重い!って言う人の参考になれば幸いです
- 投稿日:2020-09-18T19:32:42+09:00
検索条件(get)を複数ページ持ち越す方法
開発中に以下のような遷移時にgetパラメターを持ち越せず苦戦。
①ページ内で検索(get)
②検索結果表示
③検索結果を並び替え(get)
調べてみるとページネーションの際などでも結構はまっている人がいるっぽい。
自分なりに解決した方法が以下。③の処理の際にurlのパラメターをhideで投げる。
<input type="hidden" name="condition" :value="setGetParams()"> setGetParams() { return window.location.search },urldecodeでパラメータと並び替えの条件を合体させurl作成⇒リダイレクト
public function action_result() { $get = \Input::get(); //urlのパラメターが投げられていたら以下処理 if(!empty($get['condition'])): $url = urldecode(\Uri::current().$get['condition']); $url = $url.'&order='.$get['order']; \Response::redirect($url); endif; //パラメータが投げられていなければ通常の検索処理 $data = Model_Data::search($get); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~多少強引ですが以下で検索条件をページを跨いでも引き継げます。
- 投稿日:2020-09-18T18:10:39+09:00
Vue + typescript ~vue-class-component, vue-property-decorator って何?~
はじめに
この4月から入った会社がvue.jsを使って開発をしているので、vue.jsを勉強しています。
コードを読んで似たような処理を行う箇所を探してやっている処理を推論して参考にして書くことを繰り返していても理解は深まらないので、vue.jsってそもそもなんなの、ってところからvueの書き方色々を調べてみてまとめようかと思います。
いろんな記事を読んで、そこから自分が知りたかったことを抜粋してまとめてる感じです。Vue.jsについて
Vue.jsとは
Vue.jsとは、javascriptのフレームワークの内の一つ。他のjavascriptのフレームワークで代表的なものには、ReactやAngularなどがある。
javascriptのライブラリとして有名なものにjQueryがあったが、SPD(Single Page Application)を用いたwebサイトの増加等、フロントエンド側に開発主体が移りつつある中で、DOMの操作を全て手動で行わなければいけないという面倒臭さがあり、それに対応するように新たな上述のフレームワーク群が登場した。
そうしたフレームワークの中でも、Vue.jsは低い学習コストで開発が始められるのが特徴。AngularやReactと比較してフレームワークの規模が小さい分、覚えることも少ない。JavaScriptやjQueryの基礎知識があれば数時間の学習で開発を開始することができる。(らしい)
Vue.jsと他のフレームワークとの比較
React
ReactはFacebookが開発を主導している、JavaScriptフレームワーク。
- viewに関する機能のみを提供 : 自由なライブラリの選定が可能
- JSX記法 : JavaScriptで記述することができ、導入・学習コストが高くない。
- virtualDOM : 実際のDOMへの操作より高速・軽量に操作可能な仮想DOM
- Vue.jsと違いReactの場合、データバインディングがデータから画面(HTML)に行く片方向のみ。
- Angular、Vue.jsと比較すると、Reactは日本語での記事や書籍が少ない。
Angular(AngularJS)
AngularはGoogleと個人や企業のコミュニティから開発されたJavaScriptフレームワーク。
- フルスタックフレームワーク : 技術選定や各ライブラリの相性問題に悩まさない一方、柔軟性もない
- typescriptが前提 : フレームワーク以外に、typescriptの学習コストもかかる
- 双方向データバインディングの実現
vue.js
Evan Youという個人が開発したフレームワーク。
vueはReact, Angularよりも後発で、両者のいいとこ取りをしている感じ。
- 低い学習コスト : AngularやReactと比較してフレームワークの規模が小さい分、覚えることも少ない。JavaScriptやjQueryの基礎知識があれば数時間の学習で開発を開始することができる。(らしい)
- Virtual DOMを採用
- 双方向データバインディングも採用
- HTTP通信やルーティングなどは別ライブラリと組み合わせて実現する方式
Vue + typescriptの書き方
さて、では本題。
Vueにtypescriptを導入する場合、Vue.extend
とvue-class-component
を使う二つの書き方ができるらしい。vue-class-componentってなに?
TypeScript(.tsファイル)でコンポーネントが書けるようになる。
Componentデコレータをつけて、Vueを継承したクラスとして書く。
例えば、空のコンポーネントはこんなかんじらしい。import Vue from 'vue' import Component from 'vue-class-component' @Component class MyComponent extends Vue{ }書き方
- data : クラスの変数として書く
- computed (算出プロパティ) : getterとして書く
- methods : 普通にメソッドとして書く
- ライフサイクルフック : 名前を合わせてメソッドとして書く
詳しくはvue-class-componentを見れば大体わかるらしい。ソースコード読むの大事。
vue-property-decoratorってなに?
vue-class-componentをさらに使いやすくするためのもの。
vue-class-componentではpropsなどはComponentデコレータの中に書いていく。import Vue from 'vue' import Component from 'vue-class-component' @Component({ props: { hoge: String } }) class MyComponent extends Vue { }vue-property-decoratorを使うと、デコレータを使って書ける。
import Vue from 'vue' import Component from 'vue-class-component' import { Prop } from 'vue-property-decorator'; @Component class MyComponent extends Vue { @Prop({ type: String }) hoge: string }クラスメンバとしてかけるため、嬉しい。
詳しくはvue-property-decorator。ちゃんとソースコード読まねば。
vue.extend
vue-class-component
の書き方比較例えばこんなVue.jsコードがある場合、
<template> <div class="hello"> <h1>{{ msg }}</h1> <p>{{ saySomething() }}</p> </div> </template> <script> export default { name: "HelloWorld", props: { msg: { type: String }, }, methods: { saySomething() { const something = "something"; return something; }, }, }; </script>
Vue.extend
を使うとこうなり,<template> <div class="hello"> <h1>{{ msg }}</h1> <p>{{ saySomething() }}</p> </div> </template> <script lang="ts"> import Vue from "vue"; export default Vue.extend({ name: "HelloWorld", props: { msg: { type: String }, }, methods: { saySomething(): string { const something = "something"; return something; }, }, });
vue-class-component
を使うとこうなる<template> <div class="hello"> <h1>{{ messsag }}</h1> <p>{{ saySomething() }}</p> </div> </template> <script lang="ts"> import { Component, Prop, Vue } from "vue-property-decorator"; @Component export default class HelloWorld extends Vue { @Prop() private msg!: string; saySomething(): string { const something = "something"; return something; } } </script>
vue.extend
を用いる記法は、従来のvue記法と変わらずわかりやすい。
vue-class-component
の書き方は、コード記述が全くと言っていいほど変わっている。でも、何が何に対応しているとかちゃんとわかれば、大丈夫そう。
勉強頑張ります。参考記事
Vue.js概要、フレームワーク比較
- Vue.jsとは何かを現役エンジニアが解説【初心者向け】 : 概要を掴むのに良い
- qiita : Vue.js概要? : 詳しく書いてあるから今度ちゃんと読みたい
- 【Vue.js入門】特徴や他のフレームワークとの比較などを紹介! : 他のフレームワークとの比較をさらっと読める
- 3大フロントエンドフレームワーク(React・Angular・Vue.js)について : 一個上の記事より詳細に書いてある
- 私たちはなぜReactではなくVue.jsを選んだのか : 実際に使ってる人の感想って感じで面白い
Vue.js + typescriptの記法に関して
- Vue.js : TypeScript のサポート : 公式ドキュメント大事
- Spice Picks : Vue v3前夜のTypeScript事情をまとめた : Vue3.0にも触れてる
- qiita : TypeScriptではじめるVueコンポーネント(vue-class-component) : 概要がよくまとまっていてわかりやすい
- qiita : はじめてのvue-property-decorator (nuxtにも対応) : 実際の書き方がまとまってる!コーディングの際に参考になる
- 投稿日:2020-09-18T18:10:39+09:00
Vue + typescript について(vue-class-component, vue-property-decorator って何?)
はじめに
この4月から入った会社がvue.jsを使って開発をしているので、vue.jsを勉強しています。
コードを読んで似たような処理を行う箇所を探してやっている処理を推論して参考にして書くことを繰り返していても理解は深まらないので、vue.jsってそもそもなんなの、ってところからvueの書き方色々を調べてみてまとめようかと思います。
いろんな記事を読んで、そこから自分が知りたかったことを抜粋してまとめてる感じです。Vue.jsについて
Vue.jsとは
Vue.jsとは、javascriptのフレームワークの内の一つ。他のjavascriptのフレームワークで代表的なものには、ReactやAngularなどがある。
javascriptのライブラリとして有名なものにjQueryがあったが、SPD(Single Page Application)を用いたwebサイトの増加等、フロントエンド側に開発主体が移りつつある中で、DOMの操作を全て手動で行わなければいけないという面倒臭さがあり、それに対応するように新たな上述のフレームワーク群が登場した。
そうしたフレームワークの中でも、Vue.jsは低い学習コストで開発が始められるのが特徴。AngularやReactと比較してフレームワークの規模が小さい分、覚えることも少ない。JavaScriptやjQueryの基礎知識があれば数時間の学習で開発を開始することができる。(らしい)
Vue.jsと他のフレームワークとの比較
React
ReactはFacebookが開発を主導している、JavaScriptフレームワーク。
- viewに関する機能のみを提供 : 自由なライブラリの選定が可能
- JSX記法 : JavaScriptで記述することができ、導入・学習コストが高くない。
- virtualDOM : 実際のDOMへの操作より高速・軽量に操作可能な仮想DOM
- Vue.jsと違いReactの場合、データバインディングがデータから画面(HTML)に行く片方向のみ。
- Angular、Vue.jsと比較すると、Reactは日本語での記事や書籍が少ない。
Angular(AngularJS)
AngularはGoogleと個人や企業のコミュニティから開発されたJavaScriptフレームワーク。
- フルスタックフレームワーク : 技術選定や各ライブラリの相性問題に悩まさない一方、柔軟性もない
- typescriptが前提 : フレームワーク以外に、typescriptの学習コストもかかる
- 双方向データバインディングの実現
vue.js
Evan Youという個人が開発したフレームワーク。
vueはReact, Angularよりも後発で、両者のいいとこ取りをしている感じ。
- 低い学習コスト : AngularやReactと比較してフレームワークの規模が小さい分、覚えることも少ない。JavaScriptやjQueryの基礎知識があれば数時間の学習で開発を開始することができる。(らしい)
- Virtual DOMを採用
- 双方向データバインディングも採用
- HTTP通信やルーティングなどは別ライブラリと組み合わせて実現する方式
Vue + typescriptの書き方
さて、では本題。
Vueにtypescriptを導入する場合、Vue.extend
とvue-class-component
を使う二つの書き方ができるらしい。vue-class-componentってなに?
TypeScript(.tsファイル)でコンポーネントが書けるようになる。
Componentデコレータをつけて、Vueを継承したクラスとして書く。
例えば、空のコンポーネントはこんなかんじらしい。import Vue from 'vue' import Component from 'vue-class-component' @Component class MyComponent extends Vue{ }書き方
- data : クラスの変数として書く
- computed (算出プロパティ) : getterとして書く
- methods : 普通にメソッドとして書く
- ライフサイクルフック : 名前を合わせてメソッドとして書く
詳しくはvue-class-componentを見れば大体わかるらしい。ソースコード読むの大事。
vue-property-decoratorってなに?
vue-class-componentをさらに使いやすくするためのもの。
vue-class-componentではpropsなどはComponentデコレータの中に書いていく。import Vue from 'vue' import Component from 'vue-class-component' @Component({ props: { hoge: String } }) class MyComponent extends Vue { }vue-property-decoratorを使うと、デコレータを使って書ける。
import Vue from 'vue' import Component from 'vue-class-component' import { Prop } from 'vue-property-decorator'; @Component class MyComponent extends Vue { @Prop({ type: String }) hoge: string }クラスメンバとしてかけるため、嬉しい。
詳しくはvue-property-decorator。ちゃんとソースコード読まねば。
vue.extend
vue-class-component
の書き方比較例えばこんなVue.jsコードがある場合、
<template> <div class="hello"> <h1>{{ msg }}</h1> <p>{{ saySomething() }}</p> </div> </template> <script> export default { name: "HelloWorld", props: { msg: { type: String }, }, methods: { saySomething() { const something = "something"; return something; }, }, }; </script>
Vue.extend
を使うとこうなり,<template> <div class="hello"> <h1>{{ msg }}</h1> <p>{{ saySomething() }}</p> </div> </template> <script lang="ts"> import Vue from "vue"; export default Vue.extend({ name: "HelloWorld", props: { msg: { type: String }, }, methods: { saySomething(): string { const something = "something"; return something; }, }, });
vue-class-component
を使うとこうなる<template> <div class="hello"> <h1>{{ messsag }}</h1> <p>{{ saySomething() }}</p> </div> </template> <script lang="ts"> import { Component, Prop, Vue } from "vue-property-decorator"; @Component export default class HelloWorld extends Vue { @Prop() private msg!: string; saySomething(): string { const something = "something"; return something; } } </script>
vue.extend
を用いる記法は、従来のvue記法と変わらずわかりやすい。
vue-class-component
の書き方は、コード記述が全くと言っていいほど変わっている。でも、何が何に対応しているとかちゃんとわかれば、大丈夫そう。
勉強頑張ります。参考記事
Vue.js概要、フレームワーク比較
- Vue.jsとは何かを現役エンジニアが解説【初心者向け】 : 概要を掴むのに良い
- qiita : Vue.js概要? : 詳しく書いてあるから今度ちゃんと読みたい
- 【Vue.js入門】特徴や他のフレームワークとの比較などを紹介! : 他のフレームワークとの比較をさらっと読める
- 3大フロントエンドフレームワーク(React・Angular・Vue.js)について : 一個上の記事より詳細に書いてある
- 私たちはなぜReactではなくVue.jsを選んだのか : 実際に使ってる人の感想って感じで面白い
Vue.js + typescriptの記法に関して
- Vue.js : TypeScript のサポート : 公式ドキュメント大事
- Spice Picks : Vue v3前夜のTypeScript事情をまとめた : Vue3.0にも触れてる
- qiita : TypeScriptではじめるVueコンポーネント(vue-class-component) : 概要がよくまとまっていてわかりやすい
- qiita : はじめてのvue-property-decorator (nuxtにも対応) : 実際の書き方がまとまってる!コーディングの際に参考になる
- 投稿日:2020-09-18T17:01:49+09:00
〇〇のセールを見逃さないサービス作りました。【AV半額オブザーバー】
はじめに
みなさんは、AVのセールを見逃して後悔した事はありませんか?
私にはあります。と言うことでAVの割引を見逃さない為のサービスを作りました。具体的に言うと、割引になってる作品を人気順の一覧で見れるページと、会員登録から『指定の作品が割引になったとき』のみ通知を送るページを通して、より便利な購入体験を提供します。
https://hao.japaneast.cloudapp.azure.com (18歳未満はアクセス禁止です)
出来ること
①割引作品を人気順に表示
これが一応メインコンテンツですね。紳士淑女のみなさんはFanzaから定期的に似たようなメールが届くかもしれませんが、メールをいちいち確認するのって面倒じゃないですか?
しかもキャンペーンページは一時的な物なのでブックマーク出来ません。なので割引作品の一覧を毎日更新し、人気順に表示するリストを作成しました。両サイドにはリストの前後40件の作品画像を背景として使用しています。一覧性という面ではかなり拘った仕様なので、使っていただけると幸いです。
②女優別で割引作品をリスト化
例によって黒塗りの多い画面ですが、女優さんの名前を登録すると出演作品が割引になった場合自動でリストに表示する事ができます。お気に入りの女優さんの作品がセールになってないか確認したい。そういう時にぜひご活用ください。
③マイリストを設定
URLを直接入力することで監視リストに動画を追加することができます。Fanzaにも似たような機能はあるのですが、ポチポチって押してるとすぐリストの件数が膨れ上がりがちなので、「これぞ!」と思うお気に入り動画の記録にオススメです。
開発の舞台裏
「個人開発だし、どうせフロントはJSで書くからNode.js使おう」
技術選定に関しては多分ここから始まったと思います。PHPという選択肢もあったのですが、今更感が強かったので今回は不採用。逆にフロントは詳しくなかったので資料が充実しているVue.jsを選びました。インフラはKeyVaultなる素敵機能を使ってみたかったのでAzureです。
(大正義KeyVault君、実際これが無ければ普通にAWS選んでた気がする)
大まかな開発の流れとしては
①設計
②バッチの実装
③バックエンドの実装(ルーティングとか主要なAPI)
④フロント(htmlやVue.js)の実装
⑤バックエンドの修正(フロントを実装した事でバグや考慮漏れが多数発覚)
⑥デザイン
⑦インフラ周りの設定とか
⑧リリースという感じだったような気がします。一応番号は振りましたが④⑤⑥に関しては「プロトタイプが欲しい」「今日はデザインの気分じゃない」「あれ実装してないじゃん」みたいな理由で結構反復横跳びしてますね。
まあ時系列順に振り返ると、設計に関しては結構グダりました。
というのも、今までオープン系のアプリ開発しかやったことがないし、ましてや設計なんて初めてなので、「DBから作ろうぜ!」って発想になる訳です。まあこれも依存の方向から考えると一定の合理性はあるのですが、そうなると問題なのが「アレこうした方が良くね(仕様変更)(仕様漏れ)」からの「DB設計直さなきゃ駄目じゃん……」からの「既存設計に引きずられて苦しい………(死)」となる黄金パターン。今回はどっぷり嵌りました。
ねー、WebバックエンドのDB設計なんて機能が増えれば当然カラム増えるのになんで最初にやったんだろね。
今から思えば裏側はモックに留めてフロントから仕様をガチッと固めてしまうのが最速な気がしますが、その反省は次回に活かすとします。
そしてある程度設計が固まってから実装に取り掛かったのが5月の頭ですね。
この段階ではフロントエンド全然わからんマンだったのと、バックエンドもいきなりWebサーバ書くのは脆弱性作りそうだったので消去法でバッチから作り始めました。(その結果、後で半分以上書き直しになった)特に大変だった所は無いと思いますが、JSをガッツリ書くのは何気に初めてだったので、バッチ処理全体を書くのに丸々1か月も掛けてしまいました。Promiseが全然分からなくて死んでたり、コードのどこが非同期処理で動いてるのか今一掴めずに「forが動かねぇ……」って絶望してたのも今となっては懐かしい思い出です。
6月は丸々ルーティングとHTML、ログイン認証の実装に使いました。
後述しますが、特にログイン機能の実装は結構大変でした。まず認証が通らなかったり、逆にどんな値でも通ったり、通ってもセッションを保持できなかったりとてんやわんやです。SNS認証とか実装しなくて本当に良かった7月はようやく機能とデザインの実装です。
CRUDとかバックエンドの側の実装は6月から並行でちょいちょい着手してたのですが、いざ動かしてみたら変な所で止まったりバグッたりと散々だったので、実質書き直しになりましたね。デザインに関してはTailwindCSSを使って見たのですが、今思えば教養として素のCSSを書いたほうが良かったかもしれません。TailwindCSS、作る時は便利なんですがHTMLが汚くなるし、
sm:invisible
するとSafariで表示崩れるし、運用フェーズだと都度都度ビルド要るしでなかなか面倒。
8月前半は細かいデバッグや表示の追加をメインに行いました。レスポンシブの対応とかもそうですが実際使ってみると思ったより使い勝手微妙だなみたいな感じになったので位置を修正したり、ツールチップを実装したりしました。表示に関してはあまりゴテゴテするのも良くないかもとか思ったけど、余白を生かしたデザインとかアレはアレで高度芸能(素人は手を出さない方が無難)なので、今回は出来るだけ詰め込んでみました。次回作はもっとゴリゴリに表示を動かしたいを思います。8月後半は予定を繰り上げてAzure上にVMを立ち上げ、テスト環境を構築。
まあ私のTwitter見てる方は既にご存知かもしれませんが、詰まりに詰まり散らかしました。うん、何というか3ヶ月半掛けて作った動くはずのアプリが突然動かなくなったら焦るよね。
まあ原因の9割はmysqlのせいだったんですけど、テーブル名にキャメルケースを使ってはいけない。大事な事なのでもう一回言うけど、テーブル名にキャメルケースを使ってはいけない。Do you understand?
データベースオブジェクトの命名規約9月はほぼ消化試合でしたね。本番移行って言っても丸々同じ手順を繰り返すだけですし、まあ強いて言えば、ここに来てダダ下がりしたモチベの維持が大変でした。リアルでも色々忙しかったのもあり、ここの工程はボリューム的には正味一週間ぐらいで終わりそうな感じだったのですが、何やかんやで丸1か月掛かりました。
ちなみにAzureのVMやKeyVaultで幾らか詰まると思ったのですが、その辺りは意外にも公式ドキュメントだけですんなり構築できました。流石マイクロソフト謹製のPaaSですね。ネタに出来なくて残念です
出来なかった事
・TypeScript
・Nuxt.jsとかのナウいフレームワーク
・綺麗なコード
・自動テストとか
まあ今回の1件でJavaScriptとSQLさえ書ければ全てが解決するという事を証明してしまったので、学習意欲はわりかし低めです。下2つは時間があったら極めたいなと思いつつ「時間があったら」などと逃げ口上かましてる時点でやる気無いんだよなぁ みつお
それにTypeScriptは記法の癖が強いし、Nuxt.jsも何というか色々勝手にやってくれる代わりに覚えること多いしで、個人的にあんまり好きじゃないです。あときれいなコードは目指したかったんだけど、それが開発速度を担保してくれるかって言うとそうでもないので、動いて読めてそこそこ整理されてればいいかって感じに妥協しました。
一つ反省点を上げるとすれば、自動テストを導入するかどうかをさておいても、テスタブルな実装は目指すべきだったなと思います。具体的な所で言うと、APサーバの実装で内部の処理とレスポンスの返却を同じメソッドに書いてしまった結果、単体でテスト出来ないコードが生まれたりって感じですね。インターフェースいちいち考えるの面倒くさかったとは言え、最後のテストが地味に大変だったので、ここはもうちょっと拘っても良かった気がします。
頑張った点とか
①自動ログイン
これは今日日どんなサイトでも付いてる機能なのでどうにか実装したかったのですが、結構手間取りました。というのもnode-modulesにあるpassport君は自動ログインをサポートしてないので、認証の発火とCookieへの読み書き、ハッシュ化したトークンの生成や管理は自前で実装する必要があります。
(あれ?これもう自分でミドルウェア実装したほうが早くない?)まあ最終的にランダムかつ一意なハッシュを定期的にセットし、passport経由で認証を通すことに成功しました。まあメッセージ返す部分は結局解決できなくて、ログイン認証の前に「ログイン認証のメッセージ」を返すAPIを叩くことで解決しました。悔しい……
②女優検索DBはmysqlなのですが、流石にLike検索で返すのは遅い&不便なので、ngramによるフルテキストキーを貼ってあいまい検索を実装しています。細かい調整とかは出来なかったのですが、まあまあ実用範囲かなと、本当はサジェストとかやりたかったんですが、それは次回の宿題ですね。
③ツールチップ
これはログイン先にあるマイページでの演出なのですが、URLや縮小画像にマウスカーソルを持っていくと近傍にオリジナルのパッケージ写真を表示するようになっています。実装としてはシンプルにJSでイベントを発火してdiv要素の内容とCSSを都度都度DOMで書き換える感じです。ただ何故かz-indexが適用されず、悩みに悩んで一日詰まった結果、div要素の位置を5回ぐらい変更してようやく適応される位置を見つけることが出来ました。
④reCAPTCHA
このサービス、実はそこそこセキュリティにも力を入れていて、ログイン画面にはDDoSにも対応したBOTの検出機能を実装したりしています。ただ登録画面に関しては人とBOTを区別するのは難しいのでreCAPTCHAを使用しました。セキュリティ上バックにも実装が必要って言うのは分かりますが、フロント側で一度作り込んだJSを書き換えるのは結構ヒヤヒヤしました。登録時に実際のURLが必要ですが、実装するなら最初からテンプレートを組み込んでコメントアウトしておいた方が良いです。
ちなみにバックの実装はこんな感じの関数を書いて適宜叩けばOKなので意外と楽でしたね。reCAPTCHAfunction reCaptcha(token){ if(!token){ console.log("Error token is null"); return false; } let options = { url: 'https://www.google.com/recaptcha/api/siteverify', method: 'POST', form: { secret:/*シークレット*/, response:token }, json: true } request(options, (error, response, body) => { if (error) { console.log(error); return false; } // 閾値により判定する if (body.score < 0.5) { return false; }else{ return true; } }); }
⑤Slackの活用
通知の送信用として使用しているG Suiteには2000通/日の送信制限があります。まあ制限にかかることは無いと思いますが、容量を無駄に削るのも嫌なので、自分宛ての通知(お問い合わせとか鯖の情報とか)はバックエンドからSlackAPIを経由して送信するようにしています。これが中々便利で、メールと違ってスマホにプッシュ通知が出るので通知を見逃すという事もありません。これから個人開発を始めようという方はぜひ使ってみて下さい。
詰まった所とか
①Promise
最初はメソッドチェーンとか面倒臭いなって感想しか出てこなかったんですが、短い関数でちゃっちゃっとPromise返したら、async/awaitで普通に同期実行できると知ってすぐに手のひらクルーしました。
便利ですねこれ。………………え?まだコールバック関数とか使ってる人居るんですか?
Promise自体の説明に関してはやめ太郎さんの書かれた記事が日本一分かりやすいので是非どうぞ
4歳娘「パパ、Promiseやasync/awaitって何?」〜Promise編〜
②passport前述の通りログイン関係でPassportを使っているのですが、ログインした後セッションを有効化出来ないという現象が発生しました。具体的にはユーザー情報が入ってるはずのreq.userが何故かundefinedのまま……………
まあ結論から言えば犯人はAxios君でしたね。axios.defaults.withCredentials = true;を適当な所に書いてあげれば、認証情報を含むCookieをサーバに送信できるようになります。
③Cheerioスクレイピングと言えばCheerio君。ただコイツには結構苦労させられました。結論から言えば近傍5つ以内にClassが振ってない要素を取得するには新卒Sierを秒で退職してMicrosoftに就職を成功させるぐらいの豪運を必要とします。実質砂金掘りですね。
必要な要素が取れないときは闇雲に試行回数を増やすよりも、別のページから同じ情報が取れないか探したり、PCの電源ケーブルを抜き差ししたり、懐かしのゲームを楽しむのが肝要です。実際私も自棄になり、開発をほったらかして一日中エスコン6をプレイしていたら何故か要素が取れない問題が解決しました。
あと
each
で要素の取得をぶん回すとき、attr("href")
は先にfind("a")
を指定しないとちゃんと拾ってくれないので気を付けましょう。
④Vue.jsまあこれに関しては後で別の記事に起こそうと思いますが、特に苦労した部分だけでも紹介したいと思います。
・v-modelの変更を監視してイベントを発火したい。まあ誰しも一度はやると思いますが、
<input v-model="hoge" @change="huga()">
みたいな感じのやつです。
ちなみに↑のコードはv-model
と@change
でイベントリスナーが二重になってるので@change
は動きません。
一応公式ではv-modelをv-bindに書き換える方法が推奨ですが、v-bindだと何故かバインド出来ない現象が発生したので別の対策を講じます。(←今思えば普通にタイポだった可能性ある)対策、new Vue()の時にmodelのリスナーを追加する
let vue = new Vue({ el:'#app', data:{}, watch:{/*監視したいv-modelの名前*/:function(){ //変更があった時に走らせたい処理を記述 }} });
・new Vue()の中からMethodsのメソッドを呼びたい。当然ですが
this
が必要です。この例に限らず、Vueでundefined
って怒られた時はまずthis
の付け忘れを疑いましょう。
⑤LinuxこれLinux(Ubuntu)君は全然悪くないけど、環境移行する時に結構詰まったので覚え書きを残しておきます。
まずアプリを雑にインストールするとWindowsとバージョンが違うという事を肝に命じておくべきだと思う。Node.jsとか結構顕著で、何と12.18.3 LTSだと
try{hoge()}catch{/*何もしない*/}
みたいな変な文法のコードを書いても普通に動いたりする。動くなやあと一度やった変更はメモったほうが良いですね。ミスした時もリカバリが効きやすいのと、環境立て直す時「何かCronの動きがおかしい」→「時刻設定がグリニッジ標準時でした」とかやりがちなので対策したほうがベターです。
⑥mysqlリピートアフターミー、テーブル名にキャメルケースを使ってはいけない。
何故かって言うと雑にmysqlをインストールした時、WindowsとLinuxでバージョンが違うから。8.0(win)だと
CREATE TABLE
の時に名前を全部小文字にしやがるしてくれるけど、5.7(Lin)だと普通に通る。なので突然テーブルが見つかりませんとか言われて死にます。死にました。あとLinux版は権限周りが固いっぽいので、雑にパスワードを設定すると
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
で怒られます。良い子のみんなはRSA2048に記号挟んだパスワードをぶち込んでいこうな!
まとめ
作り終わった今だから思うのですが、半分以上無駄な機能を作ってしまった気がします。作った当初はDMMにお気に入り機能があると知らなかったのでガッツリ作り込む気満々でしたが、ただ単に「半額〇〇の一覧をブックマークできるサイト」というコンセプトならログイン機能とか付けずにトップページだけ作って2~3ヶ月でリリースするのが最適解でした。
まあそのおかげでCRUDの実装とかも出来ましたし、Linux触ったり、SQLをガッツリ書く経験も積めたので結果オーライだと思います。これで私も真にフルスタックエンジニアの仲間入りですね。
まあそんな与太は置いておくとしても、やはり個人開発に関して大切なのは『モチベの維持』と『まあいいかの精神』だと思います。というのも納期が無い開発で仕様なんて固まってる訳ないですし、設計はグダグダ、人手は足りてないといった具合に個人開発はおおよそ炎上or凍結プロジェクトの前提条件を満たした状態でスタートします。今回モチベの維持としては主にGitHubを利用しました。定期的にPushしないと芝が枯れるという危機感は進捗にかなり貢献してくれますね。後はまあ今のバイト先が普通にブラックなのでそこから脱出したいという思いも地味にあったりします。
『まあいいかの精神』と言うのは、一定以上のクオリティを求めない事ですね。今回実はパフォーマンスに関しては結構ザルでして、VMのスペックに関しては同接100~200ぐらいしか見込んでないですし、アプリ自体もDBにインデックス張ったぐらいで計算量の最適化はやってなかったりと中々お粗末な仕上がりです。
ただ、同人界隈でも「出ない神本より出る糞本」という言葉がありますし、「それでも要件は満たすから良いだろ」ぐらいの割り切りが肝要だと自分は思います。それに今回アプリを作ることで、間違いなく自分の実力は伸びました。実を言うと9月にモチベが枯れかけた理由も半分以上それで、急に実力が上がったせいか「今更これを公開するのか?」みたいな躊躇いと気恥ずかしさを乗り越える必要がありました。ここだけの秘密ですよ。
あとここまで辿り着けた要因の一つとして、Twitterで進捗を呟く度に「いいね」を下さるファボ魔(約2名)の存在も大きかったと思います。多分アレが無ければ8月ぐらいで折れていた疑惑ある。大変感謝です。
それとこれは余談なのですが、次回作については既に設計が上がっています。詳しいコンセプトはまだ秘密ですが、今度こそきっと皆様の度肝を抜くサービスをお届け出来ると思います。それではまた次回、goodbye
- 投稿日:2020-09-18T17:00:51+09:00
【Nuxt.js】Nuxt文法編:component③動的コンポーネント
? この記事はWP専用です
https://wp.me/pc9NHC-GF前置き
liを使いまわして親のulによって
中のテキストを変えたりしたい!
というような場合に便利なkey属性をご紹介?
component②の続きです?♀️ul、ol、table、selectといった要素には
子要素にできるタグli、tr、optionが
決まっていますね。
これらを分けてコンポーネント化したい場合に
活躍するのがkeyです。公式: https://jp.vuejs.org/v2/guide/components.html#DOM-テンプレートパース時の警告
keyに使う値については
こちらをご覧ください?tableでいうならthは親、
trを子コンポーネントに分けると
管理がしやすいといったメリットもあります?コード①
liタグに使うコンポーネントは
is属性で指定してあげます?ListItem.vue<template> <li>{{ text }}</li> </template> <script> export default { props: ['text'] } </script>index.vue<template> <div class="page"> <ul> <li is="ListItem" v-for="(fruit, index) in fruits" :text="fruit" :key="index" > {{ fruit }} </li> </ul> </div> </template> <script> import ListItem from '~/components/Lists/ListItem.vue' export default { data () { return { fruits: ['りんご', 'みかん', 'ぶどう'], } }, components: { ListItem, }, } </script>コード②
? 続きはWPでご覧ください?
https://wp.me/pc9NHC-GF
- 投稿日:2020-09-18T16:45:32+09:00
【Vue.js】 IF文・For文 条件分岐、繰り返し処理
【ゴール】
VueJSでの IF文・For文 条件分岐、繰り返し処理
【環境】
mac catarina 10.156
Vue.js v2.6.12
【実装】
①適当にワークスペース作成
②Vue.jsインストール or 埋め込み(重要)If文
■「v-if」 / 「v-else」 を使用
index.html<div id="app"> <p v-if="ok">OK</p> <p v-else>Not OK</p> </div> . . . . <script> new Vue ( { el: '#app', data: { ok: true //ここが、true:OK表示、false: NotOKが表示される } }) </script>For文
■「v-for」使用
index.html<div id="app"> <ul> <li v-for="name in names">{{name}}</li> </ul> </div> . . . . <script> new Vue ( { el: '#app', data: { names: ['tarou', 'hanako', 'misaki'] } }) </script>結果
【まとめ】
■基本天気な挙動を理解している方だとすぐに理解できる
■If文は「true」「false」を上手く使い分ける
■for文は記述の省略につながるので覚えていて損なし
【オススメ記事】
■ 【node.js】ルーティング設定ホーム画面表示させる。
https://qiita.com/tanaka-yu3/items/1c8859e16070e67d73c0■ 【Node.js mysql】mysql接続 データを取り出す
https://qiita.com/tanaka-yu3/items/6b007dd96618bb6c844e■ 【javascript】 テンプレートリテラル とは 一言で。
https://qiita.com/tanaka-yu3/items/9b07bd9fc4126291be28
- 投稿日:2020-09-18T12:22:14+09:00
Developper Toolがなぜか使えない時のデバック方法
はじめに
コード書き終わった! リロード!
。。。。。
なんじゃこりゃ。
Vue.jsでフロントを開発している際にCromeブラウザ、Developper Toolの両方がエラーを起こして使えなくなってしまい、デバッグをしようにもできない状態になったのでその解決方法を手順に沿って共有しようと思います。
1.コミット履歴を遡りロールバックしてみる。
まず、Gitを使用していることが前提になりますが、問題が起こったところの手前のコミット履歴からコードの差分を見てみましょう。
正常に動作していた時がコミット履歴から分かれば、原因の範囲を特定することができます。
細かい粒度でのコミットができていれば、ここでその原因が判明することもあります。
2.コメントアウト
コミット履歴を参考に、ここ原因だと思われるメソッドなどをコメントアウトしてみましょう。
原因であるところを引き当てた場合、DevelopperToolが動作します。
3.console.log
その原因に関連するコードをひたすらにconsole.logして原因箇所を絞り込んでいきましょう。
しっかりと値が渡されているか、意図していない動きがでていないか確認していきましょう。
この段階で原因箇所が特定できると思います。
終わりに
私の場合はfor文による”無限ループ”が原因でした。
コミットの粒度や意義を考えずに適当にコミットしていたので、原因を特定するのにかなり時間がかかってしまいました。
適切な粒度でのコミットについて考えるいいきっかけになりました。
参考記事
- 投稿日:2020-09-18T11:34:47+09:00
Vue.jsでの制作物をHerokuへデプロイする
備忘録になりますので、参考にならないかもしれません
前提条件
以前デプロイしたことがあるので、Herokuのアカウントは既に持っている
デプロイ前準備
※cd <アプリ名>で移動した状態
①まずはHerokuをインストール(Mac)ターミナル$ brew tap heroku/brew && brew install heroku②Herokuへアカウント情報(メール、パスワード)を使ってログイン
ターミナル$ heroku login何かキーを押してとターミナルに出てくるので、適当なキーを押す。
その後、ブラウザにログイン画面が表示されるので、Loginボタンを押す。③Herokuにプロジェクトを作成
ターミナル$ heroku create <プロジェクト名>※結構プロジェクト名が既に使用されていることが多いので注意!
使用されていると以下の文がターミナルに表示されるターミナルCreating ⬢ vue-project... ! ▸ Name vue-project is already taken成功すると、新しいアプリのURLが生成されます!
ターミナルhttps://vuetang.herokuapp.com/ | https://git.heroku.com/vuetang.git④Herokuでデプロイする際に環境依存を防ぐためにNODE_ENVのproductionを設定しておく。
ターミナル$ heroku config:set NODE_ENV=production --app <プロジェクト名>⑤フロントエンドのVue.jsを簡単にサーバーにアップするにはExpressというNode.jsのフレームワークが便利なので、Expressをインストール
ターミナル$ npm install express --save⑥プロジェクトのルートディレクトリ直下にserver.jsを作成。
server.jsvar express = require('express'); var path = require('path'); var serveStatic = require('serve-static'); app = express(); app.use(serveStatic(__dirname + "/dist")); var port = process.env.PORT || 5000; app.listen(port); console.log('server started '+ port);⑦ビルドする
ターミナル$ npm run build⑧下記コマンドでserver.jsを実行。
ターミナル$ node server.js⑨package.jsonを編集。
package.json{ "name": "<プロジェクト名>", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "start": "node server.js" <--- ここを書き換え }, ...デプロイ
①Gitリポジトリの初期化
ターミナル$ git init②Herokuリモートリポジトリを設定。
ターミナル$ heroku git:remote --app <プロジェクト名>③Herokuへデプロイしたdistディレクトリを保持しておくために.gitignoreから外す。
gitignore.DS_Store node_modules dist/ <--- 削除 # local env files .env.local .env.*.local ...④Gitにステージング&コミット
ターミナル$ git add . && git commit -a -m "Herokuセットアップ"⑤Herokuのリモートリポジトリにpush
ターミナル$ git push heroku masterこれでOKの筈ですが、私の場合はエラーが出てきました。
↓こんな感じターミナルEnumerating objects: 73, done. Counting objects: 100% (73/73), done. Delta compression using up to 4 threads Compressing objects: 100% (66/66), done. Writing objects: 100% (73/73), 319.19 KiB | 4.99 MiB/s, done. Total 73 (delta 24), reused 0 (delta 0), pack-reused 0 remote: Compressing source files... done. remote: Building source: remote: remote: -----> Node.js app detected remote: parse error: Invalid numeric literal at line 2, column 5 remote: ! Unable to parse package.json remote: remote: remote: -----> Build failed remote: remote: We're sorry this build is failing! You can troubleshoot common issues here: remote: https://devcenter.heroku.com/articles/troubleshooting-node-deploys remote: remote: If you're stuck, please submit a ticket so we can help: remote: https://help.heroku.com/ remote: remote: Love, remote: Heroku remote: remote: ! Push rejected, failed to compile Node.js app. remote: remote: ! Push failed remote: Verifying deploy... remote: remote: ! Push rejected to vuetang. remote: To https://git.heroku.com/vuetang.git ! [remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to 'https://git.heroku.com/vuetang.git'エラー解消の記事を見つけたので、それを参考にしやってみました。
ターミナル$ touch index.php $ git add index.php $ git commit -m "add index.php" $ git push heroku master無事デプロイできました!!
参考記事
https://qiita.com/kottyan/items/dbc1edb82e8562235fac
https://gist.github.com/konitter/5370904
- 投稿日:2020-09-18T08:49:51+09:00
【メモ】vue-routerを使ったアプリで画面が真っ白になる
問題
vue.jsの画面が真っ白になって表示されない。
前提
- vue-routerを使っている。
- サブディレクトリにデプロイしている
TL;DR
vue-routerにbaseプロパティでサブディレクトリ(ベースURL)を教える必要がある。
もう少し詳しく説明すると
/var/www/html/subdir
にデプロイすることで、URLがhttps://www.example.com/subdir/
がアプリケーションのトップとなる場合に、ベースURLとして、/subdir/
(前後のスラッシュ必須)をvue-routerに教える必要がある。以下のように初期化処理で
base
プロパティで教えてあげる。https://router.vuejs.org/ja/api/#mode
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) const routes = [ { path: '/', component: xxxxxx, children: [ { path: '', name: 'top', component: () => import(xxxxxxx) }, { path: '/login', name: 'login', component: () => import(xxxxxxx) }, ] } ] export default new Router({ mode: 'history', base: '/subdir/', <-これ routes })今回は、どこに設置するかわからなかったので、
base
プロパティを環境変数で設定するようにした。例えば、
base
が以下のような場合は、ベースURLの判定ができずに、ルーティングできずに画面が真っ白になる。
- /subdir :最後のスラッシュがない
- // : スラッシュが2個ある。
- https://example.com/subdir/ : URLになっている
環境変数で適当に設定するようにしちゃったので、書き方が統一されなくて画面が真っ白になっていました。
一度、設定すれば問題ないので、忘れちゃいます。
自戒をこめて記載しました。