“I don't ever want to be perfect,
Cause I'm a singer that you
Never want to see shirtless”
― Ed Sheeran
Name vars/const
-s semantically, skip declaration if it can be deconstructed to get object property:
<aside> 💡 Destruct when possible, and avoid having a mix of destructuring and dot-notation.
</aside>
/*
* character: {
* firtName: Luke
* lastName: Skywalker
* equipment: {
* mainWeapon: lightsaber
* }
* }
*/
// VVV Do deconstruction as follows
const { firstName } = character;
// OR
const {
firstName,
equipment: {
mainWeapon
} = {}
} = character;
// ^^^ Note that "equipment" is not assigned to its constant,
// ^^^ as we are deconstructing from it
/*
* Deconstruct like this to assign deconstructed value
* to a new constant
* VVV
*/
const { firstName: characterName } = character;
// To deconstruct from the default path you can use single dot-notation
const { character } = instance.props;
// Don't
const characterWeapon = character.equipment.mainWeapon
// ^^^ An exception to this rule is "optional chaining"
// ^^^ checkout [MDN](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining>) for more info about it
/*
* If you are destructuring from an array of objects
* i.e. args in PWA plugins
*/code
const { propertyInObjectAtIndexZero } = args[0];
// ^^^ Is the same as vvv
const [{ propertyInObjectAtIndexZero }] = args;
// The same goes for destructuring arrays
const firstElement = args[0];
// ^^^ Is the same as vvv
const [ firstElement ] = args;
Never drill props from Redux to children, it is better to read them from Redux every time in each component.
Do not setState
multiple values separately, combine calls to setState
.
Avoid creating new Redux stores, prefer implementing context.
Avoid setting style props, move logic to CSS where possible; Mind the BEM.
Compatibility does not mean you are REQUIRED to copy the original template code. You still can copy it IF IT IS CONVENIENT to modify it.
<aside> 💡 i.e. use ScandiPWA buttons, over the ones used in the extension
</aside>
Comment the code! For every function that might be misread or misunderstood, add comments. Make sure to describe your solutions, and incoming/returned type if writing the self-explaining code is impossible (sometimes it is).
Please make sure your new line approach is consistent, write consistent code, so it is easier to review:
constants
.constant
declaration and every other clause (if
/for
/forEach
).Components
should only contain rendering logic, so if you need to do anything based i.e. on click, provide a handler from Container
.
Avoid providing related props separately to components/functions
, it is better to group them under a single prop. So it will be easier to deconstruct the target and also to read.
The .config
files should contain configs only, not functions.
extension/component
must come from its config file.constant
.Prefer async
over .then
when working with promises.
Write/nest/style if
conditions in one of two ways, not any other:
if (condition) {
// code
}
if (
condition1
|| condition2
&& condition3
) {
// code
}
Do not forget to add comments to CSS files atop.spanString
Do not keep unused code, remove it, or note some behavior in the comments.
Avoid using _
for method naming (i.e. _getBlogPosts
=> getBlogPosts
), JS does not support private functions, so it is not convenient to name them this way.
On the other hand, you can use _
to name unused arguments i.e. (_args, _callback, instance)
.
Use vvv
or ^^^
to note which code is commented by the current line, as long lines of comments are hard to read.
Do not nest folders in the component
folder, which makes it hard to see the scope of the extension, prefer prefixing with the name of the parent component
(arguable rule, I agree).
<aside> 💡 Do: BlogPost, BlogPostTitle, BlogPostReviews (Separate folders) Don’t: Post→Title, Reviews, Comments (All nested in ‘Post’ folder)
</aside>
Remove all .gitkeep
files, they are meant for keeping empty first committed.
If you have some ESLint rule you want to disable, add a comment about why are you doing this. Also disable ESLint for areas of code, using the following:
/* eslint-disable fp/no-let */
// TODO: code
/* eslint-enable fp/no-let */