
Viena koda bāze, divas lietotnes: kā veidot white-label bez forkošanas
GeekBye un Pavleur ir divas atšķirīgi zīmolotas darbvirsmas lietotnes, kas būvētas no viena repozitorija — bez forka, bez dublētas koda bāzes. Lūk, būvēšanas laika mehānisms, kas ļauj vienai koda bāzei nokompilēties divos produktos, un vienas rindas kļūda, kuras dēļ mūsu otrā lietotne stādījās priekšā ar nepareizu vārdu.
GeekBye ir sanāksmju pierakstu rīks. Pavleur ir AI interviju prakses lietotne. Tās izskatās pēc diviem dažādiem produktiem, jo tās ir divi dažādi produkti — bet tās ir būvētas no vienas koda bāzes, bez forka un bez zara, kas pamazām attālinās. Šī ir white-label inženierijas puse: nevis "kāpēc pārdot zīmolotu lietotni" (tas ir cits ieraksts), bet kā tu patiesībā nokompilē vienu repozitoriju divās lietotnēs — un tā neglamūrā kļūda, kas slēpjas katrā white-label sistēmā, līdz tu sāc to meklēt.
Ģenerē, nevis zaro
Nepareizais veids, kā darbināt divus produktus no vienas koda bāzes, ir izkaisīt if (product === 'pavleur') pa visu lietotni vai forkot un lūgties, lai abas kopijas nekad neizšķirtos. Abi varianti ātri sapūst.
GeekBye pieeja ir būvēšanas laika koda ģenerēšana. Katram produktam ir konfigurācijas fails — configs/geekbye/config.ts, configs/pavleur/config.ts — kurā glabājas tā identitāte: nosaukums, bundle id, URL protokols, laidienu repozitorijs automātiskajiem atjauninājumiem un tā tālāk. Pirms būvēšanas tiek palaists viens skripts:
node scripts/build-product.js pavleur
Šis skripts nolasa izvēlētā produkta konfigurāciju un izdara trīs konkrētas lietas:
- Ģenerē divus konfigurācijas moduļus — vienu renderētājam (
src/config/product.ts), vienu galvenajam procesam (electron/config/product.ts) — katru ar "DO NOT EDIT MANUALLY — changes will be overwritten" galveni. Pārējā lietotne vienkārši importēproductName,applicationIdunprotocolno konfigurācijas un nekad nedomā par to, kurš zīmols tā ir. - Kopē tikai attiecīgā zīmola resursus — ikonas, mazo logotipu, paziņojumu ikonu. GeekBye būvējums fiziski nesatur nevienu Pavleur grafikas failu un otrādi. Nav kam noplūst.
- Pārraksta
package.json(laidiena būvējumos) — lietotnes id, produkta nosaukumu, URL protokolu, GitHub laidienu repozitoriju, kurā publicēt, un — jauki — zīmoloto mikrofona atļaujas tekstu, lai macOS jautātu "Pavleur vēlas piekļūt mikrofonam", nevis nepareizo zīmolu.
Visa lietotne ir zīmolneitrāla; zīmols tiek injicēts būvēšanas laikā. Nav izpildlaika produkta pārslēdzēja, ko sajaukt, jo izpildlaikā vienmēr ir iecepts tikai viens produkts.
Viens backend, divi zīmoli
Abas lietotnes sarunājas ar vienu un to pašu backend. Kā tad serveris zina, kuram produktam — un kurai cenu politikai, uzvednēm un limitiem — pieprasījums pieder?
Divi signāli, abi iestatīti būvēšanas laikā. Pirmkārt, application id (geekbye vai pavleur), iecepts konfigurācijā un sūtīts līdzi pieprasījumiem, lai backend varētu maršrutēt uz pareizā produkta uzvedību. Otrkārt, User-Agent, ko klients pievieno katram backend izsaukumam, formā Product/version (platform) — piemēram, Pavleur/1.2.5 (win32) vai GeekBye/1.7.3 (darwin). Šī viena galvene par brīvu dod backend attiecinājumu gan pa produktiem, gan pa operētājsistēmām, bez atsevišķa analītikas lauka. Automātiskie atjauninājumi tikmēr paliek izolēti: katrs produkts publicē savā laidienu repozitorijā, tāpēc GeekBye atjauninājums nekad nevar tikt pasniegts Pavleur instalācijai.
Arī ievadapmācība katram produktam atšķiras — GeekBye vednis ir par sanāksmju transkripciju, Pavleur — par interviju praksi — un pareizais tiek izvēlēts izpildlaikā pēc tā viena ieceptā application id. Viens mehānisms, divas parādes durvis.
Kļūda: kad Pavleur sauca sevi par GeekBye
Lūk, kara stāsts, un tieši šai kļūdai sava versija ir katrā white-label sistēmā.
Konfigurācijas ģenerēšana strādāja. Ikonas mainījās. Mikrofona uzvedne bija zīmolota. Protokoli un bundle id bija pareizi. Pēc visiem redzamajiem mērījumiem Pavleur būvējums bija Pavleur. Un tomēr kādu laiku katrs Pavleur būvējums zvanīja mājās uz backend, saukdams sevi par GeekBye.
Vaininieks bija viena vienīga hardkodēta virkne, un tā slēpās visneglamūrākajā iedomājamā vietā: User-Agent būvētājā, iebāztā tīkla retry palīgā. Viss lietotājam redzamais bija izvadīts caur konfigurāciju, bet šai vienai dziļās santehnikas utilītai iekšā joprojām bija literālis `GeekBye/${version}`. Neviens nedomā par retry utilītu kā par "zīmolvedību", tāpēc neviens to nebija pārbaudījis. Labojums bija četras rindas — importēt dinamisko productName no konfigurācijas un interpolēt to hardkodētā zīmola vietā — bet mācība ir visa būtība:
White-label nav "vai logotips nomainījās". Tas ir "vai katra identitātes virkne iet caur konfigurāciju." Un pēdējie izturētāji nekad nedzīvo UI, kur tu skatītos. Tie dzīvo User-Agent, dziļo saišu protokola apstrādātājā, atļauju uzvedņu tekstos, kļūdu ziņojumos — santehnikā, ko neviens neklasificē kā "zīmolu". Vienīgā uzticamā aizsardzība ir izturēties pret zīmola literāli kā pret kaut ko, ko aktīvi medī: izgrepot koda bāzē hardkodēto nosaukumu un gāzt būvējumu, ja tas parādās jebkur ārpus konfigurācijas, kurai to paredzēts definēt.
Trīs lietas, ko mums iemācīja white-label
- Ģenerē, nevis zaro. Divu sīku konfigurācijas moduļu būvēšanas laika ģenerēšana plus selektīva resursu kopēšana pārspēj gan forkošanu, gan izpildlaika produkta pārbaužu biezokni. Lietotne paliek zīmolneitrāla; zīmols ir būvēšanas ievade.
- Identitātes virknes noplūst santehnikā. UI ir vieglie 90%. Grūtie 10% ir User-Agent, URL protokols, mikrofona atļaujas virkne, kļūdu teksti. Izvadi tos visus caur vienu
productName/applicationIdeksportu — un grepo pēc neapstrādātā zīmola nosaukuma kā CI vārtiem, lai noklīdis literālis nekad nenonāktu laidienā. - Viens backend, daudzi zīmoli, atšķir pēc id un galvenes. Būvēšanas laika application id plus
Product/version (platform)User-Agent dod attiecinājumu pa produktiem un platformām ar nulli dublētas infrastruktūras — tīri nodalot nemainīgo būvēšanas laika identitāti no izpildlaika uzvedības.
Par produkta un privātuma pusi, kā darbināt white-label pierakstu rīku zem sava zīmola, skati white-label AI pierakstu rīku. Šī ir sestā nodaļa v1 stāstā, kas kļūst par GeekBye v2 — iepriekšējai nodaļai skati kas patiesībā ir 127 komitu laidiens (v1.7.0); un visai lokai — programmatūras piegādes līdz pilnībai anatomija.