amount of components

in the world

time

mistakes made building

components

time

learning about

components

time

WHAT

ARE

COMPONENTS

?

Cristiano Rastelli @areaweb

WHERE

HAVE WE

COME FROM

?

💾

🎨

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

twitter

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

twitter

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

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

✅ 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

  • 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

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

WE DISLIKE IT

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

WE LIKE IT!

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>

Made with Slides.com