“I don't ever want to be perfect,

Cause I'm a singer that you

Never want to see shirtless”

― Ed Sheeran

  1. 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;
    
  2. Never drill props from Redux to children, it is better to read them from Redux every time in each component.

  3. Do not setState multiple values separately, combine calls to setState.

  4. Avoid creating new Redux stores, prefer implementing context.

    How to Work with Redux?

    How to work with React Context API?

  5. Avoid setting style props, move logic to CSS where possible; Mind the BEM.

    How to use BEM?

  6. 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>

  7. 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).

  8. Please make sure your new line approach is consistent, write consistent code, so it is easier to review:

    1. Do not add new lines while declaring constants.
    2. Add new lines after constant declaration and every other clause (if/for/forEach).
    3. Try not to spread and stack the code, so that the context is clear at first glance.
  9. Components should only contain rendering logic, so if you need to do anything based i.e. on click, provide a handler from Container.

    How to work with components?

  10. 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.

  11. The .config files should contain configs only, not functions.

    1. All static strings that are specific to your extension/component must come from its config file.
    2. The static string should be declared as constant.
  12. Prefer async over .then when working with promises.

    How to work with requests?

  13. Write/nest/style if conditions in one of two ways, not any other:

    if (condition) {
    	// code
    }
    
    if (
      condition1
      || condition2
      && condition3
    ) {
    	// code
    }
    
  14. Do not forget to add comments to CSS files atop.spanString

  15. Do not keep unused code, remove it, or note some behavior in the comments.

  16. 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).

  17. Use vvv or ^^^ to note which code is commented by the current line, as long lines of comments are hard to read.

  18. 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>

  19. Remove all .gitkeep files, they are meant for keeping empty first committed.

  20. 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 */