Slide 1

Slide 1 text

レスポンシブから逆戻り!?WEBサービス のマルチデバイス対応方法 DAY #2 (2017/11/26) 小田島 太郎 / @shimataro 東京NODE学園祭2017

Slide 2

Slide 2 text

自己紹介 / / / ウェブリオ株式会社所属(京都) サーバサイドエンジニア 趣味は手品 小田島 太郎 shimataro@GitHub odashima.taro@Facebook shimataro999@Twitter

Slide 3

Slide 3 text

この発表について 対象: マルチデバイス対応に苦労している人 技術レベル: 初〜中級 実戦向けの話です ↓スライドはこちら↓ https://speakerdeck.com/shimataro https://shimataro.github.io/slides/

Slide 4

Slide 4 text

それでは始めます

Slide 5

Slide 5 text

マルチデバイス対応してま すか?

Slide 6

Slide 6 text

3つの選択肢 1. 対応しない 2. デバイスごとに出力を変える 3. 1つの出力ですべて対応 歴史とともに説明します。

Slide 7

Slide 7 text

1. 対応しない デバイスを決め打ち かつてはPC向けサイトしかなかった This page is written in Japanese only. 踏み逃げ禁止!キリ番ゲッターは要報告! 今でもやりようによっては使える

Slide 8

Slide 8 text

2. デバイスごとに出力を変える UAからデバイスを判別して、異なるHTMLを出力 判別方法は割愛 ガラケーの普及に伴い主流に

Slide 9

Slide 9 text

3. 1つの出力ですべて対応 レスポンシブウェブデザイン Googleが推奨 スマホの普及によって注目 表示はクライアント側で調整

Slide 10

Slide 10 text

そして今… まだレスポンシブデザインで大丈夫?

Slide 11

Slide 11 text

レスポンシブデザインの問 題 ガラケーに対応できない 出力内容は最大公約数的なものになる 本格的にやろうとするとメンテナンスは意外と面倒 Google AMP

Slide 12

Slide 12 text

GOOGLE AMPについて Accelerated Mobile Pages HTML/CSS/JSの仕様を制限 一瞬で表示! AMP専用のHTMLが必要

Slide 13

Slide 13 text

お分かり頂けただろうか レスポンシブデザインは万能ではない モバイル端末こそ別の出力が必要なときもある 回帰現象が起きているとでもいうのだろうか

Slide 14

Slide 14 text

ようやく本題 同じURLでもリクエストごとにHTMLを変えたい Node(Express)ではどうやる?

Slide 15

Slide 15 text

EXPRESSでのUA別出力方法 標準では用意されていない ビューを res.render() 時に切り替えるのが一般的? ページ数×デバイス数のビューが並ぶ views ├index.pug ├index-smartphone.pug └index-tablet.pug

Slide 16

Slide 16 text

やりたいこと デバイスごとに階層化 ソースコードの変更は最小限で! views ├default │└index.pug <- ビューはデバイスディレクトリ内に配置 ├smartphone │└index.pug └tablet <- ビューがないデバイスでは規定のビューを表示

Slide 17

Slide 17 text

ミドルウェア作りました https://github.com/shimataro/express-view-switcher npm install -S express-view-switcher

Slide 18

Slide 18 text

使い方1: マルチデバイス対応 import viewSwitcher from "express-view-switcher"; const app = express(); app.use(viewSwitcher((req) => { // "User-Agent" ヘッダを解析して検索したいディレクトリを列挙 // ※実際の判別ロジックはREADME参照 // https://www.npmjs.com/package/express-view-switcher // 最初に見つかったビューを表示 // 1. views/smartphone // 2. views/default return [["smartphone", "default"]]; })); // あとは普通に res.render() をコール

Slide 19

Slide 19 text

使い方2: 多言語対応 app.use(viewSwitcher((req) => { // "Accept-Language" ヘッダやクエリストリングなどを解析 // ※実際の判別ロジックは(ry // 1. views/en-us // 2. views/en // 3. views/ja return [["en-us", "en", "ja"]]; }));

Slide 20

Slide 20 text

使い方3: 多言語+マルチデバイス app.use(viewSwitcher((req) => { // 組み合わせてもOK // ※実際の(ry // 1. views/en-us/smartphone // 2. views/en-us/default // 3. views/en/smartphone // 4. views/en/default // 5. views/ja/smartphone // 6. views/ja/default return [ ["en-us", "en", "ja"], ["smartphone", "default"], ]; }));

Slide 21

Slide 21 text

導入してみた Weblio英会話 Perl→Node.jsに書き換え ※完了したとは言ってない ※全ページマルチデバイス対応とは言ってない https://eikaiwa.weblio.jp/

Slide 22

Slide 22 text

まとめ デバイスごとに出力を変えなきゃいけない状況はまだま だあるよ ミドルウェア作ったよ 多言語対応もできるよ 手品に興味があったら声をかけてね!

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

おまけ ここまで見てくれてありがとう( *´艸`)

Slide 25

Slide 25 text

Q&A

Slide 26

Slide 26 text

Q: 対応バージョンは? A: Node.js 4以上 Express 4以上 動作中のNodeバージョンに合わせて最適化する素敵 仕様!

Slide 27

Slide 27 text

Q: REQUIRE できないよ! A: // NG: これだと使えない const viewSwitcher = require("express-view-switcher"); // OK: 時代はES6!babelで変換しよう import viewSwitcher from "express-view-switcher"; // OK: 宗教上の理由でrequireしか使えない方はこちら const viewSwitcher = require("express-view-switcher").default;

Slide 28

Slide 28 text

Q: ベースディレクトリを指定したい! A: // 第二引数を指定すると、実際に使われたディレクトリが // res.locals オブジェクトのkey/valueとして追加される。 // includeやextendのベースディレクトリを指定する際に使える。 // 例: res.locals.basedir = "views/smartphone" app.use(viewSwitcher((req) => { // ※(ry return [["smartphone", "default"]]; }, "basedir")); // ただし、 "view engine" が "pug" の場合は // 自動的に "basedir" が設定されるので指定不要

Slide 29

Slide 29 text

Q. VARY ヘッダを指定したい! A: ごめんなさい。まだできてません。

Slide 30

Slide 30 text

No content