支えなくて良い技術を支える技術 2018-12-12 BIT VALLEY -INSIDE- Vol.4
フロントエンド全身ちぎれ節支えなくて良い技術を支える技術2018-12-12 BIT VALLEY -INSIDE- Vol.4
View Slide
Satoshi Takeda@tkdn株式会社 medibaauパートナー本部 auサービス開発部フロントエンドエンジニア"ブラウザが主戦場"
本日話すこと1.「支えなくて良い技術」とは2.支えなくて良い技術を支えていく技術how 1: webpack + Babelhow 2:不足しているネイティブ APIhow 3: OS固有バグとの付き合い方3.まとめ・言いたいこと
1.「支えなくて良い技術」とはdeprecated, obsoletedな技術例えば
TLS 1.0/1.1TLS 1.0/1.1のサポート停止
これによって対応出来なくなるブラウザOS・ブラウザAndroid 2.x - 4.x
弊社大人の事情でまだまだ支えている
対応は辛い端末やOS由来によるバグチケットかさむ工数たまっていくカルマ⬇ 開発体験 DXの悪化
このカルマを燃やすためにエンジニアリングでなんとかする
ゴールレガシー端末をフォローしていくことに疲れない開発者が(ある程度)意識せずコーディング・オペレーションできる自動化できることは自動化し開発体験を良くしたい
how 1: webpack + Babelwebpack=>モジュール解決のためのバンドラーBabel=> ES2015~の構文を解釈し ES5相当に変換babel-preset-env=> browserslistが提供する DSLに従い、サポートブラウザを記述する
{{"browserslist""browserslist":: [[// Android 2.1以上に最適化// Android 2.1以上に最適化"Android >= 2.1""Android >= 2.1",,// iOS 8以上に最適化// iOS 8以上に最適化"iOS >= 8""iOS >= 8",,]]}}ターゲットブラウザに準じた変換が可能
exportexport defaultdefault classclass HumanHuman {{constructorconstructor((namename)) {{thisthis..namename == namename |||| "Tom""Tom";;}}eateat((foodfood)) {{consoleconsole..loglog((``${${thisthis..namename}} eatseats ${${foodfood}}``));;}}}}こんなのが
exportsexports..__esModule__esModule == truetrue;;varvar HumanHuman == ((functionfunction(()) {{functionfunction HumanHuman((namename)) {{_classCallCheck_classCallCheck((thisthis,, HumanHuman));;thisthis..namename == namename |||| "Tom""Tom";;}}HumanHuman..prototypeprototype..eateat == functionfunction eateat((foodfood)) {{consoleconsole..loglog((StringString((thisthis..namename)) ++ " eats "" eats " ++ StringString((foodfood))));;}};;returnreturn HumanHuman;;}}))(());;exportsexports..defaultdefault == HumanHuman;;
だがしかし。このままではAndroid 2系, 4.0系までフォローできないES5相当のJavaScriptネイティブ APIが不足している
やってやろうじゃねえか
how 2:足りないネイティブAPIを足すES5相当のネイティブ APIを埋める es5-shimを依存として追加しファイルにバンドルさせるes-shims/es5-shim: ECMAScript 5 compatibility shims for legacy (and modern)JavaScript engines
これでもう大丈夫やろ…(;´∀`)これでもう大丈夫やろ…(;´∀`)
「一部のAndroid 2系ではES3相当の記述をしないと対応出来ない」
まじかよ…(;´∀`)まじかよ…(;´∀`)
objectのプロパティが予約語となる場合エラーとなる...etc//下記の構文がエラーとなる//下記の構文がエラーとなるvarvar objobj == {{ classclass:: truetrue }};;varvar objobj..classclass == truetrue;;//こうしないとだめ//こうしないとだめvarvar objobj == {{ "class""class":: truetrue }};;varvar objobj[["class""class"]] == truetrue;;
ES3相当に書き換える必要があるBranches · sophiebits/es3ify最終的な生成ファイルをリビルドするスクリプトを書いた
ファイルサイズ膨れ上がってきたんだが…(;´∀`)ファイルサイズ膨れ上がってきたんだが…(;´∀`)ここまでやったんならさすがにもう大丈夫やろ…(;´∀`)ここまでやったんならさすがにもう大丈夫やろ…(;´∀`)
OS固有のバグ
OS固有のバグUncaught TypeError: Cannot assign to read onlyproperty '__esModule' of #なにこれ…(;´∀`)任意の構文からJavaScriptオブジェクトへ直接的なプロパティ書き込みが出来ないというエラー内容
1530 - De ning function's 'prototype' property with Object.de neProperty setsdifferent value and makes property immutable - v8 - Monorail
出処Android 4.0.xに搭載された JavaScriptエンジン V8のバグ起因V8のバージョンまで特定は出来ないが、Android 4.0.3, 4.0.4の標準ブラウザもしくは webviewの V8 JavaScriptエンジンではバグを持ったまま実装されている。なお 2.x系ではバグは起きない
どうしたもんか
回避パッチで何とかなりそう
// Android 4.x support// Android 4.x supportvarvar definePropertydefineProperty == ObjectObject..definePropertydefineProperty;;ObjectObject..definePropertydefineProperty == functionfunction ((exportsexports,, namename)) {{ifif ((namename ====== '__esModule''__esModule')) {{exportsexports[[namename]] == truetrue;;returnreturn;;}}returnreturn definePropertydefineProperty..applyapply((thisthis,, argumentsarguments));;}};;パッチを差し込むプラグインを作った無事に動いた…
紹介しきれませんがでも他にも OS固有のバグが多くあります…OS固有バグは網羅すること自体が人智を越えているため、トライ&エラーとナレッジの共有しかない
まとめターゲットブラウザを明示し設定、意識せずコーディング不足した APIは適宜 poly ll, shimを足し込んでフォローOS固有のバグは知見でしかない、ぶつからないと分からない全身ちぎれて血まみれになりながらまとめた
考えていくべきこと紹介したことはいずれ価値のなくなるハックユーザがセキュアな環境で通信出来ない事自体をきちんと考えるレガシー対応に引きずられてサービスグロースの足を引っ張らないと良い
支えなくて良い技術を支える少なくともユーザがいる限りはフロントエンドの技術で支えきる