ಪ್ರತಿಯೊಬ್ಬ ಡೆವಲಪರ್ ಹತ್ತಿರವೂ ಅಂತಹ ಒಂದು ಫೋಲ್ಡರ್ ಇರುತ್ತದೆ. ಅದನ್ನು utils ಅಥವಾ helpers ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ ಮತ್ತು ನೀವು ಅದನ್ನು ಒಂದು ರೆಪೊ (repo) ಇಂದ ಇನ್ನೊಂದಕ್ಕೆ ಕಾಪಿ ಮಾಡಿಕೊಳ್ಳುತ್ತೀರಿ. ಅದನ್ನು ಪೇಸ್ಟ್ ಮಾಡಿದ ನಂತರ, ಹಳೆಯ ಡೇಟಾಬೇಸ್ ಸ್ಕೀಮಾಗಳ ರೆಫರೆನ್ಸ್ಗಳನ್ನು ಡಿಲೀಟ್ ಮಾಡಲು, ಅನ್ವಯವಾಗದ ಆಥ್ (auth) ಚೆಕ್ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಮತ್ತು ನಿಮ್ಮ ಹೊಸ ಲಂಟರ್ (linter) ಎಚ್ಚರಿಸದಂತೆ ವೇರಿಯೇಬಲ್ಗಳನ್ನು ಮರುನಾಮಕರಣ ಮಾಡಲು ಇಪ್ಪತ್ತು ನಿಮಿಷಗಳನ್ನು ವ್ಯಯಿಸುತ್ತೀರಿ. ನಾನು ಕೂಡ ನಾನು ನಿರ್ಮಿಸಿದ್ದ Dynamice Theme Kit ಎಂಬ ಥೀಮಿಂಗ್ ಸಿಸ್ಟಮ್ನೊಂದಿಗೆ ಹೀಗೆ ಮಾಡುತ್ತಿದ್ದೆ. ಅದು ಒಂದು ಅಪ್ಲಿಕೇಶನ್ನ ಒಳಗಿನ ಫೀಚರ್ ಆಗಿ ಪ್ರಾರಂಭವಾಯಿತು ಮತ್ತು ತಿಂಗಳುಗಟ್ಟಲೆ ನಾನು ಅದನ್ನು ಒಂದು ಪೋರ್ಟಬಲ್ ಟೂಲ್ನಂತೆ ಬಳಸಿಕೊಂಡೆ. ನಾನು ತಪ್ಪು ಮಾಡಿದ್ದೆ. ಕೋಡ್ ಅನ್ನು ಕಾಪಿ ಮಾಡುವುದು ಮರುಬಳಕೆಯಲ್ಲ. ಅದು ಹೆಚ್ಚುವರಿ ಹಂತಗಳೊಂದಿಗೆ ಮಾಡುವ ನಕಲು (duplication) ಅಷ್ಟೆ.
ಏಕ-ಯೋಜನಾ ಮನೋಭಾವದ (Single-Project Mindset) ಬಲೆ
ನೀವು ಒಂದು ಪ್ರಾಜೆಕ್ಟ್ನ ಒಳಗೆ ಫೀಚರ್ ಅನ್ನು ನಿರ್ಮಿಸಿದಾಗ, ನೀವು ನೂರಾರು ಅದೃಶ್ಯ ಕಲ್ಪನೆಗಳನ್ನು (assumptions) ಮಾಡಿಕೊಳ್ಳುತ್ತೀರಿ. ಕಲರ್ ಪ್ಯಾಲೆಟ್ (color palette) ಒಂದು ನಿರ್ದಿಷ್ಟ CSS-in-JS ಸೆಟಪ್ ಅನ್ನು ಅವಲಂಬಿಸಿರಬಹುದು. ಸ್ಪೇಸಿಂಗ್ ಸ್ಕೇಲ್ (spacing scale) ನಿಮ್ಮ ಕಂಪನಿಯ ಬ್ರ್ಯಾಂಡ್ ಗೈಡ್ನ ಡಿಸೈನ್ ಟೋಕನ್ ಅನ್ನು ಉಲ್ಲೇಖಿಸಿರಬಹುದು. ಲೈಟ್ ಮತ್ತು ಡಾರ್ಕ್ ಮೋಡ್ ನಡುವಿನ ಬದಲಾವಣೆಯು ಆ ಅಪ್ಲಿಕೇಶನ್ನ ಬ್ಯಾಕೆಂಡ್ನ ವಿಶಿಷ್ಟ ಯೂಸರ್ ಪ್ರೆಫರೆನ್ಸ್ ಎಂಡ್ಪಾಯಿಂಟ್ ಅನ್ನು ಕರೆಯಬಹುದು. ಈ ಅವಲಂಬನೆಗಳು ಪ್ರಾಜೆಕ್ಟ್ನ ಒಳಗಿರುವಾಗ ಹಾನಿಕಾರಕವಾಗಿ ಕಾಣಿಸುವುದಿಲ್ಲ. ಅವು ಅಲ್ಲಿಗೆ ಸೇರಿರುತ್ತವೆ.
ಆ ಕೋಡ್ ಅನ್ನು ಹೊರತೆಗೆಯಲು ನೀವು ಪ್ರಯತ್ನಿಸಿದಾಗ ಸಮಸ್ಯೆ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ. ಆ "ಮರುಬಳಕೆ ಮಾಡಬಹುದಾದ" (reusable) ಕಂಪೊನೆಂಟ್ ವಾಸ್ತವವಾಗಿ ಆ ಒಂದು ಕೋಡ್ಬೇಸ್ಗೆ ಸಂಪರ್ಕ ಕಲ್ಪಿಸುವ ಅಡಗಿರುವ ಸ್ಟ್ರಿಂಗ್ಗಳ ಜಾಲ ಎಂಬುದು ನಿಮಗೆ ತಿಳಿಯುತ್ತದೆ. ನಾನು ಇದನ್ನು DTK ಮೂಲಕ ಕಲಿತೆ. ಅದು ಥೀಮ್ ವೇರಿಯೇಬಲ್ಗಳನ್ನು ಜನರೇಟ್ ಮಾಡುತ್ತಿತ್ತು, ಹೌದು. ಆದರೆ ಅದು ಒಂದು ನಿರ್ದಿಷ್ಟ ಫೋಲ್ಡರ್ ಸ್ಟ್ರಕ್ಚರ್ ಅನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತಿತ್ತು. ಅದು ಮೂಲ ಅಪ್ಲಿಕೇಶನ್ನ ಟೈಪ್ಸ್ ಡೈರೆಕ್ಟರಿಯ ಆಳದಲ್ಲಿ ಎಲ್ಲೋ ಇದ್ದ ಟೈಪ್ ಡಿಫಿನಿಷನ್ ಅನ್ನು ಇಂಪೋರ್ಟ್ ಮಾಡುತ್ತಿತ್ತು. ಆ ಒಂದು ರೆಪೊಸಿಟರಿಯಲ್ಲಿ ಮಾತ್ರ ಇರುವ ಗ್ಲೋಬಲ್ ಕಾನ್ಫಿಗರೇಶನ್ ಆಬ್ಜೆಕ್ಟ್ನ ಉಪಸ್ಥಿತಿಯನ್ನು ಅದು ಭಾವಿಸಿತ್ತು. ಆ ಪ್ರಾಜೆಕ್ಟ್ನ ಒಳಗೆ ಎಲ್ಲವೂ ಯಾವಾಗಲೂ ಲಭ್ಯವಿದ್ದ ಕಾರಣ ನಾನು ಇದನ್ನು ಎಂದಿಗೂ ಗಮನಿಸಿರಲಿಲ್ಲ.
DTK ಅನ್ನು ಸ್ಟ್ಯಾಂಡ್ಅಲೋನ್ ಪ್ಯಾಕೇಜ್ ಆಗಿ ಪರಿವರ್ತಿಸುವುದು ವಿಸ್ತರಣೆಯಲ್ಲ, ಬದಲಾಗಿ ಶಸ್ತ್ರಚಿಕಿತ್ಸೆಯಂತಿತ್ತು (surgery). ನನಗೆ ಹೆಚ್ಚಿನ ಫೀಚರ್ಗಳ ಅಗತ್ಯವಿರಲಿಲ್ಲ. ನನಗೆ ಕಡಿಮೆ ಅವಲಂಬನೆಗಳ ಅಗತ್ಯವಿತ್ತು.
Dynamic Theme Kit ಅನ್ನು ಹೊರತೆಗೆಯುವುದು
ಅತ್ಯಂತ ಕಷ್ಟದ ಕೆಲಸವೆಂದರೆ ಕೋಡ್ಬೇಸ್ನೊಂದಿಗೆ ಕುಳಿತು ಪ್ರತಿಯೊಂದು ಫಂಕ್ಷನ್ ಮತ್ತು ಪ್ರತಿಯೊಂದು ಎಕ್ಸ್ಪೋರ್ಟ್ಗೆ ಕೇಳುವುದು: ಇದು ಥೀಮಿಂಗ್ ಲಾಜಿಕ್ಗೆ ಸೇವೆ ಸಲ್ಲಿಸುತ್ತದೆಯೇ ಅಥವಾ ಪ್ರಾಜೆಕ್ಟ್ಗೆ ಸೇವೆ ಸಲ್ಲಿಸುತ್ತದೆಯೇ? ನಾನು ಸ್ಟೈಲಿಂಗ್ ಪ್ರೆಸೆಟ್ಗಳನ್ನು (styling presets) ತೆಗೆದುಹಾಕಿದೆ. ಕನ್ಸ್ಯೂಮರ್ ಒಂದು React ಅಪ್ಲಿಕೇಶನ್ ಆಗಿರುತ್ತದೆ ಎಂಬ ಕಲ್ಪನೆಯನ್ನು ತೆಗೆದುಹಾಕಿದೆ. ಡಿಫಾಲ್ಟ್ ಕಲರ್ ಪ್ಯಾಲೆಟ್ಗಳನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಡಿಲೀಟ್ ಮಾಡಿದೆ. ಮೂಲ ಪ್ರಾಜೆಕ್ಟ್ನ ಡಿಫಾಲ್ಟ್ಗಳಲ್ಲಿ ನೇವಿ-ಅಂಡ್-ಸ್ಲೇಟ್ ಕಾರ್ಪೊರೇಟ್ ಎಸ್ತೆಟಿಕ್ (aesthetic) ಅಡಗಿತ್ತು. ಅದನ್ನು ತೆಗೆದುಹಾಕಲೇಬೇಕಿತ್ತು. ಒಂದು ಪ್ಯಾಕೇಜ್ ನಿಮ್ಮ ಬ್ರ್ಯಾಂಡ್ ಬಣ್ಣಗಳನ್ನು ಒಳಗೊಂಡಿರಲು ಸಾಧ್ಯವಿಲ್ಲ.
ಹೊಸ ಕಿಟ್ ಕೇವಲ ಒಂದು ಕೆಲಸವನ್ನಷ್ಟೇ ಮಾಡುತ್ತದೆ. ಅದು ಒಂದು ಕಾನ್ಫಿಗರೇಶನ್ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ—ಕೆಲವು ಕಲರ್ ವ್ಯಾಲ್ಯೂಗಳು, ಕೆಲವು ಸ್ಪೇಸಿಂಗ್ ನಂಬರ್ಗಳು, ಕೆಲವು ಟೈಪೋಗ್ರಫಿ ಸ್ಕೇಲ್ಗಳು—ಮತ್ತು ಅದು CSS ಕಸ್ಟಮ್ ಪ್ರಾಪರ್ಟಿಗಳನ್ನು ಜನರೇಟ್ ಮಾಡುತ್ತದೆ. ಅಷ್ಟೆ. ಅದು ಅವುಗಳನ್ನು ಅನ್ವಯಿಸುವುದಿಲ್ಲ. ಅವು ನಿಮ್ಮ DOM ನಲ್ಲಿ ಎಲ್ಲಿ ಹೋಗಬೇಕು ಎಂದು ನಿರ್ಧರಿಸುವುದಿಲ್ಲ. ನೀವು Tailwind, Styled Components ಅಥವಾ ಪ್ಲೇನ್ HTML ಬಳಸುತ್ತಿದ್ದೀರಾ ಎಂಬುದರ ಬಗ್ಗೆ ಅದಕ್ಕೆ ಕಾಳಜಿಯಿಲ್ಲ. ಅದು ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ಗೆ ವೇರಿಯೇಬಲ್ಗಳನ್ನು ನೀಡುತ್ತದೆ, ಮತ್ತು ನಿಮ್ಮ ಪ್ರಾಜೆಕ್ಟ್ ಅವುಗಳನ್ನು ಹೇಗೆ ಬಳಸಬೇಕೆಂದು ನಿರ್ಧರಿಸುತ್ತದೆ.
ಆ ಮಿತಿ ಆರಂಭದಲ್ಲಿ ಸೀಮಿತವಾಗಿ ಕಂಡಿತು. ಆದರೆ ಅದು ಬಿಡುಗಡೆ ನೀಡುವಂತಾಯಿತು (liberating).
ನೀವು ಅದನ್ನು ನಿಜವಾಗಿಯೂ ಮರುಬಳಕೆ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದಾಗ ಏನಾಗುತ್ತದೆ?
ನಾನು ಏನನ್ನೂ ಪ್ರಕಟಿಸುವ ಮೊದಲು, ಆ ಅಬ್ಸ್ಟ್ರಾಕ್ಷನ್ (abstraction) ಸರಿಯಾಗಿದೆಯೇ ಎಂದು ಸಾಬೀತುಪಡಿಸುವ ಅಗತ್ಯವಿತ್ತು. ನಾನು ನನ್ನ ಆರ್ಕೈವ್ನಿಂದ ಮೂರು ಸಣ್ಣ ವೈಯಕ್ತಿಕ ಪ್ರಾಜೆಕ್ಟ್ಗಳನ್ನು ಹೊರತೆಗೆದೆ: ಒಂದು ಮಾರ್ಕ್ಡೌನ್ ಪ್ರಿವ್ಯೂ ಟೂಲ್, ಒಂದು ಹ್ಯಾಬಿಟ್ ಟ್ರ್ಯಾಕರ್ ಮತ್ತು ಒಂದು ಇವೆಂಟ್ಗಾಗಿ ಲ್ಯಾಂಡಿಂಗ್ ಪೇಜ್. ಅವುಗಳಲ್ಲಿ ಯಾವುದೂ ಒಂದೇ ಫ್ರೇಮ್ವರ್ಕ್ ಅಥವಾ ಫೋಲ್ಡರ್ ಸ್ಟ್ರಕ್ಚರ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರಲಿಲ್ಲ. ನಾನು ಪ್ರತಿಯೊಂದರಲ್ಲೂ ಸ್ಥಳೀಯವಾಗಿ DTK ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ ಅವುಗಳಿಗೆ ಥೀಮ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸಿದೆ.
ಮೊದಲ ಪ್ರಯತ್ನ ತಕ್ಷಣವೇ ವಿಫಲವಾಯಿತು. DTK ಜನರೇಟ್ ಮಾಡಿದ ವೇರಿಯೇಬಲ್ ಹೆಸರುಗಳು ತುಂಬಾ ನಿರ್ದಿಷ್ಟವಾಗಿದ್ದವು. ಅದು --primary-action ಮತ್ತು --background-overlay ನಂತಹ ಟೋಕನ್ಗಳನ್ನು ಔಟ್ಪುಟ್ ಮಾಡುತ್ತಿತ್ತು, ಇದು ಒಂದು ನಿರ್ದಿಷ್ಟ UI ಲೇಔಟ್ ಅನ್ನು ಸೂಚಿಸುತ್ತಿತ್ತು. ಮಾರ್ಕ್ಡೌನ್ ಪ್ರಿವ್ಯೂಯರ್ನಲ್ಲಿ, ಆ ಹೆಸರುಗಳಿಗೆ ಯಾವುದೇ ಅರ್ಥವಿರಲಿಲ್ಲ. ಅಲ್ಲಿ ಯಾವುದೇ ಆಕ್ಷನ್ ಬಟನ್ ಇರಲಿಲ್ಲ. ಯಾವುದೇ ಓವರ್ಲೇ ಇರಲಿಲ್ಲ. ನಾನು ಜನರೇಶನ್ ಲಾಜಿಕ್ ಅನ್ನು ಮರುನಾಮಕರಣ ಮಾಡಿ, ವಿಜೆಟ್ ಅನ್ನು ವಿವರಿಸುವ ಬದಲು ಅದರ ಮೌಲ್ಯವನ್ನು ವಿವರಿಸುವ ನ್ಯೂಟ್ರಲ್, ಸ್ಟ್ರಕ್ಚರಲ್ ಹೆಸರುಗಳನ್ನು ಉತ್ಪಾದಿಸುವಂತೆ ಮಾಡಿದೆ.
ನನ್ನ ಡಿಫಾಲ್ಟ್ ವ್ಯಾಲ್ಯೂಗಳು ತುಂಬಾ ಅತಿರೇಕದವು ಎಂದು ನನಗೆ ತಿಳಿಯಿತು. ಬಳಕೆದಾರರು ಅಪೂರ್ಣ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ನೀಡಿದಾಗ, DTK ಗ್ಯಾಪ್ಗಳನ್ನು ತುಂಬಲು ಬಳಸುತ್ತಿದ್ದ ವ್ಯಾಲ್ಯೂಗಳು ಒಂದು ដೆನ್ಸ್ ಡ್ಯಾಶ್ಬೋರ್ಡ್ನಲ್ಲಿ ಸರಿಯಾಗಿ ಕಾಣಿಸುತ್ತಿದ್ದವು, ಆದರೆ ಒಂದು ಸ್ಪಾರ್ಸ್ ಲ್ಯಾಂಡಿಂಗ್ ಪೇಜ್ನಲ್ಲಿ ಅವು ಅಸ್ತವ್ಯಸ್ತವಾಗುತ್ತಿದ್ದವು. ನಾನು ಟ್ರಾನ್ಸ್ಪರೆಂಟ್ ಡಿಫಾಲ್ಟ್ಗಳಿಗೆ ಬದಲಾಯಿಸಿದೆ, ಅಲ್ಲಿ ಮಿಸ್ಸಿಂಗ್ ಟೋಕನ್ಗಳು ರೆಂಡರ್ ಆಗುವುದಿಲ್ಲ, ಇದರಿಂದ ಕನ್ಸ್ಯೂಮಿಂಗ್ ಪ್ರಾಜೆಕ್ಟ್ ತನ್ನದೇ ಆದ ಫಾಲ್ಬ್ಯಾಕ್ಗಳನ್ನು (fallbacks) ನಿರ್ಧರಿಸಬಹುದು.
ನಂತರ ಡಾಕ್ಯುಮೆಂಟೇಶನ್ ವಿಷಯ ಬಂದಿತು. ನನಗೆ ಸ್ಪಷ್ಟವಾಗಿ ಕಂಡ ವಿಷಯ—"ಕೇವಲ ಒಂದು ಕಾನ್ಫಿಗರೇಶನ್ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಪಾಸ್ ಮಾಡಿ"—ಅದು ಮಧ್ಯರಾತ್ರಿಯಲ್ಲಿ README ಓದುತ್ತಿರುವ ಯಾರಿಗಾದರೂ ಅಸ್ಪಷ್ಟವಾಗಿ ಕಾಣುತ್ತಿತ್ತು. ನಾನು ನೈಜ ಆಬ್ಜೆಕ್ಟ್ಗಳು, ನೈಜ ಫೈಲ್ ಪಾತ್ಗಳು ಮತ್ತು ನೀವು ಫಂಕ್ಷನ್ ಅನ್ನು ಕರೆಯಿದಾಗ ಏನಾಗುತ್ತದೆ ಮತ್ತು ಅದರ ನಂತರ ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಏನು ಮಾಡಬೇಕಾಗುತ್ತದೆ ಎಂಬ ಸ್ಪಷ್ಟ ವಿವರಣೆಗಳೊಂದಿಗೆ ಅದನ್ನು ಮರುಬರೆಯಿದೆ.
ಈ ಸಣ್ಣ ವೈಯಕ್ತಿಕ ಪ್ರಾಜೆಕ್ಟ್ಗಳು ಪರೀಕ್ಷಾ ವೇದಿಕೆಗಳಾಗಿ (test beds) ಕಾರ್ಯನಿರ್ವಹಿಸಿದವು. ಅವುಗಳಲ್ಲಿ ಅಪಾಯ ಕಡಿಮೆ ಇತ್ತು, ಆದರೆ ಅವು ಮೂಲ ಕೋಡ್ ಅನ್ನು ಪ್ರತ್ಯೇಕವಾಗಿ ನೋಡುವಾಗ ನನಗೆ ತಿಳಿಯದ ನೈಜ ದೋಷಗಳನ್ನು ಎತ್ತಿ ತೋರಿಸಿದವು.
ನಿಜವಾದ ಪರೀಕ್ಷೆ: Web Weavers World ನಲ್ಲಿ ಪ್ರೊಡಕ್ಷನ್
Personal projects are sandboxes. They do not have deadlines, stakeholders, or legacy CSS that predates your package. The real test came when I integrated DTK into Web Weavers World, my business site. This was a live property with existing styles, client expectations, and analytics to consider. If the package broke something, I could not just delete the repo and start over.
I added DTK to the build pipeline, pointed it at a new color configuration, and let it generate a fresh set of CSS variables. The integration took an afternoon, not a week. That was the signal. Previously, adding a new theme meant writing new CSS, hunting down hardcoded hex values in twenty files, and hoping I did not miss an edge case. Now I add a palette to the configuration file, DTK generates the variables, and the rest of the site consumes them. The theme logic went from being a fragile manual process to something I trust enough to hand off to collaborators.
Three Questions That Changed How I Build
Going through this process forced me to formalize a mental checklist I now use before I abstract anything:
- Is this variable truly generic? If the name or the logic references a domain concept from the original project, it stays behind.
- Does this belong in the package or the application? Business rules, brand identities, and layout assumptions live in the app. Plumbing that generates standardized output lives in the package.
- Am I solving a reusable problem or a project-specific one? This is the hardest to answer honestly. We like to think our solutions are universal. Usually they are local.
Answering these questions forced me to simplify my design, often by removing code rather than adding it. DTK taught me that reuse is not a gift you give yourself. It is a discipline you practice by saying no to convenience.
A Different Way to Think About Refactoring
I used to measure refactors by how much shorter they made the code. Fewer lines felt like progress. Now I measure them by how many doors they open. The Dynamic Theme Kit is not elegant because it is concise. It is useful because it survived three unrelated personal projects and a production business site without needing to change its internals.
That is the metric that matters. Code that works once is an expense. Code that works repeatedly is an asset. Before I start any feature now, I stop. I ask if I am building something I will need again. If the answer is yes, I build it differently from the first line. I isolate the inputs. I define the outputs. I remove the assumptions.
The best refactor does not make your code shorter. It makes your code work in places you have not imagined yet.
