# 「再入門!フロントエンドエンジニアが押さえておくべき技術」
<!--
1. 19:00〜19:10: オープニングトーク
1. 19:10〜19:15: 自己紹介
1. 19:15〜20:20: メイントーク
* JS: 短め
* TS: 長め
* FW: 長め
* SPA: 短め
* test: 短め
* ブラウザ: 短め
1. 20:20〜20:30: クロージングトーク
1. 20:30: 終了
-->
## ①JavaScript
<!-- - 押さえておいた方が良いポイント、という体
- https://roadmap.sh/frontend -->
### 基本構文
- 割愛
### DOM操作の仕方
- DOM(DocumentObjectModel)とは
- ブラウザが表示しているHTMLの要素をJavaScriptで操作しやすいようにしたデータ構造
- 「操作しやすい」といっても、最近では直接DOMを扱うこと自体を避けるようにもなってきている
- DOM操作の例
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>タイトル</title>
</head>
<body>
<section>
<img src="example.png">
<p>リンクは<a href="https://foo.example.com/">こちら</a></p>
</section>
</body>
</html>
```
- リンクの要素を取得する
- ``const link = document.querySelector('a');``
- リンクの文字列を変更する
- ``link.textContent = 'あちら';``
- リンクのURLを変更する
- ``link.href = 'https://bar.example.com';``
- 「DOMを更新する」ことでユーザーの操作に対して結果を伝える(メッセージを表示する、ダイアログを表示する、色が変わる…)
- JavaScriptフレームワークが代わりにやってくれたり、簡便に記述できたりするが、最終的にやっていることはコレなので重要な要素。
### ES6(ES2015)以降の記法
- ES(ECMAScript)とは
- JavaScriptの標準規格を定めたもの
- JavaScriptとECMAScriptの関係
- JavaScriptはあくまでブラウザ上で動作するスクリプト言語で、厳密にはブラウザによって仕様が異なる
- ECMAScriptはJavaScriptの標準規格で、各ブラウザはECMAScriptの仕様に沿ってJavaScriptを開発する
- ひと昔前はよく聞いた「IE動かない問題」は古いIEほど標準規格に則ってなかったりするものの名残
- 例:``Promise.any``
- [提案](https://github.com/tc39/proposal-promise-any)
- [ブラウザの対応状況](https://caniuse.com/?search=%20Promise.any)
- ES6(ES2015)とは
- ECMAScriptの2015年に公開された規格。6世代目。ES6と言ったりES2015と言ったり。
- それ以前のJavaScriptの構文から、モダンな構文に大きく変化があった世代。
- ES6より前と後で大きく記述方法が異なるため、一つの区切りとされる。
- Before ES6 / After ES6
- let/const
```js
// Before ES6
var a = 1;
// After ES6
let b = 2;
const c = 3
```
- Promise
```js
// Before ES6
// 1秒ごとにカウントダウンする(わざわざこんな書き方する必要はないのですが)
function countDown(count, callback) {
setTimeout(function() {
console.log(count)
callback(count - 1);
},1000);
}
// 非同期で実行する処理がどんどん入れ子になる
countDown(2, function(count){
countDown(count, function(count) {
countDown(count, function(count) {
console.log("finish!");
});
});
});
// Promise
function countDown(count) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(count)
resolve(count - 1);
},1000);
});
}
// 入れ子にならずに書ける
countDown(2)
.then(countDown)
.then(countDown)
.then(function (count) {
console.log("finish!");
});
```
- async/await
```js
// 非同期で実行する関数定義は同じ
function countDown(count) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log(count)
resolve(count - 1);
},1000);
});
}
// async/await Promiseより直感的に書ける
async function asyncCall() {
let count = await countDown(2);
count = await countDown(count);
count = await countDown(count);
console.log("finish!");
}
asyncCall();
```
### API呼び出し
- フロントエンド開発ではバックエンドのAPI呼び出しの知識が必須
- この辺りもJSフレームワーク任せなことが多いが、基礎知識として。
- XMLHttpRequest(XHR)
- すごく古い書き方。古いプロダクトで稀に見かける。
```js
// APIを呼び出した結果をconsoleログに出力
const url = 'https://foo.example.com/api'
let request = new XMLHttpRequest();
request.onload = function() {
console.log(request.response);
};
request.open('GET', url);
request.responseType = 'text';
request.send();
```
- jQuery
- 一昔前の主流。割とまだ見かける。
```js
// APIを呼び出した結果をconsoleログに出力
const url = 'https://foo.example.com/api'
$.ajax({
type: "GET",
url: url,
success: function(text){
console.log(text)
}
});
```
- FetchAPI
- モダンな書き方。
- ちなみにIE11では[基本的には使えない](https://caniuse.com/fetch)
```js
// APIを呼び出した結果をconsoleログに出力
const url = 'https://foo.example.com/api'
async function callApi() {
const res = await fetch(url);
const text = await res.text();
console.log(text);
}
callApi();
```
## ②TypeScript
### TypeScriptの特徴
- JavaScriptに変換される
- TypeScriptで書かれたプログラムを実行したい場合、TypeScriptをそのまま実行するのではなくTypeScriptをJavaScriptに変換させて実行する
- [TypeScript Playground](https://www.typescriptlang.org/play?#code/Q)
```typescript=
// typescript
const foo: string = 'foo';
```
↓
```javascript=
// javascript
"use strict";
var foo = 'foo';
```
- 静的型システム
- TypeScriptがJavaScriptに変換されるときに型チェックが行われる
- 文字を入れるところに数値を入れたりしているとエラーを出してくれる
- JavaScriptのスーパーセット
### なんでTypeScriptを使うのか
- 開発者体験の向上
- JavaScriptは動的型付け言語、TypeScriptは静的型付け言語
- エラーに早く気づける
- たとえば、これは実行時にエラー
```javascript=
// javascript
console.log(foo)
// foo is not defined
```
- TypeScriptならコンパイル時にエラー
```typescript=
// typescript
console.log(foo)
// Cannot find name 'foo'
```
- VSCodeのようなTypeScriptに対応したエディタを使ってるならコードを書いた瞬間に画面上で教えてくれる
- ※ エラーにはなるがコンパイルはできる
- あとはコードジャンプもエディタによる補完も効く
- ドキュメントの役割
- ここで言うドキュメントは変数だったり関数だったりがどういうものかを教えてくれるもの
- TypeScriptを使うと半自動的に実現できる
- たとえばこういう関数があったときに数値の足し算なのか、文字列の連結なのかわからない
```javascript=
// javascript
function add(a, b) {
return a + b
}
```
- TypeScriptを使うと足し算する関数なんだなとわかりやすい
```typescript=
function add(a: number, b: number): number {
return a + b
}
```
- コメント書けばいいじゃん?
```javascript=
// 数値を2つ引数に受け取りその和を返す
function add(a, b) {
return a + b
}
```
- コメントはあくまでコメントで合ってる保証はないし、将来実装に変更が入ってコメントはそのままということも
- TypeScriptならちゃんとエラーになる
```typescript=
function add(a: string, b: number): number {
return a + b
}
// Type 'string' is not assignable to type 'number'.
```
- 古いJavaScriptに変換してくれる
- JavaScript(EcmaScript)にはバージョンがある
- 最新のJS使えばいいじゃん?
- ブラウザが追いついていなかったり、ブラウザベンダーが頑張ってアップデートしてもユーザが更新していなかったりする。まだIE使ってるユーザも多い?
- なのでES5くらいで書かなきゃいけないけど、開発者は最新のバージョンで書きたい
- TypeScriptはESNextなコードをES5やES3に変換してくれる
- お仲間に[babel](https://babeljs.io/)とか
### 関連技術
- [webpack](https://webpack.js.org/)
- [Prettier](https://prettier.io/)
- [ESLint](https://eslint.org/)
- [storybook](https://storybook.js.org/)
- [Node](https://nodejs.org/ja/)
- [Deno](https://deno.land/)
## ③フレームワーク
### フロントエンドフレームワークとは?
* UIのコンポーネント化やリアクティブなデータバインティング処理をまとめたもの
* リッチなWebページを求められる中で先人たちが知見や共通処理などをまとめたもの
* 参考資料
* [フロントエンドフレームワークとは](https://elated-blackwell-51e103.netlify.app/post/%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%83%89%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%A8%E3%81%AF/)
* [なぜフロントエンドフレームワークを使うのか](https://qiita.com/jacksmam/items/86b82721674dd2b88e65)
* [フロントエンドの必要性について](https://teratail.com/questions/138648)
### フロントエンドフレームワークの種類
* メジャーなものを抜粋
1. [Vue.js](https://jp.vuejs.org/index.html)
* 公式ドキュメントの日本語訳が多い
* [SFC(単一ファイルコンポーネント)](https://v3.vuejs.org/guide/single-file-component.html#introduction)を採用
* 部品(コンポーネント)に関するHTMLとCSSとJavaScriptを1つのファイルに記述する
* 関心ごとを1つのファイルに集約できるかつ従来通りの文法をほぼそのまま使用できる
* ```vue=
<script>
export default {
data() {
return {
greeting: 'Hello World!'
}
}
}
</script>
<template>
<p class="greeting">{{ greeting }}</p>
</template>
<style>
.greeting {
color: red;
font-weight: bold;
}
</style>
```
1. [React](https://ja.reactjs.org/)
* 公式でUIライブラリと言っているがVue.jsとよく比較されるので記載
* コンポーネント指向であることはVue.jsと変わらないが、[JSX](https://ja.reactjs.org/docs/introducing-jsx.html)と呼ばれる記法でJavaScriptの一部として画面構成を記述する
* ```tsx=
import style from './style.css'
const HelloWorld () => {
const greeting = 'Hello World!!'
return (
<div className="style.greeting">
{greeting}
</div>
)
}
```
```css=
.greeting {
color: red;
font-weight: bold;
}
```
* 周辺ライブラリの選択肢が多い(=Vue.jsに比べ自由度が高い反面どれを選択するかの知識が必要)
1. [Angular](https://angular.jp/)
* TypeScript標準採用(=開発に必須)
* フルスタックフレームワークを自称しており、Viewの構成だけでなく一通りの機能が入っている
* Vue.jsやReactだと周辺ライブラリ(公式のものを含む)を別途導入しなければならないものが多い
### シェア
* 世界ではReactが人気。日本ではVue.jsとReactが同じくらいでややVue.jsの方が人気
* [直近一年間の検索状況(世界)](https://trends.google.co.jp/trends/explore?cat=13&date=today%2012-m,today%2012-m,today%2012-m&geo=,,&q=%2Fm%2F012l1vxv,Angular,%2Fg%2F11c0vmgx5d#TIMESERIES)
* [直近一年間の検索状況(日本)](https://trends.google.co.jp/trends/explore?cat=13&date=today%2012-m,today%2012-m,today%2012-m&geo=JP,JP,JP&q=%2Fm%2F012l1vxv,Angular,%2Fg%2F11c0vmgx5d#TIMESERIES)
* [State of JS 2020](https://2020.stateofjs.com/ja-JP/technologies/front-end-frameworks/)
* 比較記事
* [React/Vue/Angular](https://qiita.com/gumiTECH/items/13eb7da8224bf93c67b5)
* [VueとReactの比較](https://zenn.dev/tomon9086/articles/5f4014d8004dc5b5f63e)
* [三大Javascriptフレームワーク「Angular、React、Vuejs」について
](https://it-kyujin.jp/article/detail/1647/)
### コンポーネント指向
* 部品単体で完結するコンポーネントを複数組み合わせていくことでアプリケーションを組み上げていく設計手法
* 部品の再利用が用意なため画面間での統一感の維持や素早い開発に役立つ
* コンポーネント
* UIの部品化の単位
* 参考記事
* https://qiita.com/seya/items/8814e905693f00cdade2
* https://jp.vuejs.org/v2/guide/#%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AB%E3%82%88%E3%82%8B%E6%A7%8B%E6%88%90
### 仮想DOM
* 主に画面の表示内容に変更があった際に、JSフレームワーク上で構成される仮のDOM
* 変更があった際に直接DOMを書き換えるのではなく、一度仮想DOMを構成して実際に変更があった箇所のみをDOMに反映することで直接DOMを操作する際よりパフォーマンスが向上する
* 参考記事
* https://qiita.com/seira/items/6767e222890c9890ecb9
* https://ja.reactjs.org/docs/faq-internals.html
## ④SPA(Single Page Application)
### SPAとは
- (極めてざっくり言うと)ユーザーがアクセスするWebページは空の最初の1ページのみで、バックエンドのAPIを呼び出し動的に画面の要素の構築、画面遷移を行うタイプのアプリケーション
- 従来のような画面全体を切り替えて画面遷移を行うタイプのアプリケーションを対比でMPA(Multi Page Application)と呼んだり
### なぜSPAが重要なのか
- 近年では、Webアプリケーションでも、スマートフォンのアプリのような柔軟で表現に富んだ操作性や体験が求められることが多くなった
- メリット/デメリット ※余談ですがメリデメって死語だったりするんですかね。pros/cons?
- メリ
- 前述の通り
- ~~イケてる感~~
- デメ
- 初回のJavaScript読み込みがMPAで作った時より相対的に増えるので、読み込みが遅くなりがち
- Googleなどの検索エンジンにうまくインデックスされない場合がある。
- が、Google側の巡回BOTも進化しているのでうまくインデックスされたりされなかったり
- 確実にインデックスされてほしい場合だけ、後述の対策をするというのでも良さそう
<!-- - [xxx](https://ssr.vuejs.org/ja/#%E3%81%A9%E3%81%86%E3%81%97%E3%81%A6-ssr-%E3%81%AA%E3%81%AE%E3%81%8B) -->
### SSR(Server Side Rendering)
- SPAのデメリットを解消する方法の一つ。
- サーバーサイドでJavaScriptを実行し、実行結果をブラウザに返す方法
- Next.js/Nuxt.jsなど、ReactやVueでSSRを実現しやすくする上位フレームワークなども
### SSG(Static Site Generator)
- ビルド時に先にHTMLを生成する方法。
- Aboutページなどユーザーや状態によって変化がなく、更新頻度の低い画面に有用
- HTMLファイルを直接置いておくのと何が違うんだという話ですが
- 表示する情報はDBなどから動的に構築するが、更新頻度が低いなどキャッシュ的な用途が適している
- ブログ、デイリーでしか更新されないランキングページなど
- ページ全体だけでなく、一部はキャッシュ、一部は動的に更新といった形も
## ⑤テスト
### テストの種類
- 静的テスト
- 単体テスト
- 結合テスト
- E2Eテスト
↑の方が実行速度が速く、実行コストもメンテコストも低い
### 静的テスト
- 型やLinterによる静的チェック
- TypeScript, ESLint
### 単体テスト
- 単一のメソッドやコンポーネントに対して入出力が正しいかチェック
- ロジックが破綻していないか確認できる
- Jest, Jasmine, Mocha, Ava
### 結合テスト
- 複数のメソッドやコンポーネントを組み合わせたときに正しく動作するかチェック
- 実際のユーザの操作に近いふるまいをテストできる
- Jest, Testing Library, Enzyme
### E2Eテスト
- ブラウザ上でアプリケーションを操作して正しく動作するかチェック
- ユーザ操作に着目するので実装の中身は関係しない
- Cypress, Puppeteer, Selenium
### どれをどらくらいやればいい?
- [Unit test vs. Integration test](https://medium.com/android-testing-daily/unit-test-vs-integration-tes-fba13b92fbf6)
- [Testing Pyramid](https://testing.googleblog.com/2015/04/just-say-no-to-more-end-to-end-tests.html)
- 単体/結合/e2e = 70/20/10
- [Testing Trophy](https://testingjavascript.com/)
- 結合テストの割合が大きい
## ⑥ブラウザ
### メジャーなブラウザ
* Google Chrome
* Internet Explorer
* Firefox
* Safari
* Microsoft Edge
### ブラウザ間の差異
* [MDN Web Docs](https://developer.mozilla.org/ja/docs/Web)
* [例: -webkit-line-clamp](https://developer.mozilla.org/ja/docs/Web/CSS/-webkit-line-clamp)
* [Can I Use](https://caniuse.com/)
### 開発者ツールの活用
* [Chrome DevTools](https://murashun.jp/article/performance/chrome-devtools.html)
* https://willcloud.jp/knowhow/dev-tools-01/
* [VueのChrome拡張](https://techblog.roxx.co.jp/entry/2019/05/15/131747)
* https://qiita.com/nonkapibara/items/8b587013b6b817d6dfc4