2020 - 2023
ES6
- Node.js ES6 compatibility table
- ECMAScript 6 modules: the final syntax
- ES6 Promises: http://exploringjs.com/es6/ch_promises.html, https://promisesaplus.com/
- If you're thinking about SEO, you have to either have a static version of a page or transpile to ES5. Google still uses Chrome 41 for their Googlebot rendering (still valid in 2019!). This means: no ES6 and no webGL.
Optimal JS, how V8 is built, V8 flags, memory optimization etc.
- Understand how data structures are represented, what's Smi, HeapObject etc: JavaScript Performance Pitfalls in V8
- How JavaScript works: inside the V8 engine plus tips about code optimization
also How JavaScript works: the rendering engine and tips to optimize its performance
- Node.js V8 internals: an illustrative primer - hidden classes, comparison of "build process vs C++", "hot code" and JS compiler optimizations
- The flag of
will limit the "old generation" max size to 350 MBytes, effectively limiting the memory usage of node.js--max-old-space-size=350
- V8 flags in node.js:
display a list of all v8 flags.node --v8-options
Unofficial documentation:
https://github.com/thlorenz/v8-flags/blob/master/flags-0.11.md#max_old_space_size-0-integer
- For-idx or for-each: https://jsperf.com/fast-array-foreach
node.js and javascript in browser - good practices
Autorestarts
- during development: nodemon. Don't manually kill and restart server for each iteration of code development.
- for qa/production: forever - for simple, manual, 1-2 server deployments.
For anything bigger, automate (docker + kubernetes is a good example, but not the only solution).
- any form of live-reload instead of hitting F5:
- Webpack dev server: when developing FE, it auto-compiles and auto-reloads in the background.
- I mostly use the one which is a part of Kinession Framework, but there is plenty of choice of packages for each of your beloved frameworks: Angular, React, Vue - have their own development servers. Also Webpack has its own live-reload solution.
- Webpack dev server: when developing FE, it auto-compiles and auto-reloads in the background.
NPM
- Enforce lockfile
- Install in CI modemake sure you’re doing a clean install of your dependencies:
It can be significantly faster than a regular npm install by skipping certain user-oriented features.npm ci
- Install for production env:
npm install --production
- Read this: 10 npm Security Best Practices
Good OOP
KISS is king, OOP is another king, functional programming is one another king. :)Prefer modular architecture, instead of monolith. But also learn what mono-repo is.
Don't reinvent the wheel - there is plenty of code packages for most of stuff you want to do. But don't be afraid of writing your own code - when what's available is just weak.
Forget false promises of "the only one framework" like Angular, React, Vue, etc.* - these will not solve a problem of NOT having architecture in your project.
* I'm not saying not to use them!
Callback hell ? Promises chasing other promises are "promises hell". Think about structure, design your code, log stuff, think again.
Functional, OOP and classes
For people coming from C++/Java/PHP/similar the main architectural entity is the class. It's important to understand, that class is considered as antipattern in JS as per 2017-2019. That's strongly opinionated thing, but JavaScript OOP is now encouraged by composition, instead of class-based architecture.JavaScript's 1st citizen is Function, not class (yes, in ES6 too). Functional programming is king.
A lot of reading/watching below. if you're not convinced, watch/read even more - it's important to understand benefits of non-class based approach.
- Some intro: Not awesome ES6 classes and 10 interview questions for JavaScript developer
- Good explanation of inheritance problems - they WHY: You should favor composition over inheritance in Java. Here’s why.
- Composition vs inheritance: quick thing on YouTube and the Article about barking, pooping and driver-killer-robot
- In context of React: https://stackoverflow.com/questions/46648493/should-react-redux-development-be-object-oriented-programming-or-functional-prog
- In context of Angular: http://blog.wolksoftware.com/the-rise-of-functional-programming-and-the-death-of-angularjs
- The comparison, code example of how to implement "class/extends/super" between ES6 and ES5: http://es6-features.org/#ClassInheritance
- 3 Different Kinds of Prototypal Inheritance: ES6+ Edition:
- Stampit library and its API, which provides some sugar to "Create objects from reusable, composable behaviors"
- Class-based compositions pattern - use of "class extends mixins" and use of "self"
- Guide to Functional Programming
- Performance comparison - how much memory it takes to use prototypes vs closures vs Object.create()
Good logs
Log a lot and often. Log EVERY error. Log every warning.It's easier to get through good logs when something strange happened, than to investigate from "zero" point.
Don't safe too much of space - MBs and GBs of logs per day are managable.
I log witk K.Log as it logs with a good "context path" (machine->app->http_connection path), but there is plenty of libs.
Auto tests
Runner: Mocha.js, new kid in the block (2018) - Jest.jsWeb testing: Selenium. If you need more stuff: karma.
Do not ignore tests, do not disable test - they are there for the reason, they make your development quicker, more agile. Skipping, ignoring, disabling - makes your test-suite aging fast, after some time making it unusuable.
Do not write too many tests - testing too obvious stuff makes developers slower not faster.
Do not write unit tests for what is not an unit: think twice if it's better to test a thing at the module level, or API level or UI level. It's rare case that you need them all.
Too many tests on too many layers - slow development. Not enough tests or stupid tests - slow development.
Links
- You Don't Know JS - great book - must read !
- https://www.airpair.com/node.js/posts/top-10-mistakes-node-developers-make
- best practices for Express applications: https://expressjs.com/en/advanced/best-practice-performance.html
- 23 node js security best practices: https://medium.com/@nodepractices/were-under-attack-23-node-js-security-best-practices-e33c146cb87d
- Meta programming with Proxy Object: https://blog.greenroots.info/metaprogramming-an-introduction-to-javascriptes6-proxy-cjwkk64ly000gvds10db4l034
CSS
About JS/GUI Frameworks
- How Virtual-DOM and diffing works in React
- How Virtual-DOM really works - and what React.createElement() actually does
Some "psychology" of JavaScript
The concept of JavaScript fatigue - "Everything is amazing and nobody is happy."General Web
- The UK government approach to "Progressive enhancement": https://www.gov.uk/service-manual/technology/using-progressive-enhancement which is "based on the idea that you should start by making your page work with just HTML, and consider everything else an extra".
General code
Some general node.js
npm install --global --production windows-build-toolsHTTPs/TLS, security certificates, encryption
- https://www.ssllabs.com/ssltest/analyze.html
- https://letsencrypt.org/docs/certificates-for-localhost/
- https://www.openssl.org/docs/man1.0.2/man1/req.html
Rendering to browser from node: Electron, Carlo
CarloElectron-gitbook
Using forever to run/restart/stop node.js server
This line is the main hint:sudo forever -l log_production.log -o log_production.out -e log_production.err start -c "nodejs --max_old_space_size=300" production/src/run_production.js
WARNING: Look for max_old_space_size instead of max-old-space-size - which is advised in many old forums/stackoverflows etc.
Restarting and listing:
sudo forever list
sudo forever restart <uid>
sudo forever stop <uid>
Deployment, containers, docker, Kubernetes (k8s)
"If you’re doing automation, you’re already doing something right. It’s not about how you do it."- Use Docker to Create a Node Development Environment
- Nice intro-s to kubernetes:
HTML, CSS, Frontend libraries
Login, Authentication, Security
- OAuth explained: OAuth 2 simplified, OAuth 2.0 simplified guide
- Understanding JSON Web Token Authentication (or simply JWT)
- 23+ node.js security best practices
NPM, packages
npm and the Future of JavaScript by Laurie Voss from npm, Inc.Transpiling
How to serve ES6 to modern browsers, and ES5 to old ones.HTTP2
HTTP/2CoffeeScript is dead
We loved CoffeeScript at some point and 99% of node.js/browser code we did in CS.However, now with ES6 in place, the CS is a bit of dying thing.
Some thoughts:
- The tool which is good enough to convert CoffeeScript to Javascript: https://github.com/decaffeinate/decaffeinate
- return: it produces a lot of return statements at the end of functions which don't make sense - it's because of "functional" nature of CS
- Array.from: in many/all for-loops which iterate over arrays it does Array.from(), which in many cases is useless and makes the code harder to read/optimise. And this breakes IE11
- get the good thinking about ; (semicolons). We decided to have a loose policy - we mostly leave them in the code.
- formatting of linebreaks around {} and few other formattings
- an ugly hack for class constructors, where this code:produces a lot, lot of noise JS code
constructor: (@x, @y) -> super()
- return: it produces a lot of return statements at the end of functions which don't make sense - it's because of "functional" nature of CS
- Reading/editing CS is a big pleasure for us, while JS looks a lot more clunky
- ES6 classess work well, the one missing point is static class variables (or class consts !)
- we use a lot of namespacing for class names (react does it too ?)which doesn't work with ES6 classes.
class K.somethingA extends K.somethingB ...code of the class...
The ES6 pattern is ugly:K.SimpleObjectReadRemoteModel = class K_SimpleObjectReadRemoteModel extends K.Model { ...code of the class... }
- we really miss @. I mean this:comparing to this:
this.fieldA = this.fieldB + this.fieldC;
when code is more advanced makes it a lot harder to read now...@fieldA = @fieldB + @fieldC;
- we miss good existence operator
It means this:is nowif x? @set(x)
In our Kinession framework we use "operators" on K.Object:if (typeof x !== 'undefined') { this.set(x); }
However, still, writing CS code of:K.isExistent(x) K.isNotNull(x) K.isNotEmptyString(x) K.isUndefined(x)
is now a huge pain.main?.instance?.of?.some?.class?.setVariable(x)
Libs, Frameworks, tools etc.
- Enquirer - Stylish CLI prompts that are user-friendly, intuitive and easy to create.
- How express.js works - Understanding the internals of the express library
- Frontend
- Good intro to Webcomponents in context of React - contains a number of references to quite good libraries (Inferno, Preact, Snabbdom, virtual-dom and few more)
- w2ui - Nice small GUI library (no react/angular crap). The Grid is quite good !
- https://modernizr.com/ - "Modernizr tells you what HTML, CSS and JavaScript features the user’s browser has to offer."
- https://www.polymer-project.org/ - the Power of Web Components. Polymer is a JavaScript library that helps you create custom reusable HTML elements, and use them to build performant, maintainable apps.
- Good intro to Webcomponents in context of React - contains a number of references to quite good libraries (Inferno, Preact, Snabbdom, virtual-dom and few more)
- List: awesome-nodejs - github/open list of packages and resources
- UML style pictures in documentation: https://mermaidjs.github.io/
- Annotator: http://annotatorjs.org/ - to annotate PDF
Other stuff
node-gyp and Python problems
If you haven't got python installed along with all the node-gyp dependencies, simply open Powershell or Git Bash with administrator privileges and execute:npm install --global --production windows-build-tools
Bonus
- Play Diablo in browser: https://diablo.rivsoft.net/
Some code snippets
- Node.js performance quick check:
const { performance } = require('perf_hooks') const timings = { dataPoints: [], triggerDisplay: () => { setTimeout(() => { //console.log('timings:', timings.dataPoints) let stats = { sum: 0, cnt: 0 } timings.dataPoints.forEach( (point) => { stats.sum += point stats.cnt++ }) stats.avg = stats.sum / stats.cnt //console.log(stats) }, 800 ) } }
Node.js: too many open files (on linux)
You see something like this:Error: EMFILE: too many open files, watch...
at FSWatcher.start (internal/fs/watchers.js:169:26)
I'm using Ubuntu at the moment and running lot of visual studio code, nodemon and node.js instances at once.
Quick things to check:
- limits per user, all things:
or more specific - limits just for files:ulimit -a
ulimit -n
- general limits for processes in your system:
prlimit
- system settings (look for fs.* which relate to "file-system")
or simply:sysctl -a
$ sysctl -a | grep fs.file-max fs.file-max = 308115
- Count open handles:
sudo lsof | wc -l
Now depending on which limit you hit, different things to try...
- Edit the following file
Add the following lines to it/etc/security/limits.conf
root soft nproc 65535 root hard nproc 65535 root soft nofile 65535 root hard nofile 65535
(TODO - more on that later)