Frontend: CSS, structure, and tech debt
This page documents observable characteristics of Sylva Enterprise that affect maintainability, CSS specificity, bundle shape, or upgrade path. It is not a performance audit (no timings here); use DevTools and bundle analyzers before optimizing.
For the overall frontend map, see Frontend (Sylva Enterprise).
Global SCSS (app.scss)
Section titled “Global SCSS (app.scss)”Duplicate @import entries
Section titled “Duplicate @import entries”src/css/app.scss imports components/inputs and components/cards twice in a row. Sass still resolves this, but it is redundant work for the preprocessor and confuses readers about intentional load order.
Improvement: Deduplicate imports; optionally group imports (tokens → global → layout → widgets) and document the order rule in a one-line comment.
Monolithic global cascade
Section titled “Monolithic global cascade”Most styling flows through one global entry plus many partials (_global, _menu, _fullscreen, …). Component SFCs add scoped styles, but Quasar overrides and cross-cutting rules often live in globals.
Trade-off: Fast to apply org-wide tweaks; higher risk of unintended overrides when adding new features.
Improvement: Prefer design tokens (CSS variables already used for themes) for new surfaces; migrate hot spots from deep global selectors to variables or scoped modules incrementally.
Theming and !important
Section titled “Theming and !important”The cssThemes mixin (src/mixins/cssThemes.js) sets Quasar-related variables with !important on entries such as --q-color-${name}.
Why it hurts: Any fight with Quasar’s internal specificity becomes harder; debugging “which rule won” requires checking mixin output, not only SCSS files.
Improvement: Where possible, use Quasar’s theming APIs or CSS variables without !important, and reserve !important for known third-party conflicts. Document orgs that rely on aggressive overrides before changing behavior.
!important in shared SCSS partials
Section titled “!important in shared SCSS partials”Several files under src/css/components/ use !important (e.g. cards, inputs, fullscreen, auth, buttons, progress, menu, global).
Improvement: For each file, track which Quasar version or which legacy markup required the override; remove or narrow selectors when touching that UI.
Layout components
Section titled “Layout components”Duplicated q-layout view strings
Section titled “Duplicated q-layout view strings”In MainLayoutCourse.vue, the view computed property returns the same string for both breakpoints (gt.xs branch and the else branch). That is either dead logic or an unfinished responsive tweak.
Improvement: If both should match, collapse to a constant; if mobile should differ, set the distinct Quasar view values explicitly.
Route name as a layout CSS class
Section titled “Route name as a layout CSS class”MainLayoutCourse applies $route.name as a class on the main grid. Convenient for one-off layout CSS, but it couples layout styling to router names (rename route → silent style breakage).
Improvement: Prefer explicit meta.layoutClass or a small set of layout “modes” decoupled from route names.
Component tree depth and navigation
Section titled “Component tree depth and navigation”Editor and admin UIs nest deeply, for example under components/Menus/AdminMenu/ (submenus, toolbars, option types, …). Deep trees:
- Increase cognitive load when tracing props/events
- Make code-splitting and lazy routes more important (some routes already use dynamic
import())
Improvement: Introduce facade components or composition-friendly subfolders with a single public entry; document “start here” components in README or Storybook where stories exist (*.stories.js).
Vue 2 and Quasar 1 stack
Section titled “Vue 2 and Quasar 1 stack”The app is Vue 2 with Quasar 1 and a Webpack-based CLI. That implies:
- Ecosystem moves toward Vue 3 / Quasar v2+ and Vite; large migrations are incremental at best.
quasar.conf.jsdocuments a crypto / Webpack workaround (md4→md5) until Webpack 5 or Vite—build-chain debt with security/upgrade implications over time.
Improvement: Treat any greenfield feature as a candidate for isolation (clear boundaries, minimal global state) to ease a future migration; avoid new global Vue plugins without necessity.
Vuex surface area
Section titled “Vuex surface area”There are many Vuex modules (see Frontend store table). Large modular Vuex is manageable but:
- Cross-module dependencies can be hard to trace
- Pinia (Vue 3) would be a big migration, not a drop-in
Improvement: Prefer clear action names, namespaced modules, and thin components that dispatch a few well-documented actions; avoid growing “god” modules.
Client bundle concerns (plugins.js)
Section titled “Client bundle concerns (plugins.js)”plugins.js registers several heavy client libraries globally (e.g. ApexCharts, InstantSearch, MathLive, video players). Anything registered here affects baseline bundle size for routes that never use them.
Improvement: Lazy-load rare players (e.g. only on routes that need Vimeo/MathLive) where webpack splitting proves viable without breaking Quasar’s boot order assumptions.
Sentry initialization
Section titled “Sentry initialization”Sentry is initialized from src/router/index.js with a hardcoded DSN in source (visible in the repo). That is a configuration smell: rotation and environment separation are harder than with build-time env injection.
Improvement: Move DSN and sampling to build.env (or runtime config) without committing secrets; align with your security policy.
Summary table
Section titled “Summary table”| Area | Issue / trade-off | Possible direction |
|---|---|---|
app.scss | Duplicate imports | Deduplicate; document import order |
| Globals | Wide cascade | More tokens; fewer global overrides |
cssThemes mixin | !important on Quasar vars | Narrow use; prefer Quasar theming APIs |
| SCSS partials | Multiple !important uses | Audit per override; tighten selectors |
| Layouts | Route name as CSS class | meta or explicit layout mode |
| Layouts | Redundant view computed | Simplify or fix responsive intent |
| Components | Very deep trees | Facades; lazy routes; documentation |
| Stack | Vue 2 / Quasar 1 / Webpack | Isolate features; plan migration separately |
| Vuex | Many modules | Discipline in actions/getters; avoid growth of god modules |
| Plugins | Global heavy libs | Lazy-load where proven safe |
| Observability | DSN in source | Env-driven config |