Upgrade to Pro — share decks privately, control downloads, hide ads and more …

新規モバイルアプリを React Native for Web で Web 対応した話

新規モバイルアプリを React Native for Web で Web 対応した話

React Native Matsuri 2022 Session Talk

株式会社JMDCでは、現在新規プロダクトをReact Nativeで開発しています。

昨今プロダクト立ち上げの際にモバイルアプリファーストを選ぶのは自然なことですが、アプリをストアに公開するには、Webアプリケーション以上に公開基準を満たすための最初期の開発が必要です。
また、アップデートの際のストアの審査も仮説検証のイテレーションをクイックに回すことを難しくします。

そんな時、React Native for Webを用いて開発中のネイティブアプリをWeb用に流用すれば、PMFまでの仮説検証フェーズを素早く回すことができるのではないかと考えました。

本発表ではJMDCでのReact Native for Webの採用事例と、導入の際に得た知見を共有します。

Kazunobu Kawane

October 08, 2022
Tweet

Other Decks in Programming

Transcript

  1. © JMDC Inc. ࣗݾ঺հ Kazunobu Kawane גࣜձࣾ +.%$ϢʔβʔϓϥοτϑΥʔϜ։ൃ෦ Accounts w

    5XJUUFS!GMBU@ w (JU)VCLLBXBOF Favorites w ΧϨʔिͰ৯΂Δ 2
  2. © JMDC Inc. )5.-ΑΓ௚ײతͳλά // Plane React 
 <div> 


    <p>Hello World</p> 
 </div> 
 
 // React Native 
 <View> 
 <Text>Hello World</Text> 
 </View> 12
  3. © JMDC Inc. BDDFTTJCJMJUZ3PMFͰηϚϯςΟοΫ)5.-ʹ΋ରԠ <View accessibilityRole="section"> 
 <Text accessibilityRole="heading">heading</Text> 


    <Text accessibilityRole="paragraph">This is an article</Text> 
 </View> 
 
 /* 
 <section> 
 <h1>title</h1> 
 <div role="paragraph">This is paragraph</div> 
 </section> 
 */ 13
  4. © JMDC Inc. 4UZMF1SPQTʹΑΔϓϩύςΟʔͷ੍ݶ 7JFXʹ౰ͯΒΕΔ4UZMFͱ5FYUʹ౰ͯΒΕΔελΠϧ͕ɺ1SPQTʹΑΓ۠ผ͞Ε͍ͯΔ return ( 
 <View style={styles.container}>

    
 <Text>Hello World</Text> 
 </View> 
 ); 
 
 const styles = StyleSheet.create({ 
 container: { 
 color: '#FF0000' // color͸ ViewStyleͷpropsʹఆٛ͞Ε͍ͯͳ͍ͷͰerrorʹ
 }, 
 }); ελΠϦϯάͷείʔϓ͕ߜΒΕΔͷͰίϯϙʔωϯτࢤ޲ͷ(6*։ൃͱ૬ੑྑ͠ 14
  5. © JMDC Inc. $PSF$PNQPOFOU͕༏ल w ཁૉΛғΉ͚ͩͰࢠཁૉ͕εΫϩʔϧ ίϯςϯπʹͳΔ4DSPMM7JFX w ғͬͨཁૉ΁ͷλονΛෆಁ໌౓ͷݮ গͰϑΟʔυόοΫͯ͘͠ΕΔ

    5PVDIBCMF0QBDJUZ w ແݶεΫϩʔϧͰͷ௥ՃಡΈࠐΈ΍ QVMM5P3FGSFTIͷαϙʔτ͞ΕͨϦε τදࣔ༻6*'MBU-JTU 16
  6. © JMDC Inc. 8FC༻ʹϏϧυ # Expo SDK 45 $ npx

    expo export:web # ~Expo SDK 44 (Classic build) $ npx expo build:web Ҏ্ʂ &YQPΛ࢖༻͍ͯ͠Δ৔߹ɺ41"༻ͷ JOEFYIUNMͷ࡞੒΍ 8FCQBDLͷઃఆϑΝΠϧͷ ࡞੒͸ෆཁ 34
  7. © JMDC Inc. ࣮ྫɿ4UPSZCPPLͷ৔߹ module.exports = { 
 webpackFinal: (config)

    => { 
 // WebpackͷAliasઃఆ
 config.resolve.alias = { 
 "react-native$": "react-native-web", 
 }; 
 
 // react-native-webʹม׵͢Δ͜ͱͰมߋ͞ΕΔ֦ுࢠΛղܾ͢Δ
 config.resolve.extensions.unshift(".web.js"); 
 
 return config; 
 }, 
 }; 36
  8. © JMDC Inc. ෦෼తʹ࣮૷Λ෼͚ͨ 3FBDU/BUJWFͰ͸ɺ1MBUGPSNϞδϡʔϧΛ࢖༻ͯ͠ϓϥοτϑΥʔϜݻ༗ͷίʔυΛ࣮૷Ͱ͖Δ import { Platform } from

    'react-native'; --- লུ --- {Platform.OS === 'ios' && return <WebComponent /> } {Platform.OS === 'android' && return <NativeComponent /> } 38
  9. © JMDC Inc. 1MBUGPSNϞδϡʔϧʹ͸Լهͷ 045ZQF͕ఆٛ͞Ε͍ͯΔ export type PlatformOSType = 


    | "ios" 
 | "android" 
 | "macos" 
 | "windows" 
 | "web" 
 | “native"; 39
  10. © JMDC Inc. ͜ΕΛར༻ͯ͠8FCͱ/BUJWFͷ࣮૷Λ੾Γ෼͚ͨ import { Platform } from 'react-native';

    --- লུ --- {Platform.OS === 'web' && return <WebComponent /> } {Platform.OS === 'native' && return <NativeComponent /> } ͪΐͬͱͨ͜͠ͱͳΒ͜ΕͰ0, 👌 40
  11. © JMDC Inc. ಺෦࣮૷ΛಡΜͰΈͨ • react-native-msal͕ wrap ͍ͯ͠ΔϥΠϒϥϦͷϙοϓΞοϓ΢Πϯυ΢Λ࢖ͬͨ ೝূϝιουʹ໰୊͕͋Γͦ͏ w

    XSBQ͞Ε͍ͯΔϥΠϒϥϦʹ͸ϙοϓΞοϓ΢Πϯυ΢Λ࢖ͬͨೝূҎ֎ʹɺϝΠϯ ΢Πϯυ΢ΛϦμΠϨΫτͤ͞Δೝূϝιου΋ఆٛ͞Ε͍ͯΔΑ͏ 46
  12. © JMDC Inc. 8FCϒϥ΢β༻ͷ࣮૷Λ੾Γ෼͚ͨ SFBDUOBUJWFNTBM͕ XSBQ͍ͯ͠ΔϥΠϒϥϦΛ௚઀࢖༻ͨ͠ XFC༻ͷ IPPLT • src/hooks/useAuthClient.ts

    SFBDUOBUJWFNTBMΛ࢖༻ͨ͠ OBUJWF༻ͷ IPPLT • src/hooks/useAuthClient.native.ts ͜͏JNQPSU͢Ε͹ 0,👌  JNQPSU\VTF"VUI$MJFOU^GSPNl!IPPLTVTF"VUI$MJFOU 49
  13. © JMDC Inc. ·ͱΊ w 3FBDU/BUJWFGPS8FC͸ɺ3FBDU/BUJWFޓ׵ͷ+BWBTDSJQUίʔυΛ࢖ͬͯ8FCϒϥ΢β ͷ6*Λ࡞੒Ͱ͖Δ w /BUJWF༝དྷͷ༏लͳ(6*ϥΠϒϥϦΛ࢖͑Δ w

    8FCͱ/BUJWFͷ6*ίϯϙʔωϯτΛڞ௨ԽͰ͖Δ w 3FBDU/BUJWFGPS8FC͸ɺΞϓϦͷԾઆݕূΛ8FCͰΫΠοΫʹߦ͏खஈͱͯ͠΋͓͢͢Ί w 8FCͰ/BUJWF༻ͷϥΠϒϥϦΛ࢖͏৔߹͸ɺଟগπϥϛ͕͋Δ͕ͳΜͱ͔ͳΔʢ୯ʹΫϩεϓ ϥοτϑΥʔϜ։ൃͷπϥϛͰɺ8FCΦϯϦʔͰ3FBDU/BUJWFGPS8FCΛ࢖͏৔߹͸շదʣ 53
  14. © JMDC Inc. ࢀߟ 3FBDU/BUJWFGPS8FC IUUQTOFDPMBTHJUIVCJPSFBDUOBUJWFXFC 3FBDU/BUJWF IUUQTSFBDUOBUJWFEFW 3FBDU/BUJWF%JSFDUPSZ IUUQTSFBDUOBUJWFEJSFDUPSZ

    &YQP IUUQTEPDTFYQPEFW 4UPSZCPPL IUUQTTUPSZCPPLKTPSH 3FBDU/BUJWF.4"- IUUQTHJUIVCDPNTUBTIFOFSHZSFBDUOBUJWFNTBM 57