amount of components
in the world
time
mistakes made building
components
time
learning about
components
time
Cristiano Rastelli @areaweb
💾
🎨
Model
View
Controller
Model
View
Controller
<a href="/notifications">
Notifications
</a>
a
img
h2
span
em
a
img
main
h2
span
div
em
h4
strong
nav
h2
span
div
em
a
img
nav
span
div
em
img
nav
h2
span
div
em
Components
React
Ember
Vue
Web
components
Angular
Svelte
lit-html
Polymer
Preact
search
feed
tweet
tweet
tweet
form
input
icon
The examples in this deck use React
But this is not a React talk
That's the theory...
Let's get into the reality...
our eight year old app is built on Backbone!
we've got a bunch of old Angular 1 components we can't prioritise ugprading
we have a bunch of 6 year old jQuery that functions perfectly well
Components are designed to be black boxes of functionality
We'd like a nice carousel on our home page
<fancy-carousel
speed="1000"
infinite-playback
></fancy-carousel>
strive for black box components
black box components let you work in isolation
thread.com/shop
We've had bug reports on the site where users are unable to like or dislike individual items. Please could you investigate? Thanks!
thread.com/shop
thread.com/shop
thread.com/shop
thread.com/shop
ItemCard
ItemCard
<ExclusiveBadge />
<ItemImage />
<ItemShipping />
<ItemDetails />
<ItemSize />
<ItemSentiment />
/item-sentiment
sentiment.js
sentiment.module.css
sentiment.test.js
sentiment-positive.svg
sentiment-negative.svg
keep as little in your head as possible
the re-usability seesaw
feed
tweet
tweet
tweet
these are all the same component
👩💻 please build a component to view an item of clothing on Thread.com
Done!
<thread-item
product-id="1234"
></thread-item>
👩💻 sometimes it needs to show the brand as well as the title
Done!
<thread-item
product-id="1234"
include-brand-name
></thread-item>
👩💻 and we need to specify if to show the old price alongside the new sale price
Done!
<thread-item
product-id="1234"
include-brand-name
show-old-price-sale
></thread-item>
👩💻 and sometimes we might not want sentiment
Done!
<thread-item
product-id="1234"
include-brand-name
show-old-price-sale
no-sentiment
></thread-item>
more options lead to more confusion
Present Jack
Past Jack
Future Jack
Present Jack
Past Jack
Future Jack
he's an idiot
Present Jack
Past Jack
Future Jack
actually, he's always trying his best
Past Jack
remember, there is no such thing as a bad decision, only a decision made with less data than you have now.
so great job, past Jack! 👍
Present Jack
Past Jack
Future Jack
what can I learn from Past Jack?
that will make Future Jack's life easier?
this does not work well!
<thread-item
product-id="1234"
include-brand-name
show-old-price-sale
no-sentiment
></thread-item>
the seesaw creeps up on you
You will constantly trade off maintainability and configurability
This is one of the hardest things to get right consistently
"Compact"
"Feed"
"Full"
nearly the same
allowing components to differ slightly when required
variants
export const variants = {
FULL,
COMPACT,
FEED
}
Encode an allowed set of variants rather than individual options that can be toggled on or off.
<ItemCard
variant={variants.COMPACT}
/>
Users can explicitly pass in the variant they want.
always prefer explicit configuration over implicit options
breaking components down
components are cheap, but not free
maintaining the component
£
complexity in the system
£
communication between components
£
documentation
£
components should be small and you should have lots of them
component size
and complexity
time
When is a component ready to be split up?
How many lines of code is it?
How "hard" is this component to understand?
How many different HTML elements does this component render?
Is the component hard to name? Do I naturally want to put "and" in the name?
🤦♂️ItemNameAndPrice
there are no hard rules here - find a set of guidelines that you're comfortable with
breaking the black box abstraction
could you pick up a component and drop it into a new project with no additional work or setup?
not all of your components can or should be black boxes
hello...is anyone there?
Your app's data
Your app's components
how do we give a component data?
fetching from an API
via attributes passed in HTML
via data in script tags
1
2
3
fetching from an API
1
✅ Component always has the most up to date data
✅ Easy to re-fetch the data later.
❌Have to handle error state
❌JS dependency on showing the user anything
via attributes passed in HTML
2
✅ no API required to fetch data
✅ no error state
❌long strings in HTML
❌data might be out of date by the time it's rendered
via data in script tags
3
✅ useful for data that's global across your system
❌can get outdated
❌user could change this data - so be careful what you use it for!
fetching from an API
via attributes passed in HTML
via data in script tags
1
2
3
the path to components in your application
2 years ago
Today
software migrations
time
ground up rewrite
value added
time to reach feature parity
slower at first as you build tools to bridge the legacy gap, but quickly you're shipping and adding value
incremental rebuild with new features
shipped and building new features
incremental rebuilds let you test assumptions
how we adopted CSS Modules at Thread
🤓 hey, I think we should try CSS Modules at Thread because...
👩💻 sounds great to me, let's give it a go on the next component we build!
Regular CSS, global styles, trying to name things uniquely
CSS Modules
Replace the CSS Modules component with our usual solution. We learned a bunch and reversed out easily.
Decide on next step:
Yes, all your components should be built using the same technology.
But don't let ideals get in the way of experimenting and trying something new.
A failed experiment is a great chance to learn.
It's easy to get bogged down comparing and debating different frameworks, libraries, and approaches
It's quicker to just try it.
Thank You
javascriptplayground.com
fishandscripts.com
@fishandscripts
@Jack_Franklin
<div>Icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></div>