time in the world amount of components

time components mistakes made building

time components learning about

WHAT ARE COMPONENTS ?

Cristiano Rastelli @areaweb

WHERE HAVE WE COME FROM ?

Model

Model View

Model View Controller

Model View Controller

Model View Controller

Model View Controller

Model View Controller

<a href=”/notifications”> Notifications </a>

n h2 div n main an div na v em div an em img sp an em em sp a em img na v h2 a na img v div a sp a sp img str ong sp 4 h h2 a h2

Components

React

React Svelte

React Svelte Polymer

React Svelte Polymer Web components

React Svelte Polymer Angular Web components

React Svelte Vue Polymer Angular Web components

React Svelte Vue Polymer Angular lit-html Web components

React Svelte Vue Polymer Preact Angular lit-html Web components

React Ember Svelte Vue Polymer Preact Angular lit-html Web components

twitter feed search form icon tweet input tweet tweet

The examples in this deck use React

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’v e got Ang a bu ular n c can 1 c omp h of o ‘t pr ld one iorit nts ise we ugp radi ng

we h ave a bu jQu n ch o ery f6y tha ear t fu per ncti o ld fect ons ly w ell

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

<ExclusiveBadge /> <ItemImage /> <ItemShipping /> <ItemDetails /> <ItemSentiment /> <ItemSize /> ItemCard

<ItemImage /> <ItemShipping /> <ItemDetails /> <ItemSentiment /> <ItemSize /> ItemCard

<ItemShipping /> <ItemDetails /> <ItemSentiment /> <ItemSize /> ItemCard

<ItemDetails /> <ItemSentiment /> <ItemSize /> ItemCard

<ItemSentiment /> <ItemSize /> ItemCard

<ItemSentiment /> ItemCard

/item­ sentiment sentiment.j s sentiment.module.c ss sentiment.test.js sentiment­ positive.svg sentiment­ negative.svg

keep as little in your head as possible

e h t i l i b a s u re w a s e e s y t

twitter feed these are a ll the same comp onen t tweet tweet tweet

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-brandname ></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-brandname show-old-pricesale ></thread-item>

and sometimes we might not want sentiment

Done! <thread-item product-id=”1234” include-brandname show-old-pricesale no-sentiment ></thread-item>

more options lead to more confusion

Past Jack

Past Jack Present Jack

Past Jack Present Jack Future Jack

Past Jack Present Jack Future Jack

he’s an idiot Past Jack Present Jack Future Jack

actually, he’s always trying his best Past Jack Present Jack Future Jack

Past Jack

remember, there is no such thing as a bad decision, only a decision made with less data then you have now. Past Jack

remember, there is no such thing as a bad decision, only a decision made with less data then you have now. Past Jack so great job, past Jack!

Past Jack Present Jack Future Jack

“ Past Jack what can I learn from Past Jack? Present Jack Future Jack

“ what can I learn from Past Jack? Present Jack Past Jack “ that will make Future Jack’s life easier? Future Jack

this does not work well! <thread-item product-id=”1234” include-brandname show-old-pricesale no-sentiment ></thread-item>

e h t u s p e e r c w a s e e s u o y n o p

You will constantly trade off maintainability and configurability This is one of the hardest things to get right consistently

“Feed” “Full” m o C ” ” t c a p

“Feed” “Full” m o C ” ” t c a p

“Full” “ e m “Feed” a s e h t y l r a e n m o C ” ” t c a p

allowing components to differ slightly when required

variants

Encode an allowed set of variants rather than individual options that can be toggled on or off. export const variants = { FULL, COMPACT, FEED }

Users can explicitly pass in the variant they want. <ItemCard variant={variants.COMPACT} />

always prefer explicit configuration over implicit options

breaking components down

components are cheap, but not free

£ maintaining the component

£ maintaining the component £ complexity in the system

£ maintaining the component £ complexity in the system £ communication between components

£ maintaining the component £ complexity in the system £ communication between components £ documentation

components should be small and you should have lots of them

and complexity component size When is a component ready to be split up? time

and complexity component size When is a component ready to be split up? time

and complexity component size When is a component ready to be split up? time

and complexity component size When is a component ready to be split up? time

?

? How many lines of code is it?

? How many lines of code is it? How many different HTML elements does this component render?

? How many lines of code is it? How many different HTML elements does this component render? How “hard” is this component to understand?

? How many lines of code is it? How many different HTML elements does this component render? How “hard” is this component to understand? Is the component hard to name? Do I naturally want to put “and” in the name?

? How many lines of code is it? How many different HTML elements does this component render? How “hard” is this component to understand? c i r Is the component hard to name? Do IdP n A ename? naturally want to put “and” in the m a N m e t I ♂ e

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

“ an yo hel ne lo th …is er e?

Your app’s data Your app’s components

Your app’s data Your app’s components

Your app’s data Your app’s components

Your app’s data Your app’s components

how do we give a component data?

1 fetching from an API 2 via attributes passed in HTML 3 via data in script tags

1 fetching from an API 1. Component renders loading spinner 2. Make request to /api to fetch JSON 3. Parse response 4. Render data onto page

1 fetching from an API ✅1.Component the most up to date data Componentalways rendershas loading spinner 2.Easy Maketorequest tothe /apidata to fetch ✅ re-fetch later.JSON 3. Parse response ❌Have to handle error state 4. Render data onto page ❌JS dependency on showing the user anything

2 via attributes passed in HTML

2 via attributes passed in HTML ✅ 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

3 via data in script tags

3 via data in script tags ✅ 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!

1 fetching from an API 2 via attributes passed in HTML 3 via data in script tags

the path to components in your application

2 years ago jQuery, jQuery and more jQuery Server side templates with Django No true component system in place Today ~100 components across the site Reusable components make it easier for others to contribute Starting to form a Thread design system to improve consistency We’ve never stopped shipping features.

software migrations

value added ground up rewrite time to reach feature parity time ew n g n i d uil b nd a d e p p shi es r u t fea

value added ground up incremental rewrite rebuild with new features time

value added ground up incremental rewrite rebuild with new features time

value added ground up incremental rewrite rebuild with new features slower at first as you build tools to bridge the legacy gap, but quickly you’re shipping and adding value time

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

Regular CSS, global styles, trying to name things uniquely

Regular CSS, global styles, trying to name things uniquely CSS Modules

WE DISLIKE IT Replace the CSS Modules component with our usual solution. We learned a bunch and reversed out easily.

WE DISLIKE IT WE LIKE IT! Replace the CSS Modules component with our usual solution. We learned a bunch and reversed out easily. Decide on next step: enforce that every component uses CSS Modules from now on decide to experiment or figure out how to answer any more concerns that we have.

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>