Gian Marco Toso
Drinking coffee and saving the world. Software Engineer and professional geek
A talk about choices and technical debt
Gian Marco Toso
@gianmarcotoso
gianmarcotoso
gianmarcotoso.com
polarityb.it
Software Engineer, The Pirate I Was Meant To Be
Born and raised in Turin, Italy
@gianmarcotoso
gianmarcotoso
gianmarcotoso.com
polarityb.it
MSc in Computer Engineering
Self Employed Consultant and Software Engineer
JavaScript and PHP Developer
Docker
PHP/Laravel
"It was working on my machine!"
The monolith is here to stay
NodeJS/TypeScript
Seriously, it's awesome!
React + Redux
The Flux Capacitor!
Starting a new project requires decisions
Decisions are hard
Problems are not solved all at once
Divide et Impera
Presentation
State Management
Tooling
Testing
Environment and Configuration
Error Handling
Logging
Styling
Accessibility
Folder Structure
Asynchronous Call Handling
Offline Capabilities
Mobile Support
Real-time Capabilities
Performance Considerations
Source Language
Most developers turn to boilerplate projects
There are *a lot* of boilerplate projects
The most popular React Starter Kit, made by Facebook
Come with most choices already made, out of the box
A powerful tool (especially for beginners)
An excellent reference for everyone
Does it have most of what I'm looking for?
Can I justify all the choices that have been made?
Could I build it myself from scratch?
Are its dependencies up to date?
State Management
Bundling
Testing
A State Manager is required for most real world React applications
Using a State Manager instead of managing state within React is more future proof
A State Manager helps address many concerns, such as:
Error Handling
Logging
Asynchronous Call Handling
Performance Considerations
There are many State Managers available, but you'll probably end up choosing one of these:
Redux
MobX
+ MobX State Tree
+ Middlewares
Let's choose Redux as our state manager. Which middlewares could we use?
Async Data Flow
redux-thunk / redux-saga / redux-observable
Logging
redux-logger / redux-devtools / custom middleware
Persistence
redux-persist / localforage + custom middleware
Tooling
Testing
State Management
A well configured toolchain will make our app lighter and more performant
Tooling addresses many concerns, such as:
Source Language
Folder Structure
Styling
Environment and Configuration
Performance Considerations
We'll want to use a transpiler to convert our code from the source language to plain JS.
Babel
TypeScript
+ Presets / Plugins
When using Babel, we need to choose a preset and add plugins for features which are not yet standard
Presets
@babel/preset-env + @babel/preset-react
Plugins
@babel/transform-runtime (async-await)
@babel/plugin-proposal-class-properties (class properties)
@babel/plugin-proposal-object-rest-spread (object spread)
@babel/plugin-syntax-dynamic-import (dynamic imports)
And of course we want a bundler to put things together
Webpack
Parcel
+ Plugins / Configuration
We'll need to setup loaders and plugins to build things the way we want to
Loaders
babel-loader (JavaScript)
ts-loader (TypeScript)
style-loader / css-loader / sass-loader (CSS, SCSS)
file-loader / url-loader (images and assets)
Plugins
SplitChunksPlugin (chunking)
UglifyPlugin (minification)
We might want to use a more featured engine for CSS, but we could also go with plain CSS or CSS-in-JS
SASS / SCSS
PostCSS
Tooling
Testing
State Management
Testing our code makes it more predictable, and easier to reason about.
While testing doesn't cover any secondary concern directly, it encompasses most of them.
We need to be able to run our tests. A test runner allows us to do just that.
Jest
Mocha
+ Chai
Since we test React components from the CLI, we need a library to help with that.
Enzyme
React Testing Library
Instead of creating JS files to store configuration, it's good practice to use environment variables
The dotenv node package and Webpack's DefinePlugin can be used in concert to inject the configuration inside our compiled code
// env.js
module.exports = {
serverURL: process.env.SERVER_URL
logToken: process.env.LOG_TOKEN
}
// webpack.config.js
plugins: [
new webpack.DefinePlugin({
config: JSON.stringify(require('./env.js'))
}),
]
Choosing a folder structure for a project can be hard, and there is no solution that fits all projects
+ src/
+ app/
+ auth/
+ components/
+ connectors/
+ services/
+ sources/
+ views/
auth.routes.jsx
+ components/
button.component.jsx
+ core/
app.store.js
+ resources/
+ styles/
+ utils/
index.js
package.json
webpack.config.js
It's usually a good idea to separate by domain
React is just a UI library, the rest is up to you.
Making all this choices is hard, and every library you add will contribute to the project's overall technical debt
When adding a library, always make sure that
you really need it
it's regularly maintained
issues get resolved
(ideally) it has more than one contributor
Thank you! :)
By Gian Marco Toso
Slides for my talk at the 2018 WebAppConf in Torino
Drinking coffee and saving the world. Software Engineer and professional geek