20190711のHTMLに関する記事は18件です。

PHP で Google reCAPTCHA v3 付きのお問い合わせフォームを作る (2)

PHP で Google reCAPTCHA v3 付きのお問い合わせフォームを作る (1) の続きです。
前回までで、 Google reCAPTCHA v3 スコア算出とそれによる条件分岐を作成しました。
ここからは Swift Mailer でのメール送信処理を書いていきます。

メール送信処理

日本語メールを扱うための設定

Swift Mailer の公式ドキュメントにもある、日本語メールを扱うための設定を追加します。
Using Swift Mailer for Japanese Emails

send.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use ReCaptcha\ReCaptcha as ReCaptcha;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $response = (new ReCaptcha('<シークレット キー>'))
                  ->setExpectedHostname($_SERVER['SERVER_NAME'])
                  ->setExpectedAction('inquiry')
                  ->setScoreThreshold(0.5)
                  ->verify($_POST['token'], $_SERVER['REMOTE_ADDR']);
  $challenge_result = $response->toArray();

  if ($challenge_result['success']) {
    \Swift::init(function () {
    \Swift_DependencyContainer::getInstance()
      ->register('mime.qpheaderencoder')
      ->asAliasOf('mime.base64headerencoder');

      \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
    });
  }
}

SMTP 認証情報を設定する

以下のコードは Gmail の SMTP サーバを使用した例ですが、お使いになるものに置き換えてください。

send.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use ReCaptcha\ReCaptcha as ReCaptcha;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $response = (new ReCaptcha('<シークレット キー>'))
                  ->setExpectedHostname($_SERVER['SERVER_NAME'])
                  ->setExpectedAction('inquiry')
                  ->setScoreThreshold(0.5)
                  ->verify($_POST['token'], $_SERVER['REMOTE_ADDR']);
  $challenge_result = $response->toArray();

  if ($challenge_result['success']) {
    \Swift::init(function () {
    \Swift_DependencyContainer::getInstance()
      ->register('mime.qpheaderencoder')
      ->asAliasOf('mime.base64headerencoder');

      \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
    });

    $transport = (new \Swift_SmtpTransport('smtp.gmail.com', 587, 'tls'))
        ->setUsername('username@gmail.com')
        ->setPassword('****************');
  }
}

送信先・件名・本文を設定する

バリデーション処理などは一旦おいておいて、とりあえず送信テストをするための記述を行います。
setTo() メソッドは例外が起きる可能性があるので、 try-catch で例外処理をしておきます。

Sending Emails in Batch

If you add recipients automatically based on a data source that may contain invalid email addresses, you can prevent possible exceptions by validating the addresses using Egulias\EmailValidator\EmailValidator (a dependency that is installed with Swift Mailer) and only adding addresses that validate. Another way would be to wrap your setTo(), setCc() and setBcc() calls in a try-catch block and handle the Swift_RfcComplianceException in the catch block.

info@example.com の部分は送信したいメールアドレスに置き換えてください。

send.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use ReCaptcha\ReCaptcha as ReCaptcha;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $response = (new ReCaptcha('<シークレット キー>'))
                  ->setExpectedHostname($_SERVER['SERVER_NAME'])
                  ->setExpectedAction('inquiry')
                  ->setScoreThreshold(0.5)
                  ->verify($_POST['token'], $_SERVER['REMOTE_ADDR']);
  $challenge_result = $response->toArray();

  if ($challenge_result['success']) {
    \Swift::init(function () {
    \Swift_DependencyContainer::getInstance()
      ->register('mime.qpheaderencoder')
      ->asAliasOf('mime.base64headerencoder');

      \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
    });

    $transport = (new \Swift_SmtpTransport('smtp.gmail.com', 587, 'tls'))
        ->setUsername('username@gmail.com')
        ->setPassword('****************');

    $mailer = new \Swift_Mailer($transport);

    $message = (new \Swift_Message('お問い合わせフォームからお問い合わせがありました'))
        ->setFrom([filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL) => filter_input(INPUT_POST, 'name', FILTER_SANITIZE_FULL_SPECIAL_CHARS)])
        ->setBody(
          'お名前: ' . filter_input(INPUT_POST, 'name', FILTER_SANITIZE_FULL_SPECIAL_CHARS) . PHP_EOL .
          'メールアドレス: ' . filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL) . PHP_EOL .
          'お問い合わせ内容: ' . filter_input(INPUT_POST, 'contents', FILTER_SANITIZE_FULL_SPECIAL_CHARS));

    try {
      $message->setTo(['info@example.com']);
    } catch (\Swift_RfcComplianceException $e) {
      echo '不正なメールアドレスです。';
    }
  }
}

送信処理

send.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use ReCaptcha\ReCaptcha as ReCaptcha;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $response = (new ReCaptcha('<シークレット キー>'))
                  ->setExpectedHostname($_SERVER['SERVER_NAME'])
                  ->setExpectedAction('inquiry')
                  ->setScoreThreshold(0.5)
                  ->verify($_POST['token'], $_SERVER['REMOTE_ADDR']);
  $challenge_result = $response->toArray();

  if ($challenge_result['success']) {
    \Swift::init(function () {
    \Swift_DependencyContainer::getInstance()
      ->register('mime.qpheaderencoder')
      ->asAliasOf('mime.base64headerencoder');

      \Swift_Preferences::getInstance()->setCharset('iso-2022-jp');
    });

    $transport = (new \Swift_SmtpTransport('smtp.gmail.com', 587, 'tls'))
        ->setUsername('username@gmail.com')
        ->setPassword('****************');

    $mailer = new \Swift_Mailer($transport);

    $message = (new \Swift_Message('お問い合わせフォームからお問い合わせがありました'))
        ->setFrom([filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL) => filter_input(INPUT_POST, 'name', FILTER_SANITIZE_FULL_SPECIAL_CHARS)])
        ->setBody(
          'お名前: ' . filter_input(INPUT_POST, 'name', FILTER_SANITIZE_FULL_SPECIAL_CHARS) . PHP_EOL .
          'メールアドレス: ' . filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL) . PHP_EOL .
          'お問い合わせ内容: ' . filter_input(INPUT_POST, 'contents', FILTER_SANITIZE_FULL_SPECIAL_CHARS));

    try {
      $message->setTo(['info@example.com']);
    } catch (\Swift_RfcComplianceException $e) {
      echo '不正なメールアドレスです。';
    }

    try {
      $send_result = $mailer->send($message);
    } catch (\Swift_TransportException $e) {
      echo 'メール送信エラーです。';
    }

    if ($send_result) {
      echo 'メールを送信しました。';
    } else {
      echo 'メール送信に失敗しました。';
    }
  }
}

とりあえずここまででメールの送信テストが可能な状態になりました。
すべての入力欄を埋めて 送信する ボタンを押して試してみてください。

このままでは実用に耐えないので、

  • バリデーション処理
  • エラーが発生したときにお問い合わせフォームに戻し、エラーの内容を表示する
  • メール本文をテンプレート化して編集しやすくする

など、細かな改善を次回以降で行っていきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

cssで記述する基本的なレスポンシブ(メディアクエリ)

この記事で説明していること

  • メディアクエリについて
  • メディアクエリの書き方
  • その他

メディアクエリについて

メディアクエリとは、Webページの見栄えを記述するCSS3で追加された仕様の一つで、表示された画面環境に応じて適用するスタイルを切り替えることが出来る機能のこと。

画面サイズに応じてcssを変更することが出来る。


メディアクエリの書き方

<link rel="stylesheet" href="css/style.css" media="screen">

上記コードをhtmlに記載

@media screen and (min-width:299px){
  /*299px以下で適用する内容*/
}

@media screen and (min-width:300px){
  /*300px以上で適用する内容*/
}

@media screen and (min-width:600px){
  /*600px以上で適用する内容*/
}

上記コードをcssに記載
これで各画面サイズごとにcssを変更することが出来ます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTML で 文字 を 入力する 欄 を表示する

目的

  • HTMLの画面に文字を入力する欄の表示を行う方法をまとめる

押さえるポイント

  • 一行の入力欄を表示させる時はinputタグ使用する
  • 複数行の入力欄を表示させる時はtext-areaタグを使用する
  • お問い合わせフォームの作成などで送信ボタンを設置するときはinputタグでtype属性にてsubmitを指定する。 送信ボタンは何も設定しないとボタン部分に「送信」と表示される。任意の文字を表示させたい時はvalue属性にて表示させたい文言を与える

書き方の例

  • 下記にHTMLファイルの内容を記載する。
<!-- 一行の入力欄を表示する -->
<input>

<!-- 複数行の入力欄を表示する -->
<text-area></text-area>

<!-- 送信ボタンを表示する -->
<input type="submit">

より具体的な例

  • 企業webサイトによくある問い合わせ用フォームを作成する。
  • 返信用メールアドレスを記入する欄を作成する。
  • 問い合わせ主の名前を入力する欄を作成する。
  • 問い合わせ内容を入力する欄を作成する。
  • 送信ボタンを作成する。
    ※返信用メールアドレスと問い合わせ主の名前の入力欄は一行の入力欄とする。
    ※問い合わせ内容の入力欄は複数行の入力が可能な入力欄とする。
    ※各入力欄の上に入力欄の概要を記載する

  • 下記にHTMLファイルの内容を記載する。

<p>返信用メールアドレス(必須)</p>
<input class="mail">

<p>お名前(必須)</p>
<input class="name">

<p>お問い合わせ内容</P>
<text-area></text-area>

<input type="submit">
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTML の 要素 に 下線 や 枠線 を つける

目的

  • HTMLファイルの要素に下線や枠線をつける方法をまとめる。

押さえるポイント

  • 下線や枠線をつけたい要素をCSSで指定してborderプロパティを用いて設定する。
  • 線の太さ、種類、色をそれぞれ指定可能。
  • 太さはピクセル数で設定する。
  • 種類は線の名前で設定する。
  • 色はカラーコードで設定する。

枠線をつけたい時の書き方の例

  • 下記にCSSファイルの内容を記載する
要素の名前かクラス名 {
    border: 太さ 種類 カラーコード;
}

下線をつけたい時の書き方の例

  • 下記にCSSファイルの内容を記載する
要素の名前かクラス名 {
    border-bottom: 太さ 種類 ;
}

より具体的な例

h1要素に太さ5px、種類solid、色が赤の枠線をつける
p要素に太さ10px、種類solid、色が黒の下線をつける

〜サンプルコード〜
- 下記にHTMLファイルの内容を記載する。

<h1>おはようございます</h1>
<p>これは日本の挨拶です。</p>
  • CSSで上記のHTMLファイルのh1タグとpタグに対して枠線と下線の設定をする。
  • 下記にCSSファイルの内容を記載する。
h1 {
  border: 5px solid red;
}

p {
  border-bottom: 10px solid black;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTML の 文章 の 一部だけ 文字の色を 変更する

目的

  • HTMLファイルの文章の1部のみ文字の色を変更する方法をまとめる

押さえるポイント

  • 変更したい文字をspanタグで囲みCSSで文字の色を設定する

書き方の例

  • 下記にHTMLファイルの内容を記載する
<h1>おはよう<span>ございます</span></h1>
  • CSSにて色を設定する
  • 下記にCSSファイルの内容を記載する
span {
    color: カラーコード;
}

より具体的な例

h1要素の「おはようございます。」の「。」を赤色に設定する。

〜サンプルコード〜
- 下記にHTMLファイルの内容を記載する。

<h1>おはようございます<span></span></h1>
  • CSSで上記のHTMLファイルのspanタグに対して文字を赤色に設定する。
  • 下記にCSSファイルの内容を記載する。
span {
  color: red;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

すべての新米フロントエンドエンジニアに読んでほしい50の資料

はじめに

さいきんのWebはSPA技術を中心としたフロントエンドが賑わっていますね?

従来サーバーサイドを扱っていた人もフロントを触る機会が増えていたり、これからプログラミングを学んでいく人も、フロントエンド領域に興味を持っているのではと思います。
そこで、フロントエンドの経験が浅い方や初学者向けに、おすすめのドキュメントや勉強すべき領域をまとめました。

とりあえず動けば良い段階から一歩進んで、フロントエンドエンジニアとして、良いアプリケーションを作るために必要な知識を浅く広く紹介します。

※補足
新米と表記しましたが、実際には新卒や未経験でなく、新卒2~3年目の若手フロントエンドエンジニアやフロント分野に苦手意識のあるバックエンドエンジニアの方を対象としています。
数日で目を通せるような内容ではないため、マイルストーンやスキルセットの一つの参考にして頂けると幸いです。

フロントエンド入門

公式ドキュメントを知る

[1] https://jp.vuejs.org/v2/guide/
一例としてVueを貼りましたが、Vueに限らず信頼出来る情報に当たる癖付けがとても大切です。
特にVue.jsは一昔前のjQueryやRailsやPHPのように、技術に明るくない方が書いたページが多いと感じていて、ちゃんとVueを学ぶならまずは公式を見ましょう。

言語を知る

JSを知る

[2] https://jsprimer.net/basic/introduction/
今からJSを学ぶなら特別な事情がない限り、ES2015以降の文法で良いと思います。
js-primerはES2015以降のJSを知る上で素晴らしいドキュメントです。

昔のJSもちょっと知る

[3] https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures
データの隠蔽やカプセル化を実現するために使われたテクニックです。
今のJSを書く場合に意識する機会は少ないと思いますが、知っておいて損ないです。

[4] https://www.yunabe.jp/docs/javascript_class_in_google.html
ES5以前の古いJSで記述しなきゃいけない仕事に遭遇した際、あらためて読み返したい素晴らしいドキュメントです。ベストプラクティスのひとつだと思います。

昔のJSもしっかり学びたい方は、「JavaScript: The Good Parts」や「開眼!JavaScript」といった書籍の購入も検討してください。
上記の書籍を読んで、DouglasやJohnResigやSubstackを知っていると、先輩のフロントエンドエンジニアから気に入られる確率が向上します(当社比)

非同期処理を知る

[5] http://azu.github.io/promises-book/
非同期処理は初学者にとって大きな壁の一つだと思いますが、しっかりとPromiseオブジェクトを理解することがJSでは必須です。
ES2017で追加されたAsync Functionは、Promiseを返す関数なのでPromiseが分かればすぐ理解できます。

Promiseを理解したら、Asyncjsのようなライブラリで複雑な非同期処理を実装したり、
RxJSのようなライブラリを用いてPromise以外の非同期を扱う方法を学んでみると良きです。

HTMLLivingStandard & ECMAScript を知る

[6] https://html.spec.whatwg.org/multipage/
[7] https://www.ecma-international.org/publications/standards/Ecma-262.htm
聖書。HTMLやJSといった言語の仕様が記載してあります。

ちなみに私のチームでは、実装周りの裁判が発生した際に、六法全書代わりとして活用しています。
※私はおそらく全体の3%ほどしか読んでませんが、ちゃんと読んだぞという空気を出して会話します?

コーディング規約を知る

[8] https://qiita.com/mysticatea/items/f523dab04a25f617c87d
[9] https://qiita.com/soarflat/items/06377f3b96964964a65d
これからフロントエンドを学ぶ方すべてに、まずはLintとコードフォーマッターの導入をお勧めします。
Lintではeslintやstylelint、コードフォーマッターではprettierがデファクトです。
利用するルールは何でも良いと思いますが、とにかくルールを用意することが大切です。

UIを知る

モーショングラフィックやインタラクションを知る

[10] https://goodpatch.com/blog/ui-micro-interaction/
マイクロインタラクションはデザイナーの仕事という認識の方も多いと思いますが、
特殊な例外発生時にユーザーへ適切なフィードバックを返すべきといった気付きはエンジニアの方が強いと思うので、常にプログラム的な例外とUI的な例外(フィードバック)の両方を考える姿勢が大切だと感じます。

マテリアルデザインを知る

[11] https://material.io/design/
Google公式のデザインガイドです。英語のドキュメントですが、グラフィック中心なので分かりやすいです。

アトミックデザインを知る

[12] https://ygoto3.com/posts/atomic-design-on-actual-project/
ReactやVueを用いる際にコンポーネント分割の粒度としてアトミックデザインを活用するといったケースがあります。
アトミックデザインに固執する必要はないですが、コンポーネントをどう分割していくかをデザイナー交えて検討するのは大切だと考えていて、土台としてアトミックデザインは有用と思います。

アクセシビリティを知る

セマンティックを知る

[13] https://developer.mozilla.org/ja/docs/Learn/Accessibility/HTML
[14] https://developer.mozilla.org/ja/docs/Learn/Accessibility/CSS_and_JavaScript
セマンティックなコーディングを行うことでアクセシビリティだけでなく、SEOに対してもメリットがあると言われています。

ARIAを知る

[15] https://developer.mozilla.org/ja/docs/Learn/Accessibility/WAI-ARIA_basics
可能な限りネイティブなHTMLで解決すべきで、必要なときだけ使うことが推奨されています。
業務アプリなど利用ブラウザが制限できて、かつ複雑なUIでは活躍の機会があるかもしれません。

SEOを知る

お上の言うことを知る

[16] https://support.google.com/webmasters/answer/35769?hl=ja
まずはお上の言うことに従いましょう。
私は毎晩、「Googleは神」と三回復唱してから寝るようにしています。

構造化データを知る

[17] https://developers.google.com/search/docs/data-types/article?hl=ja
担当業務領域によっては、構造化データを設定することが必要かもしれません。

SEOと直接関係ありませんが、GAやdatalayerを正しく設定することもフロントでは大切です。

ブラウザを知る

ブラウザの仕組みを知る

[18] https://www.html5rocks.com/ja/tutorials/internals/howbrowserswork/
結構長いので、他国の文化を知るような気持ちで、ブラウザってこうなってんだって読むのをお勧めします。

デバイスおよびブラウザの特性を知る

[19] https://caniuse.com/
フロントエンドの辛いところとして、コードの実行環境(ブラウザ)が無数にあることが挙げられますが、JSやCSSがその環境で実行可能か確認できます。

JSに関しては、IE11などでもES2015以降の機能を使えるbabel-polyfillの導入も検討しましょう。

Threadを知る

[20] https://nhiroki.jp/2018/05/07/off-the-main-thread-api
JavaScriptにはメインスレッド(=UIスレッド)が一つしかないので、普通に書くと非同期処理であってもシングルスレッドの直列で実行されます。
重たい処理(UI的にカクついてしまうとか)をマルチスレッドで実行するために、Web Workerの利用を考えましょう。

JITを知る

[21] https://dev.mozilla.jp/2017/05/%E3%82%B8%E3%83%A3%E3%82%B9%E3%83%88%E3%83%BB%E3%82%A4%E3%83%B3%E3%83%BB%E3%82%BF%E3%82%A4%E3%83%A0-jit-%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E3%81%AE%E3%82%AF%E3%83%A9%E3%83%83%E3%82%B7/
(難しくてよく分かってませんが?)モダンブラウザは実行時最適化と呼ばれるコンパイルを行っているそうです。

常に同じ型で呼び出される型を仮定するそうなので、私のような市井のプログラマには、型を意識した開発を心掛けることでJITの恩恵を享受できる可能性があります。
お気づきの方も多いと思いますが、それはTypeScriptと相性が良いです。

セキュリティを知る

DOM Based XSSを知る

[22] https://gihyo.jp/dev/serial/01/javascript-security/0006
モダンなフロントのフレームワークを使っている場合、もはや意識しないかもしれませんが、JS初学者は一度目を通しましょう。

CORSを知る

[23] https://developer.mozilla.org/ja/docs/Web/HTTP/CORS
CORSを理解しそのクライアントとサーバーを実装すると、HTTPに対する理解も深まるのでとてもお勧めです。

CSRF脆弱性とjwtを知る

[24] https://techblog.yahoo.co.jp/advent-calendar-2017/jwt/
jwt(json web token)は、OAuth2.0という認可の仕組みのアクセストークンとして採用されるなど広く使われています。

CSRFという、なりすましのような脆弱性が存在すること、その対策の一つとしてredirect_uriの制限が可能なjwtが存在することを理解出来るとOKです。
GoogleやFacebookのような代表的なOpenID Providerは、stateにredirect_uriを含めuriのホワイトリストと突合するのが必須になっていると思います。

テストを知る

ユニットテストを知る

[25] https://jestjs.io/docs/ja/getting-started
Reactはもちろん、Vueを使う際もJestがお勧めです。
ただフロントエンドのテストはベストプラクティスが無いと言われていて、下記のようにどういったテストをすべきかをまず検討しましょう。
[26] http://akito0107.hatenablog.com/entry/2018/08/27/190333

もしかしたらあなたに必要なのはユニットテストではなく、TypeScriptかもしれません。

E2Eテストを知る

[27] https://techblog.lclco.com/entry/2018/06/28/080000
フロントエンドが自主的に行うE2EとしてはPuppeteerがデファクトではないかと思います。
ユニットテストでも書きましたが、E2Eの運用も楽ではないので何をテストするのかちゃんと計画しましょう。

代表的なUIテストを知る

[28] https://qiita.com/masaakikunsan/items/dad8d84807918f3a43cb
storybookを採用することで、再利用性やテスト容易性が向上すると思います。
実装やメンテは大変なので、小規模なチームでの採用はコストに見合わない可能性があります。

データストアを知る

cookieを知る

[29] https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies
仕様が複雑ですが、とても良く使うためちゃんと理解しましょう。ブラウザのユーザー固有情報においてサーバーとやり取りできる唯一のストレージです。

他にもブラウザだけで扱えるWeb Storageも存在します。サーバーとのやり取りが不要ならこちらを使いましょう。
[30] https://developer.mozilla.org/ja/docs/Web/API/Web_Storage_API#Web_Storage_concepts_and_usage
HTTPヘッダに乗ることもなくブラウザだけで完結するため扱いやすいですが、外部サービスのJSから取得可能な領域のため個人情報を置いたりするのは止めましょう?

NoSQLを知る

[31] https://firebase.google.com/docs/database/ios/structure-data?hl=ja
リンク先はFirebaseのRealtime Databaseですが、MysqlのようなRDBとは設計思想がまるで異なることが分かると思います。
※Cloud Firestoreの設計は、上記のベストプラクティスと異なります。

Cloud FirestoreやDynamoDBといった新世代の優れたデータストアは、これまでバックエンドエンジニアが培ってきた設計が通用しないため運用が難しいと議論されています。
[32] https://qiita.com/funasaki/items/6cdc8f7f7b709e5e601f

一方、多くのネイティブアプリエンジニアが運用してきたように、UIに近い立場のフロントエンドにとっては比較的自然に扱えるデータストアだと感じるので、触れてみるのがお勧めです。

モダンフロントエンドへ

Fluxと仮想DOMを知る

[33] https://qiita.com/mizchi/items/4d25bc26def1719d52e6
Qiita史に燦然と輝く魂の名文。
なぜVueやReactがこれほど重要な位置を占めたか、そのすべてが書いてあります。

私的な余談ですが、右も左も分からない新卒エンジニアだった当時この文章を読んで、全然内容は分からなかったんですが、この筆者が一体何に興奮しているのか興味を持ち、Reactを学びたくなったという背景があります。

言語を知る

TSを知る

[34] https://www.typescriptlang.org/docs/home.html
折に触れてTypeScriptの名前を出してきましたが、今からJSのプロジェクトを始める場合、どんなケースにおいてもTSの採用をオススメします。そこに迷いはありません?

React, Vueを知る

[35] https://ja.reactjs.org/docs/getting-started.html
とりあえずReactかVueのどちらかを学びましょう。

現時点ではTSとの相性がReactの方が高いです。Vue3.0がリリースされるとVueでもTSXがネイティブサポートされ解消される見込みですが。

個人的には、Vueの双方向と単方向データバインディングの合わせ技を便利と感じるか邪悪と感じるかで、VueとReactのどちらを採用するかが決まるかなと考えています。

CSS in JSを知る

[36] https://qiita.com/taneba/items/4547830b461d11a69a20
styled-componentsの採用が多いです。

CSS in JSを嫌っている人もいますが、コンポーネント単位でインターフェースやインタラクションを定義していきましょうという時代に適した手法と感じます。

アーキテクチャを知る

CDNを知る

[37] https://speakerdeck.com/sisidovski/nikkei-itpro-cdn
リリース当時、界隈で話題になった日経電子版のCDNを中心とした設計の話です。
とにかくCDNで出来ることが増えていて、なぜ使うのか、どういったことが可能なのか知ることが大切です。

JAMStackを知る

[38] https://qiita.com/ossan-engineer/items/4fe0e3e388f510bd5c68
CDNファーストを考えた際に、第一候補となる構成です。
この構成を目指す際に採用するGatsbyやVuePressのようなFWは、静的サイトジェネレータ(SSG)と呼ばれる事が多いです。

BFFを知る

[39] https://www.atmarkit.co.jp/ait/articles/1803/12/news012.html
特にこの記事で素晴らしいと思った点は、フロントエンドの担当領域を明確に定義している点です。

私的な余談ですが、なぜBFFという考え方が誕生しその領域をフロントエンドが担うべきなのか、おぼろげに理解できたとき私のなかで点だった技術や思想が線で繋がった感覚がありました。

BFFとSSRを知る

[40] https://speakerdeck.com/yosuke_furukawa/ssrfalsehua
SSRも一種のBFFと呼べますが、なぜSSRをすべきなのかが最もわかりやすいと思います。
さすが日本Node.jsユーザグループ会長、ウォーリーのアイコンも可愛いです。

アーキテクチャの補足ですが、既存の技術資産を活用するためRailsをAPIで残して、フロントエンドだけをモダンにするみたいなケースも見られます。
[41] https://speakerdeck.com/fukuiretu/notewonuxt-dot-jsdezai-gou-zhu-sitahua

レンダリングを知る

[42] https://developers.google.com/web/updates/2019/02/rendering-on-the-web
モダンなフロントエンドのアーキテクチャをレンダリングという観点からまとめたGoogle謹製ページ。
2019年に生きるすべてのフロントエンド必読です。

SSRやSSGを実現する方法を知る

[43] https://ja.nuxtjs.org/guide
NuxtやNextを良く聞くけどイマイチ分かってなかった方々、ここまでの話を読むと凄さが伝わるのではないかと思います。
サーバーサイドでReactやVueが実行可能になったことで、SSRが市井のエンジニアでも実現可能になりました。
NuxtやNextではSSGも可能です。

パフォーマンス改善を知る

Service Workerを知る

[44] https://developers.google.com/web/fundamentals/primers/service-workers/?hl=ja
Service Workerを用いたcacheを行うことで、2回目以降のFCPなどのタイムを大幅に削減可能です。

このAPIを用いると、従来Webから出来なかったプッシュ通知などの体験を提供できることから、Service Workerを活用したWebアプリはPWAとも呼ばれてます。

lighthouseを知る

[45] https://developers.google.com/web/tools/lighthouse/?hl=ja
lighthouseを用いることで、これまで紹介してきたアクセシビリティやパフォーマンスといった項目がサイト上でどの程度実現出来ているかの測定が可能です。

Performance Budgetを知る

[46] https://developers-jp.googleblog.com/2019/03/blog-post_15.html
ウェブサイトを高速に保つための手法として、Performance Budgetの導入が推奨されています。
上記で紹介したlighthouseなどと組み合わせてCIに導入すると良い感じだと思います。

Webpackを知る

[47] https://webpack.js.org/guides/asset-management/
本来パフォーマンスの項目で紹介するものではありませんが、Webpackをちゃんと使うことでBundleサイズの削減、ひいてはパフォーマンスの向上が期待できます。
出来ることはたくさんありますが、tree-shakingとcode-splittingをまず検討しましょう。

Webpackは汎用的な知識ではないし、vue-cliやNuxtのAPIでラッパーすれば触らなくても良いんですが、
現時点では未だフロントエンドが頑張るべき分野かなと思っています。

アセット最適化を知る

[48]https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/automating-image-optimization/?hl=ja
画像はCDNから配信するのがスタンダードだし、じゃぁCDN上で画像の最適化をするのがベストプラクティスという話です。
Googleが開発しているモダンな画像フォーマットである、webpも紹介されています。

ここまでの総括として、サーバーレスを知る

[49] https://qiita.com/jshimazu/items/e102cde5124609384d0c
[50] https://inside.dmm.com/entry/2018/11/06/nuxt2-pwa-gae-se
これまでに話してきたことを詰め込んだような内容で、かつインフラのメンテコストを減らす形でサーバーレスのNetlifyやGAEを用いた構成です。

SSGやSSRをサーバーレスで動かすのは現代のベストプラクティスの一つだと確信しています。
※弊社では専門のインフラチームがいるため実際にPaaSなどのサーバーレスを採用するケースは少ないですが、多くのチーム・個人にとって有用だと思います。

さいごに

GoogleやAWSのインフラエンジニアの力を借りることが可能な現代で、
フロントエンドエンジニアは自分たちの力で良いWebサービスを実現できる存在だと思います。

知るべきことも、やるべきことも、山ほどありますが、
みんなでWebを少しでも良い世界にしていきましょう?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

すべての新米フロントエンドに読んでほしい50の資料

はじめに

さいきんのWebはSPA技術を中心としたフロントエンドが賑わっていますね?

従来サーバーサイドを扱っていた人もフロントを触る機会が増えていたり、これからプログラミングを学んでいく人も、フロントエンド領域に興味を持っているのではと思います。
そこで、フロントエンドの経験が浅い方や初学者向けに、おすすめのドキュメントや勉強すべき領域をまとめました。

とりあえず動けば良い段階から一歩進んで、フロントエンドエンジニアとして、良いアプリケーションを作るために必要な知識を浅く広く紹介します。

フロントエンド入門

公式ドキュメントを知る

[1] https://jp.vuejs.org/v2/guide/
一例としてVueを貼りましたが、Vueに限らず信頼出来る情報に当たる癖付けがとても大切です。
特にVue.jsは一昔前のjQueryやRailsやPHPのように、技術に明るくない方が書いたページが多いと感じていて、ちゃんとVueを学ぶならまずは公式を見ましょう。

言語を知る

JSを知る

[2] https://jsprimer.net/basic/introduction/
今からJSを学ぶなら特別な事情がない限り、ES2015以降の文法で良いと思います。
js-primerはES2015以降のJSを知る上で素晴らしいドキュメントです。

昔のJSもちょっと知る

[3] https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures
データの隠蔽やカプセル化を実現するために使われたテクニックです。
今のJSを書く場合に意識する機会は少ないと思いますが、知っておいて損ないです。

[4] https://www.yunabe.jp/docs/javascript_class_in_google.html
ES5以前の古いJSで記述しなきゃいけない仕事に遭遇した際、あらためて読み返したい素晴らしいドキュメントです。ベストプラクティスのひとつだと思います。

昔のJSもしっかり学びたい方は、「JavaScript: The Good Parts」や「開眼!JavaScript」といった書籍の購入も検討してください。
上記の書籍を読んで、DouglasやJohnResigやSubstackを知っていると、先輩のフロントエンドエンジニアから気に入られる確率が向上します(当社比)

非同期処理を知る

[5] http://azu.github.io/promises-book/
非同期処理は初学者にとって大きな壁の一つだと思いますが、しっかりとPromiseオブジェクトを理解することがJSでは必須です。
ES2017で追加されたAsync Functionは、Promiseを返す関数なのでPromiseが分かればすぐ理解できます。

Promiseを理解したら、Asyncjsのようなライブラリで複雑な非同期処理を実装したり、
RxJSのようなライブラリを用いてPromise以外の非同期を扱う方法を学んでみると良きです。

HTMLLivingStandard & ECMAScript を知る

[6] https://html.spec.whatwg.org/multipage/
[7] https://www.ecma-international.org/publications/standards/Ecma-262.htm
聖書。HTMLやJSといった言語の仕様が記載してあります。

ちなみに私のチームでは、実装周りの裁判が発生した際に、六法全書代わりとして活用しています。
※私はおそらく全体の3%ほどしか読んでませんが、ちゃんと読んだぞという空気を出して会話します?

コーディング規約を知る

[8] https://qiita.com/mysticatea/items/f523dab04a25f617c87d
[9] https://qiita.com/soarflat/items/06377f3b96964964a65d
これからフロントエンドを学ぶ方すべてに、まずはLintとコードフォーマッターの導入をお勧めします。
Lintではeslintやstylelint、コードフォーマッターではprettierがデファクトです。
利用するルールは何でも良いと思いますが、とにかくルールを用意することが大切です。

UIを知る

モーショングラフィックやインタラクションを知る

[10] https://goodpatch.com/blog/ui-micro-interaction/
マイクロインタラクションはデザイナーの仕事という認識の方も多いと思いますが、
特殊な例外発生時にユーザーへ適切なフィードバックを返すべきといった気付きはエンジニアの方が強いと思うので、常にプログラム的な例外とUI的な例外(フィードバック)の両方を考える姿勢が大切だと感じます。

マテリアルデザインを知る

[11] https://material.io/design/
Google公式のデザインガイドです。英語のドキュメントですが、グラフィック中心なので分かりやすいです。

アトミックデザインを知る

[12] https://ygoto3.com/posts/atomic-design-on-actual-project/
ReactやVueを用いる際にコンポーネント分割の粒度としてアトミックデザインを活用するといったケースがあります。
アトミックデザインに固執する必要はないですが、コンポーネントをどう分割していくかをデザイナー交えて検討するのは大切だと考えていて、土台としてアトミックデザインは有用と思います。

アクセシビリティを知る

セマンティックを知る

[13] https://developer.mozilla.org/ja/docs/Learn/Accessibility/HTML
[14] https://developer.mozilla.org/ja/docs/Learn/Accessibility/CSS_and_JavaScript
セマンティックなコーディングを行うことでアクセシビリティだけでなく、SEOに対してもメリットがあると言われています。

ARIAを知る

[15] https://developer.mozilla.org/ja/docs/Learn/Accessibility/WAI-ARIA_basics
可能な限りネイティブなHTMLで解決すべきで、必要なときだけ使うことが推奨されています。
業務アプリなど利用ブラウザが制限できて、かつ複雑なUIでは活躍の機会があるかもしれません。

SEOを知る

お上の言うことを知る

[16] https://support.google.com/webmasters/answer/35769?hl=ja
まずはお上の言うことに従いましょう。
私は毎晩、「Googleは神」と三回復唱してから寝るようにしています。

構造化データを知る

[17] https://developers.google.com/search/docs/data-types/article?hl=ja
担当業務領域によっては、構造化データを設定することが必要かもしれません。

SEOと直接関係ありませんが、GAやdatalayerを正しく設定することもフロントでは大切です。

ブラウザを知る

ブラウザの仕組みを知る

[18] https://www.html5rocks.com/ja/tutorials/internals/howbrowserswork/
結構長いので、他国の文化を知るような気持ちで、ブラウザってこうなってんだって読むのをお勧めします。

デバイスおよびブラウザの特性を知る

[19] https://caniuse.com/
フロントエンドの辛いところとして、コードの実行環境(ブラウザ)が無数にあることが挙げられますが、JSやCSSがその環境で実行可能か確認できます。

JSに関しては、IE11などでもES2015以降の機能を使えるbabel-polyfillの導入も検討しましょう。

Threadを知る

[20] https://nhiroki.jp/2018/05/07/off-the-main-thread-api
JavaScriptにはメインスレッド(=UIスレッド)が一つしかないので、普通に書くと非同期処理であってもシングルスレッドの直列で実行されます。
重たい処理(UI的にカクついてしまうとか)をマルチスレッドで実行するために、Web Workerの利用を考えましょう。

JITを知る

[21] https://dev.mozilla.jp/2017/05/%E3%82%B8%E3%83%A3%E3%82%B9%E3%83%88%E3%83%BB%E3%82%A4%E3%83%B3%E3%83%BB%E3%82%BF%E3%82%A4%E3%83%A0-jit-%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E3%81%AE%E3%82%AF%E3%83%A9%E3%83%83%E3%82%B7/
(難しくてよく分かってませんが?)モダンブラウザは実行時最適化と呼ばれるコンパイルを行っているそうです。

常に同じ型で呼び出される型を仮定するそうなので、私のような市井のプログラマには、型を意識した開発を心掛けることでJITの恩恵を享受できる可能性があります。
お気づきの方も多いと思いますが、それはTypeScriptと相性が良いです。

セキュリティを知る

DOM Based XSSを知る

[22] https://gihyo.jp/dev/serial/01/javascript-security/0006
モダンなフロントのフレームワークを使っている場合、もはや意識しないかもしれませんが、JS初学者は一度目を通しましょう。

CORSを知る

[23] https://developer.mozilla.org/ja/docs/Web/HTTP/CORS
CORSを理解しそのクライアントとサーバーを実装すると、HTTPに対する理解も深まるのでとてもお勧めです。

CSRF脆弱性とjwtを知る

[24] https://techblog.yahoo.co.jp/advent-calendar-2017/jwt/
jwt(json web token)は、OAuth2.0という認可の仕組みのアクセストークンとして採用されるなど広く使われています。

CSRFという、なりすましのような脆弱性が存在すること、その対策の一つとしてredirect_uriの制限が可能なjwtが存在することを理解出来るとOKです。
GoogleやFacebookのような代表的なOpenID Providerは、stateにredirect_uriを含めuriのホワイトリストと突合するのが必須になっていると思います。

テストを知る

ユニットテストを知る

[25] https://jestjs.io/docs/ja/getting-started
Reactはもちろん、Vueを使う際もJestがお勧めです。
ただフロントエンドのテストはベストプラクティスが無いと言われていて、下記のようにどういったテストをすべきかをまず検討しましょう。
[26] http://akito0107.hatenablog.com/entry/2018/08/27/190333

もしかしたらあなたに必要なのはユニットテストではなく、TypeScriptかもしれません。

E2Eテストを知る

[27] https://techblog.lclco.com/entry/2018/06/28/080000
フロントエンドが自主的に行うE2EとしてはPuppeteerがデファクトではないかと思います。
ユニットテストでも書きましたが、E2Eの運用も楽ではないので何をテストするのかちゃんと計画しましょう。

代表的なUIテストを知る

[28] https://qiita.com/masaakikunsan/items/dad8d84807918f3a43cb
storybookを採用することで、再利用性やテスト容易性が向上すると思います。
実装やメンテは大変なので、小規模なチームでの採用はコストに見合わない可能性があります。

データストアを知る

cookieを知る

[29] https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies
仕様が複雑ですが、とても良く使うためちゃんと理解しましょう。ブラウザのユーザー固有情報においてサーバーとやり取りできる唯一のストレージです。

他にもブラウザだけで扱えるWeb Storageも存在します。サーバーとのやり取りが不要ならこちらを使いましょう。
[30] https://developer.mozilla.org/ja/docs/Web/API/Web_Storage_API#Web_Storage_concepts_and_usage
HTTPヘッダに乗ることもなくブラウザだけで完結するため扱いやすいですが、外部サービスのJSから取得可能な領域のため個人情報を置いたりするのは止めましょう?

NoSQLを知る

[31] https://firebase.google.com/docs/database/ios/structure-data?hl=ja
リンク先はFirebaseのRealtime Databaseですが、MysqlのようなRDBとは設計思想がまるで異なることが分かると思います。
※Cloud Firestoreの設計は、上記のベストプラクティスと異なります。

Cloud FirestoreやDynamoDBといった新世代の優れたデータストアは、これまでバックエンドエンジニアが培ってきた設計が通用しないため運用が難しいと議論されています。
[32] https://qiita.com/funasaki/items/6cdc8f7f7b709e5e601f

一方、多くのネイティブアプリエンジニアが運用してきたように、UIに近い立場のフロントエンドにとっては比較的自然に扱えるデータストアだと感じるので、触れてみるのがお勧めです。

モダンフロントエンドへ

Fluxと仮想DOMを知る

[33] https://qiita.com/mizchi/items/4d25bc26def1719d52e6
Qiita史に燦然と輝く魂の名文。
なぜVueやReactがこれほど重要な位置を占めたか、そのすべてが書いてあります。

私的な余談ですが、右も左も分からない新卒エンジニアだった当時この文章を読んで、全然内容は分からなかったんですが、この筆者が一体何に興奮しているのか興味を持ち、Reactを学びたくなったという背景があります。

言語を知る

TSを知る

[34] https://www.typescriptlang.org/docs/home.html
折に触れてTypeScriptの名前を出してきましたが、今からJSのプロジェクトを始める場合、どんなケースにおいてもTSの採用をオススメします。そこに迷いはありません?

React, Vueを知る

[35] https://ja.reactjs.org/docs/getting-started.html
とりあえずReactかVueのどちらかを学びましょう。

現時点ではTSとの相性がReactの方が高いです。Vue3.0がリリースされるとVueでもTSXがネイティブサポートされ解消される見込みですが。

個人的には、Vueの双方向と単方向データバインディングの合わせ技を便利と感じるか邪悪と感じるかで、VueとReactのどちらを採用するかが決まるかなと考えています。

CSS in JSを知る

[36] https://qiita.com/taneba/items/4547830b461d11a69a20
styled-componentsの採用が多いです。

CSS in JSを嫌っている人もいますが、コンポーネント単位でインターフェースやインタラクションを定義していきましょうという時代に適した手法と感じます。

アーキテクチャを知る

CDNを知る

[37] https://speakerdeck.com/sisidovski/nikkei-itpro-cdn
リリース当時、界隈で話題になった日経電子版のCDNを中心とした設計の話です。
とにかくCDNで出来ることが増えていて、なぜ使うのか、どういったことが可能なのか知ることが大切です。

JAMStackを知る

[38] https://qiita.com/ossan-engineer/items/4fe0e3e388f510bd5c68
CDNファーストを考えた際に、第一候補となる構成です。
この構成を目指す際に採用するGatsbyやVuePressのようなFWは、静的サイトジェネレータ(SSG)と呼ばれる事が多いです。

BFFを知る

[39] https://www.atmarkit.co.jp/ait/articles/1803/12/news012.html
特にこの記事で素晴らしいと思った点は、フロントエンドの担当領域を明確に定義している点です。

私的な余談ですが、なぜBFFという考え方が誕生しその領域をフロントエンドが担うべきなのか、おぼろげに理解できたとき私のなかで点だった技術や思想が線で繋がった感覚がありました。

BFFとSSRを知る

[40] https://speakerdeck.com/yosuke_furukawa/ssrfalsehua
SSRも一種のBFFと呼べますが、なぜSSRをすべきなのかが最もわかりやすいと思います。
さすが日本Node.jsユーザグループ会長、ウォーリーのアイコンも可愛いです。

アーキテクチャの補足ですが、既存の技術資産を活用するためRailsをAPIで残して、フロントエンドだけをモダンにするみたいなケースも見られます。
[41] https://speakerdeck.com/fukuiretu/notewonuxt-dot-jsdezai-gou-zhu-sitahua

レンダリングを知る

[42] https://developers.google.com/web/updates/2019/02/rendering-on-the-web
モダンなフロントエンドのアーキテクチャをレンダリングという観点からまとめたGoogle謹製ページ。
2019年に生きるすべてのフロントエンド必読です。

SSRやSSGを実現する方法を知る

[43] https://ja.nuxtjs.org/guide
NuxtやNextを良く聞くけどイマイチ分かってなかった方々、ここまでの話を読むと凄さが伝わるのではないかと思います。
サーバーサイドでReactやVueが実行可能になったことで、SSRが市井のエンジニアでも実現可能になりました。
NuxtやNextではSSGも可能です。

パフォーマンス改善を知る

Service Workerを知る

[44] https://developers.google.com/web/fundamentals/primers/service-workers/?hl=ja
Service Workerを用いたcacheを行うことで、2回目以降のFCPなどのタイムを大幅に削減可能です。

このAPIを用いると、従来Webから出来なかったプッシュ通知などの体験を提供できることから、Service Workerを活用したWebアプリはPWAとも呼ばれてます。

lighthouseを知る

[45] https://developers.google.com/web/tools/lighthouse/?hl=ja
lighthouseを用いることで、これまで紹介してきたアクセシビリティやパフォーマンスといった項目がサイト上でどの程度実現出来ているかの測定が可能です。

Performance Budgetを知る

[46] https://developers-jp.googleblog.com/2019/03/blog-post_15.html
ウェブサイトを高速に保つための手法として、Performance Budgetの導入が推奨されています。
上記で紹介したlighthouseなどと組み合わせてCIに導入すると良い感じだと思います。

Webpackを知る

[47] https://webpack.js.org/guides/asset-management/
本来パフォーマンスの項目で紹介するものではありませんが、Webpackをちゃんと使うことでBundleサイズの削減、ひいてはパフォーマンスの向上が期待できます。
出来ることはたくさんありますが、tree-shakingとcode-splittingをまず検討しましょう。

Webpackは汎用的な知識ではないし、vue-cliやNuxtのAPIでラッパーすれば触らなくても良いんですが、
現時点では未だフロントエンドが頑張るべき分野かなと思っています。

アセット最適化を知る

[48]https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/automating-image-optimization/?hl=ja
画像はCDNから配信するのがスタンダードだし、じゃぁCDN上で画像の最適化をするのがベストプラクティスという話です。
Googleが開発しているモダンな画像フォーマットである、webpも紹介されています。

ここまでの総括として、サーバーレスを知る

[49] https://qiita.com/jshimazu/items/e102cde5124609384d0c
[50] https://inside.dmm.com/entry/2018/11/06/nuxt2-pwa-gae-se
これまでに話してきたことを詰め込んだような内容で、かつインフラのメンテコストを減らす形でサーバーレスのNetlifyやGAEを用いた構成です。
SSGやSSRをサーバーレスで動かすのは現代のベストプラクティスの一つだと確信しています。

さいごに

GoogleやAWSのインフラエンジニアの力を借りることが可能な現代で、
フロントエンドエンジニアは自分たちだけで優れたサービスを提供できる存在だと思います。

知るべきことも、やるべきことも、山ほどありますが、
みんなでWebを少しでも良い世界にしていきましょう?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsでログイン画面作り続けないと発作が出るお話(環境構築編)

2019-07-10-miyaji-vue-create-login_test-000.jpg

「...うぅ...つ...作りたい...作りたいぃ...」

2019-07-10-miyaji-vue-create-login_test-001.jpg

ログイン画面を...作りたいィィィィィィィィィ!!!!!

2019-07-10-miyaji-vue-create-login_test-002.jpg

すいません。唐突にログイン画面を作らないと発症する発作が出てしまいました。みやゆーです。

発作を収めるために早速ログイン画面を作っていきたいと思います。

どうやって発作を抑えるか

とはいえ、どのようにログイン画面を作っていくかが問題です。

今回の発作は急に発症し、症状も激しいので一刻の猶予もありません。

ここはサクッとページを作成していけるVue.jsと,導入やユーザー管理も簡単なFirebaseを使って作っていきましょう。

なぜVue.jsとFirebaseを使うのかは、それを説明しないと発症する発作が出れば説明します。強いて言えば「少しだけ知見があるから」。そんなもんです。

できるかな?じゃない、やるんだよ

早速やっていきましょう。まずは環境構築です。

環境構築

$ node -v
v10.15.3

$vue -V
3.7.0

$ npm -v
6.4.1

Vue-cliのバージョン確認は-Vね。小文字じゃないよ。

んでVue-cliは、3.0以前と以降で若干インストールのコマンドが違うんですよ。

まだ導入してない人は気を付けてね!

パッケージのインストール

いわゆるログインページの""を作ります。

コンソールで今いる場所を確認してから作ってね。直下にプロジェクトファイルができます。

vue create login_test

なんか出てきた。

Vue CLI v3.7.0
┌───────────────────────────┐
│  Update available: 3.9.2  │
└───────────────────────────┘
? Please pick a preset: (Use arrow keys)
> default (babel, eslint)
  Manually select features

ほーん。defaultManually select featuresを選べってか。

defaultにはbabeleslintしか入ってないのね。

他にもいっぱいぶち込みたいのでManually select featuresを選びましょう。

? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection)
 (*) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support
 ( ) Router
>( ) Vuex
 ( ) CSS Pre-processors
 (*) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing

必要なものにカーソルを合わせてスペースでチェックを入れていきましょう。

今のところ必要なのは以下の2つ。

  • Router: ページ遷移するのに必要
  • Vuex: 後述

Vuexについては後で説明しますがめちょめちょに大事なので絶対入れといてください。後からでも入れれるけどね。だるいので。

? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)

Yesで大丈夫です。

? Pick a linter / formatter config: (Use arrow keys)
> ESLint with error prevention only
  ESLint + Airbnb config
  ESLint + Standard config
  ESLint + Prettier

これも1番上で大丈夫。

? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) Lint on save
 ( ) Lint and fix on commit

上でいいでしょう。

? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arrow keys)
> In dedicated config files
  In package.json

BabelとかESLintの設定をどこに置くか。私は全部package.jsonにまとめてあるほうが好きなので下ですね。ここら辺は全部好みです。

? Save this as a preset for future projects? (y/N)

今後プロジェクトを作るときに今までの設定を反映させるか。んー...今回だけなのでNoで。

Vue CLI v3.7.0
✨  Creating project in C:\Users\miyaji.yusei\Documents\login_test.
?  Initializing git repository...
⚙  Installing CLI plugins. This might take a while...

yarn install v1.15.2
info No lockfile found.
[1/4] Resolving packages...

( ^ω^)おっ

インストール始まりましたね。

success Saved lockfile.
Done in 14.09s.
⚓  Running completion hooks...

?  Generating README.md...

?  Successfully created project login_test.
?  Get started with the following commands:

 $ cd login_test
 $ yarn serve

インストール終わりっ!めっちゃ簡単。

これで環境が整いました!テンプレートができてるはずなので起動してみましょう!

$ cd login_test
$yarn serve

起動してくれます。。。

 DONE  Compiled successfully in 5902ms                                                                                                               17:43:36


  App running at:
  - Local:   http://localhost:8080/
  - Network: http://192.168.116.39:8080/

  Note that the development build is not optimized.
  To create a production build, run yarn build.

起動完了!Vue.jsのlocalhostはデフォルトで8080です。chrome等でURLを叩きましょう。

localhost:8080

2019-07-10-miyaji-vue-create-login_test-003.png

できた!あとはログイン画面を作るだけや!

2019-07-10-miyaji-vue-create-login_test-004.jpg

まだまだ長いやんけ...

でも発作は収まったので良しとします。

また発症したら続きを描きます。みやゆーでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ティラノスクリプトのシナリオファイルの流れを視覚化

視覚化ツール?

ティラノスクリプトでプロジェクトをはじめました。
規模が大きくなると、ファイル分岐の流れのチェックが大変です。
それでこのツールを作りました。
このツールを使うとシナリオファイルの流れが一目でわかります。
これを使うと以下のようなシナリオファイルのjump, link, glink の移動先の流れを一目で確認できます。

image.png

ただし変数とかマクロには対応してません。
そしてラベルではなく、ファイル分岐だけに使えます。
ファイルを沢山作るタイプの人に向いてます。
いつかはラベル分岐にも対応できるようにしたいですね。

ちなみに、ティラノスクリプトの本体サンプルプロジェクトに適用してみたら、こんな図になりました。

image.png


開発

シナリオファイルの分析は、ティラノスクリプトエンジンのソースを利用しました。(ver 4.5)

https://github.com/ShikemokuMK/tyranoscript

核心はこれです。シナリオファイルを呼び出してのパーシングする部分です。

$.loadText(fullpath,function(text_str){
        var scenario = tyrano.plugin.kag.parser.parseScenario(text_str);
        console.log(scenario);
});

そしてその視覚化にはvis.js を使いました。

https://visjs.org/


ソース、使い方

以下のファイルをティラノスクリプトプロジェクトのindex.html と同じ位置に置いてブラウザで開くだけでオッケーです。

  • scenario_visualizer.html
<!DOCTYPE html>
<html>
<head>
  <title>Tyrano Scenario Visualizer</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content=" user-scalable=no" />
<meta name="robots" content="noindex,nofollow" />
<script src="//cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js" type="text/javascript" ></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis-network.min.css" rel="stylesheet" type="text/css" />
<style type="text/css">
  html,body{
    margin: 0;
    height: 100%;
    overflow: hidden;
  }
  #mynetwork {
    width:100%;
    height:100%;
    border: 1px solid lightgray;
  }
  .spinner {
    width: 40px;
    height: 40px;
    background-color: #333;

    margin: 100px auto;
    -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
    animation: sk-rotateplane 1.2s infinite ease-in-out;
  }

  @-webkit-keyframes sk-rotateplane {
    0% { -webkit-transform: perspective(120px) }
    50% { -webkit-transform: perspective(120px) rotateY(180deg) }
    100% { -webkit-transform: perspective(120px) rotateY(180deg)  rotateX(180deg) }
  }

  @keyframes sk-rotateplane {
    0% { 
      transform: perspective(120px) rotateX(0deg) rotateY(0deg);
      -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg) 
    } 50% { 
      transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
      -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg) 
    } 100% { 
      transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
      -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
    }
  }  
</style>

<script type="text/javascript" src="./tyrano/libs/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="./tyrano/libs/jquery-ui.min.js"></script>
<script type="text/javascript" src="./tyrano/libs/jquery.a3d.js"></script>
<script type="text/javascript" src="./tyrano/libs/jsrender.min.js"></script>


<script type="text/javascript" src="./tyrano/libs/alertify/alertify.min.js"></script>

<script src="./tyrano/libs/remodal/remodal.js"></script>

<script type="text/javascript" src="./tyrano/libs/html2canvas.js"></script>

<script type="text/javascript" src="./data/system/KeyConfig.js"></script>

<script type="text/javascript" src="./tyrano/lang.js" ></script>
<script type="text/javascript" src="./tyrano/libs.js" ></script>

<script type="text/javascript" src="./tyrano/tyrano.js" ></script>
<script type="text/javascript">
$(document).ready(function() {
    alert("ready");
});

// stop the ready handler
$.isReady = true;
</script>
<script type="text/javascript" src="./tyrano/tyrano.base.js" ></script>

<script type="text/javascript" src="./tyrano/plugins/kag/kag.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.event.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.key_mouse.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.layer.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.menu.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.parser.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.rider.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.tag_audio.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.tag_camera.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.tag_ext.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.tag_system.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.tag_system_mod.js" ></script>
<script type="text/javascript" src="./tyrano/plugins/kag/kag.tag.js" ></script>
<script type="text/javascript" src="./tyrano/libs/lz-string.min.js"></script>
<!-- <script type="text/javascript" src="./tools/graph.js"></script>
<script type="text/javascript" src="./tools/tyrano_analysis_for_web.js"></script> -->
<script type="text/javascript">
function ScenarioGraph(){
    this.node = {};
    this.edge = {};
    this.addNode = function(nodename){
        if(this.node[nodename]){
            return false;
        }
        this.node[nodename] = nodename;
        return true;
    }

    this.addEdge = function(nodename, child){
            if(!this.edge[nodename]){
                this.edge[nodename] = [];
            }
            if(this.edge[nodename].indexOf(child) == -1){
              this.edge[nodename].push(child);
            }
        }

    this.get_vis_edges = function(){
            var edges = [];
            for(var n in this.edge){
                var child_nodes = this.edge[n];
                for(var i in child_nodes){
                    var child = child_nodes[i];
                    edges.push({from: n, to: child, arrows:'to'});
                }
            }
            return edges;
        }

    this.get_vis_nodes = function(){
            var nodes = [];
            for(var n in this.node){
                nodes.push({id: n, label: n });
            }
            return nodes;
        }
}


if (typeof module !== 'undefined'){
    module.exports = ScenarioGraph;
}

var start_file_name = "first.ks";
var scenarioDir = "./data/scenario/";
var reqCnt = 0;
function createGraph(filename){
    var g = new ScenarioGraph();
    seekDAG(g, filename);
    return g;
}

function seekDAG(graph, filename){
    if(!filename){
        console.log(filename);  
        return;  
    }
    var isNew = graph.addNode(filename);
    if(!isNew){
        console.log("already exists " + filename);  
        return;  
    }

    var fullpath = scenarioDir + filename;
    console.log(fullpath);
    reqCnt++;
    $.loadText(fullpath,function(text_str){
        var scenario = this.tyrano.plugin.kag.parser.parseScenario(text_str);
        var child_list = [];

        for(var i = scenario.array_s.length-1; 0 <= i ; i--){
            var result_obj = scenario.array_s[i];
            //console.log(scenario);
            if(["jump","A","B","glink","link"].includes(result_obj.name)){
                if(result_obj.pm){
                    var child_filename =  result_obj.pm.storage;
                    if(child_filename){
                        child_list.push(child_filename);
                    }
                }
            }
        }

        for(var i=0; i<child_list.length; i++){
            var child_filename = child_list[i];
            graph.addEdge(filename, child_filename);
            seekDAG(graph, child_filename);
        }
        reqCnt--;
    });

}

function loadVis(document_id, g){
    if(0 < reqCnt){
        console.log("loading scenario files not complete ... ");
        return false;        
    }
    var nodes = new vis.DataSet(g.get_vis_nodes());
    var edges = new vis.DataSet(g.get_vis_edges());

    var container = document.getElementById(document_id);
    var data = {
    nodes: nodes,
    edges: edges
    };
    var options = {};
    var network = new vis.Network(container, data, options);
    $(".spinner").remove();
    return true;
}

function wait_and_load_vis(document_id, g, cnt){
    if(cnt > 10){
        console.log("loading text timeout " + cnt);
        return;
    }
    console.log("("+ cnt +"/10) waiting 0.5 second and retry create graph ");
    setTimeout(function(){
        var ret = loadVis(document_id, g);
        if(!ret){
            wait_and_load_vis(document_id, g, cnt+1);    
        }
    },500);
}

function create_vis(document_id){
    var g = createGraph(start_file_name);
    wait_and_load_vis(document_id, g, 0);
}


</script>

</head>

<body>
<!-- <div id="tyrano_base" class="tyrano_base" style="overflow:hidden" unselectable="on" ondragstart="return false" ></div> -->
<div id="mynetwork">
  <div class="spinner"></div>
  Now Loading...
</div>

<script type="text/javascript">
window.onload = function() {
  create_vis("mynetwork");
}
</script> 

</body>
</html>

ただし、ティラノスクリプト本体みたいに、file:// みたいなローカルファイルSchemaでは動きません。
http:// で開く必要があります。
そのためにはlocalhost Webサーバを起動する必要があるから、非プログラマーには難しいかも知れません。
一番簡単なアプローチは、nodejs の http-server を使う事です。
https://qiita.com/standard-software/items/1afe7b64c4c644fdd9e4

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

firebaseのデータベースを使うときにUncaught TypeError: firebase.database is not a functionと吐かれた時の解決法

未来電子テクノロジーでインターンをしています、Sotaです。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

今回は、firebaseでホームページを作るときに、firebase.database();でエラーを吐かれた時の解決策のメモです。

Uncaught TypeError: firebase.database is not a function

databaseに問い合わせのデータを格納しようとjsを書いていたら、コンソールに見出しのエラーを吐かれました。
色々なサイトを参考に初期設定から立ち上げいていたのですが、このエラーに関する情報がなかなか無くて詰んでしまいました。
その時の解決法です。
firebaseで最初に

<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/6.2.4/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
     https://firebase.google.com/docs/web/setup#config-web-app -->

<script>
  // Your web app's Firebase configuration
  var firebaseConfig = {
    apiKey: "***",
    authDomain: "***",
    databaseURL: "***",
    projectId: "***",
    storageBucket: "",
    messagingSenderId: "***",
    appId: "***"
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
  </script>

このコードをindex.htmlに書き込むと思います。
この部分に少しコードを加えると解決できました。

<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/6.2.4/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.2.4/firebase-auth.js"></script>  
<script src="https://www.gstatic.com/firebasejs/6.2.4/firebase-database.js"></script>

このように下の2行を追加すると解決しました。
auth.jsやdatabase.jsが読み込めていなかったのかもしれません。
参考にしたサイトは
https://stackoverflow.com/questions/38248723/firebase-database-is-not-a-function
こちらです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSSでモーダルウィンドウをレスポンシブな感じで画面中央に配置する

レスポンシブな感じでモーダルウィンドウを画面中央に配置したいときに使ったスタイルです。

index.html
<body>
  <div class="modal">
    <span>ITEM1</span>
    <input type="text" name="item1">
    <span>ITEM2</span>
    <input type="text" name="item2">
    <button>send</button>
  </div>
<body>
main.css
body {
  background: rgba(0, 0, 0, .2);
}
.modal {
  height: 20em;
  background: #fff;
  padding: 20px;
  /* ↓ 画面中央に配置するためのスタイル */
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  margin-left: 10%;
  margin-right: 10%;
}

上下左右の余白の比率は変化することなく、画面サイズに合わせてモーダルウィンドウのサイズが変化します。

↓ ウィンドウを小さくすると
small_display.png

↓ ウィンドウを大きくすると
large_display.png

ただしこのやり方だと、画面サイズが大きくなるにつれて モーダルウィンドウの横幅も大きくなってしまうため、他の良い方法を探し中です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

イベントハンドラも含めてDOMを複製する(注!jQuery)

jQueryをバンバン使用している案件において、
clickイベント登録されたボタンを別の場所にも配置したい
でもCMS改修はしたくないから、フロントで何とかしてほしい
という要件でちょっとググったら出てきました。

今の今まで存在を知らなかっただけですが、自分用のメモとして…

clone(true)を使う

clone()はある要素のコピーを作成してDOMの他の場所に配置する関数です。
jQuery("#A").clone().insertBefore("#B")のように使います。

clone(true)とtrueをセットすることでイベントハンドラも含めてDOMをコピーできます。

jQuery("#clone-sitai-el").clone(true).insertBefore("#kono-el-no-ueni-insert");




長いページにおいて、ライブラリを使って簡単に実装したモーダル表示ボタンとかをいろんば場所に置いておきたい、等の場面で便利だなぁ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

この夏プログラミングはじめました

未来電子テクノロジーでインターンをしている mrm1027 です。

今回は、初めてQiitaで記事を投稿するので、書き方がいまいち分からず緊張しております。。

プログラミングを始めて、2週感経ちました。
進捗としては、ProgateのHTML&CSSの上級編まで修了しました。
これまでは基本的な部分を学びながら、それぞれのステージで簡単な成果物を作りあげるような学習でした。
しかし、まだどうしたらどうなって、なぜそれが必要でといった根本をまだまだ理解できていないので、
今後は、これまでに学習した範囲の復習を小まめに入れつつ、次の自由課題に向けて取り組んでいこうと思います。

次回からは、ちゃんとした専門的な内容の記事を書けるようにプログラミングの学習を引き続き頑張りたいと思います!!

【プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし誤りがある場合は、すぐさま修正しますのでどんどん指摘してください。】

誤りからもたくさん学んで吸収していきたいです!よろしくお願いします!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTMLで画像だけを透過させたい

はじめに

今回は、「HTMLで画像の上に文字を表示し、画像だけを透過させる方法」について書きます。

何で困ったか

画像の上に文字を表示し、画像だけを透過させたいが、全て透過してしまう。
↓こんな感じ。

スクリーンショット 2019-07-11 11.17.33.png

その時のコードがこちら。(関係のないところのコードは割愛)

index.html
<div class="contents-bg">
          <div class="header-logo">
            Home
          </div>
        <div class="header-list">
          <ul>
            <div>
            <li><input class = "button2" type="submit" value="menu" onClick="alert('Sorry. The menu button is broken.');" ></li>
            <li><button class = "button1" type=“button” onclick="location.href='#'">contact</li>

          </ul>
        </div>
    </div>
stylesheet.css
.contents-bg {
    background-image: url("header.png");
    background-size: cover;
    background-position: center;
    height: 200px;
    opacity:0.6;
}

いろいろ調べてみると・・・

opacityでは要素全体に適用されてしまうコードであることが判明。
以下のサイトを参考にして、文字と画像の間にもう1つレイヤーを挿入する方法でコードを書き直してみました。
http://www.yabi-blog.xyz/css_background_rgba/

書き直し後

div の class として新しくcontentsというレイヤーを挿入しました。
そして、contentsのstylesheetで、rgbaを使用して透過を実装。
(rgbaはプロパティにだけ適用されるコード)

index.html
<div class="contents-bg">
        <div class="contents">
          <div class="header-logo">
            Home
          </div>
        <div class="header-list">
          <ul>
            <div>
            <li><input class = "button2" type="submit" value="menu" onClick="alert('Sorry. The menu button is broken.');" ></li>
            <li><button class = "button1" type=“button” onclick="location.href='#'">contact</li>

          </ul>
        </div>
  </div>
    </div>
stylesheet.css
.contents-bg {
    background-image: url("header.png");
    background-size: cover;
    background-position: center;
    height: 200px;
}

.contents {
    background-color: rgba(255,255,255,0.78);
    height: 200px;
}

実行結果

スクリーンショット 2019-07-11 11.46.37.png

きちんと画像だけ透過させることができました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Emmet】コーディング方法について

Emmetとは

今回はHTMLの記述を簡略化するemmetについてまとめていきたいと思います。
Emmetは、ほとんどのエディターでプラグインとして用意されています。

Emmet(旧:Zen Coding)は既定形式の入力補完機能によりHTML、XML、XSL等を素早く編集できる、テキストエディタ用プラグインである。2008年にVadim Makeevが開発を始め、Sergey Chikuyonokと利用者によりMIT Licenseのオープンソースとして継続して開発されている。 多くの著名なエディタに実装されているが、特定のソフトウェアに特化して開発されておらず、どのテキストエディタにも偏向していない。-- Wikipedia(日本語訳)

使用方法

今回はatomでの使用方法について解説します。
環境設定のパッケージでemmetと入力しインストールだけで使用できます。
スクリーンショット 2019-07-11 10.56.02.png

記述方法

記述したらtabキーで実行します。

div>ul>li>*3
 <!-- tabキーで実行する-->
 <!--実行結果 -->
<div>
  <ul>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

上記ではdivタグの中にli*3でliタグを3つ作成しています。

p+ul>li
 <!-- tabキーで実行する-->
 <!--実行結果 -->
<p></p>
<ul>
    <li></li>
</ul>

親子にしたくない場合+で繋いだコードを入力します。

div#section>ul.list>li.item>a
 <!-- tabキーで実行する-->
 <!--実行結果 -->
<div id="section">
    <ul class="list">
        <li class="item"><a href=""></a></li>
    </ul>
</div>

.や#で、class名とid名を設定できます。

div>a[href=http://hogehoge.com]
 <!-- tabキーで実行する-->
 <!--実行結果 -->
<div><a href="http://hogehoge.com"></a></div>

"は自動で付けられます。
imgタグはimg[src=hoge.png]で同様に使用できます。

ul>(li>a{link$})*4
 <!-- tabキーで実行する-->
 <!--実行結果 -->
<ul>
    <li><a href="">link1</a></li>
    <li><a href="">link2</a></li>
    <li><a href="">link3</a></li>
    <li><a href="">link4</a></li>
</ul>

()でグループ化を行い、{}内にテキストを入力し、$を使用して連番を付け加え、*4でまとめてliタグ4つを作成しています。

あとがき

以上、今回はEmmetについてまとめてみました。
Emmetを使用する事に捉われると逆に時間がかかったりする場合もあるので、普段面倒だなと感じる時に使うくらいが丁度良いかもしれませんね、、:ghost:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Webデザイン初心者に役立つ(と思う)サイト3選

はじめに

某新宿のIT系専門学校一年のYuumaと申します。
今学校の授業でhtmlでWebページを製作しているのですが制作している過程で役に立ちそうなサイトをいくつか見つけたので紹介していきたいと思います。

Unsplash

知っている人も多いと思いますがこのサイトは60万枚以上の美麗な写真が著作権フリーで使えるサイトです。(しかも商業利用もOK)
著作権フリーなので探せばいろいろなブログやサイトでこのサイトの写真が使われてます。

キャプチャ.JPG

サイトには検索機能があるほかアカウントを作ればお気に入りを設定することもできますし複数の写真をまとめたコレクションといったものを作ることもできます。

robert-bock-cV4qkkorDFY-unsplash.jpg

↑こんな感じの綺麗でエモい画像がたくさんあります。
Url https://unsplash.com/

fontisto

こちらは様々なアイコンが使えるCSSファイルを配布しているサイトです。また、アイコンを個別にsvgファイル形式でダウンロードすることも可能です。
キャプチャ.JPG

fontistoにあるアイコンは例えば車や携帯、顔文字といった一般的なものからTwitterやInstagram,Lineなどといった有名なアプリのアイコンやappleやgoogleといったブランドのロゴ。果てはubuntuのロゴまであります。
また、ページにアクセスすると画面下部にメニューが表示されそのメニューの設定次第で背景のスタイルや角度回転のアニメーションなどが設定可能です。
Url https://www.fontisto.com/icons

flatuicolors

このサイトは色を選ぶ際に使えるサイトです。flatuicolors.JPG
サイトにアクセスすると上のような画面が出てきます。
画面の好きな色のボタンをクリックするとクリップボードに指定した色のカラーコードが保存できます。
サイトを作る際に色をどうしようかと迷った場合にとても役に立つサイトです。
Url https://flatuicolors.com/

 おわり

今回の記事はいかがでしたか?
良かったらいいね押していってくださいm(__)m
(良い締めが思いつかなかったのでいかがでしたかブログみたいになってしまった)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

これからを生きる。なぜエンジニアなのか

どうも!!!チャンクノです。
今回は技術的なことについてではありません。
私がなぜ前職を退職し、エンジニアを目指したのかを書きます。
同じ考えを持っている方がいてくださると私としても励みになります!
私はプロフィール欄に書いてある通り葬儀社で働いていました。
ここでは私が前職を退職した理由について書きます。

①自分のキャリアが全く見えなかった

最初に言っておきますと葬儀業界は毎日のようにありがとうをもらえるやりがいのある仕事だと思います。
ただ、私は働いていく中で、これから先自分がどうなっているのか全くイメージできませんでした。
葬儀社は基本的に毎日同じことの繰り返しです。つまり日常に変化がないんですね。そしてプログラミングみたいに技術的な何かが身につくわけでもありません。現代の背景を考えるとそれはまずいのではないかと考えるようになりました。
「葬儀社なんてなくならないから将来安泰じゃん」と言われたこともあります。たしかになくならないでしょう。人は誰しも必ずいつかは死を迎えますからね。しかし、なくならない=安泰ではないです。少子高齢化によって亡くなる人は確実に増えていきます。ただ、葬儀業界の現状として一件単価の著しい低下が見られます。これは低単価の仕事をたくさんこなさなければならないということです。さて、そのしわ寄せは誰に来るでしょう。そう、自分たちです。
私の中で、低単価→会社として利益があがらない→自分たちの賃金低下や待遇悪化につながる恐れ。
このような流れが考えられました。
また、冠婚葬祭系の会社は値段はそのままでプランの内容を以前のものより少しグレードを落として提供するようになってきています。
以上のことからもう衰退産業であると感じるようになりました。
そして、思い切って退職という選択をしました。
新卒10ヶ月でやめるというのはそれなりにリスクがあったと思います。ただ、未来のないところに居続ける方がリスクがあると私は考えています。
自分の決断に悔いがのこらないようにしましょう。
私は辞めたことを一ミリも後悔していません。

②なぜエンジニアなのか

私がプログラミングを改めてしっかり学ぼうと思った理由は二つです。
一つ目は技術さえしっかり身につければ今後の人生において選択肢が大幅に広がるから、二つ目はやってみたら結構楽しかったからです。

1.自分の可能性を広げる

私はプログラミング技術を身につけることで将来の選択肢が大幅に広がると考えています。
まず、仮に勤めている会社が無くなってもそんなに困らない。これが一番大きいかなと考えています。おそらくですが一般企業に勤めている方だと会社が倒産するとなった場合とても困りますよね。そして基本的に選択肢は転職しかないと思います。
これがエンジニアだとフリーランスになるという選択肢もあるんですよね。クラウドソーシングなどで食いつないでいくこともできるでしょう。思い切って海外に行くのもありですね。やりたいことが形になっている人なら起業してみるのもいいと思います。どうですか。何かあってもなんとかなりそうですよね。まあ私はエンジニアの実態というものをよく知らないので現実は全然違うのかもしれませんが、そんなことを考えても仕方ないです。ただ一つ言えるのは自分次第でこれだけの選択肢を選べるようになる職種であるということです。
なので私はプログラミングを学ぶことを決めました。

②やってみたら意外と楽しかった

これ結構大事なんじゃないですかね。私はhtmlに触れてみて楽しいと感じました。当然楽しいことばかりではないですけどね笑
むしろ今は辛いことの方が多いです。でも辛いのは当たり前のことだと思います。だって初めて学ぶことだもん。
まあ楽しいと感じるかどうかというよりもやってみるということが大事ですね。中にはプログラミングに全く触れずにスクールに通い、結果辞める方がいるみたいですが流石にそれは時間の無駄だと思います。有料のスクールだったらお金も無駄になってしまいます。今は無料で学べる環境が整っているみたいなのでまずはそちらで学んでみるのがいいでしょう。
現在プログラミングを学んでいる人はこれからもお互いに頑張っていきましょう!!!
では皆様のよきプログラミングライフを祈っております。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHP で Google reCAPTCHA v3 付きのお問い合わせフォームを作る (1)

はじめに

Google reCAPTCHA v3 を付けたお問い合わせフォームを PHP で作っていきます。
メール送信ライブラリは Swift Mailer を使用します。
reCAPTCHA v3 については こちら

Google reCAPTCHA v3 とは

巷でよく見かける 私はロボットではありません と書かれたチェックボックスの新しいバージョンです。
ですが、 チェックを付けたり、写真を選んだりする必要がなくなりました。
その代わりに、ユーザの行動から 0.0~1.0 のスコアが算出され、 0 に近いほどロボットによる操作の疑いが強く、 1 に近いほど人間による自然な操作の可能性が高いということみたいです。

前提条件

  • PHP 7.3 (これより低くても可)
  • Composer をインストールしておく

事前準備

reCAPTCHA v3 のキーを取得する

まず、 こちら から reCAPTCHA v3 の Admin console にアクセスします。
はじめて Admin console を開いた場合、「新しいサイトを登録する」という画面がされるので、ラベル・reCAPTCHA タイプ(reCAPTCHA v3)・ドメインを入力します。
ラベルは任意の名前で構いません。ドメインは使用するサイトのドメイン、またはローカル開発環境であれば localhost 等を入力してください。
最後に「reCAPTCHA 利用条件に同意する」にチェックを入れて「送信」を押します。
サイトキー と シークレット キー が表示されたらコピーしておきます。

Composer で使用するパッケージをインストールする

使用するパッケージは以下の2つです。

  1. reCAPTCHA PHP client library (Google 公式)
  2. Swift Mailer

composer require でパッケージをダウンロードします。

composer require google/recaptcha && composer require swiftmailer/swiftmailer

パッケージのダウンロードが終わったらひとまず準備は完了です。
ここから実際にコードを書いていきます。

導入手順

1. HTML でフォームを作る

まずは HTML でシンプルなお問い合わせフォームを作っていきます。

index.php
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>お問い合わせフォーム</title>
</head>
<body>
  <form action="send.php" method="POST" name="inquiry">
    <p>
      <label for="name">お名前</label>
      <input type="text" name="name" id="name">
    </p>
    <p>
      <label for="email">メールアドレス</label>
      <input type="email" name="email">
    </p>
    <p>
      <label for="contents">お問い合わせ内容</label>
      <textarea name="contents" id="contents" cols="30" rows="10"></textarea>
    </p>
    <button type="submit">送信する</button>
  </form>
</body>
</html>

2. reCAPTCHA トークンの生成

ここで事前準備の際に取得した サイトキー が必要になります。
JavaScript でトークンの生成とトークンをフォームに hidden で配置するコードを </body> の直前に書いていきます。
<サイトキー> のところは取得したサイトキーを入れてください。
{action: 'inquiry'}inquiry は任意のもので構いません。

index.php
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>お問い合わせフォーム</title>
</head>
<body>
  <form action="send.php" method="POST" name="inquiry">
    <p>
      <label for="name">お名前</label>
      <input type="text" name="name" id="name">
    </p>
    <p>
      <label for="email">メールアドレス</label>
      <input type="email" name="email">
    </p>
    <p>
      <label for="contents">お問い合わせ内容</label>
      <textarea name="contents" id="contents" cols="30" rows="10"></textarea>
    </p>
    <button type="submit">送信する</button>
  </form>

  <script src="https://www.google.com/recaptcha/api.js?render=<サイトキー>"></script>
  <script>
    grecaptcha.ready(function() {
      grecaptcha.execute('<サイトキー>', {action: 'inquiry'}).then(function(token) {
        var rcpt = document.createElement('input');
        rcpt.type = 'hidden';
        rcpt.name = 'token';
        rcpt.value = token;
        document.inquiry.appendChild(rcpt);
      });
    });
  </script>
</body>
</html>

3. reCAPTCHA v3 のスコアを算出して処理を分岐する

フォームからの POST を受け取って、PHPで処理していきます。
ここで事前準備で取得した シークレット キー<シークレット キー> に入れます。
setExpectedAction('inquiry')inquiry は、先ほどトークン犯行の際に指定した {action: 'inquiry'} と同じ名前にします。

ここからが一番重要です。 setScoreThreshold(0.5)0.5 は、人間とロボットを分ける閾値です。
ここの数値が 1 に近いほど厳しい判定になり、 0 に近いほど緩い判定になります。

send.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use ReCaptcha\ReCaptcha as ReCaptcha;

if ($_POST['token']) {
  $response = (new ReCaptcha('<シークレット キー>'))
                  ->setExpectedHostname($_SERVER['SERVER_NAME'])
                  ->setExpectedAction('inquiry')
                  ->setScoreThreshold(0.5)
                  ->verify($_POST['token'], $_SERVER['REMOTE_ADDR']);
  $result = $response->toArray();

  if ($result['success']) {
    echo 'あなたはロボットではありません。';
  } else {
    echo 'あなたはロボットです。';
  }
}

ここまでが reCAPTCHA v3 の基本的な使い方です。

続き → PHP で Google reCAPTCHA v3 付きのお問い合わせフォームを作る (2)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む