$30 off During Our Annual Pro Sale. View Details »

SlackはどうやってBrowserViewに乗り換えたのか / How Slack move from webview to BrowserView

tipo159
December 21, 2017

SlackはどうやってBrowserViewに乗り換えたのか / How Slack move from webview to BrowserView

Slackは、デスクトップ 3.0でどうやってElectronのwebviewからBrowserViewに乗り換えたのか
・webviewの問題点
・BrowserViewへの乗り換えで必要な変更
・electron-reduxを使ったRedux Stateの集約
・redux-observableを使った非同期Actionとユーザ操作に伴うActionの一元化
・TypeScriptによる速く正確なリファクタリング

tipo159

December 21, 2017
Tweet

More Decks by tipo159

Other Decks in Programming

Transcript

  1. Slack͸Ͳ͏΍ͬͯBrowserViewʹ৐Γ׵͔͑ͨ We Are JavaScripters! @14th 2017.12.21 tipo159

  2. LT಺༰ • webviewͷ໰୊఺ͱBrowserView΁ͷ৐Γ׵͑ • ৐Γ׵͑࣌ʹमਖ਼ͨ͠໰୊఺ • ෳ਺Redux Storeؒͷಉظ • ඇಉظActionʹΑΔ෭࡞༻

    • ϦϑΝΫλϦϯά • ·ͱΊ Growing Pains: Migrating Slack’s Desktop App to BrowserView https://slack.engineering/growing-pains-migrating- slacks-desktop-app-to-browserview-2759690d9c7b 2
  3. webviewͷ໰୊఺ • ChromiumͰҡ࣋؅ཧΛߦ͍ͬͯΔͷͰɼElectron͔Βͷཁ ๬௨Γʹόάमਖ਼͕ߦΘΕͳ͍ • Chrome extensionsͰ͔͠࢖ΘΕ͍ͯͳ͍ͨΊɼόάमਖ਼ͷ༏ઌ ౓͕௿͍ • ͜Ε·ͰͷҰ൪ͻͲ͍όά͸ɼwebviewΛඇදࣔʹͨ͠ޙ࠶දࣔ

    ͯ͠΋ίϯςϯπ͕࠶ඳը͞Εͳ͔ͬͨ͜ͱ 3
  4. BrowserView΁৐Γ׵͑ • BrowserViewͷಛ௃ • webViewΑΓChromeͷλϒʹ͍ۙಈ࡞ • DOMΤϨϝϯτΑΓωΠςΟϒwindowʹ͍ۙಈ࡞ • ElectronͰҡ࣋؅ཧ •

    มߋ͕ඞཁͳՕॴ • HTML΍CSSͰѻ͏͜ͱ͕Ͱ͖ͳ͍ͨΊɼτοϓϨϕϧwindowͱಉ༷ʹόο Ϋάϥ΢ϯυϓϩηεͰ࡞੒ • ϨΠϠʔ͸ϓϩάϥϜͰ؅ཧ • BrowserView͸βͷͨΊAPIมߋͷՄೳੑ͋Γ 4
  5. BrowserViewͷίʔυྫ // In the main process. const {BrowserView, BrowserWindow} =

    require('electron') let win = new BrowserWindow({width: 800, height: 600}) win.on('closed', () => { win = null }) let view = new BrowserView({ webPreferences: { nodeIntegration: false } }) win.setBrowserView(view) view.setBounds({ x: 0, y: 0, width: 300, height: 300 }) view.webContents.loadURL('https://electronjs.org') 5
  6. ෳ਺Redux Storeؒͷಉظ • ϫʔΫεϖʔεʹରԠ͢Δϓϩηε͕ෳ਺ଘࡏ͠ɼͦΕͧΕ ͷRedux StoreΛಉظ͢Δඞཁ͕͋ͬͨ • electron-reduxΛ࢖͍ϝΠϯϓϩηεͷRedux Stateʹू໿ 6

  7. ඇಉظActionʹΑΔ෭࡞༻ • Redux͚ͩͰ͸ඇಉظActionͱͦΕʹΑΔ෭࡞༻Λ͏·͘ѻ ͑ͳ͍ʢSlackͷ۩ମతͳهड़ͳ͠ʣ • redux-observableΛ࢖͍ඇಉظActionͱϢʔβૢ࡞ʹ൐͏ ActionΛҰݩԽ • ActionͷετϦʔϜΛૢ࡞͢ΔepicΛهड़ •

    epic͸Ϧσϡʔε͞ΕͨstateͰ͸ͳ͘ɼActionͷετϦʔ ϜΛੜ੒ 7
  8. redux-observableͷίʔυྫ import { BrowserWindow } from 'electron'; import { REHYDRATE

    } from 'redux-persist/constants'; import { getWorkspacesCount } from '../reducers/workspaces'; const signInWindowEpic = (action$, store) => { // Rehydrate is just a $10 word for "we loaded saved state from a file" // Since we're a redux-persist app, it's one of the first actions that occurs return action$.ofType(REHYDRATE) .filter(() => getWorkspacesCount(store) > 0) .map(() => createSignInWindow(store)) .do((browserWindow) => browserWindow.show()); }; function createSignInWindow(store) { const browserWindow = new BrowserWindow( /* ... you get the idea */ ); } 8
  9. ϦϑΝΫλϦϯά • TypeScriptʹΑΔ଎͘ਖ਼֬ͳϦϑΝΫλϦϯά • JavaScriptͷlinterΑΓ༗ޮͳίʔυνΣοΫ • TypeScript͸ैདྷ͔Β࠾༻͍͕ͯͨ͠ɼϦϑΝΫλϦϯά ͰҖྗΛൃش • Ҿ਺΍໭Γ஋ͷܕ͕ObservableΛ࢖ͬͨίʔυهड़ͷॿ͚

    ʹ 9
  10. ·ͱΊ • webview͔ΒBrowserView΁ͷ৐Γ׵͑ • electron-reduxΛ࢖͍ϝΠϯϓϩηεͷRedux Stateʹू໿ • redux-observableΛ࢖͍ඇಉظActionͱϢʔβૢ࡞ʹ൐͏ ActionΛҰݩԽ •

    TypeScriptʹΑΔ଎͘ਖ਼֬ͳϦϑΝΫλϦϯά 10