Frontend code conventions
Establishing code conventions is important in order to keep a more consistent codebase. Therefore the goal for the tools and principles below is to help ensure any committed code is properly aligned with the conventions.
For design conventions, see the Kolibri Design System.
Linting and auto formatting
Many of our conventions are enforced through various linters including ESLint, ESLint Vue plugin, stylelint, and HTMLHint. The enforced rules are located in the eslint.config.js
, .stylelintrc.js
, and files located at the root of the project.
Also available are options and tools that enable auto-formatting of .vue
, .js
, .scss
, and .py
files to conform to code conventions. To facilitate this, we use Black to auto-format .py
files, and Prettier to auto-format the others. Auto-formatting runs by default while running the dev server, otherwise be sure to run the dev server with -warn
as described in Getting started to prevent it from auto-formatting.
In addition, pre-commit
hooks can be installed to perform linting and auto-formatting. To enable the hooks, be sure to follow the directions described in Getting started.
You can also install the appropriate editor plugins for the various linters to see linting warnings/errors inline.
Vue.js components
Make sure to follow the official Vue.js style guide when creating Vue components.
Keep components stateless and declarative as much as possible
For simple components, make SomeComonent.vue. For more complex components, make SomeComponent/index.vue and add private sub-components
All user-visible app text should be internationalized. See Internationalization for details
Avoid direct DOM references and Vue component “lifecycle events” except in special cases
Props, slots, and Vuex state/getters for communicating down the view hierarchy
Events and Vuex actions for communicating up the view hierarchy
If possible, use <template/> for conditionals to avoid extra unnecessary nested elements.
Styling anti-patterns
Adding unnecessary new rules - whenever possible, delete code to fix issues
Unscoped styles - if absolutely necessary, use deep selectors to style component children. SCSS supports
/deep/
Classes referenced in javascript - if absolutely necessary, use ref instead (also an anti-pattern)
References by ID - use a
class
insteadHTML tag selectors - define a
class
insteadFloats or flexbox for layout - use
KGrid
insteadMedia queries - use
responsive-window
orresponsive-element
Nested selectors - make a sub-component instead (more reading here and here)
Dynamically-generated class names - avoid patterns which fail the grep test
Complex pre-processor functionality - use Vue computed styles instead
Hard-coded values - rely on variables defined in the core theme
Left or right alignment on user-generated text - use
dir="auto"
instead for RTL support