深層フロントエンド
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深層
- 1,230