Here are the conventions followed by this project.
For variables that embed acronyms and initialisms such as
- URL
- XML
- HTTP
- JSON
- etc.
When it appears in the middle of an identifier, capitalize all letters:
// good
function fetchJSON() {
}
// bad
function fetchJson() {
}
// good
let modelID;
// bad
var modelId;
Commented-out code should never be committed to production
. If there
is some reason for keeping around the code that was commented out, use
git instead.
If you need to comment out some code, make sure your working copy is clean.
$ git status
On branch production
Your branch is up to date with 'origin/production'.
nothing to commit, working tree clean
Then, delete the code 🔥🔥🔥
Next, write a commit with the keyword remove
Let's say we
just deleted code that implemented an old algorithm for felincating
bjorndingers. Write a message like:
git commit -am "remove: old algorithm for felincating bjorndingers"
You probably don't. But just in case you do, you can find the commit that deleted that code using git log and git revert.
First use git log
to find the commit with that remove
keyword. You
can get a list of all commits with remove
in the message with the following
command:
git log --grep="remove"
commit 1e0698367b9b7ef2aae56b9af0073cb051a4192b
Merge: 9728a42 7ff662f
Author: Eddie Antonio Santos <[email protected]>
Date: Mon Sep 28 15:49:27 2020 -0600
remove: custom BCP-47 types
commit e7dfbf98d9d45f0e194d6b9162cfe91ae892a02e
Author: Eddie Antonio Santos <[email protected]>
Date: Mon Sep 28 15:00:13 2020 -0600
remove: old algorithm for felincating bjorndingers
I like to use a more compact display, so I add the --oneline
argument:
git log --oneline --grep="remove"
1e06983 remove: custom bcp-47 types
e7dfbf9 remove: old algorithm for felincating bjorndingers
There are probably too many commits to sift through manually, so you can
add extra keywords by providing --all-match
and one or more
--grep="KEYWORD"
arguments. In this example, I seem to recall that
I removed some code that involved “bjorndingers” somehow, so I use the
following command:
git log --oneline --all-match --grep="remove" --grep="bjorndinger"
e7dfbf9 remove: old algorithm for felincating bjorndingers
The hexadecimal number to the left is the git SHA of the commit that
removed the code we're interested in. Copy this number. So in this case,
I want to copy e7dfbf9
.
Now, using the commit SHA, use git revert
to undo the delete:
git revert e7dfbf9
This creates a new commit undoing the delete.
I'm not the only one who says you should just delete commented-out code. See here:
- https://kentcdodds.com/blog/please-dont-commit-commented-out-code
- https://markhneedham.com/blog/2009/01/17/the-danger-of-commenting-out-code/
- https://softwareengineering.stackexchange.com/a/190222/284069
- https://softwareengineering.stackexchange.com/a/213685/284069
When in doubt, consult Airbnb's JavaScript style guide for naming conventions.
This is derived from Cypress Best Practices
Instead of using IDs, classes, the name=
attribute, or the element's
inner text to select an element in Cypress (using cy.get()
or
cy.contains()
), do the following.
Add the data-cy="..."
attribute with a descriptive name of your
choice. For example, I added data-cy="download-button"
here:
<button id="my-button" class="button button--primary" data-cy="download-button">
Download!
</button>
Now select the element using cy.data()
cy.data("download-button").click()
cy.data()
is non-standard command that is defined in
/cypress/support/commands.js
.
It is equivalent to the following:
cy.get("[data-cy=download-button]").click()
describe()
, context()
, and it()
can be modified with
.only
so that ONLY that test runs. This is useful when
you're in the process of testing a feature or debugging a failing test:
it.only("this is the test that I'm working on", function () {
cy.visit("/");
// ...
});
This way, only the test you care about runs, instead of running the entire test suite!
Caveat: Always delete .only
before marking your PR for review!
A PR will not be accepted if it has .only()
anywhere in the test
suite.
Smooth scroll is really nifty, but as of Cypress 5.x, it introduces all kinds of issues in tests.
If you're testing pages with smooth scrolling (e.g., the landing page
currently has smooth scrolling enabled) run this custom command
immediately after cy.visit()
ing the page:
cy.disableSmoothScroll()
This is a custom command that disables smooth scrolling for the current page, and allows tests to run normally!
If you're writing many tests for a page that uses smooth scrolling, you
might want to consider using a beforeEach()
block:
cy.visit("/");
cy.disableSmoothScroll();
Try to stick to the following order of grouping of declarations in CSS:
div {
/* Positioning */
position: relative;
top: 1rem; /* order from top, right, bottom, left (like most shorthand properties */
right: 1rem;
z-index: 20;
/* Display & Box model */
display: inline-block;
box-sizing: border-box; /* let width and height INCLUDE the border and padding */
width: 20ch;
max-height: .5vh;
padding: .75rem .5rem;
margin: 2rem;
/* exception: border! */
/* Anything to do with color */
color: var(--blue);
background-color: hsl(var(--blue-hue) 20% 50% / 80%);
border: 1px solid var(--blue);
box-shadow: 1px 1px 6px 2px rgb(0 0 0 / 20%);
/* Text & Typography */
font-family: var(--main-font);
line-height: 1.25;
text-align: end;
text-transform: uppercase;
/* Misc */
transition: transform 1s;
overflow: hidden;
}
content
should always be the first element ::before
or ::after
pseudo-element selectors, due to its effect on these elements:
::before, ::after {
content: " ";
/* everything else... */
}
These guidelines have been adapted from the following sources:
- https://gist.github.com/awkale/ad46e2ade70e833fa178
- https://css-tricks.com/poll-results-how-do-you-order-your-css-properties/
- https://webdesign.tutsplus.com/articles/outside-in-ordering-css-properties-by-importance--cms-21685
- https://9elements.com/css-rule-order/
The rem
unit or :root
em is relative to the size of 1em for the
root element of the document (i.e., the <html>
element)
[mdn, csswg].
The advantage of using rem
s over px
is that we can scale the
entire site by scaling the :root
font-size. We can even scale the
entire site using media queries (breakpoints) to scale the site for
different display sizes. This also allows the user's custom
style sheets and assistive technologies the ability to scale the
entire site as desired.
Use rem
s for setting margin and non-text positioning:
/* good */
article {
margin-top: .5rem;
padding: 1rem;
}
/* bad */
article {
margin-top: 8px;
padding: 16px;
}
Since we want the size of a rem
to change, but often tools produce
units in px
, use the following guideline to convert between the
two:
16px == 1rem
The entire point of rem
is that it can change, and there is exactly
one place to change it, but this conversion guideline stems from a few
sources [1, 2,
3]. There is also a converter.
em
are scaled according to the current font-size
.
So if you are styling a <small>
element, you want it to be small
relative to its surrounding text.
Hence:
/* good */
small {
font-size: 0.75em;
}
/* bad */
small {
font-size: 12px;
}
See also this CSS tricks article.
If you set something to 0px
, 0em
, 0rem
, 0%
, etc., omit the unit.
/* good */
button {
border: 0;
}
/* bad */
button {
border: 0px;
}
It's temping to write a lot of code in the <script>
of a Svelte
component. However, in our current project configuration, it causes
a few issues:
- TypeScript type checking is NOT done during compilation of the
Svelte files due to technical limitations. Instead,
type checking needs to be done at a later stage by running
svelte-check
(automatically run byyarn run validate
). - Source mapping does not work properly with Svelte files, which makes using the debugger a pain.
Refactor so that the majority of your logic can go into standalone .ts
TypeScript files.
Here's how to do it:
- write tests for your Svelte component (probably using Cypress)
- implement your component in one large Svelte component.
- Commit! Make sure your component is working as expected and commit the working code.
- Refactor! Try to get as much of the implement in the
.svelte
file into functions that do not modify local variables. - One-by-one, extract these functions into a standalone
.ts
file.