javascripterのための typescript入門

82
HTML5/フロントエンド開発 最前線 2016/10/24 株式会社オープンウェブ・テクノロジー TechFeed統括 白石 俊平

Upload: doannga

Post on 30-Jan-2017

234 views

Category:

Documents


3 download

TRANSCRIPT

HTML5/フロントエンド開発最前線

2016/10/24株式会社オープンウェブ・テクノロジー

TechFeed統括

白石 俊平

自己紹介

• 白石俊平– shumpei.shiraishi

• 株式会社オープンウェブ・テクノロジーCEO– TechFeedというサービスを

やっています

• HTML5 Experts.jp編集長• html5jファウンダー

TechFeed

• http://techfeed.io

• ITエンジニア向けキュレーションサービス– Web&モバイルアプリ

• エンジニアの興味・関心に沿った情報を、世界中から日々自動的に収集し、整理して届ける。

こんな問いかけから始めてみたい。

Webはいまだに重要なのか?

※ https://www.wired.com/2010/08/ff_webrip/

すごい人達呼んで「Webは死ぬか?」をマジメに語り合ってもらった

※ http://jp.techcrunch.com/2012/09/14/20120911mark-zuckerberg-our-biggest-mistake-with-mobile-was-betting-too-much-on-html5/

※http://www.netratings.co.jp/news_release/2015/11/Newsrelease20151125.html

スマートフォン利用時間の80%がアプリ利用

2016年2月 Firefox OS開発終了

※ http://japan.cnet.com/news/commentary/35077521/

(ブラウザ向け)Chromeアプリ2018年終了

※ http://internet.watch.impress.co.jp/docs/news/1015893.html

技術トレンドとしてはどうか?

W3Cにおけるニュースリリース数(月平均)

0

5

10

15

20

25

30

2011 2012 2013 2014 2015 2016

W3Cのニュースリリース数(月平均)

W3Cのニュースリリース数(月平均)

Web技術の未来を「Extensible Web」から探る

HTML5は問題だらけ?

※ https://html5experts.jp/shumpei-shiraishi/16597/

W3Cのは『欠陥フォーク』!?

HTML5標準はWHATWGの「Living Standard」とW3CのHTML5仕様に分裂した状態が続いている

プラットフォームとして見ると、

• Webの利用時間は減ってきている

– →Webの重要度は、以前に比べて下がっている。「モバイル・オンリー」という選択も珍しくない。

– →モバイル中心で考えると、Webはオプショナルな存在になった。

• Webには技術的な問題や制約も多い

– →しかし、技術的なトレンドとしては退潮傾向にあり、停滞も予想される

Webを使うか使わないか、それが問題だ。

Webの利点Web技術の利点

これらを再評価する

Webの利点

• Secure (安全)

• Linkable (リンク可能)

• Indexable (インデックス可能)

• Composable (再構成可能)

• Ephemeral (一時的な利用)

出典: https://html5experts.jp/agektmr/20527/

Deep Link / Universal Link

• Webブラウザ上のURLを踏んだら、アプリを起動できる

• さらに、アプリは渡されたURLを解析して、情報を直接表示できる

App Indexing

• Googleの検索結果から、アプリを直接起動できる

Webとネイティブ、双方のプラットフォームを往来する

Linkable

SecureComposableEphemetalIndexable

Web技術の利点

• クロスプラットフォーム

• 開発者が多い

• まだまだ進化がやまない

クロスプラットフォーム

JavaScriptは世界で最も人気のある言語

まだまだ進化がやまない

• ECMAScript.next

• コンポーネント指向開発の本格化

• プログレッシブ・ウェブアプリ

ECMAScript.next

ECMAScriptとは?

• ECMAScript = JavaScriptの仕様• この仕様に基づき、各ベンダーが

JavaScriptエンジンの開発を行っている

• 仕様書はGitHub上でオープンに開発されている– https://github.com/tc39/ecma262

• 現在の正式な最新バージョンはES2016。– バージョン番号はスナップショット

的な扱いであり、それほど深い意味はない

– 本スライドでは、「次期ES」という意味のES.nextと呼称する

ES.nextを書くには

• ブラウザごとの対応状況にばらつきがあることから、トランスパイラ(ES.nextのコードをES5に変換する)を使う必要がある

// ES6const f = (a,b) => a+b;

// ES5var f = function(a,b) {return a+b;}

ES.nextが変えたWeb開発

• ES.nextの変更点は多岐にわたるが、特に以下の点でWeb開発を大きく変える

– モジュール&クラス

– 非同期処理に対する言語レベルでのサポート

• その他、「書いていて楽しい」機能も満載

クラスとモジュール

ES6を試してみる:

クラス

• クラス定義

• コンストラクタ

class Greeter {greeting: string;constructor(message: string) {

this.greeting = message;}greet() {

return "Hello, " + this.greeting;}

}

ES6を試してみる:

クラス

• 継承

– 親クラスのメンバーを引き継いだ新たなクラスを作れる

...(略)...class MorningGreeter extends Greeter {

greet() {return "Good morning, " + this.greeting;

}}

モジュール

• 基本は1ファイル=1モジュール

• export…モジュール外にメンバーを公開

• import…他のモジュールを参照

export const GREETING = 'Hello';export class Greeter {}

import {GREETING, Greeter} from './greetings';

モジュールバンドラー

• JavaScriptモジュールをまとめ上げ、1つ(以上)のファイルを出力するツール• 以下の画像はWebpackのサイトより引用(WebpackはJS以外も対象

にできる)

モジュールバンドラー

• モジュールバンドラーで、import/exportをJSコードに変換

import {Component} from '@angular/core'↓ (TypeScriptコンパイラ)var Component = require('@angular/core').Component;↓ (モジュールバンドラーがrequireをブラウザ上で使えるよう変換)var component_1 = __webpack_require__(1);

言語組み込みの非同期処理

ES6を試してみる:

Promise• 非同期処理を、コールバックよりも記述しやすくする

– コードのネストが少なくなるため読みやすい– エラー処理を行いやすい

// 指定したミリ秒待つ関数function waitFor(millis): Promise<void> {

return new Promise((resolve, reject) => {if (millis >= 0)setTimeout(resolve, millis);

elsereject(new Error(`Invalid arg:${millis}`));

});}// 非同期関数function hello(seconds) {

waitFor(seconds * 1000).then(() => alert('Hello')).catch (e) {}

}hello(3); // 3秒後に「Hello」が表示される

ES6を試してみる:

async/await• Promiseベースの非同期なコードを、あたかも同期的なコードであるかのように記述できるようにな

る– 処理は依然として非同期なので、並列度が下がることもない– 一度使うとやめられないくらい便利。

• asyncキーワードは関数に指定する。– 指定した関数内ではawaitを使える– async関数の戻り値はPromiseとなる

• awaitキーワードは、Promiseを返す関数呼び出しの前に付与する– Promiseを返す関数の結果を戻り値として受け取れる。– エラーをtry-catchできる。

…// 非同期関数async function hello(seconds) {

try {// awaitで、Promiseの終了を待ち合わせawait waitFor(seconds * 1000);alert('Hello');

} catch (e) {}}hello(3); // 3秒後に「Hello」が表示される

その他の(書いていて楽しい)言語機能

ES6を試してみる:

変数• letやconstが使えます。

– let: スコープが {...} に限定された変数の定義• varは、関数スコープしか持たない

– const: 再代入不可のlet

• 正直、varの出番はもうありません– ぼくらは、「基本const、たまにlet」というルールでやってます

let a ='Hello';const b = 'World';b = 'Error'; // 再代入不可

ES6を試してみる:

文字列

• テンプレート文字列

– バッククォートで囲んだ文字列内では、"${ }" を使って式を埋め込める

let a ='Hello';const b = 'World';const c = `${a}, ${b}`;

ES6を試してみる:

配列

• spread演算子

– 配列の中身をいい感じに展開

• for...of

– 配列(正確にはイテレータ)をループ処理

let a ='Hello';const b = 'World';const c = `${a}, ${b}`;const d = [a, b];const e = [1, 2, ...d]; // [1, 2, 'Hello', 'World']e.push(...d); // [1,2,'Hello','World','Hello','World']for (let f of e)console.log(f); // 1, 2, Hello, World

ES6を試してみる:

オブジェクトリテラル• Property Shorthand

– 変数名と同名のプロパティを簡単に定義– {a: a} みたいなのを {a} で宣言できる– 個人的には異様に便利

• Computed PropertyNames– {[式]: 値} とすることで、プロパティ名に式を使用できる

• Method properties– オブジェクトのメンバーに関数を指定するのが楽になった

let a ='Hello';const b = 'World';const c = {a, b}; // {a: Hello, b: World}const d = {[a]: a}; // {Hello: Hello}const f = {method() {}

};

ES6を試してみる:

デストラクチャリング

• 配列やオブジェクトの中身を変数に展開するのがとても楽に

• オブジェクトも配列も展開可能

const fullName ={firstName: 'Shumpei', lastName: 'Shiraishi'};

// Destructuringconst {firstName, lastName} = fullName;

const array = [firstName, lastName];// Destructuringconst [first, last] = array;

ES6を試してみる:

関数1• アロー関数

– ( ) => { 関数本体 } という形式で関数定義可能– 関数本体が単一の式な場合、中括弧を省略可能

• デフォルト引数– 関数の仮引数に「= デフォルト値」と指定することで、引数

のデフォルト値を指定可能

const sum = (a = 0, b = 0) => { return a + b; };

// 上と同義// const sum = (a = 0, b = 0) => a + b;

ES6を試してみる:

関数2

• Rest Parameter– 関数の最後の仮引数を「...仮引数名」とすることで、

可変長引数を配列として扱うことが可能

• Spread Operator– 「...配列」とすることで、配列を関数の引数に展開で

きる

// 可変長引数を取る関数const join = (s, ...rest) => [s, ...rest].join(' ');

let s = ['Wor', 'ld'];// 配列を引数に展開join('Hello,', ...s);

Advanced: TypeScript

• Microsoftが開発したJavaScriptトランスパイラ。

• 大きな特徴は厳密な型付き言語であること。– ざっくりいうと「ES.next + 型 + α」

• どうせビルドが必要な昨今、型チェックもしてもらえるTypeScriptの人気は増している– Angular2は、TypeScriptで書くのがほぼ前提

コンポーネント指向開発の本格化

コンポーネント指向とは

• アプリケーションをコンポーネント(部品)という単位で分割して扱えること

コンポーネント指向がなぜ有用か

• 従来のWebページ(アプリ)は、全てがグローバルな単一空間– HTML (DOM)– CSS– JavaScript

• SPA (Single Page Application) では、常に衝突や状態破壊の危険性がある– CSSのIDやクラス名はその典型– 外部ライブラリに勝手にDOMをいじられたり– 非SPAでは、毎回ページがリフレッシュされるから問題は少ない

SPAとは

• 単一ページアプリケーション、つまり「HTMLが1枚のアプリ」

• UI変更は、JavaScriptによるDOM操作によって実現される– ページ全体の書き換えが発生しないため、UXに優れる

SPAの開発は難しい

• 実現すべき要件が数多い

– 一貫したアーキテクチャ

– より良いパフォーマンス

– ブックマーク可能に(URLルーティング)

– SEO対策

• 開発の助けとなるフレームワーク・ライブラリが必要となる

コンポーネント指向がなぜ有用か

• アプリケーションをコンポーネントに分割して管理する– 問題がコンポーネントに局所化される

– コンポーネント単位で再利用が可能になる

一覧の項目はいたるところで再利用する

なぜ今頃コンポーネント指向か?

• コンポーネント分割は、UIプログラミングの基本

• なぜ今頃、ようやく?

https://www.amazon.com/Adobe-Flash-Builder-4-Premium/dp/B003739DRS

http://win32easy.blogspot.jp/2011/03/dialog-controls-explained-part-1.html

なぜ今頃コンポーネント指向か?

• 基盤技術のアップデートが必要だった

– HTML/CSS…Web Components

– JavaScript…ECMA Script 6 Modules & Classes

• 厳密には、これらのアップデートはまだ道半ばであり、ツールの手助けを必要とする

– Web Components…相当する機能(+α)を提供するフレームワークやライブラリが存在

– ESモジュール…モジュールバンドラーが、モジュール間の関連性を考慮しつつまとめ上げる

AngularJSとReactが二大巨頭

この両者の共通点がコンポーネント指向のフレームワークであること

Web Components

• コンポーネント指向を実現するための標準技術

• 以下の要素技術から成る

– HTML Templates

– Shadow DOM

– Custom Elements

– HTML Imports

HTML Templates

• template要素のこと。

• 不可視の要素

<template id="tmpl"><div>テンプレート内のコード</div>

</template>

<script>var template = document.getElementById('tmpl');template.content; // テンプレートの内容(DOM)を参照</script>

Shadow DOM

• DOMの詳細を隠蔽し、カプセル化することのできる仕組み• 例えば、video要素などは複数の要素から構築されているが、詳細

は隠蔽されている。– 開発者ツールの設定で「Show user agent Shadow DOM」を有効にす

ると詳細を見ることが出来る

• Chrome 53から、Shadow DOM v1が利用可能になった

Custom Elements

• カスタム要素を作れる仕組み• 既存の要素を継承し、document.registerElement()という

APIで登録する• Chromeがバージョン54から対応

class XFoo extends HTMLElement {connectedCallback() {this.innerHTML =

`<b>I'm in the custom element'!</b>`;}

}window.customElements.define('x-foo', XFoo);

HTML Imports

• 他のHTMLをインポートできる仕組み

• link要素のrel属性にimport、href属性にHTMLのURLを指定する

<head><link rel="import" href="bootstrap.html">

</head>

Web Componentsを使う<template id="sdtemplate"><style>p { color: orange; }

</style><p>Shadow DOM内部のコード</p>

</template><script>class XFooTemplate extends HTMLElement {connectedCallback() {var t = document.querySelector('#sdtemplate');var clone = document.importNode(t.content, true);this.attachShadow().appendChild(clone);

}}customElements.define('x-foo-from-template', XFooFromTemplate);

</script>

プログレッシブ・ウェブアプリ

なんだかんだ言って今のところはWebも大事

• とはいえどっちも作ってメンテし続けるのはしんどい

Web Mobile

想像してみよう

1. (モバイル)Webサイトにアクセスする

2. 何度目かのアクセスで、「ホームスクリーンに入れとく?」と聞かれる

3. ホームスクリーンから起動すると、ネイティブアプリと同様にアドレスバーなしで表示される。

4. そのアプリ経由で、プッシュ通知が届くようになる

5. そのアプリは高速で起動し、オフラインでも動作する

このスライドの画像はこちらのページより引用:https://googledevjp.blogspot.jp/2015/04/service-worker-google-developers-summit.html

これを実現するのがプログレッシブ・ウェブアプリ

「プログレッシブ」=「徐々に、だんだんと」

既存のWebサイトを「だんだんと」Webアプリ化していくこともできる。

– PWA化は実は簡単

– HTTPSであることは前提

インストールバナーが出るようにするには

• manifest.jsonを書き、linkタグに指定する• バナーの出現タイミングはブラウザが自動で決定する

{"name": "Weather","short_name": "Weather","icons": [{"src": "images/icons/icon-128x128.png","sizes": "128x128","type": "image/png"

}],"start_url": "/index.html","display": "standalone"

}

<link rel="manifest" href="/manifest.json">

プッシュ通知が出るようにする

• ServiceWorkerを使用する– ServiceWorkerはバックグラウンドで動作し続ける

JavaScriptコードを定義できる仕組み

• 既存のWebサイトにそれほど影響を与えずに組み込める

self.addEventListener('push', function(event) {const data = event.data.json();const notification = {

body: data.message,data: {url: data.url}

};event.waitUntil(self.registration

.showNotification('TechFeed', notification));});

高速起動&オフライン動作

• ServiceWorkerのCache APIや、Indexed Database API(ブラウザ組み込みのデータベースAPI)を使用する。

var filesToCache = [...];self.addEventListener('install', function(e) {e.waitUntil(caches.open('TechFeed').then(function(cache) {

return cache.addAll(filesToCache);})

);});

TechFeedの実コードで学ぶWeb最新トレンド

TechFeedの実コードで学ぶWeb最新トレンド

• これまで学んだことを、実際に動作するコードを見ながら復習しましょう

– ECMAScript.next

– コンポーネント指向開発

– プログレッシブ・ウェブアプリ

TechFeedのアーキテクチャ

Ionic2

Angular2

Cordova

Webpack App

Node.js

サーバー

99% JavaScriptで出来てます

プログレッシブ・ウェブアプリ

• アプリケーションマニフェスト– manifest.jsonを置き、linkタグに指定するだけ

プログレッシブ・ウェブアプリ

• ServiceWorker & プッシュ通知

– ServiceWorkerの登録

– プッシュ通知

navigator.serviceWorker.register('file')

self.addEventListener('push', function(event) {const data = event.data.json();const notification = {

body: data.message,data: {url: data.url}

};event.waitUntil(self.registration

.showNotification('TechFeed', notification));});

Angular2(コンポーネント指向フレームワーク)

• Angular2におけるコンポーネントは、@Component でデコレートされたクラス

• HTMLでコンポーネントのテンプレートを、CSSでスタイルを定義– これらもデコレータ内に指定する– TechFeedでは、require() を使用して別ファイルに切り出し

• CSSはカプセル化されるので、クラス名の衝突は考えなくて良い

tf-entry-listitem

というタグで使えるコンポーネント。CSSとHTMLはrequireで別出し

※現在のTechFeedはAngular2 RC.4ベースのコードです

Angular2(コンポーネント指向フレームワーク)

• コンポーネントのツリー構造でアプリケーションが構築される

• コンポーネントに値を受け渡すには属性を、コンポーネントから値を受け取るにはイベントを用いる

※現在のTechFeedはAngular2 RC.4ベースのコードです

tf-entry-listitem

を使用adプロパティに値を

セット

Digest

Realtime

EntryList EntryListItem1 *

1

*

*1

TypeScript + Webpack(ES.next)

• import/export

• interface

• const

• デコレータ

• private

• ジェネリクス

• …

開発フロー上のポイント

• 基本的にはブラウザで開発

• 実機上の開発版アプリも、コードを修正すると自動的にリブートする

BrowserSync

ブラウザはもちろん、アプリもリロードできる(CordovaがリモートWebアプリも読み込めるのを利用)動画あります: http://goo.gl/ub6AxU

まとめ

Webはいまやオプショナルな存在。

ではあるが、

メリットをきちんと理解し、

最新技術とともに活用しよう!

ご清聴ありがとうございました。

http://techfeed.io

http://facebook.com/techfeedapp

http://twitter.com/techfeedapp

“エンジニアなら、使っとけ。”