Projects written in less LOC are easier to maintain. For example, it's easier to maintain a project that is written in 200 LOC
vs 1000 LOC
. Thus, using that as one of the main metrics helps in maintaining semi-big projects. Simplicity over complexity should be the main approach. But variable / function names should still be understandable.
Self-contradicting with the upper goal, but npm and security is a big concern. So let's try to avoid node-ipc type of situations. One way to avoid this is by using as little dependencies as possible. This means:
lib
dirThe main framework is tailwind + some helper classes.
I wrote a mini article on how to write css more effectivley. Pretty much all of the points mentioned there should be used here.
While in theory seperation of concerns seems valid, when it comes to CSS, the benefits of tailwind outweight its negatives. Article explaining why (semi biased, because it's written by the author of tailwind). As LOC is one of the main metrics, tailwind wins.
The main point of adding the linked utility classes is to centralize the main project CSS settings under root variables, so that there is a single point of reference. The name of the root variable is binded to the classname.
:root {
/* define the color palette ( mapped to main-col-x and text-col-x class ) */
--main-col-1: #000000;
--main-col-2: #ffffff;
/* font-sizes, --fs-1 is equal to fs-1 class etc etc */
--fs-1: 78px;
--fs-2: 64px;
}
The :root
variables hold --max-width-x
variables. These are used to define the max-width of the content. --max-width-1
is the global content width. To center content, use this block.
// block of content with optional full width backgrounds
<div className="flex-center">
<div className="max-width-1">content</div>
</div>
// If the page is wrapped in a single container, use this block instead.
// The additional `global-page-content-padding-class` seperates the
// content from header and footer grids
<div className="flex-center global-page-content-padding">
<div className="max-width-1">
</div>
</div>
This block allows to center the content on the page, while also allowing optional full-width backgrounds. So new content section is a block that is contained in the upper example.
No OOP. Everything is a function.
Avoid :any
keyword when the input or return types are known.
/lib
dir holds reusable / agnostic stuff that can be reused across multiple projects. The only real dependecy used there is tailwind for component styling + the boolean variable that is imported from the config dir (used to toggle Debug Grids automatically)
In terms of the structure of the project, the approach could be classified as flat. Meaning, isolate pages as much as possible. Avoid inheritace as much as possible.
In terms of file structure, the preference for the current project is -> less files, longer components
. Don't split individual functions in seperate files. Longer than average files are preferred.
DRY a much as possibe, except in situations when inheritace can become a problem.
Relative paths
If you want to call exported values from files that are far away, use absolute imports.
For example,
// when calling something from `lib` dir, use this
import { CartSvg } from 'lib/assets/svg'
// instead of this
import { CartSvg } from '../../../../lib/assets/svg'
Comments are an exception to that as little LOC as possible
rule. If they are used to explain how a certain thing works, then there is no limit.
If a component / function will be reused, include a full example of how it should be used under the @example
tag in the JSDocs. (not fully followed everywhere currently, will do a bit later).
Examples are the best way to understand how something works. So they should be included in comments as much as possible.
####### Mini style notes
export default
is used to export a component, store it in the same line as the component.// instead of this
const SomeComponent = () => {
return <div>hello</div>
}
...
export default SomeComponent
// write this
export default function SomeComponent(){
return <div>hello</div>
}
index.ts
file. That way, the import path will be shorter. Example of this is:// /reusable/utilComponent1.tsx
export const something = 'hello'
// /reusable/index.ts
export * from './utilComponent1'
// file in which we import the reusable stuff
import { something } from '/reusable'
One thing to note is that default
exports won't work with this.