eslint for javascript

Standard

javascript + eslint= ‘better coding’


JavaScript Coding Standards

Follow FIRST – Focused, Independent, Reusable, Small, Testable
  1. Embrace functions, avoid hidden state when every possible
  2. Whenever you fix a bug, write a automated regression test. A bug fixed without a regression test is almost certainly going to break again in the future.

Approach

  1. The best way in javascript to learn and use coding standards is via a linter like eslint, tie-in with an editor, check upon build, and pre-commit hook (https://github.com/observing/pre-commit)
  2. The second best way is to ask someone to help you setup the best way

ESLINT options and reasons

You can also use these files at your root: .eslintrc

Simple approach: standard plus standard-react

  1. “accessor-pairs”: [2, {“getWithoutSet”: true}],
    • All sets should have gets
  2. “camelcase” : 0,
    • reason snake_case and dash-case are useful in javascript in many contexts since it reduces the number of word to variable changes
    • generally in javascript CamelCase is use for functions that require ‘new’ or for React components; therefore, naming variables in a different convention like snake_case can increase the readability of the code for other types of functions or variables.
  3. “comma-dangle” : [2, “always-multiline”],
    • having a comma at the end of every line in arrays and objects decrease the number of lines that have to be change (think git tracking) when added or removing a line in the future.
  4. “complexity”  : [2, 6],
    • makes all programmer think about one purpose one function approaches. 6 is good unless recursion is used at then with a code review that function can overwrite complexity if needed otherwise 6 is good.
  5. “consistent-return”: 2,
    • reduces the odds that one is returning undefined when not expecting it.
  6. “curly” : [2, “multi-line”, “consistent”],
    • multi-line ifs without {} is just asking for trouble; however, if (something) return; is a fine type of statement
  7. “dot-location”: [2, “property”],
    • allows commenting out a line more easily
  8. “eqeqeq”: [2, “allow-null”],
    • using `== null` is way nicer than checking for both null and undefined
  9. “guard-for-in”: 2,
    • not checking where a property came from is almost always a mistake
  10.  “max-depth” : [2, 3],
    • allow only 3 levels deep which forces more functional writing which means more testability
  11. “max-len”: [2, 120, 2],
    • Long line are hard to read but 80 is old school, we do have wide screen monitors now
  12. “max-params” : [2, 3],
    • In javascript it is preferable to pass objects so that the params are named and not order dependent. In some cases I use just 1 and make it so that everything must pass a object. With es6 it like having named parameters!
  13. “max-statements”: [2, 15],
    • functions with too many statements are most likely not doing one purpose
  14. “no-case-declarations”: 2,
    • generally the sign of a mistake
  15. “no-else-return”: 2,
    • If your IF has a return everything else is your ELSE block and you do not need one explicitly so don’t code one as the generally improves readable
  16. “no-extend-native”: 2,
    • generally the sign of a mistake
  17. “no-eval”: 2,
    • If you need a reason stop programming and go read about javascript for awhile
  18. “no-extend-native”: 2,
    • This is like the dark side of inheritance so don’t do it. Create a new object that wraps and adds what you need.
  19. “no-fallthrough”: 2,
    • generally the sign of a mistake
  20. “no-implied-eval”: 2,
    • No tricking your way into evals please
  21. “no-loop-func”: 2,
    • generally the sign of a mistake
  22. “no-magic-numbers”: 2,
    • Where did you get your number from?
  23. “no-multi-spaces”: 2,
    • Generally extra spaces not used for indentation is a mistake so fix it
  24. “no-native-reassign”: 2,
    • generally the sign of a mistake
  25. “one-var”: [2, “never”],
    • One statement one purpose (make git history cleaner too). Do not do let x, y, z;
  26. “quotes”: [2, “single”, “avoid-escape”],
    • Generally double and backticks are use to denote that variable can be mixed into the string so single quotes makes it clear that this is just a plain string.
  27. “semi”: [2, “never”],
    • cleaner javascript
  28. “no-unexpected-multiline”: 2,
    • protects against misusing javascript without semicolons
  29. “space-before-function-paren” : 2,
    • Generally improves readability

For React

  1. “react/jsx-key”: 2,
    • catches missing key needed by react loops
  2. “react/jsx-no-bind”: 2,
    • stops the creation of new function on every render
  3. “react/prop-type”: 2,
    • makes sure the prop value is specified in the types
  4. “react/no-deprecated”: 2,
  5. “react/no-did-mount-set-state”: 2,
    • setState should not be used in this life-cycle call
  6. “react/no-direct-mutation-state”: 2,
    • Did you read react?
  7. “react/react-in-jsx-scope”: 2,
    • ensures react is present when jsx is used
  8. “react/sort-comp”: 2,
    • have functions in the same order makes reading easier
  9. “react/wrap-multilines”: 2,

Get Sentry for Different Environments Plus Webpack

Standard

getsentry || getsentry +eslint  = ‘great error catching’


Problem

  1. You are using getsentry to catch errors
  2. You have more then one project or environment
  3. You want the same static files to work for 2 and 1

Solution One – just index.html

This approach requires just added a big of logic into your index.html to look at the window url to determine environment and make the switch.  Possible gotchas are if your site works with www or without like www.main.com and main.com.  You will have to check for either but it is really best to redirect one to the other and not have two sets of urls).

Solution Two – with Webpack

Since I use webpack I prefer this solution.  This one requires the the HtmlWebpackPlugin and also has the bonus of using git to provide a version to ravenjs.  This code is based on the react-redux-starter-kit file of the same name.

And the one line that has to be added to your index file for the raven to be injected.

React CSS Modules, Webpack, & Symbol not defined error

Standard

 react  + css-modules-logo +eslint+ yosemite-safai_icon = `Error: Symbol not defined`


What?

We we setup our react stack and mixed in webpack & react-css-modules we had an issue with older browsers like safari 8.  Nothing would load and we would get a `Symbol not defined` error.  We were loading babel-polyfil at the top of our main.js file like `import babel-polyfill` so what were we doing wrong?

Source

The error turn out to be caused because we had move react-css-modules into the vender chuck in webpack.  Wait for it… no did see it either?  the vender chuck is loaded BEFORE the app chucks which include main and the `import babel-polyfill` line.  Therefore react-css-modules that needed the polyfill was loaded before babel had a chance to create the polyfill.

Solution

Add `babel-polyfill` to the vender list for webpack. Yep that is it. A one liner.

Testing a React component that is a wrapper with enzyme with chai-enzymes

Standard

 react <wrapper /> + chai-logo-small + {this} = ‘Good Testing’


Summary

  1. If wrapping one child use PropTypes.children and use the chai-enzyme test to.contain(node)
  2. If wrapping more than one child use ProptTypes.node and use enzyme contains([node, node]) and check to true

Details

Essential Libraries in use:

  • react
  • enzyme
  • chai-enzymes

Wrapping Just One Child Example

Wrapping Many Children Example

Eslint for React with Sublime

Standard

sublime text + eslint= ‘better coding’


Sometimes sublime with sublime-linter needs eslint globally (I’m not sure why but some folders in the same project work with local install and some do not).  So you will also need to install the following globally assuming eslint standard:

  • eslint
  • eslint-config-standard
  • eslint-config-standard-jsx
  • eslint-config-standard-react
  • eslint-plugin-flow-vars
  • eslint-plugin-promise
  • eslint-plugin-react
  • eslint-plugin-standard
  • babel-eslint

Command for install is:

Testing for styles using React, css-modules, and enzyme with chai-enzymes

Standard

chai-logo-small + css-modules-logo + {this} = ‘Good Testing’


Summary

  1. Change the style strings by adding a ‘.’ to make them ready for finding
  2. Use enzyme render
  3. Expect with chai-enzyme descendants check

Details

Essential Libraries in use:

  • react
  • enzyme
  • lodash for mapValues
  • chai-enzymes
  • react-css-modules or just css-modules

All based on the project setup by Dave Zukowski: https://github.com/davezuko/react-redux-starter-kit

Example

 

Setting up Sublime Text 3 Packages and Preferences

Standard

sublime textI often find myself having to setup Sublime Text 3 on some new machine so I’ve gather all the plugins I usually use when building React ES6 code in a gist including some that are linked directly to a Github repo.

Start with: https://packagecontrol.io/installation

Also here is my usually preference file (Should be called Preferences.sublime-settings):

Hopefully both help!

From Angular 1.x to React or Angular 2 – Trade Study

Standard

Elements of importance:

 

  1. Testing ability, how easy is it to get to 100% code coverage
  2. Bundling, managing dependences and making
  3. Debugging tools
  4. Live code changes
  5. Ease of integration with other scripts
  6. Easy at chucking and optimizing time to first paint draw
  7. Path forward for existing code
  8. Migration cost (downsides)

 

Feature React + Redux + Webpack Angular 2 + SystemJS Angular 1.X
Testing to 100% Easiest I’ve seen, React itself is 87% Not complete yet,

Who knows (not a good sign)

Very hard
Documentation Lots of good quality Some more likely to come (A2 is still beta) Lots of docs but many promote bad CS patterns
Dependences Easy (many formats) Easy (many formats) Via magic variable names (not good)
Debugging React devtools, Redux devtools, webpack errors push to the browser (cool), sourcemaps

Overall best I’ve seen

Beta tools (ok) Angular devtools (ok)

debugging $digest is very hard

Live Code Changes Hot module loading! With redux this is just amazing – reloading at the same state No hot module loading yet css only, does not save state
CSS Helpers CSS Modules! so cool normal normal
Integration 3rd party Pretty easy (for example bootstrap JS just works) would need to do a test example Can be very hard if it competes with $digest
Chucking Webpack is the best SystemJS is good but not great yet manual
Other notes ES6, logic easy to be in anything – geared towards functional programming Typescript prefered – geared towards .NET developers Change expectations when it came out
Path Forward Co-host sites (I’ve done it before it’s not bad) Co-mingle (this sounds like a debug nightmare)
Migration Costs for redesign Basic site css+html will have to be done for both A1.x and React. All new features/pages done in React. All logic should move over pretty easily (I’ve done this before) A1.x and 2 could potentially use the same site template (however bindings are not quite the same). All new features/pages done in A2.  All logic should move over ok No migration cost.

None-trial cost in speed and testability which leads to bugs and loss of trust.

Supported by Facebook, Airbnb, Netflix, NFL Some of Google and Microsoft. (Google also supports polymer) Not as many as you would think (I’ve been using Chrome’s Library Detector for years and most big sites do not use Angular they still using backbone or just jQuery. Some are now using React.

 

Other frameworks:

Vuejs: nicely tested, more performant than A1 or 2), uses webpack, vue files are cool

Riotjs: small and simple, pretty fast, better for smaller sites

Aurelia.io: by Rob Eisenberg

Mithril: very fast, but very small usage. Sortof conceptually like React

Ember: best for people who don’t know what they are doing (as I’ve been told by a couple of teams that picked it)