Electronによるアプリケーション開発事情2018 / builderscon2018

Ba0b2e7a2783ae54f12665086315ed83?s=47 h3poteto
September 07, 2018

Electronによるアプリケーション開発事情2018 / builderscon2018

builderscon tokyo 2018『Electronによるアプリケーション開発事情2018』

Ba0b2e7a2783ae54f12665086315ed83?s=128

h3poteto

September 07, 2018
Tweet

Transcript

  1. ElectronʹΑΔΞϓϦ έʔγϣϯ։ൃࣄ৘ 2018 builderscon tokyo 2018 @h3_poteto

  2. ࣗݾ঺հ • Akira Fukushimaʢ෱ౡ ໌ʣ • github: h3poteto • twitter:

    h3_poteto • Mastodon: @h3_poteto@mstdn.jp • ࢓ࣄɿterraform৬ਓ@scouty
  3. એ఻

  4. None
  5. σεΫτοϓ޲͚ͷ MastodonΫϥΠΞϯτΛ ࡞͍ͬͯ·͢

  6. None
  7. ࠓ೔͸͜ͷΞϓϦέʔγϣ ϯΛ୊ࡐʹElectronͷ࿩Λ ͠·͢

  8. None
  9. એ఻ऴΘΓ

  10. ࠓ೔ͷ࿩ • ElectronͰΞϓϦέʔγϣϯ࡞ΔͷϚδͰָ ͩΑʢͲΜͲΜָʹͳΓͭͭ͋Δ • Ͱ΋SNSͷΫϥΠΞϯτ࡞Δͷ͸େม • ւ֎੎͔Βͷҙ֎ͳ൓Ԡ͋ͬͨ • ΈΜͳMastodon΍ͬͯ΄͍͠

  11. ElectronͰΞϓϦέʔγϣϯ Λ։ൃ͢Δ

  12. Electron? • ੲ͸Atom-shellͱݺ͹Ε͍ͯͨ • Chromium + Node.js • Windows/Mac/Linux޲͚ͷΞϓϦέʔγϣϯ ͕࡞ΕΔ

  13. ͭ·Γ • දࣔ෦෼͸ϒϥ΢βͳͷͰWebϑϩϯτΤϯ υͷٕज़Λ࢖͑Δ • React.js/Vue.js΋ࡌͤΒΕΔ • SPAͰΞϓϦ͕࡞ΕΔ

  14. vue-cliͰ਽ܗ͕࡞ΕΔ $ npm install -g vue-cli $ vue init simulatedgreg/electron-vue

    \ whalebird
  15. vue-cliͰͷ਽ܗ • webpackʹΑΔ։ൃ࣌ͷϏϧυઃఆ • auto-reload • ςετͷ਽ܗ

  16. Electronͷجຊߏ଄ • mainϓϩηε: όοΫάϥ΢ϯυδϣϒɼΞϓ Ϧέʔγϣϯͷ؅ཧΛߦ͏ • rendererϓϩηε: jsΛ࣮ߦ͠html, cssΛϨϯ μϦϯά͢Δ

  17. rendererϓϩηεଆΛ͢΂ͯ SPAʹ͢Δ͜ͱ͕Մೳ ͜͜ͰReact.js/Vue.js͕࢖͑ Δ

  18. خ͍͜͠ͱᶃ React.js/Vue.js(Flux)ΛGUI ΞϓϦέʔγϣϯͰ࢖͑Δ

  19. iOS։ൃ͍ͯͨ͜͠Ζ • ViewController͕ແݶʹଠΔʂ • delegate͕ͦ͜Βதʹ…… • ϞσϧͲ͏͜͏ͱ͍͏ΑΓঢ়ଶ΍ը໘ભҠͷ ϩδοΫ͕େม

  20. None
  21. 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ͯ͠Δ
  22. React.js/Vue.sj(Flux)ʹ͢Δͱ • ࠩ෼ϨϯμϦϯά͸React.js/Vue.jsͷ૚͕΍ͬ ͯ͘ΕΔ͜ͱ͕લఏ • delegateͱ͔ඞཁͳ͍ • Flux͕σʔλͷྲྀΕΛҰํ޲ʹͯ͘͠ΕΔ • GUIΞϓϦέʔγϣϯͳͷʹݟ௨͕͠ྑ͍

  23. <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 }
  24. خ͍͜͠ͱᶄ ίϯτϦϏϡʔλ͕૿͑Δ

  25. WhalebirdͷίϯτϦϏϡʔλ • ΄΅jsͷٕज़ͳͷͰjsք۾ͷਓ͕ίϯτϦ Ϗϡʔτ͠΍͍͢ʢ͜͜ͷϘϦϡʔϜ͕ଟ͍

  26. خ͍͜͠ͱᶅ ΫϩεϓϥοτϑΥʔϜ

  27. ΫϩεϓϥοτϑΥʔϜ • Windows/Mac/LinuxͰಉ͡ιʔεͷ··Ϗϧ υՄೳ • ͨͩ͠Ұ෦Mac޲͚ͷػೳ౳΋࣮૷͞Ε͍ͯ Δ

  28. ྫ: Dockϝχϡʔ ϝχϡʔ಺༰͕ ΧελϚΠζՄೳ elecron-context-menu

  29. خ͍͜͠ͱᶆ ΞΫςΟϒʹ։ൃ͞Ε͍ͯΔ

  30. 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
  31. ΞϓϦέʔγϣϯΛύοέʔ δϯάˍϦϦʔε

  32. Let’s ElectronΈ͍ͨͳهࣄ͸ ͍ͬͺ͍͋Δ͚ͲϦϦʔεʹ ؔ͢Δهࣄ͕΄ͱΜͲͳ͍

  33. ֮͑ͯ΄͍͜͠ͱ: electron-builder͕͋Ε͹ͩ ͍͍ͨղܾ͢Δ

  34. • electron-packager • electron-builder ͱ͍͏ͷ͕͋Δ

  35. electron-packager • webpackͰίϯύΠϧ͞ΕͨϑΝΠϧ܈ΛΞ ϓϦέʔγϣϯͱͯ͠·ͱΊΔ • جຊతʹ͜Ε͔͠΍ͬͯ͘Εͳ͍ • ίϚϯυϥΠϯ

  36. electron-builder • ΞϓϦέʔγϣϯͷύοέʔδϯά • ূ໌ॻͷ௥Ճ • ֤छΠϯετʔϧՄೳͳϑΝΠϧܗࣜʹѹॖ ʢ.dmg, .deb, .rpm,

    .exe౳ʣ • package.jsonʹઃఆ͕ॻ͚Δ • ެࣜυΩϡϝϯτ͕๛෋: 
 https://www.electron.build/
  37. "build": { "productName": "Whalebird", "appId": "org.whalebird.desktop", "directories": { "output": "build"

    }, "mac": { "icon": "build/icons/icon.icns", "target": [ "dmg" ], "category": "public.app-category.social-networking" },
  38. ͓͔͛ͰϦϦʔεܗ͕ࣜ๛෋ • AppStore(.pkg) • .dmg • .exe • .deb •

    .rpm • .tar.bz2 • snapcraft (.snap)
  39. ͪΐͬͱಛघͳઃఆྫ • ΞΠίϯ • ֎෦ϦιʔεʢԻ੠౳ʣ • ূ໌ॻ • MASʢMac App

    Storeʣ
  40. ΞΠίϯ • Mac/Windows: Ϗϧυ࣌ʹຒΊࠐΉ • Linux: Ұ෦͸main.jsͰ֎෦ϑΝΠϧΛࢦఆ • ը૾ϑΝΠϧ͸asarѹॖ͞Ε͍ͯͯ΋಺෦ͷ΋ ͷΛࢦఆՄೳ

  41. "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ͷࢦఆ
  42. mainWindow = new BrowserWindow({ titleBarStyle: 'hidden', useContentSize: true, icon: path.resolve(__dirname,

    '../../build/icons/256x256.png') } BrowserWindowͷ ىಈΦϓγϣϯͰΞΠίϯΛࢦఆ
  43. ֎෦ϦιʔεͷಡΈࠐΈ • Ի੠ϑΝΠϧ౳ΛಡΈࠐΈ͍ͨ৔߹͕͋Δ • asarѹॖ಺ͷϑΝΠϧ͸ಡΈऔΕͳ͍ • ϏϧυઃఆͰasarѹॖ͔Βআ֎͢Δඞཁ͕͋ Δ

  44. "build": { "productName": "Whalebird", "appId": "org.whalebird.desktop", "directories": { "output": "build"

    }, "extraResources": [ "build/sounds/*" ], "files": [ "dist/electron/**/*", "build/icons/*" ], Ի੠ΛextraResources ʹࢦఆ
  45. 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֎ͷϑΝΠϧΛ ࢦఆ͢Δඞཁ͕͋Δ
  46. Mac༻ͷূ໌ॻ • Developer ID Installer • Developer ID Application electron-builderͳΒϏϧυ࣌ʹ

    KeyChainAccess಺ͷূ໌ॻΛ ࣗಈͰ౰ͯͯ͘ΕΔ
  47. MAS͚ͩ͸ಛผѻ͍ • electron-builderͰCodeSign·ͰͰ͖ͳ͔ͬͨ • electron-packagerͰϏϧυޙɼࣗ෼ͰCodeSign • plistΛࣗ෼Ͱॻ͘ඞཁ͕͋Δ • ͦΕΛApplication LoaderͰΞοϓϩʔυ͢Δ

    • ͋ͱ͸iTunes ConnectͰόʔδϣϯΞοϓ
  48. #!/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"
  49. #!/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ίϚϯυΛ࢖͑͹ྑ͍
  50. <?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>
  51. <?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> ͜͜Ͱ • ωοτϫʔΫΞΫηε • ϑΝΠϧΞΫηε ౳ΛڐՄ͢Δ
  52. ͜ͷ͋ͱ৹͕ࠪ͋Δʂ

  53. MAS͸݁ߏͭΒ͍

  54. ͜͜·Ͱͷ·ͱΊ • electron-builderϚδ΂ΜΓ • electron-builderͷਐา͕଎͍ͷͰ͜Ε࢖ͬͱ ͚͹ؒҧ͍ͳ͍ • MAS͸͍ͭ΋େม

  55. MastodonͷΫϥΠΞϯτΛ ࡞Δ

  56. ͳͥMastodonͷ ΫϥΠΞϯτΛ࡞Δͷ͔

  57. σεΫτοϓ޲͚ͷ ΫϥΠΞϯτ͕ͳ͍ɼຊ౰ʹগͳ͍ • Mstdnʢࣗ෼ͰjsonϑΝΠϧΛ༻ҙͯ͠token ΛೖΕΔʣ • The Desk • TsuruʢόΠφϦͷ഑෍͸ͳ͍ʣ

  58. ͳ͍ͷͰ͋Ε͹ ࣗ෼Ͱͭ͘Ζ͏

  59. Whalebirdͷίϯηϓτ • LinuxͰ࢖͑Δ΋ͷΛ • Slackʹ׳Ε͍ͯΔͷͰSlackΆ͍ݟͨ໨ • γϣʔτΧοτ͸ͱʹ͔͘ଟ͘ ࠷ڧͷTwitterΫϥΠΞϯτ ઓ૪Λࢥ͍ग़͢

  60. ॳ൛͕Ͱ͖ͨ

  61. ւ֎͔Βͷ൓Ԡ

  62. ʢӳޠαϙʔτ͔ͨ͠Β͔ʣ ࠷ॳ͸ւ֎͔Β൓Ԡ͕

  63. ϦϦʔεͯ͠࠷ॳͷҰिؒ

  64. None
  65. None
  66. None
  67. None
  68. ྑ͍ʂ͚ͩͲElectron͔…… Έ͍ͨͳ൓Ԡ͹͔Γ

  69. ͦΜͳʹElectronͬͯධ൑ѱ ͍ͷʁ ೔ຊͰ͸͋·Γฉ͔ͳ͔͚ͬͨͬͲ

  70. ධ൑ͷѱ͞ • ϝϞϦফඅ͕ଟ͍ • SlackΛىಈ͢Δ͚ͩͰ500MBҎ্ϝϞϦΛ͍͔࣋ͬͯ ΕΔ • ࠷దԽ͞Εͯͳ͍ͷͰϝϞϦফඅ͕ଟ͍ • Javaͷํ͕͍ܰ

    • node.js͕ݏ͍
  71. ϝϞϦͱઓ͏

  72. ࠷੝ظ͸1GBҎ্ ͍͔࣋ͬͯΕͨ

  73. Ͳ͜ͰϝϞϦΛ ফඅ͍ͯ͠Δͷ͔ʁ

  74. ࢼͯ͠ΈΔ • StreamingΛࢭΊͨঢ়ଶͰ͍Ζ͍Ζ৮ͬͯΈΔ • StreamingΛࢭΊͨঢ়ଶͰ์ஔ ϝϞϦϦʔΫ͔ʁ

  75. StreamingࢭΊ͍ͯΔͱ૿͑ ͳ͍ʂ ผʹϝϞϦϦʔΫ͍ͯ͠ΔΘ ͚Ͱ͸ͳ͍ʂ

  76. StreamingʹΑΔϝϞϦফඅ • ຊ਺Λ૿΍ͯ͠ΈΔʁ

  77. StreamingʹΑΔϝϞϦফඅ • όοΫάϥ΢ϯυͰStreaming͢Δ͚ͩͰ͸ର ͯ͠ϝϞϦΛফඅ͠ͳ͍ʂ

  78. ΋͏গ͠ࢼ͢ • ྲྀ଎ͷ஗͍ΠϯελϯεͰ์ஔʢmikutterʣ • ྲྀ଎ͷ଎͍ΠϯελϯεͰ์ஔʢjpʣ

  79. ໌Β͔ʹྲྀ଎͕଎͍΄͏͕ ϝϞϦফඅ͕ଟ͍

  80. ͜Ε͸΋͠΍ϨϯμϦϯά ͳͷͰ͸ʁ

  81. WhalebirdͷλΠϜϥΠϯඳը • Streaming͞Εͨ΋ͷΛ͢΂ͯhtmlͱͯ͠දࣔ ͍ͯͨ͠ • ͭ·Γ͸ϒϥ΢βͷ࣮૷ʹؙ౤͛ • FireFoxͰ΋ڊେϖʔδΛ։͍ͨΒॏ͍
 ʢ͔ͩΒΈΜͳϖʔδωʔγϣϯ͢ΔΜͩ

  82. None
  83. ଞ͸Ͳ͏͍ͯ͠Δͷ͔ʁ

  84. iOSͷ৔߹ • UITableView͸දࣔ͞Ε͍ͯΔ෦෼͔͠Ϩϯμ Ϧϯά͍ͯ͠ͳ͍ • ӅΕ͍ͯΔ෼·ͰؚΊͨεΫϩʔϧྔ͸ܭࢉ ͍ͯ͠Δ • εΫϩʔϧ͞Εͨࡍ͸දࣔ͢Δ௚લʹ಺༰Λ ౎౓ϨϯμϦϯά

  85. දࣔ͞Ε͍ͯͳ͍෦෼͸ ϨϯμϦϯά͍ͯ͠ͳ͍

  86. UITableViewController • cellForRowAt: ηϧͷத਎ΛϨϯμϦϯά • heightForRowAt: ηϧͷߴ͞Λࢉग़ • estimatedHeightForRowAt: ະදࣔ෼ΛؚΊͯ

    ηϧͷߴ͞Λࢉग़
  87. ྲྀੴʹ͜Ε͸ύΫΕͳ͍

  88. ϙΠϯτɿ ඳը͢Δൣғ͸ݟ͍͑ͯΔ ෦෼͘Β͍Ͱे෼

  89. ElectronͰͲ͏͢Δ͔ʁ • λΠϜϥΠϯΛ͢΂ͯදࣔ͢ΔͷΛ΍ΊΔ • ࠷৽40݅ͷΈΛදࣔ͠ɼඞཁͰ͋Ε͹ LazyLoading • StreamingͰߋ৽͞Εͨ৔߹͸ɼݹ͍΋ͷΛফ ͯ͠40݅ʹอͭ

  90. None
  91. εΫϩʔϧΠϕϯτΛ΋ͱʹ੍ޚͯ͠΍Δ

  92. 200MBΛ੾Δʂ

  93. ѹ౗త͡Όͳ͍͔ʂ

  94. ϙΠϯτɿ Vue.jsͷύϑΥʔϚϯεʹ΋ ؾΛ഑Δ

  95. vue.jsͷύϑΥʔϚϯε • v-ifͱv-show • v-if: ੾ସ࣌ʹhtml͕ੜ੒͞ΕϨϯμϦϯά͞ ΕΔ • v-show: ͸͡Ί͔ΒϨϯμϦϯά͞Εͯ͸͍Δ

    ͕ɼdisplay: none͞Ε͍ͯΔ͚ͩ
  96. v-ifͱv-show • v-ifͷ੾ସ࣌ϨϯμϦϯάίετ͸അࣛʹͳΒ ͳ͍ • ͔͠͠ɼඞཁͷͳ͍ͱ͜ΖΛv-showʹ͢Δͱ ͣͬͱϝϞϦΛফඅ͠ଓ͚Δ

  97. ͜͜͸ਖ਼ղ͕ͳ͍

  98. ࠷ۙͷWhalebird • ϝϞϦফඅ: 200MB ~ 500MB • 500MB͘Β͍·Ͱ͘ΔͱGC͞ΕͯϝϞϦফඅ ͕ҰؾʹݮΔ •

    ը૾͕গͳ͍࣌ؒଳ͸͍ܰʂ
 ʢpawooͷਓ͝ΊΜͳ͍͞
  99. ࠷ۙͷWhalebird • ϕʔεʹͳ͍ͬͯΔElectronΛόʔδϣϯΞο ϓ͢ΔͱϝϞϦফඅ͕ݮΔ • ύϑΥʔϚϯε͸Chromiumʹ߹ΘͤͯͲΜͲ Μྑ͘ͳΔ

  100. ͜ͷઌͷ࡞ઓ • ը૾ͷඇදࣔΦϓγϣϯ • τΡʔτ͕࿈ଓ͢Δ৔߹͸·ͱΊͯϨϯμϦ ϯάͰ͖ͳ͍͔ʁ

  101. ͓ӄ༷Ͱ࠷ۙͷ൓Ԡ͸ྑ͍

  102. APIΫϥΠΞϯτϥΠϒϥϦ Λࣗ࡞͢Δ

  103. ౰ॳ͸mastodon-apiͱ͍͏ Node.jsͷϥΠϒϥϦΛར༻

  104. ͕ɼΤϥʔʹͳΔͱ͍͏ใࠂ ͕ͪΒ΄Β

  105. mastodon-api • POSTύϥϝʔλΛbodyͰ͸ͳ͘urlύϥϝʔ λͱͯ͠ૹ৴͍ͯ͠Δ • Ұ෦αʔόͰ͸ͦΕΒ͕ڋ൱͞Ε͍ͯΔ ଞͷબ୒ࢶ͕ͳ͍

  106. ͳ͍ͷͳΒࣗ࡞͠Α͏

  107. None
  108. megalodon • TypeScriptͰॻ͍ͨmastodonAPIΫϥΠΞϯ τϥΠϒϥϦ • Streaming΋࣮૷ࡁΈ • OAuthΞϓϦέʔγϣϯొ࿥༻ϝιου΋༻ ҙ

  109. 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 }) }
  110. όάͬͯͨ৔߹͸ શ෦ࣗ෼Ͱ࣏ͤΔ

  111. ΠϯελϯεΛ ݐͯΔ͜ͱ΋͋Δ

  112. ΠϯελϯεݪҼͷ໰͍߹Θͤ ͸ଟ͍ • ϩάΠϯ͕Ͱ͖ͳ͍ • τΡʔτͰ͖ͳ͍ • Streaming͕ಈ͔ͳ͍ • ౳ʑ……

  113. ࠷ۙ͋ͬͨ൵͍͠ࣄྫ • (mastodon͕࢖͍ͬͯΔ)doorkeeper 4.3.0Ҏ ্ Ͱnative_redirect_uriʹؔ͢Δόά͕ࠞೖ • mastodon: doorkeeper ~>

    4.4.1 • σεΫτοϓΞϓϦέʔγϣϯͰೝূ͕Ͱ͖ ͳ͘ͳΔ
  114. ͔֬ΊΔ&ϓϧϦΫΛग़͢ • खݩͰmastodonαʔόΛݐͯΔ: 
 https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/ Development-guide.md • ࠶ݱͨ͠ • doorkeeperʹissueཱͯͨΓɼmastodonʹϓ

    ϧϦΫΛૹͬͨΓ
  115. None
  116. ΫϥΠΞϯτ͚ͩͷ໰୊Ͱ͸ͳ͍͜ͱ͕ଟ͍ͷͰɼ αΫοͱΠϯελϯεΛཱͯΒΕΔΑ͏ʹ ͓ͯ͘͠ͷॏཁ

  117. ·ͱΊ

  118. ੒ޭͨ͠ͳʔͱࢥ͏͜ͱ • ElectronͰ࡞ͬͨ͜ͱ • Vue.jsͱ͍͏બ୒ • ӳޠݍ΁ͷ഑ྀ

  119. ࣦഊͨ͠ͳʔͱࢥ͏͜ͱ • ΋ͬͱૣ͘࡞Ε͹Α͔ͬͨ • ΋ͬͱૣ͘TypeScriptΛߟྀ͢΂͖ͩͬͨ • megalodon(APIΫϥΠΞϯτ)͸ϝϯς͠΍ ͍͢ • ద౰ͳΦϒδΣΫτΛ౉͢͜ͱ͕ଟ͍

  120. 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Ͱߦ͏ ະ஌ͷΦϒδΣΫτ
  121. શମతʹݟͯ • Electron͸ʢϦϦʔεํ๏΋ؚΊͯʣਐԽͯ͠ ͍ΔͷͰ͓͢͢Ί͍ͨ͠ • ϝϞϦফඅ͸ରࡦՄೳ • Vue.jsͰGUIΞϓϦέʔγϣϯ։ൃ͢Δͷ͸ྑ ͍

  122. Mastodon͕ շదʹͳͬͨͷͰ TwitterΛݟΔ͜ͱ͕ݮͬͨ

  123. ͞Α͏ͳΒTwitter ΫϥΠΞϯτ