എല്ലാ ഡെവലപ്പർമാരുടെയും കയ്യിൽ ആ ഒരു ഫോൾഡർ ഉണ്ടാകും. ഒരു റെപ്പോസിറ്ററിയിൽ നിന്ന് മറ്റൊന്നിലേക്ക് കോപ്പി ചെയ്യുന്ന utils അല്ലെങ്കിൽ helpers എന്ന പേരുള്ള ആ ഫോൾഡർ. അത് പേസ്റ്റ് ചെയ്ത ശേഷം, പഴയ ഡാറ്റാബേസ് സ്കീമകളുമായുള്ള റഫറൻസുകൾ ഡിലീറ്റ് ചെയ്യാനും, ബാധകമല്ലാത്ത ഓത്ത് (auth) ചെക്കുകൾ നീക്കം ചെയ്യാനും, പുതിയ ലിന്റർ (linter) എററുകൾ ഒഴിവാക്കാൻ വേരിയബിളുകൾ റീനാം ചെയ്യാനും ഇരുപത് മിനിറ്റ് ചിലവാകും. ഞാൻ എന്റെ Dynamic Theme Kit എന്ന തീമിംഗ് സിസ്റ്റവുമായി ഇത് ചെയ്തിരുന്നു. ഒരു ആപ്ലിക്കേഷനുള്ളിലെ ഒരു ഫീച്ചറായി തുടങ്ങിയതായിരുന്നു അത്, മാസങ്ങളോളം ഞാൻ അതിനെ ഒരു പോർട്ടബിൾ ടൂൾ പോലെയാണ് കണ്ടത്. ഞാൻ തെറ്റാണ് ചെയ്തത്. കോഡ് കോപ്പി ചെയ്യുന്നത് പുനരുപയോഗം (reuse) അല്ല. അത് കൂടുതൽ ഘട്ടങ്ങളുള്ള ഡ്യൂപ്ലിക്കേഷൻ (duplication) മാത്രമാണ്.
ഒറ്റ പ്രോജക്റ്റിൽ മാത്രം ഒതുങ്ങുന്ന ചിന്താഗതിയുടെ കെണി
ഒരു പ്രോജക്റ്റിനുള്ളിൽ നിങ്ങൾ ഒരു ഫീച്ചർ നിർമ്മിക്കുമ്പോൾ, നൂറുകണക്കിന് അദൃശ്യമായ അനുമാനങ്ങൾ (assumptions) നിങ്ങൾ നടത്തുന്നുണ്ട്. കളർ പാലറ്റ് ഒരു പ്രത്യേക CSS-in-JS സെറ്റപ്പിനെ ആശ്രയിച്ചേക്കാം. സ്പേസിംഗ് സ്കെയിൽ നിങ്ങളുടെ കമ്പനിയുടെ ബ്രാൻഡ് ഗൈഡിലെ ഒരു ഡിസൈൻ ടോക്കനെ (design token) റഫർ ചെയ്തേക്കാം. ലൈറ്റ്, ഡാർക്ക് മോഡുകൾക്കിടയിലുള്ള മാറ്റം ആ ആപ്പിന്റെ ബാക്കെൻഡിന് മാത്രമുള്ള ഒരു യൂസർ പ്രിഫറൻസ് എൻഡ്പോയിന്റിനെ വിളിച്ചേക്കാം. പ്രോജക്റ്റിനുള്ളിൽ ഇരിക്കുമ്പോൾ ഈ ഡിപെൻഡൻസികൾ (dependencies) നിരുപദ്രവകാരികളായി തോന്നും. അവ അവിടെ ഉണ്ടാകേണ്ടവയാണ്.
ആ കോഡ് പുറത്തെടുക്കാൻ ശ്രമിക്കുമ്പോഴാണ് പ്രശ്നം തുടങ്ങുന്നത്. ആ "പുനരുപയോഗിക്കാവുന്ന" (reusable) കമ്പോണന്റ് യഥാർത്ഥത്തിൽ ആ കോഡ്ബേസുമായി ബന്ധിപ്പിക്കപ്പെട്ട ഒട്ടനവധി രഹസ്യമായ സ്ട്രിംഗുകളുടെ (strings) ഒരു വലയാണെന്ന് നിങ്ങൾ തിരിച്ചറിയും. ഞാൻ ഇത് DTK-ലൂടെ പഠിച്ചു. അത് തീം വേരിയബിളുകൾ നിർമ്മിച്ചു നൽകുന്നുണ്ടായിരുന്നു, ശരിയാണ്. എന്നാൽ അത് ഒരു പ്രത്യേക ഫോൾഡർ സ്ട്രക്ചറും പ്രതീക്ഷിച്ചിരുന്നു. ഒറിജിനൽ ആപ്പിന്റെ ടൈപ്പ്സ് ഡയറക്ടറിയിലെ ഒരു ടൈപ്പ് ഡെഫനിഷൻ അത് ഇംപോർട്ട് ചെയ്തിരുന്നു. ആ റെപ്പോസിറ്ററിയിൽ മാത്രം നിലവിലുള്ള ഒരു ഗ്ലോബൽ കോൺഫിഗ് ഒബ്ജക്റ്റിന്റെ സാന്നിധ്യം അത് അനുമാനിച്ചിരുന്നു. പ്രോജക്റ്റിനുള്ളിൽ എല്ലാം കൃത്യമായി ഉണ്ടായിരുന്നതുകൊണ്ട് ഞാൻ ഇത് ഒരിക്കലും ശ്രദ്ധിച്ചിരുന്നില്ല.
DTK-യെ ഒരു സ്റ്റാൻഡ്ലോൺ പാക്കേജായി (standalone package) മാറ്റുക എന്നത് വിപുലീകരണമല്ല, മറിച്ച് ഒരു ശസ്ത്രക്രിയ പോലെയായിരുന്നു. എനിക്ക് കൂടുതൽ ഫീച്ചറുകൾ ആവശ്യമില്ലായിരുന്നു. എനിക്ക് കുറഞ്ഞ കണക്ഷനുകൾ മാത്രമാണ് വേണ്ടിയിരുന്നത്.
Dynamic Theme Kit വേർതിരിച്ചെടുക്കുന്നു
ഏറ്റവും കഠിനമായ ജോലി കോഡ്ബേസുമായി ഇരുന്നുകൊണ്ട് ഓരോ ഫങ്ക്ഷനും ഓരോ എക്സ്പോർട്ടിനും (export) സ്വയം ചോദിക്കുക എന്നതായിരുന്നു: ഇത് തീമിംഗ് ലോജിക്കിന് വേണ്ടിയാണോ, അതോ പ്രോജക്റ്റിന് വേണ്ടിയാണോ? ഞാൻ സ്റ്റൈലിംഗ് പ്രീസെറ്റുകൾ (styling presets) നീക്കം ചെയ്തു. കൺസ്യൂമർ ഒരു React ആപ്ലിക്കേഷനായിരിക്കണം എന്ന അനുമാനം ഞാൻ ഒഴിവാക്കി. ഡിഫോൾട്ട് കളർ പാലറ്റുകൾ പൂർണ്ണമായും ഡിലീറ്റ് ചെയ്തു. ഒറിജിനൽ പ്രോജക്റ്റിൽ ഡിഫോൾട്ട് ആയി ഒരു നേവി-ആൻഡ്-സ്ലേറ്റ് കോർപ്പറേറ്റ് സൗന്ദര്യശാസ്ത്രം (aesthetic) ഉണ്ടായിരുന്നു. അത് ഒഴിവാക്കേണ്ടതായിരുന്നു. ഒരു പാക്കേജിന് നിങ്ങളുടെ ബ്രാൻഡ് നിറങ്ങൾ നൽകാൻ കഴിയില്ല.
പുതിയ കിറ്റ് കൃത്യമായി ഒരു കാര്യം മാത്രമേ ചെയ്യൂ. അത് ഒരു കോൺഫിഗറേഷൻ ഒബ്ജക്റ്റ് സ്വീകരിക്കുന്നു—ചില കളർ വാല്യൂസ്, ചില സ്പേസിംഗ് നമ്പറുകൾ, ചില ടൈപ്പോഗ്രാഫി സ്കെയിലുകൾ—അത് CSS കസ്റ്റം പ്രോപ്പർട്ടികൾ (CSS custom properties) നിർമ്മിക്കുന്നു. അത്രമാത്രം. അത് അവ പ്രയോഗിക്കുന്നില്ല. അവ നിങ്ങളുടെ DOM-ൽ എവിടെ പോകണമെന്ന് അത് തീരുമാനിക്കുന്നില്ല. നിങ്ങൾ Tailwind, Styled Components അല്ലെങ്കിൽ പ്ലെയിൻ HTML ഉപയോഗിക്കുന്നുണ്ടോ എന്നതിനെക്കുറിച്ച് അതിന് ആശങ്കയില്ല. അത് നിങ്ങളുടെ ആപ്ലിക്കേഷന് വേരിയബിളുകൾ നൽകുന്നു, നിങ്ങളുടെ പ്രോജക്റ്റ് അവ എങ്ങനെ ഉപയോഗിക്കണമെന്ന് തീരുമാനിക്കുന്നു.
ആ നിയന്ത്രണം ആദ്യം പരിമിതപ്പെടുത്തുന്നതായി തോന്നി. എന്നാൽ പിന്നീട് അത് വലിയൊരു സ്വാതന്ത്ര്യമായി മാറി.
യഥാർത്ഥത്തിൽ പുനരുപയോഗിക്കാൻ ശ്രമിക്കുമ്പോൾ എന്താണ് തകരാറിലാകുന്നത്?
ഞാൻ ഒന്നും പ്രസിദ്ധീകരിക്കുന്നതിന് മുമ്പ്, ഈ അബ്സ്ട്രാക്ഷൻ (abstraction) ശരിയാണെന്ന് തെളിയിക്കേണ്ടതായിരുന്നു. എന്റെ ആർക്കൈവിൽ നിന്ന് മൂന്ന് ചെറിയ പേഴ്സണൽ പ്രോജക്റ്റുകൾ ഞാൻ എടുത്തു: ഒരു മാർക്ക്ഡൗൺ പ്രിവ്യൂ ടൂൾ (markdown preview tool), ഒരു ഹാബിറ്റ് ട്രാക്കർ (habit tracker), ഒരു ഇവന്റിനായുള്ള ലാൻഡിംഗ് പേജ്. അവയിൽ ഒന്നിനും ഒരേ ഫ്രെയിംവർക്കോ ഫോൾഡർ സ്ട്രക്ചറോ ഉണ്ടായിരുന്നില്ല. ഞാൻ ഓരോന്നിലും DTK ലോക്കലായി ഇൻസ്റ്റാൾ ചെയ്യുകയും അവ തീം ചെയ്യാൻ ശ്രമിക്കുകയും ചെയ്തു.
ആദ്യ ശ്രമം ഉടൻ തന്നെ പരാജയപ്പെട്ടു. DTK നിർമ്മിച്ച വേരിയബിൾ പേരുകൾ വളരെ സ്പെസിഫിക് ആയിരുന്നു. --primary-action, --background-overlay തുടങ്ങിയ ടോക്കണുകൾ അത് ഔട്ട്പുട്ട് ചെയ്യുന്നുണ്ടായിരുന്നു, ഇത് ഒരു പ്രത്യേക UI ലേഔട്ടിനെ സൂചിപ്പിക്കുന്നു. മാർക്ക്ഡൗൺ പ്രിവ്യൂവറിൽ ആ പേരുകൾക്ക് അർത്ഥമില്ലായിരുന്നു. അവിടെ ഒരു ആക്ഷൻ ബട്ടണോ ഓവർലേയോ ഇല്ലായിരുന്നു. വിഡ്ജറ്റിനെ (widget) വിവരിക്കുന്നതിന് പകരം മൂല്യത്തെ (value) വിവരിക്കുന്ന രീതിയിൽ നിഷ്പക്ഷവും ഘടനാപരവുമായ (neutral, structural) പേരുകൾ നൽകാൻ ഞാൻ ജനറേഷൻ ലോജിക് മാറ്റി.
എന്റെ ഡിഫോൾട്ട് വാല്യൂസ് വളരെ അഗ്രസീവ് ആണെന്നും ഞാൻ കണ്ടെത്തി. ഒരു ഉപയോക്താവ് അപൂർണ്ണമായ ഒരു കോൺഫിഗ് നൽകിയാൽ, ഡാഷ്ബോർഡുകളിൽ നന്നായി തോന്നുന്ന വാല്യൂസ് ഉപയോഗിച്ച് DTK ആ വിടവുകൾ നികത്തും, എന്നാൽ ലാൻഡിംഗ് പേജുകളിൽ അത് പ്രശ്നമുണ്ടാക്കും. വിട്ടുപോയ ടോക്കണുകൾ റെൻഡർ ചെയ്യാതിരിക്കുന്ന രീതിയിലുള്ള 'ട്രാൻസ്പരന്റ് ഡിഫോൾട്ടുകളിലേക്ക്' (transparent defaults) ഞാൻ മാറി, അങ്ങനെ ഉപയോഗിക്കുന്ന പ്രോജക്റ്റിന് സ്വന്തം ഫോളബാക്കുകൾ (fallbacks) തീരുമാനിക്കാൻ കഴിഞ്ഞു.
പിന്നെ ഡോക്യുമെന്റേഷനും (documentation) ഉണ്ടായിരുന്നു. എനിക്ക് വളരെ ലളിതമായി തോന്നിയ കാര്യം—"വെറുതെ ഒരു കോൺഫിഗറേഷൻ ഒബ്ജക്റ്റ് പാസ് ചെയ്യുക"—അർദ്ധരാത്രിയിൽ README വായിക്കുന്ന ഒരാൾക്ക് അവ്യക്തമായി തോന്നും. യഥാർത്ഥ ഒബ്ജക്റ്റുകൾ, യഥാർത്ഥ ഫയൽ പാത്തുകൾ, ഫങ്ക്ഷൻ വിളിക്കുമ്പോൾ എന്ത് സംഭവിക്കുന്നു എന്നും അതിനുശേഷം നിങ്ങളുടെ ആപ്ലിക്കേഷൻ എന്താണ് ചെയ്യേണ്ടത് എന്നതിനെക്കുറിച്ചുള്ള വ്യക്തമായ വിശദീകരണങ്ങൾ എന്നിവ ഉൾപ്പെടുത്തി ഞാൻ അത് വീണ്ടും എഴുതി.
ഈ ചെറിയ പേഴ്സണൽ പ്രോജക്റ്റുകൾ ടെസ്റ്റ് ബെഡുകളായി പ്രവർത്തിച്ചു. അവയിൽ വലിയ റിസ്കുകൾ ഇല്ലായിരുന്നു, എങ്കിലും സോഴ്സ് കോഡ് മാത്രം നോക്കി ഇരുന്നാൽ കണ്ടെത്താൻ കഴിയാത്ത യഥാർത്ഥ പോരായ്മകൾ അവ വെളിപ്പെടുത്തി.
യഥാർത്ഥ പരീക്ഷണം: Web Weavers World-ലെ പ്രൊഡക്ഷൻ
വ്യക്തിഗത പ്രോജക്റ്റുകൾ പരീക്ഷണശാലകൾ പോലെയാണ്. അവയ്ക്ക് സമയപരിധികളോ, സ്റ്റേക്ക്ഹോൾഡർമാരോ, അല്ലെങ്കിൽ നിങ്ങളുടെ പാക്കേജിന് മുൻപേയുള്ള പഴയ CSS-ഓ ഇല്ല. എന്റെ ബിസിനസ് സൈറ്റായ Web Weavers World-ലേക്ക് ഞാൻ DTK സംയോജിപ്പിച്ചപ്പോഴാണ് യഥാർത്ഥ പരീക്ഷണം ഉണ്ടായത്. നിലവിലുള്ള സ്റ്റൈലുകളും, ക്ലയന്റിന്റെ പ്രതീക്ഷകളും, വിശകലനങ്ങളും (analytics) പരിഗണിക്കേണ്ട ഒരു ലൈവ് പ്രോപ്പർട്ടി ആയിരുന്നു ഇത്. പാക്കേജ് എന്തെങ്കിലും തകരാറിലാക്കിയാൽ, എനിക്ക് വെറുതെ റെപ്പോസിറ്ററി (repo) ഡിലീറ്റ് ചെയ്ത് പുതിയൊന്ന് തുടങ്ങാൻ കഴിയില്ലായിരുന്നു.
ഞാൻ DTK ബിൽഡ് പൈപ്പ്ലൈനിൽ (build pipeline) ചേർക്കുകയും, പുതിയൊരു കളർ കോൺഫിഗറേഷനിലേക്ക് അതിനെ തിരിച്ചുവിടുകയും, പുതിയൊരു കൂട്ടം CSS വേരിയബിളുകൾ നിർമ്മിക്കാൻ അതിനെ അനുവദിക്കുകയും ചെയ്തു. ഈ സംയോജനത്തിന് ഒരു ആഫ്റ്റർനൂൺ മാത്രമേ എടുത്തുള്ളൂ, ഒരാഴ്ചയല്ല. അതായിരുന്നു ആ സൂചന. മുമ്പ്, ഒരു പുതിയ തീം ചേർക്കുക എന്നാൽ പുതിയ CSS എഴുതുക, ഇരുപതോളം ഫയലുകളിൽ ഹാർഡ്കോഡ് ചെയ്ത ഹെക്സ് (hex) വാല്യൂകൾ തിരയുക, ഒരു എഡ്ജ് കേസ് (edge case) പോലും വിട്ടുപോയിട്ടില്ലെന്ന് പ്രത്യാശിക്കുക എന്നതൊക്കെയായിരുന്നു. ഇപ്പോൾ ഞാൻ കോൺഫിഗറേഷൻ ഫയലിൽ ഒരു പാലറ്റ് (palette) ചേർക്കുന്നു, DTK വേരിയബിളുകൾ നിർമ്മിക്കുന്നു, സൈറ്റിന്റെ ബാക്കി ഭാഗങ്ങൾ അവ ഉപയോഗിക്കുന്നു. തീം ലോജിക് എന്നത് വളരെ ദുർബലമായ ഒരു മാനുവൽ പ്രക്രിയയിൽ നിന്നും സഹപ്രവർത്തകർക്ക് (collaborators) കൈമാറാൻ പാകത്തിൽ ഞാൻ വിശ്വസിക്കുന്ന ഒന്നായി മാറി.
ഞാൻ നിർമ്മാണം നടത്തുന്ന രീതി മാറ്റിയ മൂന്ന് ചോദ്യങ്ങൾ
ഈ പ്രക്രിയയിലൂടെ കടന്നുപോയപ്പോൾ, എന്തെങ്കിലും അബ്സ്ട്രാക്റ്റ് (abstract) ചെയ്യുന്നതിന് മുമ്പ് ഞാൻ ഉപയോഗിക്കുന്ന ഒരു മാനസിക ചെക്ക്ലിസ്റ്റ് തയ്യാറാക്കാൻ എനിക്ക് നിർബന്ധിതമായി:
- ഈ വേരിയബിൾ ശരിക്കും ജനറിക് (generic) ആണോ? പേരോ ലോജിക്കോ യഥാർത്ഥ പ്രോജക്റ്റിലെ ഒരു ഡൊമെയ്ൻ കൺസെപ്റ്റിനെ (domain concept) സൂചിപ്പിക്കുന്നുണ്ടെങ്കിൽ, അത് അവിടെത്തന്നെ വിടണം.
- ഇത് പാക്കേജിലാണോ അതോ ആപ്ലിക്കേഷനിലാണോ വേണ്ടത്? ബിസിനസ് നിയമങ്ങളും, ബ്രാൻഡ് ഐഡന്റിറ്റികളും, ലേഔട്ട് അനുമാനങ്ങളും ആപ്പിലാണ് ഇരിക്കേണ്ടത്. സ്റ്റാൻഡേർഡൈസ്ഡ് ഔട്ട്പുട്ട് നൽകുന്ന അടിസ്ഥാന ഘടന (plumbing) പാക്കേജിലാണ് ഇരിക്കേണ്ടത്.
- ഞാൻ പരിഹരിക്കുന്നത് വീണ്ടും ഉപയോഗിക്കാൻ കഴിയുന്ന ഒരു പ്രശ്നമാണോ അതോ ഒരു പ്രോജക്റ്റിന് മാത്രമുള്ളതാണോ? ഇതിന് സത്യസന്ധമായി ഉത്തരം നൽകുക എന്നതാണ് ഏറ്റവും പ്രയാസം. നമ്മുടെ പരിഹാരങ്ങൾ സാർവത്രികമാണെന്ന് (universal) കരുതാൻ നമ്മൾ ആഗ്രഹിക്കുന്നു. എന്നാൽ സാധാരണയായി അവ പ്രാദേശികം (local) മാത്രമാണ്.
ഈ ചോദ്യങ്ങൾക്ക് ഉത്തരം നൽകിയത് എന്റെ ഡിസൈൻ ലളിതമാക്കാൻ എന്നെ പ്രേരിപ്പിച്ചു, പലപ്പോഴും കോഡ് കൂട്ടുന്നതിനേക്കാൾ കോഡ് ഒഴിവാക്കിക്കൊണ്ടാണ്. വീണ്ടും ഉപയോഗം (reuse) എന്നത് നിങ്ങൾ സ്വയം നൽകുന്ന ഒരു സമ്മാനമല്ലെന്ന് DTK എന്നെ പഠിപ്പിച്ചു. അത് സൗകര്യങ്ങളോട് 'നോ' എന്ന് പറയുന്നതിലൂടെ നിങ്ങൾ ശീലിക്കേണ്ട ഒരു അച്ചടക്കമാണ്.
റീഫാക്റ്ററിംഗിനെ (Refactoring) കുറിച്ച് ചിന്തിക്കാൻ മറ്റൊരു രീതി
റീഫാക്റ്ററുകൾ കോഡ് എത്രത്തോളം ചെറുതാക്കുന്നു എന്നതിനെ അടിസ്ഥാനമാക്കിയാണ് ഞാൻ അവ അളന്നിരുന്നത്. കുറഞ്ഞ വരികൾ പുരോഗതിയായി എനിക്ക് തോന്നിയിരുന്നു. എന്നാൽ ഇപ്പോൾ അവ എത്രത്തോളം പുതിയ സാധ്യതകൾ തുറക്കുന്നു എന്നതിനെ അടിസ്ഥാനമാക്കിയാണ് ഞാൻ അവ അളക്കുന്നത്. ഡൈനാമിക് തീം കിറ്റ് (Dynamic Theme Kit) ആകർഷകമാകുന്നത് അത് സംക്ഷിപ്തമായതുകൊണ്ടല്ല. അതിന്റെ ആന്തരിക ഘടനയിൽ മാറ്റം വരുത്താതെ തന്നെ മൂന്ന് വ്യത്യസ്ത വ്യക്തിഗത പ്രോജക്റ്റുകളിലും ഒരു പ്രൊഡക്ഷൻ ബിസിനസ് സൈറ്റിലും അത് നിലനിന്നു എന്നതുകൊണ്ടാണ് അത് ഉപയോഗപ്രദമാകുന്നത്.
അതാണ് പ്രസക്തമായ അളവുകോൽ. ഒരിക്കൽ മാത്രം പ്രവർത്തിക്കുന്ന കോഡ് ഒരു ചിലവാണ്. ആവർത്തിച്ച് പ്രവർത്തിക്കുന്ന കോഡ് ഒരു ആസ്തിയാണ് (asset). ഇപ്പോൾ ഏതൊരു ഫീച്ചർ തുടങ്ങുന്നതിന് മുമ്പും ഞാൻ ഒന്ന് നിൽക്കും. എനിക്ക് വീണ്ടും ആവശ്യമുള്ള എന്തെങ്കിലും ആണോ ഞാൻ നിർമ്മിക്കുന്നത് എന്ന് ഞാൻ സ്വയം ചോദിക്കും. ഉത്തരം 'അതെ' എന്നാണെങ്കിൽ, ആദ്യ വരി മുതൽ ഞാൻ അത് വ്യത്യസ്തമായി നിർമ്മിക്കും. ഞാൻ ഇൻപുട്ടുകൾ (inputs) വേർതിരിക്കുന്നു. ഔട്ട്പുട്ടുകൾ (outputs) നിർവചിക്കുന്നു. അനുമാനങ്ങൾ ഒഴിവാക്കുന്നു.
ഏറ്റവും മികച്ച റീഫാക്റ്റർ നിങ്ങളുടെ കോഡ് ചെറുതാക്കുകയല്ല ചെയ്യുന്നത്. മറിച്ച്, നിങ്ങൾ ഇതുവരെ സങ്കൽപ്പിക്കാത്ത ഇടങ്ങളിലും നിങ്ങളുടെ കോഡ് പ്രവർത്തിപ്പിക്കാൻ അത് സഹായിക്കുന്നു.
