The best approach is somewhere in the middle. When the implementation fully relies on data layer (global JS variables) then any new change requires an update on the website that takes long and sometimes it's now worth it resources wise. When the data elements are mapped only to CSS selectors, there is a high risk of data loss due to html/markup changes.
Consider mapping the Launch data elements to data layer whenever possible, for the rest use the other available options.