Reagovat domorodce: Proč a jak vytvořit svůj rodný kód v provozu

React Native nám umožňuje vytvářet mobilní aplikace pomocí Javascriptu. Pro mě je to první platforma, která skutečně splňuje tento slib; dělá to prostřednictvím všímavé architektury, nejlepších nástrojů ve své třídě a pracovního postupu a pragmatického přístupu pro vývoj napříč platformami. Nezmínil se o tom, že jeho účelem je poskytnout schopnost psát 100% kód Javascript pro jakýkoli daný projekt, ani neslibovat dokonalou, jednoduchou multiplatformní kódovou základnu pro vaše mobilní aplikace. To je pro mě celý rozdíl.

A tak je myšlenka perfektního sdílení napříč platformami a aplikace, která je postavena zcela v Javascriptu, ze své podstaty složitá, protože:

  1. Některé části musíte postavit nativně.
  2. Různé platformy mají různé zkušenosti.
  3. Různá zařízení fungují odlišně.
  4. Neexistuje stříbrná kulka.

To znamená, že jsme nakonec povinni napsat nějaký nativní kód. Psaní nativního kódu je radikálním posunem od naší zkušenosti s reakcí Nativní: nástroje musíme znát důvěrněji; Xcode, Android Studio a Gradle a Android SDK, Obj-C nebo Swift a Java nebo jakýkoli JVM jazyk podporující Android, například Kotlin. Musíme se také seznámit s rámcovým mentálním modelem každé platformy, jako jsou záměry a pohledy na Android a ovladače, názory a delegáti Cocoa.

Proč jít nativní?

Ale ještě předtím, i když na React Native, můžeme uvést skutečné důvody, které nás nutí k tomu, abych propadl Javascript, a jít nativní.

  • Výkon. Toto je pravděpodobně první položka, která prochází myslí každého, když říkají „rodný kód“, a je to také první položka, kterou byste měli tvrdě pracovat, aby se vyloučila. Nejprve musíte prostřednictvím čísel prokázat, že máte problém s výkonem. A pak bych zůstal podezřelý, kdybych byl ty. Stále však nativní kód převyšuje výkon Javascriptu v určité míře pro určité pracovní zatížení.
  • Nízký přístup k OS. To už je všude kolem nás. Používáme balíčky React Native, které se zabývají nativními částmi každého operačního systému, protože jádro React Native se k němu ještě nedostalo, nebo je mimo rozsah.
  • Infrastruktura a robustnost. Na stroji Javascript jsou plýtvání úkoly, jako je zpracování obrázků, přemísťování velkého množství bajtů přes most React Native, zpracování souborů a další.
  • Tricky asynchronní logika. Mohli bychom raději používat řešení nativního OS pro práci s asynchronními pracovními postupy, nebo dávat přednost tomu, aby byly vytvořeny „lokální“ jazykové konstrukty. Na mysli přicházejí různé mentální modely souběžnosti, jako je CSP a herecký model.
  • Knihovny a ekosystém. Některé knihovny nemusí být dostupné v npm, nebo nemají kvalitu, kterou očekáváme, funkce nebo podporu komunity. Nativní varianta by již mohla být zlatá.
  • Zatemnění a odolnost proti zpětnému inženýrství. Reagujte Nativní kód Javascriptu se svým binárním kódem a kdokoli ho může chytit z vašeho balíčku. Zatímco některé platformy, jako je Xamarin, šifrují a vkládají je do nativního kódu, útočník se stále otevírá, ale stále je zde (PDF). Ve většině případů to není problém, ale existuje spousta případů, kdy je vaše IP skutečně kód.
  • Sdílení kódu pomocí backendu. Zatímco jednou z hlavních výhod používání Node.js je sdílení backendového a frontendového kódu Javascript, je možné, že váš backend není postaven na Node.js ani Javascriptu a přesto byste chtěli sdílet artefakty, jako je datový model. , validace a obchodní pravidla.
  • A konečně moje oblíbená: binární komunikace. I když byste mohli komunikovat prostřednictvím binárního protokolu, jako je Protobuf, z vašeho procesu React Native, může být bolestivé a náročné rozbalit binární data, nebo aby to fungovalo dobře, a aby bylo možné je udržovat nebo podporovat existující platformou a knihovnami.

Jak se React Native vyvíjí, některé položky v tomto seznamu zmizí a stále některé, jako je zmatek a jiné, zůstanou vždy.

Používání Go for Cross-Platform Mobile Development

Vyloučení hostujících virtuálních počítačů, které jako Javascript hostují jazyk na dané platformě nebo komerční stroje jako Apportable, zůstáváme s C a C ++ (dropbox používá C ++ pro sdílení kódu mimo UI) jako cílové jazyky pro sdílení nativního kódu.

Nejsou však bezpečné (jako v oblasti bezpečnosti paměti) a ve srovnání s Javascriptem jsou pevným jádrem. Použití Java, Obj-C nebo C / C ++ může způsobit značné množství tření. Existuje také Rust, ale nejsem si jistý, jak dobře to hraje s ARM a jaký druh mobilních abstrakcí má (žádný?).

Až před několika lety to mohlo být místo, kde náš experiment skončil. Poté Go (jazyk) přidal podporu exportním binárním souborům jako C-knihovny, které otevřely svět příležitostí. Například, před lety jsem použil Go k opravě slabých míst v Ruby a později jsem napsal článek a referenční implementaci Gem, abych ukázal, jak byste to mohli také udělat.

Další z nich bylo uvedení Go na mobilní zařízení. Ukážu vám, že Go je stejně dobrý jazyk pro cloudovou infrastrukturu, stejně jako pro mobilní vývoj, a do značné míry i pro mobilní vývoj pro React Native.

Náš Prisma Clone: ​​Primer

Vytvoříme aplikaci, která bude vykreslovat podobné obrázky:

Pokud vás zajímá algoritmus zpracování obrazu za tímto obrázkem, nazývá se primitivní Michael Fogleman a můžete si také koupit aplikaci Mac, kterou zde vytvořil.

Vezmeme tento algoritmus a postavíme kolem něj mobilní aplikaci, kde je algoritmus původně napsán v Go.

A takto to bude vypadat živě (video je rychlé):

Jelikož je základní algoritmus nativní a vestavěný v Go, budeme jej používat tak, jak jsou. Abychom ale vyjasnili, pokud bychom museli vytvořit tento algoritmus nebo jakýkoli jiný algoritmus nebo část infrastruktury, která musí být nativní, a my jsme již neměli existující kódovou základnu, museli jsme se těžko rozhodnout:

  • Sestavte jej dvakrát v jazyce Java a Obj-C.
  • Jednou v C / C ++.
  • Jednou za sebou.

Ve skutečnosti pro tento konkrétní případ použití a algoritmus zatrhneme ještě více položek ze seznamu „proč jít nativně“ výše:

  1. Výkon. Go bude vykazovat lepší výkon než Javascript (uvidíme o kolik později). Potřebujeme to tady, protože primitivní je náročný algoritmus založený na CPU. Ve skutečnosti je to tak náročné, že je zpracování těchto obrázků na silném iPhone pomalé. Jděte sem blíže ke kovu a je dobré ho místo Javascriptu použít.
  2. Používání knihovny, která na npm neexistuje. A tentokrát, protože se jedná o nový algoritmus implementovaný v Go a není tam žádný port, kde by jinde, byl jsem rád, že Go on mobile (a později jsem ho nechal pracovat na React Native) funguje tak dobře.
  3. Zmatek. V tomto případě je cílová knihovna Go, kterou používáme, otevřeným zdrojovým kódem. Pokud tomu tak nebylo, a vy jste se starali o svoji IP, nikdo nemohl tento algoritmus zpětně analyzovat, aniž by investoval nepřiměřené množství času.
  4. Nativní přístup k API. Tento algoritmus může ukládat průběžné snímky na disk při každé iteraci. Pokud by to měl být Javascript, museli bychom každý snímek zakódovat a odeslat jako velký řetězec base64 přes most React Native.

A samozřejmě můžeme použít stejný nativní kód pro Android i iOS.

Go Mobile Toolchain

Pokud již víte, že jde o jazyk Go, bude to pěkný svěží vánek. Pokud ne, seznamte se s prohlídkou Go.

Poté, co jste to udělali, nainstalujte a procvičte si gomobilní nástrojovou sadu (předpokládám, že jste nainstalovali Go a mezitím jste s tím mohli udělat jednoduchý „ahoj svět“):

$ npm install -g ios-nasadit
$ go get golang.org/x/mobile/cmd/gomobile
$ gomobile init # může to trvat několik minut
$ gomobile build -target = ios golang.org/x/mobile/example/basic
$ ios-deploy -b basic.app

Pokud všechno fungovalo dobře, měla by se v simulátoru zobrazit mobilní aplikace. To, co tato mobilní sada nástrojů udělala, je vytvoření nativní knihovny iOS, vygenerování aplikace pro kostry, propojení těchto odkazů a zabalení aplikace. Všechno se to stalo tiše (nebo pokorně?), To je součást filozofie Go: úspěch by měl být tichý; jinými slovy - žádná zpráva není dobrá zpráva.

Doporučuji, abyste si přečetli krátký článek Wiki. Získat správný kontext o těchto nástrojích.

Připojení React Native a Go Mobile

Začneme vytvořením nové aplikace React Native a zde si vezmeme příklad reakce-nativní kamery. Je to pohodlný způsob, jak se dostat k bodu tohoto článku, ale možná budete chtít vytvořit svůj vlastní od nuly.

Chceme nyní vytvořit naši nativní knihovnu Go a začít jejím připojením k naší aplikaci pro iOS. To je místo, kde by to mohlo být složitější, protože musíme myslet na náš pracovní postup před vším ostatním.

V Go je nejlepší udělat, když si ve svém GOPATHu vytvoříte svůj Go kód, což je místo, kde se váš Go kód a knihovny třetích stran živí (je to solidní logika, ale je mimo rozsah tohoto článku) . A tak naším prvním rozhodnutím je dát tam také naši nativní knihovnu - a ne vedle naší aplikace.

Jednou pěkným bonusem je, že náš nový balíček Go nevědí o tom, že jej použijeme na mobilním zařízení. Ve skutečnosti na něm můžete pohodlně pracovat jako samostatná aplikace Go, a až budete připraveni, můžete se rozhodnout svázat ji s mobilní aplikací.

Pro mě to tady žije (vaše bude jiné):

 /workspaces/golang/src/github.com/jondot/primer-bind

Rozložení je jednoduché:

Tree strom vázající primer.
.
└── primer
    └── prime.go

1 adresář, 1 soubor

Pojďme se podívat na náš Go kód:

Rychlý průchod ukazuje, že exportujeme OnIterationDone, což je rozhraní typu zpětného volání, které použijeme z každé nativní strany a procesu, který je vstupním bodem našeho algoritmu. Co se týče typů dovnitř a ven, není nic zvláštního; go se stará o generování kódu pro jejich zařazení do příslušných mobilních platforem.

Pro Process jsem převzal kód CLI z primitivního a napadl ho, takže by to byla funkce, kterou mohu exportovat. Rovněž exportujeme Bench a JsonDummy pro naši srovnávací showcase.

Uvidíte, že v každém kroku v tomto článku podniknu nejmenší možný krok ke strategickému vytvoření kódu, o kterém můžeme diskutovat bez přílišného kontextu.

Jakmile to bude na místě, musíme přepnout kontext a cd do naší aplikace. Nyní chceme využít nástrojovou sadu gomobile, takže spustíme toto:

gomobilní vazba -x -v -target = ios github.com/jondot/primer-bind/primer

Vygeneruje pro vás nativní knihovnu a při tom vyplivne mnoho podrobností, protože používáme -x -v; ale můžete je vypustit, pokud chcete. Můžete vidět krásu zacházení s každým Go kódem jako s balíčkem: dodáme cestu, která je jak repo, tak lokální cestou ve vašem GOPATH, pokud nemáte lokální kopii, Go ji načte a sestaví pomocí, nebo to nechte tak, jak je, a vezme to můj balíček a zkompiluje ho, abyste nemuseli.

Dále budeme muset postavit most v našem rodném kódu, abychom vše spojili dohromady.

Tady vytváříme RCTEventEmitter, protože chceme dostávat upozornění, kde nativní algoritmus Go dokončuje svou práci. Strukturu OnIterationDone také zabalíme do hezčího rozhraní Obj-C. Pro místa, kde sedí záhlaví, to koreluje s naším balíčkem Go (vybrali jsme primer).

Pozorování: Takto byste vytvořili nativní modul bez ohledu na Go. Chceme mít na nativní straně asynchronní funkci, která získá proměnné, jako je počet iterací, velikost, režim a počet pracovníků a zpětné volání, předáme je naší procesní funkci, zde nazývané GoPrimerProcess, která se pro nás automaticky generuje, opět koreluje s názvem balíčku a názvem funkce, předponou „Go“.

To je v podstatě to. Část Javascript se nyní spustí a my to uděláme jako každé jiné nativní lepidlo modulu:

Android

Pro Android to bude ještě snazší, protože máme podporu pro Android Studio prostřednictvím pluginu Gradle. Pamatujte, že na stejném místě máme stále stejnou implementaci Go balíčku, nedotčenou. Toto umístění musíme určit v Gradle a propojit nativní most Android v Javě.

To by byly stejné kroky jako v jakékoli aplikaci pro Android a Go. Pro více informací se můžete podívat na referenční projekt a zde.

Jako každý nativní komponent Android v React Native máme i náš modul, který obsahuje zajímavé bity a balíček, který dává React Native pokyn k vložení našeho modulu.

Nyní náš kód mostu. Část modulu:

A část balíčku:

Náš kód modulu Java ukazuje, že balíček Go se magicky objevuje v go.primer a pod pseudo-objektem nazvaným Primer (jak pohodlné!). Všimněte si, že gomobile pro vás vygeneruje Go stránku a je to idiomaticky to jako skutečný Java modul.

Tím je dokončena velká prohlídka: Go, iOS (most), Javascript (lepidlo) a Android (most).

Velká prohlídka

Toto bylo turné po čtyřech jazycích, instalatérské práce: V Go jsme zapojili skutečný Go modul, abychom vytvořili funkci, kterou můžeme exportovat čistě. V systému iOS jsme vytvořili nativní modul a přemostili jej do nativní knihovny, která se neliší od žádné jiné knihovny C. V Javascriptu jsme zapojili nativní část do kódu na straně aplikace, který není na rozdíl od všeho, co bychom udělali pro normální nativní modul. Uzavřením jsme v systému Android připravili pěknou konfiguraci sestavení a jednoduchý nativní modulový most.

Většina těchto investic do instalatérských prací by byla stejná, kdybychom měli stavět jakýkoli nativní modul. Rozdíl je v tom, že nyní máme jediného nativního kodexu založeného na Go, s nímž budeme pracovat - a z dlouhodobého hlediska to ušetří spoustu času, protože nemusíme udržovat stejné paralelní kódové základny pro Android a iOS.

Otázka výkonu

Jak funguje náš kód v Javascriptu ve srovnání s Go? Provedeme hloupé měřítko, které je pravděpodobně zavádějící pro jakékoli rozhodnutí v reálném životě, takže to neberte jako fakt a můžete to vyzkoušet naživo v PrimerApp. TL; DR je, že Go je dvakrát rychlejší než Javascript pro toto a toto měřítko.

Závěr

Přejít s React Native je zápas vytvořený v nebi pro následující scénáře:

  • Jste nadšeni z Go nebo již v Go máte existující kód, nebo chcete sdílet backový Go kód s vaší mobilní aplikací. Konkrétně za to máte také GopherJS, který funguje výjimečně dobře.
  • Potřebujete výkonnostní rozpětí.
  • Chcete infrastrukturní robustnost a bezpečnostní hodnoty typu Go.
  • Chcete, aby proprietární kód zůstal v bezpečí.
  • Nechcete vyjádřit nápady v objektech C-Swift a Java.

Určitě existuje více motivace k tomu, aby odpovídala Go with React Native, ale věřím, že tento malý seznam byl tím, s čím se každodenně setkáte. Doufám, že se vám tato fúze technologií líbila a že se vám podaří postavit něco zajímavého s nápady, které jsem vám zde ukázal.

Referenční aplikaci najdete zde a modul Go zde.

Také jsem nadšený tím, že odstraním duplicitu nativního kódu. Pokud potřebujete pomoc s tímto krokem, napište mi řádek na dotan@paracode.com.

Hacker Poledne je to, jak hackeři začínají odpoledne. Jsme součástí rodiny @AMI. Nyní přijímáme příspěvky a rádi diskutujeme o reklamních a sponzorských příležitostech.
Pokud jste si tento příběh užili, doporučujeme si přečíst naše nejnovější technické příběhy a trendy technologických příběhů. Až příště nepřijímejte realitu světa jako samozřejmost!