Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Electronによるアプリケーション開発事情2018 / builderscon2018
Search
h3poteto
September 07, 2018
Technology
11k
9
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Electronによるアプリケーション開発事情2018 / builderscon2018
builderscon tokyo 2018『Electronによるアプリケーション開発事情2018』
h3poteto
September 07, 2018
More Decks by h3poteto
See All by h3poteto
EKS on Fargateは最高のJob基盤 / jawsug_bgnr
h3poteto
1
1.1k
Kubernetes上で単発のジョブを実行するkube-jobというツールを作った / kubernetesmeetuptokyo22
h3poteto
6
9.1k
fluentdサーバをchefで構築するの辛かったけどDockerも別に救世主じゃなかった / tokyu ruby kaigi 12
h3poteto
0
5.3k
ECSのサービスをslack botでデプロイする // ecs-goploy
h3poteto
1
6k
まだRailsで消耗してるの?
h3poteto
7
5k
阿澄佳奈と昇竜拳
h3poteto
1
600
Other Decks in Technology
See All in Technology
積み重なった技術負債への挑戦 〜初手としての全社ゴト化〜
techtekt
PRO
0
720
Snowflakeのコスト最適化を支えるアーキテクチャ設計
ktatsuya
1
1.6k
iOSDC Japan 2026 day1 TrackC 10:50
feedtailor
1
140
山手線を徒歩で一周してわかった、 位置情報アプリは「足」が最強のデバッガー
hinakko
0
150
Minecraft JavaのMODをSwiftで作る
1mash0
0
150
生成AIエージェントを用いた、 手動テスト手順書から自動テストへの 変換手法の検討
magicpod
0
140
DEFCON34-Write-up_HYCu-MYCu
daikiokazaki
0
160
Screen Lens - 今見てる画面を翻訳する
komagata
0
280
Microsoft 365 Copilot chat -tekoälypalvelun tietosuojaongelmat
hponka
0
890
Genieを崇めよ
kameitomohiro
0
120
Multica × 長期記憶:40個のミニプロジェクト管理
eiei114
1
280
事業課題から技術的負債に向き合う
sansantech
PRO
2
1.3k
Featured
See All Featured
The Curious Case for Waylosing
cassininazir
1
500
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
330
Mobile First: as difficult as doing things right
swwweet
225
10k
Why Our Code Smells
bkeepers
PRO
340
58k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
300
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
320
Paper Plane
katiecoart
PRO
3
53k
The Cost Of JavaScript in 2023
addyosmani
55
10k
We Are The Robots
honzajavorek
0
370
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
430
The World Runs on Bad Software
bkeepers
PRO
72
12k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Transcript
ElectronʹΑΔΞϓϦ έʔγϣϯ։ൃࣄ 2018 builderscon tokyo 2018 @h3_poteto
ࣗݾհ • Akira Fukushimaʢౡ ໌ʣ • github: h3poteto • twitter:
h3_poteto • Mastodon: @
[email protected]
• ࣄɿterraform৬ਓ@scouty
એ
None
σεΫτοϓ͚ͷ MastodonΫϥΠΞϯτΛ ࡞͍ͬͯ·͢
None
ࠓ͜ͷΞϓϦέʔγϣ ϯΛࡐʹElectronͷΛ ͠·͢
None
એऴΘΓ
ࠓͷ • ElectronͰΞϓϦέʔγϣϯ࡞ΔͷϚδͰָ ͩΑʢͲΜͲΜָʹͳΓͭͭ͋Δ • ͰSNSͷΫϥΠΞϯτ࡞Δͷେม • ւ֎͔Βͷҙ֎ͳԠ͋ͬͨ • ΈΜͳMastodonͬͯ΄͍͠
ElectronͰΞϓϦέʔγϣϯ Λ։ൃ͢Δ
Electron? • ੲAtom-shellͱݺΕ͍ͯͨ • Chromium + Node.js • Windows/Mac/Linux͚ͷΞϓϦέʔγϣϯ ͕࡞ΕΔ
ͭ·Γ • දࣔ෦ϒϥβͳͷͰWebϑϩϯτΤϯ υͷٕज़Λ͑Δ • React.js/Vue.jsࡌͤΒΕΔ • SPAͰΞϓϦ͕࡞ΕΔ
vue-cliͰܗ͕࡞ΕΔ $ npm install -g vue-cli $ vue init simulatedgreg/electron-vue
\ whalebird
vue-cliͰͷܗ • webpackʹΑΔ։ൃ࣌ͷϏϧυઃఆ • auto-reload • ςετͷܗ
Electronͷجຊߏ • mainϓϩηε: όοΫάϥϯυδϣϒɼΞϓ ϦέʔγϣϯͷཧΛߦ͏ • rendererϓϩηε: jsΛ࣮ߦ͠html, cssΛϨϯ μϦϯά͢Δ
rendererϓϩηεଆΛͯ͢ SPAʹ͢Δ͜ͱ͕Մೳ ͜͜ͰReact.js/Vue.js͕͑ Δ
خ͍͜͠ͱᶃ React.js/Vue.js(Flux)ΛGUI ΞϓϦέʔγϣϯͰ͑Δ
iOS։ൃ͍ͯͨ͜͠Ζ • ViewController͕ແݶʹଠΔʂ • delegate͕ͦ͜Βதʹ…… • ϞσϧͲ͏͜͏ͱ͍͏ΑΓঢ়ଶը໘ભҠͷ ϩδοΫ͕େม
None
class SwipeViewController: UIViewController, SwipeViewDelegate, SwipeViewDataSource, UINavigationControllerDelegate, UITabBarControllerDelegate { func navigationController(_
navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { if (type(of: viewController) === SwipeViewController.self) { for i in 0 ..< self.streamList.count() { self.viewItems[i].fCellSelect = false } } } } ͛͢ʔ͍ͬͺ͍Delegateͯ͠Δ
React.js/Vue.sj(Flux)ʹ͢Δͱ • ࠩϨϯμϦϯάReact.js/Vue.jsͷ͕ͬ ͯ͘ΕΔ͜ͱ͕લఏ • delegateͱ͔ඞཁͳ͍ • Flux͕σʔλͷྲྀΕΛҰํʹͯ͘͠ΕΔ • GUIΞϓϦέʔγϣϯͳͷʹݟ௨͕͠ྑ͍
<toot :message="message" :filter="filter" :focused="message.uri === focusedId" :overlaid="modalOpened" @update=“updateToot" @delete=“deleteToot" @focusNext="focusNext"
@focusPrev="focusPrev" @selectToot="focusToot(message)"> </toot> focusToot (message) { this.focusedId = message.uri }
خ͍͜͠ͱᶄ ίϯτϦϏϡʔλ͕૿͑Δ
WhalebirdͷίϯτϦϏϡʔλ • ΄΅jsͷٕज़ͳͷͰjsք۾ͷਓ͕ίϯτϦ Ϗϡʔτ͍͢͠ʢ͜͜ͷϘϦϡʔϜ͕ଟ͍
خ͍͜͠ͱᶅ ΫϩεϓϥοτϑΥʔϜ
ΫϩεϓϥοτϑΥʔϜ • Windows/Mac/LinuxͰಉ͡ιʔεͷ··Ϗϧ υՄೳ • ͨͩ͠Ұ෦Mac͚ͷػೳ࣮͞Ε͍ͯ Δ
ྫ: Dockϝχϡʔ ϝχϡʔ༰͕ ΧελϚΠζՄೳ elecron-context-menu
خ͍͜͠ͱᶆ ΞΫςΟϒʹ։ൃ͞Ε͍ͯΔ
ElectronͷϦϦʔεׂͱ׆ൃ • v2.0.8 - 2018/08/23 • v2.0.7 - 2018/08/09 •
v2.0.6 - 2018/08/01 3.0.0४උத: v3.0.0-beta.8
ΞϓϦέʔγϣϯΛύοέʔ δϯάˍϦϦʔε
Let’s ElectronΈ͍ͨͳهࣄ ͍ͬͺ͍͋Δ͚ͲϦϦʔεʹ ؔ͢Δهࣄ͕΄ͱΜͲͳ͍
֮͑ͯ΄͍͜͠ͱ: electron-builder͕͋Εͩ ͍͍ͨղܾ͢Δ
• electron-packager • electron-builder ͱ͍͏ͷ͕͋Δ
electron-packager • webpackͰίϯύΠϧ͞ΕͨϑΝΠϧ܈ΛΞ ϓϦέʔγϣϯͱͯ͠·ͱΊΔ • جຊతʹ͜Ε͔ͬͯ͘͠Εͳ͍ • ίϚϯυϥΠϯ
electron-builder • ΞϓϦέʔγϣϯͷύοέʔδϯά • ূ໌ॻͷՃ • ֤छΠϯετʔϧՄೳͳϑΝΠϧܗࣜʹѹॖ ʢ.dmg, .deb, .rpm,
.exeʣ • package.jsonʹઃఆ͕ॻ͚Δ • ެࣜυΩϡϝϯτ͕๛: https://www.electron.build/
"build": { "productName": "Whalebird", "appId": "org.whalebird.desktop", "directories": { "output": "build"
}, "mac": { "icon": "build/icons/icon.icns", "target": [ "dmg" ], "category": "public.app-category.social-networking" },
͓͔͛ͰϦϦʔεܗ͕ࣜ๛ • AppStore(.pkg) • .dmg • .exe • .deb •
.rpm • .tar.bz2 • snapcraft (.snap)
ͪΐͬͱಛघͳઃఆྫ • ΞΠίϯ • ֎෦ϦιʔεʢԻʣ • ূ໌ॻ • MASʢMac App
Storeʣ
ΞΠίϯ • Mac/Windows: Ϗϧυ࣌ʹຒΊࠐΉ • Linux: Ұ෦main.jsͰ֎෦ϑΝΠϧΛࢦఆ • ը૾ϑΝΠϧasarѹॖ͞Ε͍ͯͯ෦ͷ ͷΛࢦఆՄೳ
"build": { "productName": “Whalebird", "files": [ "dist/electron/**/*", "build/icons/*" ], "mac":
{ "icon": "build/icons/icon.icns", "target": [ "dmg" ], "category": "public.app-category.social-networking" }, "win": { "icon": "build/icons/icon.ico", "target": "nsis" }, iconͷࢦఆ
mainWindow = new BrowserWindow({ titleBarStyle: 'hidden', useContentSize: true, icon: path.resolve(__dirname,
'../../build/icons/256x256.png') } BrowserWindowͷ ىಈΦϓγϣϯͰΞΠίϯΛࢦఆ
֎෦ϦιʔεͷಡΈࠐΈ • ԻϑΝΠϧΛಡΈࠐΈ͍ͨ߹͕͋Δ • asarѹॖͷϑΝΠϧಡΈऔΕͳ͍ • ϏϧυઃఆͰasarѹॖ͔Βআ֎͢Δඞཁ͕͋ Δ
"build": { "productName": "Whalebird", "appId": "org.whalebird.desktop", "directories": { "output": "build"
}, "extraResources": [ "build/sounds/*" ], "files": [ "dist/electron/**/*", "build/icons/*" ], ԻΛextraResources ʹࢦఆ
const soundBasePath = process.env.NODE_ENV === 'development' ? path.join(__dirname, '../../build/sounds/') :
path.join(process.resourcesPath, 'build/sounds/') const sound = path.join(soundBasePath, 'operation_sound01.wav') simplayer(sound, (err) => { if (err) log.error(err) }) ͜͜asar֎ͷϑΝΠϧΛ ࢦఆ͢Δඞཁ͕͋Δ
Mac༻ͷূ໌ॻ • Developer ID Installer • Developer ID Application electron-builderͳΒϏϧυ࣌ʹ
KeyChainAccessͷূ໌ॻΛ ࣗಈͰͯͯ͘ΕΔ
MAS͚ͩಛผѻ͍ • electron-builderͰCodeSign·ͰͰ͖ͳ͔ͬͨ • electron-packagerͰϏϧυޙɼࣗͰCodeSign • plistΛࣗͰॻ͘ඞཁ͕͋Δ • ͦΕΛApplication LoaderͰΞοϓϩʔυ͢Δ
• ͋ͱiTunes ConnectͰόʔδϣϯΞοϓ
#!/bin/zsh -f # Name of your app. APP="Whalebird" # The
path of your app to sign. APP_PATH="./packages/Whalebird-mas-x64/Whalebird.app" # The path to the location you want to put the signed package. RESULT_PATH="./packages/$APP.pkg" # The name of certificates you requested. APP_KEY="3rd Party Mac Developer Application: Akira Fukushima (HB4N6B2YVM)" INSTALLER_KEY="3rd Party Mac Developer Installer: Akira Fukushima (HB4N6B2YVM)" # The path of your plist files. CHILD_PLIST="./plist/child.plist" PARENT_PLIST="./plist/parent.plist" LOGINHELPER_PLIST="./plist/loginhelper.plist" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" # At first, rename app.asar.unpacked directory. # Because electron-builder does not store app.asar.unpacked directory. # I want to store unpacked files at the same directory as electron-builder. mv $APP_PATH/Contents/Resources/app.asar.unpacked/* $APP_PATH/Contents/Resources/ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Electron Framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Libraries/libffmpeg.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Libraries/libnode.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP" codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH" productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH"
#!/bin/zsh -f # Name of your app. APP="Whalebird" # The
path of your app to sign. APP_PATH="./packages/Whalebird-mas-x64/Whalebird.app" # The path to the location you want to put the signed package. RESULT_PATH="./packages/$APP.pkg" # The name of certificates you requested. APP_KEY="3rd Party Mac Developer Application: Akira Fukushima (HB4N6B2YVM)" INSTALLER_KEY="3rd Party Mac Developer Installer: Akira Fukushima (HB4N6B2YVM)" # The path of your plist files. CHILD_PLIST="./plist/child.plist" PARENT_PLIST="./plist/parent.plist" LOGINHELPER_PLIST="./plist/loginhelper.plist" FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks" # At first, rename app.asar.unpacked directory. # Because electron-builder does not store app.asar.unpacked directory. # I want to store unpacked files at the same directory as electron-builder. mv $APP_PATH/Contents/Resources/app.asar.unpacked/* $APP_PATH/Contents/Resources/ codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Electron Framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Libraries/libffmpeg.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/ Libraries/libnode.dylib" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper" codesign -s "$APP_KEY" -f --entitlements "$LOGINHELPER_PLIST" "$APP_PATH/Contents/Library/LoginItems/$APP Login Helper.app/" codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP" codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH" productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH" codesignίϚϯυΛ͑ྑ͍
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://
www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.application-groups</key> <string>HB4N6B2YVM.org.whalebird.desktop</string> <key>com.apple.security.files.user-selected.read-only</key> <true/> <key>com.apple.security.network.client</key> <true/> </dict> </plist>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://
www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.application-groups</key> <string>HB4N6B2YVM.org.whalebird.desktop</string> <key>com.apple.security.files.user-selected.read-only</key> <true/> <key>com.apple.security.network.client</key> <true/> </dict> </plist> ͜͜Ͱ • ωοτϫʔΫΞΫηε • ϑΝΠϧΞΫηε ΛڐՄ͢Δ
͜ͷ͋ͱ৹͕ࠪ͋Δʂ
MAS݁ߏͭΒ͍
͜͜·Ͱͷ·ͱΊ • electron-builderϚδΜΓ • electron-builderͷਐา͕͍ͷͰ͜Εͬͱ ͚ؒҧ͍ͳ͍ • MAS͍ͭେม
MastodonͷΫϥΠΞϯτΛ ࡞Δ
ͳͥMastodonͷ ΫϥΠΞϯτΛ࡞Δͷ͔
σεΫτοϓ͚ͷ ΫϥΠΞϯτ͕ͳ͍ɼຊʹগͳ͍ • MstdnʢࣗͰjsonϑΝΠϧΛ༻ҙͯ͠token ΛೖΕΔʣ • The Desk • TsuruʢόΠφϦͷͳ͍ʣ
ͳ͍ͷͰ͋Ε ࣗͰͭ͘Ζ͏
Whalebirdͷίϯηϓτ • LinuxͰ͑ΔͷΛ • Slackʹ׳Ε͍ͯΔͷͰSlackΆ͍ݟͨ • γϣʔτΧοτͱʹ͔͘ଟ͘ ࠷ڧͷTwitterΫϥΠΞϯτ ઓ૪Λࢥ͍ग़͢
ॳ൛͕Ͱ͖ͨ
ւ֎͔ΒͷԠ
ʢӳޠαϙʔτ͔ͨ͠Β͔ʣ ࠷ॳւ֎͔ΒԠ͕
ϦϦʔεͯ͠࠷ॳͷҰिؒ
None
None
None
None
ྑ͍ʂ͚ͩͲElectron͔…… Έ͍ͨͳԠ͔Γ
ͦΜͳʹElectronͬͯධѱ ͍ͷʁ ຊͰ͋·Γฉ͔ͳ͔͚ͬͨͬͲ
ධͷѱ͞ • ϝϞϦফඅ͕ଟ͍ • SlackΛىಈ͢Δ͚ͩͰ500MBҎ্ϝϞϦΛ͍͔࣋ͬͯ ΕΔ • ࠷దԽ͞Εͯͳ͍ͷͰϝϞϦফඅ͕ଟ͍ • Javaͷํ͕͍ܰ
• node.js͕ݏ͍
ϝϞϦͱઓ͏
࠷ظ1GBҎ্ ͍͔࣋ͬͯΕͨ
Ͳ͜ͰϝϞϦΛ ফඅ͍ͯ͠Δͷ͔ʁ
ࢼͯ͠ΈΔ • StreamingΛࢭΊͨঢ়ଶͰ͍Ζ͍Ζ৮ͬͯΈΔ • StreamingΛࢭΊͨঢ়ଶͰ์ஔ ϝϞϦϦʔΫ͔ʁ
StreamingࢭΊ͍ͯΔͱ૿͑ ͳ͍ʂ ผʹϝϞϦϦʔΫ͍ͯ͠ΔΘ ͚Ͱͳ͍ʂ
StreamingʹΑΔϝϞϦফඅ • ຊΛ૿ͯ͠ΈΔʁ
StreamingʹΑΔϝϞϦফඅ • όοΫάϥϯυͰStreaming͢Δ͚ͩͰର ͯ͠ϝϞϦΛফඅ͠ͳ͍ʂ
͏গ͠ࢼ͢ • ྲྀͷ͍ΠϯελϯεͰ์ஔʢmikutterʣ • ྲྀͷ͍ΠϯελϯεͰ์ஔʢjpʣ
໌Β͔ʹྲྀ͕͍΄͏͕ ϝϞϦফඅ͕ଟ͍
͜Ε͠ϨϯμϦϯά ͳͷͰʁ
WhalebirdͷλΠϜϥΠϯඳը • Streaming͞ΕͨͷΛͯ͢htmlͱͯ͠දࣔ ͍ͯͨ͠ • ͭ·Γϒϥβͷ࣮ʹؙ͛ • FireFoxͰڊେϖʔδΛ։͍ͨΒॏ͍ ʢ͔ͩΒΈΜͳϖʔδωʔγϣϯ͢ΔΜͩ
None
ଞͲ͏͍ͯ͠Δͷ͔ʁ
iOSͷ߹ • UITableViewදࣔ͞Ε͍ͯΔ෦͔͠Ϩϯμ Ϧϯά͍ͯ͠ͳ͍ • ӅΕ͍ͯΔ·ͰؚΊͨεΫϩʔϧྔܭࢉ ͍ͯ͠Δ • εΫϩʔϧ͞Εͨࡍදࣔ͢Δલʹ༰Λ ϨϯμϦϯά
ਤ
දࣔ͞Ε͍ͯͳ͍෦ ϨϯμϦϯά͍ͯ͠ͳ͍
UITableViewController • cellForRowAt: ηϧͷதΛϨϯμϦϯά • heightForRowAt: ηϧͷߴ͞Λࢉग़ • estimatedHeightForRowAt: ະදࣔΛؚΊͯ
ηϧͷߴ͞Λࢉग़
ྲྀੴʹ͜ΕύΫΕͳ͍
ϙΠϯτɿ ඳը͢Δൣғݟ͍͑ͯΔ ෦͘Β͍Ͱे
ElectronͰͲ͏͢Δ͔ʁ • λΠϜϥΠϯΛͯ͢දࣔ͢ΔͷΛΊΔ • ࠷৽40݅ͷΈΛදࣔ͠ɼඞཁͰ͋Ε LazyLoading • StreamingͰߋ৽͞Εͨ߹ɼݹ͍ͷΛফ ͯ͠40݅ʹอͭ
None
εΫϩʔϧΠϕϯτΛͱʹ੍ޚͯ͠Δ
200MBΛΔʂ
ѹత͡Όͳ͍͔ʂ
ϙΠϯτɿ Vue.jsͷύϑΥʔϚϯεʹ ؾΛΔ
vue.jsͷύϑΥʔϚϯε • v-ifͱv-show • v-if: ସ࣌ʹhtml͕ੜ͞ΕϨϯμϦϯά͞ ΕΔ • v-show: ͡Ί͔ΒϨϯμϦϯά͞Ε͍ͯΔ
͕ɼdisplay: none͞Ε͍ͯΔ͚ͩ
v-ifͱv-show • v-ifͷସ࣌ϨϯμϦϯάίετഅࣛʹͳΒ ͳ͍ • ͔͠͠ɼඞཁͷͳ͍ͱ͜ΖΛv-showʹ͢Δͱ ͣͬͱϝϞϦΛফඅ͠ଓ͚Δ
͜͜ਖ਼ղ͕ͳ͍
࠷ۙͷWhalebird • ϝϞϦফඅ: 200MB ~ 500MB • 500MB͘Β͍·Ͱ͘ΔͱGC͞ΕͯϝϞϦফඅ ͕ҰؾʹݮΔ •
ը૾͕গͳ͍࣌ؒଳ͍ܰʂ ʢpawooͷਓ͝ΊΜͳ͍͞
࠷ۙͷWhalebird • ϕʔεʹͳ͍ͬͯΔElectronΛόʔδϣϯΞο ϓ͢ΔͱϝϞϦফඅ͕ݮΔ • ύϑΥʔϚϯεChromiumʹ߹ΘͤͯͲΜͲ Μྑ͘ͳΔ
͜ͷઌͷ࡞ઓ • ը૾ͷඇදࣔΦϓγϣϯ • τΡʔτ͕࿈ଓ͢Δ߹·ͱΊͯϨϯμϦ ϯάͰ͖ͳ͍͔ʁ
͓ӄ༷Ͱ࠷ۙͷԠྑ͍
APIΫϥΠΞϯτϥΠϒϥϦ Λࣗ࡞͢Δ
ॳmastodon-apiͱ͍͏ Node.jsͷϥΠϒϥϦΛར༻
͕ɼΤϥʔʹͳΔͱ͍͏ใࠂ ͕ͪΒ΄Β
mastodon-api • POSTύϥϝʔλΛbodyͰͳ͘urlύϥϝʔ λͱͯ͠ૹ৴͍ͯ͠Δ • Ұ෦αʔόͰͦΕΒ͕ڋ൱͞Ε͍ͯΔ ଞͷબࢶ͕ͳ͍
ͳ͍ͷͳΒࣗ࡞͠Α͏
None
megalodon • TypeScriptͰॻ͍ͨmastodonAPIΫϥΠΞϯ τϥΠϒϥϦ • Streaming࣮ࡁΈ • OAuthΞϓϦέʔγϣϯొ༻ϝιου༻ ҙ
public get<T>(path: string, params = {}): Promise<Response<T>> { return axios
.get<T>(this.baseUrl + path, { headers: { 'Authorization': `Bearer ${this.accessToken}` }, params }) .then((resp: AxiosResponse<T>) => { const res: Response<T> = { data: resp.data, status: resp.status, statusText: resp.statusText, headers: resp.headers } return res }) }
όάͬͯͨ߹ શ෦ࣗͰ࣏ͤΔ
ΠϯελϯεΛ ݐͯΔ͜ͱ͋Δ
ΠϯελϯεݪҼͷ͍߹Θͤ ଟ͍ • ϩάΠϯ͕Ͱ͖ͳ͍ • τΡʔτͰ͖ͳ͍ • Streaming͕ಈ͔ͳ͍ • ʑ……
࠷ۙ͋ͬͨ൵͍͠ࣄྫ • (mastodon͕͍ͬͯΔ)doorkeeper 4.3.0Ҏ ্ Ͱnative_redirect_uriʹؔ͢Δόά͕ࠞೖ • mastodon: doorkeeper ~>
4.4.1 • σεΫτοϓΞϓϦέʔγϣϯͰೝূ͕Ͱ͖ ͳ͘ͳΔ
͔֬ΊΔ&ϓϧϦΫΛग़͢ • खݩͰmastodonαʔόΛݐͯΔ: https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/ Development-guide.md • ࠶ݱͨ͠ • doorkeeperʹissueཱͯͨΓɼmastodonʹϓ
ϧϦΫΛૹͬͨΓ
None
ΫϥΠΞϯτ͚ͩͷͰͳ͍͜ͱ͕ଟ͍ͷͰɼ αΫοͱΠϯελϯεΛཱͯΒΕΔΑ͏ʹ ͓ͯ͘͠ͷॏཁ
·ͱΊ
ޭͨ͠ͳʔͱࢥ͏͜ͱ • ElectronͰ࡞ͬͨ͜ͱ • Vue.jsͱ͍͏બ • ӳޠݍͷྀ
ࣦഊͨ͠ͳʔͱࢥ͏͜ͱ • ͬͱૣ͘࡞ΕΑ͔ͬͨ • ͬͱૣ͘TypeScriptΛߟྀ͖ͩͬͨ͢ • megalodon(APIΫϥΠΞϯτ)ϝϯς͠ ͍͢ • దͳΦϒδΣΫτΛ͢͜ͱ͕ଟ͍
updateTimeFormat ({ dispatch, commit, state }, value) { const newGeneral
= Object.assign({}, state.general, { timeFormat: value }) const config = { general: newGeneral } ipcRenderer.send('update-preferences', config) ipcRenderer.once('error-update-preferences', (event, err) => { ipcRenderer.removeAllListeners('response-update-preferences') }) ipcRenderer.once('response-update-preferences', (event, conf) => { ipcRenderer.removeAllListeners('error-update-preferences') dispatch('App/loadPreferences', null, { root: true }) commit('updateGeneral', conf.general) }) }, actionͻͱ͔ͭ͠ҾΛऔΕͳ͍ mainͱͷ௨৴ipcͰߦ͏ ະͷΦϒδΣΫτ
શମతʹݟͯ • ElectronʢϦϦʔεํ๏ؚΊͯʣਐԽͯ͠ ͍ΔͷͰ͓͢͢Ί͍ͨ͠ • ϝϞϦফඅରࡦՄೳ • Vue.jsͰGUIΞϓϦέʔγϣϯ։ൃ͢Δͷྑ ͍
Mastodon͕ շదʹͳͬͨͷͰ TwitterΛݟΔ͜ͱ͕ݮͬͨ
͞Α͏ͳΒTwitter ΫϥΠΞϯτ