Skip to content

Instantly share code, notes, and snippets.

@ofbeaton
Last active June 1, 2019 14:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ofbeaton/cbb11bf871ca2afb629fc3642e0977a8 to your computer and use it in GitHub Desktop.
Save ofbeaton/cbb11bf871ca2afb629fc3642e0977a8 to your computer and use it in GitHub Desktop.
Learning Javascript Stack by ofBeaton

Learning Javascript Stack, by ofBeaton

This guide documents my journey in 2019 to learn the modern JS stack, for the frontend and backend ecosystem. It is sequential and each section builds on the previous one.

This guide focuses on tutorials as experienced by beginners and not a resource from a veteran, who may have lost perspective on what beginners struggle with or need to learn.

This guide will naturally become out of date as new versions of the various tools become out of date, and new tools emerge to replace old ones. Deviate as you see fit.

For a guide that has more up to date resources, but is less focused, look up the latest Front End Handbook from Front End Masters. As of this writing they have 2016-2019 editions.

License

This guide is Copyright (C) 2019 ofbeaton, under Creative Commons Attribution NonCommercial ShareAlike 4.0 International (CC BY-NC-SA 4.0). Note the Non Commercial.

Contact me (ofbeaton@gmail.com) if you wish to reproduce it in whole or in part under a different license. Republishing on your blog or website may violate the Non Commercial stipulation of this license. Best to contact me.

Contributions

Feel free to contact me (ofbeaton@gmail.com) to recommend an addition that covers a gap, understanding that I may publish it in this guide, and may relicense it at my discretion. I especially favour contributions from other beginners who found something actually useful, instead of from (well meaning) authors who think their contribution will be useful.

Content behind paywalls is not welcome.

Prior Knowledge

You do not need to start with the same knowledge I did, and it is likely not worthwhile to go back and learn many of the thing I knew. It may still be useful to know what I started with, in case you are stuck and wondering why something isn't included in the guide. If this happens to you, please see Contributions to let me know!

Before this journey, I had light exposure to pre ES5 browser Javascript, Prototypal inheritance and JQuery. No large JQuery apps, no experience with backbone, underscore, angular, vue, etc.

I had done some MVC, PHP templates, modern PHP modules (composer/namespaces/classes), and some REST APIs. I had a good understanding of SQL and Regular expressions.

Javascript

Before moving on to Javascript libraries and frameworks you need to have a decent understanding of modern Javascript itself. This tends to be hard without projects, so I didn't spend too much time on it, picking up bits and pieces as I went along. You still need some foundation in Javascript and can't just jump in with zero experience.

React

For a front-end framework I could have chosen angular, vue, ember, or many other popular libraries. They likely all have their own tradeoffs. I chose React because it does everything in Javascript (my focus right now, as opposed to say Vue and html element properties) and because of the size of the community. This meant meant I was more likely to find good quality tutorials, and alternative information sources if I didn't grok one.

  • reactjs.org "learn concepts step by step" - "Main Concepts only":
  • reactjs.org "learn by doing" - Tic Tac Toe tutorial
    • choose to setup own environment. For editor I chose VSCODE and set it up as recommended. I used yarn instead of npm for a package manager client because it causes less problems.
    • after finishing, do all the optional goals
    • extra goal: create "src/components", "src/lib" and split components apart, then import them as needed using ES6 imports
    • extra goal: split index.css into component .css files which are imported into each component import './component.css'
    • extra goal: show game status in time travel button
    • use this tic tac toe game as the base to refactor, changing it iteratively to learn and apply concepts

Immutability

So far in the react tutorial you have been using Object.assign and the Object Spread Operator ... to manually create immutable data structures. As the react tutorial itself points out, libraries can help us do these tedious tasks and provide extra value. For example nested objects become particular cumbersome and error prone to modify with the previous methods.

  • Skip immutability-helper (extra docs), recommended by react
    • Makes you learn a new lightweight syntax to describe changes to state, we can do better.
  • Convert your Object.assign and object spread immutability to Immer, recommended by redux
    • Lets you use regular javascript mutability code while giving you structure immutability.
  • Skip Immutable by facebook
    • Locks you into using their specific structures with their own API, which can get tricky when passing data back and forth with 3rd party libraries.

Code Style / Linting: ESLint / Prettier

  • eslint the code eslint src and eslint src --fix. CRA comes with eslint definition. VSCODE integrate too
  • prettier the code, add package.json lint and fix` commands.

CSS in JS: styled-components

React memoization

  • convert any function or class component that does not use state to React.memo
  • You will likely need to convert arrow functions to use .bind(undefined, ) instead

React Hooks

Types in JS: TypeScript

  • Follow microsoft: typescript Hello tutorial (also covers basic intro to Jest testing framework... skip state management / redux for now, we cover it later):
    • note: this guide is for before cra had builtin typescript support, still worth doing and instructions still work
  • port the reactjs tictactoe game above to a new typescript project
    • use the new create-react-app built-in typescript support instead of the instructions in the microsoft tutorial
    • If you want to support newer ES6 features, remember to change target in tsconfig.json to es2017
  • Skip TSLint, keep using ESLint instead. TSLint will be deprecated soon.

Mini-project: Todo List, Time to use it all

  • create a simple todo app that lets you add/edit/remove single string todo without looking at todo tutorials
    • You may want a UUID generator for keys. Trends. I chose uuid
      • note: care should be taken with uuid and keys, make sure you don't re-generate them on re-render
  • use this todo app as the base to refactor, changing it iteratively to learn and apply concepts

UI, Drag n Drop, CSS Libs, Themes

  • follow free course on drag and drop lists w/ react-beatiful-dnd
    • note: covers accessibility through keyboard navigation and screen readers throughout. Use tab key to navigate between components, and spacebar to pickup and drop components.
    • note: Chapter 13 includes a good explanation of PureComponent (and by extension memo), shouldComponentUpdate and using the React Dev Tools to show rerenders.
    • why this library: Trends. From what I could tell react-dnd and react-draggable are lower level, no list abstractions for you
  • add it (+lessons learned) to your todo app
  • add sanitize [Trends] to todo app to learn to add custom css libraries
  • add bootstrap 4.x to todo app to learn to merge old themes with react

Local Data Persistence

These are going to be slightly contrived examples, but they are simply meant to teach you the different local data persistence APIs accessible from client-side javascript, without relying on a backend or SaaS.

  • Intro to Web storage API (localStorage, sessionStorage) with react
    • Apply localStorage to your todo app, you'll need to overcome strings (explained in article, tip) and typescript (tip)
    • make sure to implement custom hook useStateWithLocalStorage (with extra initialState param, and typescript generics) as a 2nd pass if you didn't at first
    • extract useStateWithLocalStorage into custom lib/ folder
  • switch localStorage with sessionStorage (docs) and see how it behaves differently.
    • Reload your app, close your browser and reopen.
  • Modify useStateWithLocalStorage to use the Javascript Cookie API.
    • You likely will never use cookies to store large amounts of app state, however try it now just to learn the Javascript Cookie API.
    • RegExp: Careful Prettier doesn't remove the escape character \s into s. Also brush up on Javascript syntax if stuck trying to insert a variable into it.
  • Skip React Hook react-use-localstorage
    • It doesn't work with non-string data, but good to know it exists if string is all you need.
  • Switch to using React Hook react-use-storage
    • It can do localStorage and sessionStorage and handles non-string data.
    • Keep the useStateWithLocalStorage file around for now, we will use it again.
  • Switch to IndexedDB wrapper dexie.js, dexie.js + react hooks tutorial (dexie.js docs)
    • [caniuse] At time of writing, IndexedDB on IE 10/11 does not support all features. Edge does not support in blob web workers.
    • Because of the complexity of the IndexedDB API, using a wrapper library is recommended. Both MDN IndexedDB reference (dexie, others) and Google IndexedDB tutorial (idb) make recommendations.
    • Many wrappers add significant functionality and so were not chosen. The google guide required a good understanding of asynchronous javascript including await and Promises, something I don't have yet at this point in the learning process.
  • Switch to Cache API

Now read the security concerns with any data persistance that is accessible from client-side javascript.

Oncce you are done reading, I hope you can realize that any data that is readable from client-side javascript (non-httponly cookies, storage) is exploitable by a third party, and you should treat it as such. You can avoid some risks by avoiding CDNs, trading speed for security.

I once installed a custom theme in a private network and was surprised it did not work offline because it was loading custom fonts externally over the internet through the CSS files. This is a possible attack vector for reading out all your data out of storage. It is very hard to constantly audit (after all a 3rd party library could add an external load like this at any time) for external loads even if you currently load everything from your domain.

Expect you or another contributor to your app will mess up one day loading 3rd party resources, and expect your app will be compromised.

State management: Redux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment