ప్రతి డెవలపర్‌కు ఒక ఫోల్డర్ ఉంటుంది. మీరు ఒక రిపో (repo) నుండి మరొక రిపోకి కాపీ చేసే utils లేదా helpers అని పిలిచే ఫోల్డర్ అది. మీరు దానిని పేస్ట్ చేసి, పాత డేటాబేస్ స్కీమాలకు సంబంధించిన రిఫరెన్స్‌లను తొలగించడానికి, వర్తించని auth checksలను తీసివేయడానికి మరియు మీ కొత్త లీంటర్ (linter) ఎర్రర్లను చూపించడం ఆపడానికి వేరియబుల్స్‌ను రీనేమ్ చేయడానికి ఇరవై నిమిషాలు కేటాయిస్తారు. నేను కూడా నా డైనమిక్ థీమ్ కిట్ (Dynamic Theme Kit) అనే థీమింగ్ సిస్టమ్‌తో ఇలాగే చేసేవాడిని. ఇది ఒక అప్లికేషన్‌లోని ఫీచర్‌గా మొదలైంది, మరియు నెలల తరబడి, నేను దానిని ఒక పోర్టబుల్ టూల్‌లా పరిగణించాను. నేను తప్పు చేశాను. కోడ్‌ను కాపీ చేయడం అంటే తిరిగి ఉపయోగించడం (reuse) కాదు. అది అదనపు దశలతో కూడిన డూప్లికేషన్ మాత్రమే.

సింగిల్-ప్రాజెక్ట్ మైండ్‌సెట్ యొక్క ఉచ్చు

మీరు ఒక ప్రాజెక్ట్ లోపల ఒక ఫీచర్‌ను నిర్మించినప్పుడు, మీరు వందలాది అదృశ్యమైన ఊహలను (assumptions) చేస్తారు. కలర్ ప్యాలెట్ ఒక నిర్దిష్ట CSS-in-JS సెటప్‌ను ఊహించి ఉండవచ్చు. స్పేసింగ్ స్కేల్ మీ కంపెనీ బ్రాండ్ గైడ్‌లోని ఒక డిజైన్ టోకెన్‌ను రిఫరెన్స్ చేయవచ్చు. లైట్ మరియు డార్క్ మోడ్ మధ్య మారే ఆప్షన్ ఆ యాప్ యొక్క బ్యాకెండ్‌కు మాత్రమే ప్రత్యేకమైన యూజర్ ప్రిఫరెన్స్ ఎండ్‌పాయింట్‌ను పిలవవచ్చు. ఈ డిపెండెన్సీలు ప్రాజెక్ట్ లోపల ఉన్నప్పుడు హానికరంగా అనిపించవు. అవి అక్కడే ఉండాలి.

కానీ ఆ కోడ్‌ను బయటకు తీయడానికి ప్రయత్నించినప్పుడు సమస్య మొదలవుతుంది. ఆ "రీయూజబుల్" కాంపోనెంట్ నిజానికి ఆ ఒక్క కోడ్‌బేస్‌తో అనుసంధానించబడిన అనేక దాగి ఉన్న స్ట్రింగ్స్ యొక్క వలయం అని మీరు కనుగొంటారు. నేను DTK తో దీనిని నేర్చుకున్నాను. అది థీమ్ వేరియబుల్స్‌ను జనరేట్ చేసింది, అవును. కానీ అది ఒక నిర్దిష్ట ఫోల్డర్ స్ట్రక్చర్‌ను కూడా ఆశించింది. అది ఒరిజినల్ యాప్ యొక్క టైప్స్ డైరెక్టరీలోని లోతైన భాగం నుండి ఒక టైప్ డెఫినిషన్‌ను ఇంపోర్ట్ చేసింది. ఆ ఒక్క రిపోజిటరీలో మాత్రమే ఉండే ఒక గ్లోబల్ కాన్ఫిగ్ ఆబ్జెక్ట్ ఉండాలని అది ఊహించింది. ఆ ప్రాజెక్ట్ లోపల ఉన్నప్పుడు అంతా అందుబాటులో ఉండటం వల్ల నేను దీనిని ఎప్పుడూ గమనించలేదు.

DTKని స్టాండ్‌అలోన్ ప్యాకేజీగా మార్చడం అంటే విస్తరణ కాదు, శస్త్రచికిత్స చేయడమే. నాకు మరిన్ని ఫీచర్లు అవసరం లేదు. నాకు తక్కువ కనెక్షన్‌లు కావాలి.

Dynamic Theme Kitని వేరు చేయడం

అత్యంత కష్టమైన పని కోడ్‌బేస్‌తో కూర్చుని ప్రతి ఫంక్షన్ మరియు ప్రతి ఎక్స్‌పోర్ట్‌ను ప్రశ్నించడం: ఇది థీమింగ్ లాజిక్‌కు సేవ చేస్తోందా, లేదా ప్రాజెక్ట్‌కు సేవ చేస్తోందా? నేను స్టైలింగ్ ప్రిసెట్‌లను తొలగించాను. కన్స్యూమర్ ఒక React అప్లికేషన్ అయి ఉండాలనే ఊహను తొలగించాను. డిఫాల్ట్ కలర్ ప్యాలెట్‌లను పూర్తిగా తీసివేసివేసాను. ఒరిజినల్ ప్రాజెక్ట్‌లో డిఫాల్ట్‌లుగా నేవీ-అండ్-స్లేట్ కార్పొరేట్ ఎస్థెటిక్ ఉండేది. అది పోవాల్సి వచ్చింది. ఒక ప్యాకేజీ మీ బ్రాండ్ రంగులను పంపలేదు.

కొత్త కిట్ కేవలం ఒకే పని చేస్తుంది. ఇది ఒక కాన్ఫిగరేషన్ ఆబ్జెక్ట్‌ను తీసుకుంటుంది—కొన్ని కలర్ వాల్యూస్, కొన్ని స్పేసింగ్ నంబర్లు, కొన్ని టైపోగ్రఫీ స్కేల్స్—మరియు ఇది CSS custom propertiesలను జనరేట్ చేస్తుంది. అంతే. ఇది వాటిని అప్లై చేయదు. అవి మీ DOMలో ఎక్కడ ఉండాలో ఇది నిర్ణయించదు. మీరు Tailwind, Styled Components లేదా ప్లెయిన్ HTML ఉపయోగించినా దీనికి సంబంధం లేదు. ఇది మీ అప్లికేషన్‌కు వేరియబుల్స్‌ను ఇస్తుంది, మరియు మీ ప్రాజెక్ట్ వాటిని ఎలా ఉపయోగించాలో ఎంచుకుంటుంది.

ఆ పరిమితి మొదట్లో ఇబ్బందిగా అనిపించినా, చివరికి అది స్వేచ్ఛను ఇచ్చింది.

మీరు నిజంగా దానిని తిరిగి ఉపయోగించడానికి ప్రయత్నించినప్పుడు ఏవి విఫలమవుతాయి

నేను దేనినైనా పబ్లిష్ చేయడానికి ముందే, ఈ అబ్‌స్ట్రాక్షన్ (abstraction) నిజంగా పని చేస్తుందని నిరూపించుకోవడానికి నాకు ఆధారాలు కావాలి. నేను నా ఆర్కైవ్ నుండి మూడు చిన్న వ్యక్తిగత ప్రాజెక్టులను తీసుకున్నాను: ఒక మార్క్‌డౌన్ ప్రివ్యూ టూల్, ఒక హ్యాబిట్ ట్రాకర్ మరియు ఒక ఈవెంట్ కోసం ల్యాండింగ్ పేజీ. వాటిలో ఏదీ ఒకే ఫ్రేమ్‌వర్క్ లేదా ఫోల్డర్ స్ట్రక్చర్‌ను పంచుకోలేదు. నేను ప్రతి దానిలో DTKని లోకల్‌గా ఇన్‌స్టాల్ చేసి, వాటికి థీమ్ అప్లై చేయడానికి ప్రయత్నించాను.

మొదటి ప్రయత్నం వెంటనే విఫలమైంది. DTK జనరేట్ చేసిన వేరియబుల్ పేర్లు చాలా నిర్దిష్టంగా ఉన్నాయి. అది --primary-action మరియు --background-overlay వంటి టోకెన్‌లను అవుట్‌పుట్‌గా ఇస్తోంది, ఇవి ఒక నిర్దిష్ట UI లేఅవుట్‌ను సూచిస్తాయి. మార్క్‌డౌన్ ప్రివ్యూయర్‌లో, ఆ పేర్లకు అర్థం లేదు. అక్కడ ఎటువంటి యాక్షన్ బటన్ లేదు. అక్కడ ఎటువంటి ఓవర్‌లే లేదు. నేను జనరేషన్ లాజిక్‌ను మార్చి, విడ్జెట్‌ను కాకుండా విలువను వివరించే తటస్థమైన, స్ట్రక్చరల్ పేర్లను రూపొందించేలా చేశాను.

నా డిఫాల్ట్ విలువలు కూడా చాలా ఎక్కువగా ఉన్నాయని నేను గమనించాను. వినియోగదారు అసంపూర్తిగా ఉన్న కాన్ఫిగ్‌ను పంపినప్పుడు, DTK ఖాళీలను నింపడానికి కొన్ని విలువలను తీసుకుంటుంది. అవి డెన్స్ డాష్‌బోర్డ్‌లో బాగుండవచ్చు కానీ, తక్కువ కంటెంట్ ఉన్న ల్యాండింగ్ పేజీలో విఫలమవుతాయి. నేను ట్రాన్స్‌పరెంట్ డిఫాల్ట్‌లకు మారినప్పుడు, మిస్ అయిన టోకెన్‌లు రెండర్ అవ్వవు, తద్వారా కన్స్యూమింగ్ ప్రాజెక్ట్ దాని స్వంత ఫాల్‌బ్యాక్‌లను (fallbacks) నిర్వచించుకోవచ్చు.

తరువాత డాక్యుమెంటేషన్ విషయానికి వస్తే. నాకు స్పష్టంగా అనిపించినది—"కేవలం ఒక కాన్ఫిగరేషన్ ఆబ్జెక్ట్‌ను పంపండి"—అర్థరాత్రి README చదువుతున్న ఎవరికైనా అస్పష్టంగా అనిపించవచ్చు. నేను నిజమైన ఆబ్జెక్ట్‌లు, నిజమైన ఫైల్ పాత్‌లు మరియు మీరు ఫంక్షన్‌ను పిలిచినప్పుడు ఏమి జరుగుతుంది మరియు దాని తర్వాత మీ అప్లికేషన్ ఏమి చేయాలి అనే స్పష్టమైన వివరణలతో దానిని తిరిగి రాశాను.

ఈ చిన్న వ్యక్తిగత ప్రాజెక్టులు టెస్ట్ బెడ్‌లుగా పనిచేసాయి. వాటిలో రిస్క్ తక్కువ, కానీ సోర్స్ కోడ్‌ను విడిగా చూస్తూ నేను గమనించలేని నిజమైన లోపాలను అవి బయటపెట్టాయి.

అసలైన పరీక్ష: Web Weavers World లో ప్రొడక్షన్

వ్యక్తిగత ప్రాజెక్టులు ప్రయోగశాలలు (sandboxes) వంటివి. వాటికి డెడ్‌లైన్లు, స్టేక్‌హోల్డర్లు లేదా మీ ప్యాకేజీ కంటే ముందున్న పాత (legacy) CSS ఉండవు. నా వ్యాపార సైట్ అయిన Web Weavers World లో DTK ని ఇంటిగ్రేట్ చేసినప్పుడు అసలైన పరీక్ష ఎదురైంది. ఇది ఇప్పటికే ఉన్న స్టైల్స్, క్లయింట్ అంచనాలు మరియు అనలిటిక్స్‌ను పరిగణనలోకి తీసుకోవాల్సిన ఒక లైవ్ ప్రాపర్టీ. ఒకవేళ ప్యాకేజీ వల్ల ఏదైనా పాడైతే, నేను కేవలం రిపోజిటరీని డిలీట్ చేసి మళ్ళీ మొదటి నుండి ప్రారంభించలేను.

నేను DTK ని బిల్డ్ పైప్‌లైన్‌కు జోడించాను, దానిని కొత్త కలర్ కాన్ఫిగరేషన్‌కు అనుసంధానించాను మరియు కొత్త CSS వేరియబుల్స్ సెట్‌ను రూపొందించనిచ్చాను. ఈ ఇంటిగ్రేషన్ ఒక మధ్యాహ్నం మాత్రమే పట్టింది, వారం కాదు. అదే అసలైన సంకేతం. గతంలో, కొత్త థీమ్‌ను జోడించడం అంటే కొత్త CSS రాయడం, ఇరవై ఫైళ్లలో హార్డ్‌కోడ్ చేసిన హెక్స్ (hex) విలువలను వెతకడం మరియు ఎక్కడైనా ఏదైనా మిస్ అవ్వలేదేమో అని ఆశించడం. ఇప్పుడు నేను కాన్ఫిగరేషన్ ఫైల్‌కు ఒక ప్యాలెట్‌ను జోడిస్తాను, DTK వేరియబుల్స్‌ను రూపొందిస్తుంది, మరియు సైట్‌లోని మిగిలిన భాగాలు వాటిని ఉపయోగిస్తాయి. థీమ్ లాజిక్ అనేది ఒక బలహీనమైన మాన్యువల్ ప్రక్రియ నుండి, సహకారులకు (collaborators) అప్పగించగలిగేంత నమ్మకమైన ప్రక్రియగా మారింది.

నేను బిల్డ్ చేసే విధానాన్ని మార్చిన మూడు ప్రశ్నలు

ఈ ప్రక్రియ ద్వారా వెళ్లడం వల్ల, నేను ఏదైనా అబ్‌స్ట్రాక్ట్ (abstract) చేసే ముందు ఉపయోగించే ఒక మెంటల్ చెక్‌లిస్ట్‌ను రూపొందించాల్సి వచ్చింది:

  • ఈ వేరియబుల్ నిజంగా జనరిక్ (generic) గా ఉందా? ఒకవేళ పేరు లేదా లాజిక్ అసలు ప్రాజెక్ట్‌లోని డొమైన్ కాన్సెప్ట్‌ను సూచిస్తే, అది అక్కడే ఉండిపోవాలి.
  • ఇది ప్యాకేజీకి చెందినదా లేదా అప్లికేషన్‌కు చెందినదా? బిజినెస్ రూల్స్, బ్రాండ్ ఐడెంటిటీలు మరియు లేఅవుట్ అంచనాలు అప్లికేషన్‌లో ఉంటాయి. స్టాండర్డైజ్డ్ అవుట్‌పుట్‌ను రూపొందించే ప్లంబింగ్ (plumbing) ప్యాకేజీలో ఉంటుంది.
  • నేను పరిష్కరిస్తున్నది మళ్ళీ ఉపయోగించదగిన సమస్యనా లేక ప్రాజెక్ట్-నిర్దిష్టమైన సమస్యనా? దీనికి నిజాయితీగా సమాధానం చెప్పడం చాలా కష్టం. మన పరిష్కారాలు విశ్వవ్యాప్తమని (universal) మనం అనుకోవాలని అనుకుంటాము. కానీ సాధారణంగా అవి స్థానికమైనవి (local).

ఈ ప్రశ్నలకు సమాధానం చెప్పడం వల్ల నా డిజైన్‌ను సరళీకరించాల్సి వచ్చింది, తరచుగా కోడ్‌ను జోడించడం కంటే కోడ్‌ను తొలగించడం ద్వారా ఇది జరిగింది. రీయూజ్ (reuse) అనేది మీకు మీరు ఇచ్చుకునే బహుమతి కాదని DTK నాకు నేర్పింది. ఇది సౌకర్యానికి (convenience) 'నో' చెప్పడం ద్వారా మీరు పాటించాల్సిన క్రమశిక్షణ.

రిఫ్యాక్టరింగ్ (Refactoring) గురించి ఆలోచించే ఒక భిన్నమైన విధానం

గతంలో నేను రిఫ్యాక్టర్లను కోడ్ ఎంత చిన్నగా మారిందనే దానితో కొలిచేవాడిని. తక్కువ లైన్లు అంటే పురోగతి అనిపించేది. ఇప్పుడు అవి ఎన్ని కొత్త అవకాశాలను తెరుస్తాయనే దానితో కొలుస్తున్నాను. Dynamic Theme Kit అనేది సంక్షిప్తంగా (concise) ఉంది కాబట్టి మాత్రమే సొగసైనది కాదు. దాని ఇంటర్నల్స్‌ను మార్చాల్సిన అవసరం లేకుండా మూడు సంబంధం లేని వ్యక్తిగత ప్రాజెక్టులు మరియు ఒక ప్రొడక్షన్ బిజినెస్ సైట్‌లో నిలదొక్కుకున్నందువల్ల అది ఉపయోగకరంగా ఉంది.

అదే నిజమైన కొలమానం. ఒకసారి మాత్రమే పనిచేసే కోడ్ ఒక ఖర్చు. పదేపదే పనిచేసే కోడ్ ఒక ఆస్తి (asset). ఇప్పుడు నేను ఏదైనా ఫీచర్‌ను ప్రారంభించే ముందు, కాసేపు ఆగుతాను. నేను మళ్ళీ అవసరమయ్యే దానిని నిర్మిస్తున్నానా అని నన్ను నేను ప్రశ్నించుకుంటాను. సమాధానం 'అవును' అయితే, మొదటి లైన్ నుండే దానిని భిన్నంగా నిర్మిస్తాను. ఇన్‌పుట్‌లను వేరు చేస్తాను. అవుట్‌పుట్‌లను నిర్వచిస్తాను. ఊహలను (assumptions) తొలగిస్తాను.

ఉత్తమమైన రిఫ్యాక్టర్ మీ కోడ్‌ను చిన్నదిగా చేయదు. అది మీరు ఇంకా ఊహించని చోట్ల కూడా మీ కోడ్ పనిచేసేలా చేస్తుంది.