Code sharing at scale: one codebase for web, mobile and desktop

97d21da8e0ffa8f81218a293482c253a?s=47 Matheus
November 26, 2019

Code sharing at scale: one codebase for web, mobile and desktop

React.js and React-Native allow a "learn once write anywhere paradigm". This is great because one tech team can build both your web app and native mobile experience. The problem is developers hate writing things twice. There have been a couple of efforts to build a unifying technology to write an application once and have it work on both web and native. Yet this is not always the best approach.

This talk will cover identifying the best candidates for shared code and a couple of lessons learned while building an app with code sharing as a primary objective — from project setup, through shared infrastructure, all the way up to shared components and styling — and how you can achieve the same thing.

Last but not least, I'll share a couple of thoughts on what's coming down the line!

97d21da8e0ffa8f81218a293482c253a?s=128

Matheus

November 26, 2019
Tweet

Transcript

  1. CODE SHARING AT SCALE: ONE CODEBASE FOR WEB, MOBILE AND

    DESKTOP Matheus Albuquerque, Front-End Engineer at STRV
  2. Dobrý den! 2

  3. 3 ed

  4. CONTEXT 4

  5. CONTEXT • HOW IT ALL STARTED 5

  6. CONTEXT • HOW IT ALL STARTED 6

  7. CONTEXT • WHY • Velocity • No platform specialization 7

  8. CONTEXT • WHY • VELOCITY Often fewer short-term gains due

    to overhead in writing glue code Have to rearchitect existing JavaScript code Tooling is difficult (CI, unit tests etc.) Write code once Possibly long-term gains 8
  9. CONTEXT • WHY • NO PLATFORM SPECIALIZATION An engineer should

    be able to write mobile code for the product without differentiating between Android and iOS Low occurrence of OS-specific problems 9
  10. CONTEXT • CONCERNS • What if I need to implement

    a specific component separately for Web and Native? • How to use React Native-specific libraries? • What about navigation? • How to handle different storage layers? • What not to share? 10
  11. CONTEXT • TYPES OF CODE 11 UI Render Business Logic

    Configuration API / Formatting
  12. CONTEXT • TYPES OF CODE 12 UI Render Business Logic

    Configuration API / Formatting
  13. CONTEXT • TYPES OF CODE • DIFFERENT RENDER ENVIRONMENTS 13

    UI Render <div> <View> !== <ul> <FlatList> !== <WebPrimitive> <NativePrimitive> !==
  14. CONTEXT • SOLUTIONS 14 Flutter NativeScript Ionic

  15. React Native Web • Developed by Nicolas Gallagher (Facebook) •

    Parallel implementation of React Native • Web Equivalents of RN components • Used by Twitter, Major League Soccer, Uber, Flipkart, The Times 15 ReactXP • Developed by the Skype Team (Microsoft) • Abstraction layer over React-DOM and React Native • Wrappers over Web/Native components • Used by Skype CONTEXT • SOLUTIONS • ADDING WEB TO THE EQUATION
  16. CONTEXT • SOLUTIONS 16 React Native Web ReactXP Flutter NativeScript

    Ionic
  17. 17 Flutter NativeScript Ionic We’re going to mention a couple

    things. CONTEXT • SOLUTIONS React Native Web ReactXP
  18. 18 Flutter NativeScript Ionic We’re going to focus on this

    one. CONTEXT • SOLUTIONS React Native Web ReactXP
  19. 19 CONTEXT • SOLUTIONS • DISCLAIMER

  20. • I enjoy having control over the stack and being

    aware of what's happening. I want to: • Customize the installation • Install custom version of modules • Have more control of project dependencies • Use own CI/CD implementation • Use our own React Native modules • We can only use their SDK and packages that don’t require linking • Size (might) matter • Permissions eventually being needed despite the fact the app never needs them 20 CONTEXT • SOLUTIONS • DISCLAIMER
  21. CONTEXT • SOLUTIONS • DISCLAIMER 21

  22. CONTEXT • SOLUTIONS • DISCLAIMER 22 https://youtu.be/k1FdrhA2sCY

  23. ARCHITECTURE 23

  24. ARCHITECTURE • BOOTSTRAPPING 24

  25. ARCHITECTURE • BOOTSTRAPPING 25 https://github.com/brunolemos/react-native-web-monorepo

  26. ARCHITECTURE |-- packages/ | |-- mobile/ | |-- shared/ |

    |-- web/ |-- patches/ | |-- react-native-google-signin+2.0.0.patch | |-- ... |-- .eslintrc.js |-- .gitignore |-- .prettierrc.js |-- .stylelintrc |-- README.md |-- commitlint.config.js |-- package.json |-- tsconfig.base.json |-- tsconfig.json |-- yarn.lock 26
  27. ARCHITECTURE |-- packages/ | |-- mobile/ | |-- shared/ |

    |-- web/ |-- patches/ | |-- react-native-google-signin+2.0.0.patch | |-- ... |-- .eslintrc.js |-- .gitignore |-- .prettierrc.js |-- .stylelintrc |-- README.md |-- commitlint.config.js |-- package.json |-- tsconfig.base.json |-- tsconfig.json |-- yarn.lock 27 Each platform code + shared business logic
  28. ARCHITECTURE |-- packages/ | |-- mobile/ | |-- shared/ |

    |-- web/ |-- patches/ | |-- react-native-google-signin+2.0.0.patch | |-- ... |-- .eslintrc.js |-- .gitignore |-- .prettierrc.js |-- .stylelintrc |-- README.md |-- commitlint.config.js |-- package.json |-- tsconfig.base.json |-- tsconfig.json |-- yarn.lock 28 Native library patches
  29. ARCHITECTURE |-- packages/ | |-- mobile/ | |-- shared/ |

    |-- web/ |-- patches/ | |-- react-native-google-signin+2.0.0.patch | |-- ... |-- .eslintrc.js |-- .gitignore |-- .prettierrc.js |-- .stylelintrc |-- README.md |-- commitlint.config.js |-- package.json |-- tsconfig.base.json |-- tsconfig.json |-- yarn.lock 29 Dotfiles and other project-wide stuff
  30. ARCHITECTURE |-- packages/ | |-- mobile/ | |-- shared/ |

    |-- web/ |-- patches/ | |-- react-native-google-signin+2.0.0.patch | |-- ... |-- .eslintrc.js |-- .gitignore |-- .prettierrc.js |-- .stylelintrc |-- README.md |-- commitlint.config.js |-- package.json |-- tsconfig.base.json |-- tsconfig.json |-- yarn.lock 30 Shared config which can be extended
  31. ARCHITECTURE • MOBILE 31

  32. ARCHITECTURE • MOBILE 32 Regular React Native app structure.

  33. ARCHITECTURE • WEB 33

  34. ARCHITECTURE • WEB 34 Regular Create React App structure.

  35. ARCHITECTURE • SHARED 35

  36. ARCHITECTURE • SHARED 36 Inside src…

  37. ARCHITECTURE • SHARED 37

  38. ARCHITECTURE • SHARED • TYPES OF CODE 38 UI Render

    Configuration API / Formatting Business Logic
  39. ARCHITECTURE • SHARED • TYPES OF CODE 39 UI Render

    Business Logic Configuration API / Formatting
  40. ARCHITECTURE • SHARED • TYPES OF CODE 40 Business Logic

    Environment independent If a user can only add 20 items to their basket, this rule will hold true in web and native equally
  41. ARCHITECTURE • SHARED • TYPES OF CODE 41 Configuration Config

    files, translation files and most constant data are not render environment specific If I update a translation on my app, it’s very likely I want that change rolled out on the web app too
  42. ARCHITECTURE • SHARED • TYPES OF CODE 42 Configuration Shared

    config object Web Config Object Native Config Object
  43. ARCHITECTURE • SHARED • TYPES OF CODE 43 Configuration Shared

    config object Web Config Object Native Config Object { ...sharedConfig, mobileSpecificConfig: '...', }
  44. ARCHITECTURE • SHARED • TYPES OF CODE 44 API /

    Formatting API calls, authentication and formatting of request and response data If we make a POST to a REST API on web, it’s very likely to be the same POST on native
  45. ARCHITECTURE • 90%+ CODE SHARING™ 45

  46. ARCHITECTURE • PLATFORM-SPECIFIC MODULES 46

  47. TOOLS 47

  48. TOOLS • React Navigation V3 as a universal routing strategy

    • patch-package to keep me safe and sound from Xcode • Yarn Workspaces to enable our monorepo strategy 48
  49. TOOLS • REACT NAVIGATION V3 • @reach/router has no React

    Native support • react-router-native lacks screen transitions, back-button support, modals, navbars and other important stuff • Started by making a few crazy combinations: • react-router-dom + react-router-native • react-router-dom + react-navigation • … • Currently using React Navigation on the Web • This has not yet been widely used in production and it is considered to be experimental 49
  50. TOOLS • PATCH-PACKAGE 50

  51. TOOLS • PATCH-PACKAGE 51 • patch-package lets app authors instantly

    make and keep fixes to npm dependencies • My case: • Had to change a few files on the library’s iOS code (XCode stuff) • It was not worthy to submit a PR on the library, tho (the problem was literally on our machines™) • Having each member of the team changing the same stuff is simply out of consideration • Seems to be an accepted pattern on React Native community
  52. TOOLS • YARN WORKSPACES • Let you organize your project

    codebase using a monolithic repository • React is a good example of an open-source project that is monorepo. Also, React uses Yarn workspaces to achieve that • nohoist FTW • Currently: mobile, web and shared packages • Future plans: desktop (electron?) and back-end (maybe) 52
  53. CHALLENGES 53

  54. CHALLENGES • Lack of real-world-scenarios content related to React Native

    Web on the web (e.g. navigation) • (unexpected) Lack of documented stuff on popular projects (e.g. Webpack and Metro) • react-native-web supports most of the react-native API, but a few pieces are missing 54
  55. CHALLENGES • LACK OF REAL-WORLD-SCENARIOS CONTENT 55

  56. CHALLENGES • LACK OF DOCUMENTED STUFF 56

  57. CHALLENGES • LACK OF DOCUMENTED STUFF 57

  58. CHALLENGES • UNSUPPORTED APIs react-native-web supports most of the react-native

    API, but a few pieces are missing like • Alert • Modal • RefreshControl • WebView 58
  59. TIPS 59

  60. TIPS • Navigation may be a bit of a challenge;

    you can use something like react-navigation which recently added web support or you can try using two different navigators between and mobile, in case you want the best of both worlds by compromising some code sharing • To install new dependencies, use the command yarn workspace <package> add <library> from the root directory • To run a script from a package, run yarn workspace <package> start, for example • To run a script from all packages, run yarn workspaces run <script> 60
  61. TIPS • If you plan sharing code with the server,

    I recommend creating a core package that only contain logic and helper functions (no UI-related code); • For Next.js, you can check their official example with react-native-web • For native windows, you can try react-native-windows; • For native macOS, you can the new Apple Project Catalyst, but support for it is not 100% there yet 61
  62. TL;DR 62

  63. 63 TL;DR

  64. 64 TL;DR

  65. TL;DR • LESSONS LEARNT • Code sharing is a great

    advantage of React and React Native • Share your non-design render code • Your mobile app and web app (probably) should have different experiences • HOCs / hooks help sharing component logic 65
  66. TL;DR • LESSONS LEARNT "Web, mobile web and native application

    environments all require a specific design and user experience." - Matheus 66
  67. TL;DR • LESSONS LEARNT 67

  68. TL;DR • LESSONS LEARNT 68 It’s worth noting that we’re

    not chasing “write once, run anywhere.” Different platforms have different looks, feels, and capabilities, and as such, we should still be developing discrete apps for each platform, but the same set of engineers should be able to build applications for whatever platform they choose, without needing to learn a fundamentally different set of technologies for each. We call this approach “learn once, write anywhere.”
  69. TL;DR • THE FUTURE 69

  70. TL;DR • THE FUTURE 70 Simple Stuff Complex Stuff

  71. TL;DR • THE FUTURE 71 Simple Stuff • A couple

    API calls / data fetching • Not too complex lifecycle • Simple Navigation/Routing
  72. TL;DR • THE FUTURE 72 Simple Stuff Complex Stuff

  73. TL;DR • THE FUTURE 73 Simple Stuff Complex Stuff

  74. TL;DR • THE FUTURE • IONIC (CAPACITOR) 74 • Wraps

    the web app in a WebView • It injects a “bridge” into the app running in the webview, that connects the code of the web app and the code of the native part so these can interact • For Progressive Web Apps Capacitor provides fallback implementations to native functionality not present • Capacitor achieves true cross-platform and portable functionality with 100% code sharing by providing a consistent API • Backward compatible* with Cordova
  75. TL;DR • THE FUTURE • IONIC (CAPACITOR) 75 • Native

    Progressive Web Apps built with Capacitor can be used on all the relevant platforms: • iOS • Android • Browsers (Progressive Web Apps) • Windows, macOS, Linux (via Electron)
  76. TL;DR • THE FUTURE • IONIC (CAPACITOR) 76 Accessibility App

    Background Task Browser Camera Clipboard Console Device Filesystem Geolocation Haptics Keyboard Local Notifications Modals Motion Network Push Notifications Share Splash Screen Status Bar Storage Toast
  77. TL;DR • THE FUTURE • IONIC (CAPACITOR) 77 Accessibility App

    Background Task Browser Camera Clipboard Console Device Filesystem Geolocation Haptics Keyboard Local Notifications Modals Motion Network Push Notifications Share Splash Screen Status Bar Storage Toast + Community Plugins
  78. TL;DR • THE FUTURE • IONIC (CAPACITOR) 78

  79. TL;DR • THE FUTURE 79 Simple Stuff Complex Stuff

  80. TL;DR • THE FUTURE 80 Complex Stuff • Aggressive animations

    • CPU-bound stuff
  81. TL;DR • THE FUTURE 81 Simple Stuff Complex Stuff

  82. TL;DR • THE FUTURE 82 Simple Stuff Complex Stuff

  83. TL;DR • THE FUTURE • FLUTTER (SKIA) 83 • Fast

    startup and execution of an app are the benefits of compilation to native code • The UI is refreshed at 60fps – mostly using the GPU – and every pixel on the screen is owned by the Skia canvas which leads to a smooth, highly customizable UI • The same hardware-accelerated graphics engine that underpins Chrome and Android
  84. TL;DR • THE FUTURE • FLUTTER (SKIA) 84

  85. TL;DR • THE FUTURE • FLUTTER (SKIA) 85 https://link.medium.com/gtLw3LfTL1

  86. 86 ⚠ ❌ ❌ ⚠ TL;DR

  87. THAT'S IT Matheus Albuquerque @ythecombinator land@ythecombinator.space

  88. 88 MATHEUS ALBUQUERQUE @ythecombinator www.ythecombinator.space land@ythecombinator.space

  89. THAT’S IT • SLIDES 89

  90. THAT’S IT • SLIDES 90 http://bit.ly/code-sharing-lessons-learned

  91. THAT’S IT • SLIDES 91

  92. THAT’S IT • SLIDES 92 I got stickers!

  93. QUESTIONS

  94. None