深層フロントエンド

Preface

- 説明のプロではありません。


- 理解しづらいところは都度突っ込んでOK


- #深層フロントエンド で実況OK

 

- 分かりやすさ優先のため、わざと曖昧に言うことがあります。

注意書き

深層フロントエンド

第1層::JavaScript深層

いざ深層へ

JSエンジンとJS環境

§1 JSエンジンとJS環境

CPU

機械語=バイナリを解釈
文字列は解釈できない

§1 JSエンジンとJS環境

JSエンジン

JavaScriptプログラム=文字列を解釈し、CPUに実行させる。

 

V8, SpiderMonkey, など

§1 JSエンジンとJS環境

知らない子ですね

JSコーダーがお世話になるのはJSエンジンではない。

 ⇒ 他のものに組み込まれた状態で使っている。

ブラウザ:scriptタグに書いたJSが動く

 Chrome→V8 Firefox→SpiderMonkey

Node.js:.jsファイルが動く

 →V8

§1 JSエンジンとJS環境

JSエンジンがやること

JavaScript文字列をパース(分解)して、
ここは足し算だ、ここは変数宣言だ、ここは関数呼び出しだ
を解釈・実行するだけ。

 

これだけでは何のアプリケーションも作れない

§1 JSエンジンとJS環境

JS環境

ブラウザ:HTMLの操作機能等

 = windowオブジェクト
Node.js:ファイルの読み書き機能等

 = require('fs')

 

これを用意しているのがJS環境

§1 JSエンジンとJS環境

§1 JSエンジンとJS環境

JSエンジン

JS環境

.js

V8

Node.js

Node.js用.js

V8 / SpiderMonkey

Chrome / Firefox

ブラウザ用.js

ブラウザのJS

ブラウザで動くJS=ブラウザ向けJS環境には
どんな機能が必要か?

 → window.document  HTML(DOM)をいじる

 → window.location   現在のURLを取得・操作

 → window.localStorage 簡易データ保存領域

ブラウザ間で仕様の統一が進められている

§1 JSエンジンとJS環境

Node.jsのJS

他の言語が持つ「標準ライブラリ」相当のものを用意

 ・ ファイルの読み書き

 ・ ネットワーク通信(TCP・UDP)

 ・ プロセスの制御

 

JavaScriptが他の言語と同格になった

§1 JSエンジンとJS環境

コールバック

§2 コールバック

引数としての関数

例えば配列のforEach

§2 コールバック

console.log('A')

const array = [1, 2, 3]

array.forEach(function (value) {
	console.log(value)
})

console.log('B')

関数は
すぐに
呼び出される

A
1
2
3
B

イベントハンドラ

buttonがクリックされたら

§2 コールバック

console.log('A')

$('button').on('click', function (event) {
	console.log('clicked!')
})

console.log('B')

関数は
クリックする度
呼び出される

A
B
clicked!
clicked!
clicked!

タイマー式

setTimeout

§2 コールバック

console.log('A')

setTimeout(function () {
	console.log('timeout!')
}, 1000)

console.log('B')

関数は
1秒後に
呼び出される

A
B


timeout!

コールバック関数

別の場所で呼び出されるような関数のこと。

『いつ』呼び出されるか?
『何回』呼び出されるか?

実行の順番・タイミングに注意

§2 コールバック

イベント
ループ

§3 イベントループ

JavaScriptを実行するということ

§3 イベントループ

executeJavaScriptProgram()

while ( eventHandlers.length ) {

	executeTriggeredHandlers()

}

executeJavaScriptProgram()

§3 イベントループ

まず最初に
記述されたJSを
1度だけ実行する

 

イベントハンドラが
登録されている状態

executeJavaScriptProgram()

while ( eventHandlers.length ) {

	executeTriggeredHandlers()

}

eventHandlers.length > 0

§3 イベントループ

イベントハンドラが
1個以上あるならば
ループする

executeJavaScriptProgram()

while ( eventHandlers.length ) {

	executeTriggeredHandlers()

}

executeTriggeredHandlers()

§3 イベントループ

登録されたハンドラのうち
イベント
 = クリック
 = 時間

が発火したものを実行する

executeJavaScriptProgram()

while ( eventHandlers.length ) {

	executeTriggeredHandlers()

}

eventHandlers.length == 0

§3 イベントループ

イベントハンドラが
なくなったら
ループを終了する

 = プログラムが終了

executeJavaScriptProgram()

while ( eventHandlers.length ) {

	executeTriggeredHandlers()

}

非同期I/O

§4 非同期I/O

I/O

Input/Output = 入出力

 → console.log()

 → ネットワーク

 → ファイル

§4 非同期I/O

非同期I/O

URLにリクエストを送信
  ↓
レスポンスが
帰ってきたら
"done!"

§4 非同期I/O

console.log('A')

$.get('http://oro.co.jp', function (html) {
	console.log('done!')
})

console.log('B')

同期I/O

URLにリクエストを送信
  ↓
レスポンスが
帰ってきたら
"done!"

§4 非同期I/O

console.log('A')

const html = $.get('http://oro.co.jp')

console.log('done!')

console.log('B')

なぜ非同期か?

同期I/O:レスポンスが帰ってくるまで待つ
 = イベントループが止まる
 = 他の処理が実行されない
 = (ブラウザの場合)操作ができなくなる

非同期I/O:レスポンスが帰ってきたらコールバック
 = イベントループが止まらない
 = 他の処理が実行できる
 = (ブラウザの場合)操作できる

§4 非同期I/O

モジュール
システム

§5 モジュールシステム

モジュールシステムとは?

JSのコードを複数のファイル=モジュールに分割

モジュールが他のモジュールを読み込む

 → 他のモジュールに書かれた関数を使える

§5 モジュールシステム

ES Modules

JSの言語仕様としてのモジュールシステム
 
export ......
export default ......

import ...... from './path/to/file.js'

import * as ...... from './path/to/file.js'

§5 モジュールシステム

CommonJS

ES Modulesが策定される以前から
JSの様々な標準化を行っているプロジェクト

CommonJS式モジュールシステム

module.exports = ......

const ...... = require('./path/to/file.js')

§5 モジュールシステム

なぜモジュールシステムか?

これらのモジュールシステムでは、
ファイルが分かれることで「スコープ」が分かれる。

 = 変数名・関数名の被りを気にしなくてよい。

カプセル化によって見通しが良くなる。
 = 意味や役割によってコードを分割でき、読みやすい。
 = 依存関係の明確化。不要なコードを捨てやすい。

§5 モジュールシステム

ブラウザ?

これらのモジュールシステムが使われたコードは
そのままではブラウザで動かない

 

変換ツール
 - browserify
 - babel
 - rollup
 - webpack

§5 モジュールシステム

ビルド

§6 ビルド

JSアプリケーションのビルド

複数のブラウザで動くようなJSコードにするには
「ES5」仕様に合わせる必要がある。
もちろんモジュールシステムを使うことはできない。

開発環境 ←→ 動作環境
の差異を埋める処理が「ビルド」

§6 ビルド

browserify

CommonJS式モジュールシステムで書かれた
複数のファイルを結合して、
ブラウザでも動作するように変換するライブラリ。

 

 → ブラウザアプリケーションを
   モジュールシステムを使って開発できるようになった。

§6 ビルド

babel

ES6, ES7に存在する新しい文法で書かれたコードを
ES5, CommonJS仕様のコードに変換してくれる

例)spread operators, async functions

 

 → ブラウザアプリケーションを
   新しい便利な記法で書けるようになった。

§6 ビルド

rollup

ES Modulesで書かれたJSファイル群を
最適化しつつ、ブラウザで動く形式に結合してくれる。

§6 ビルド

webpack

「loader」という仕組みを導入することで
JSのモジュールシステムを使って
JS以外のファイルを読み込めるようになる。


ブラウザアプリケーションに必要なアセットの読み込みを
モジュールシステムを使って行うような記述が可能になった。

特に画像やCSS

§6 ビルド

今の時代のビルド

Vue.js、React、Angularのアプリケーションでは、
用意されたScaffoldingツールを使うことで、
ビルドに関する作業を全く気にしなくて良くなった。

内部でwebpackが用いられているので
知っておく分には◎

§6 ビルド

深層フロントエンド

第1層::JavaScript深層

つづく

深層フロントエンド 第1層 JavaScript深層

By Shigeki Suwa

深層フロントエンド 第1層 JavaScript深層

  • 807