This graph shows how many times the word ______ has been mentioned throughout the history of the program.
Bueno, gracias a todos por venir.
Este talk, como puedes leer,
del título de Catch,
es sobre cómo hacer un reaccionado
y cómo estamos haciendo en el puzzle.
Pero, espero que todos
obtengan algo de esto y pueden aplicarlo
en tus compañías.
Voy a intentar muy difícil hacer eso.
Y en caso de esto,
para ser muy interactivo
y asegurar que se aplica a todos,
puedes sentir free to interact with me
a any point,
any question,
we have a lot of time
and I'm ready to answer anything you want
if I'm able to.
So, let's get started.
Basically, I'll split the talk
in these four sections.
We'll start with a short intro to the puzzle.
The goal here is to understand
exactly what our technical needs are,
what our current stack is,
what kind of application we are working with,
because the migration to react depends
really on what kind of app you're working with,
all the requirements and that stuff.
So, it's good that I introduce
the application because you will understand
more of the decisions we took later
with more context.
Then I'll go through the step-by-step
of the migration journey and the conclusions
y, finalmente, we can end up with more questions
if you have any.
So, as a short introduction to the puzzle,
well, an education media platform
that was founded four years ago
by three colleagues of mine and myself
in the USA.
We basically allowed teachers to
search for any video on the internet
or upload their own
and then quickly edit it
and make it a very useful lesson for the classroom.
Basically, they can do stuff like
cut the video, add questions in between
that would pop up as the student watches
for their voice, things like that,
just to make the video personal and ready
for the specific students that teachers
work in.
And in the end, when the teacher assigns it
to their students, they can watch it in any platform
and the teacher will start to get insight
of who needs help, who understands, who can move on,
etc., etc.
So, basically making video useful for education
instead of just looking for the number of
views on your YouTube video,
which doesn't tell you much about how your
students are learning.
This would be, for example, a very simple
lesson.
Somebody took a video from YouTube
and they added four questions in the end.
These questions are there, for example,
to check for understanding, maybe trigger some thoughts,
start a debate in the classroom, whatever.
The important part is that after the student watches
this very short video, the teacher will know
who watched it, who didn't, who got stuck
in which areas of the video, maybe that will help
the teacher have a more informed decision
about what to do next.
And there are many education apps now
based on video, but I want to clearly
explain from the rest.
You probably know as developers,
platforms like Udacity, Coursera,
even Khan Academy, if you're learning math
and stuff like that.
This platform, based on the
student, you can individually go to them
and start learning by yourself.
We follow a different path.
Basically, we believe that in order to
reach the 23 students, the 30 students,
in every classroom you have to help the teacher.
Otherwise, the teacher feels hopeless
and basically teachers
are a community that is very undervalued
and they need more technology to help them
rather than replace them in the classroom
which other platforms who are more student-centered
try to do.
We believe firmly in supporting the teacher
in this sense.
And after four years working on this project
we have now two offices.
We started in San Francisco in an incubator
there, but we have a technical office
now in Barcelona.
And at the moment, more than 16 million
teachers and students have used our platform
creating more than 5 million lessons
and that's approximately 50% of the schools
in the USA.
So the penetration has been great
and we're really proud of this
and it keeps learning quite fast.
So what are the technical specs for our application?
It's basically a single-page app
with a lot of applications inside,
things like the video editor, the player
with all the tracking in the background,
the progress reporting for each assignment
for a whole classroom, for an individual student,
all the classroom management stuff
like which student joins which classroom
and stuff like that.
But also a platform for the schools
and even things like a grade book
which would be, for example, the more state heavy view
you would have in an app like this.
So there's a lot of front and state
both written right, it's not just like a reporting system
you have to modify a lot of state in the video editor,
great stuff, give feedback to the students
so there's a lot of back and forth
and this makes the application
quite complicated.
And at the moment, well not anymore
we're reading in background and marionette
which is what we started with four years ago.
So once you have a little bit of context
of the technical aspects of the application
the kind of traffic we're getting
and the kind of work that we have
to do because of the traffic
you have a little bit more of an idea
of with a small team that we have now
which is slightly over 20 people
how can we handle all this and still migrate
and make these technical changes on the go.
So the journey.
Why even react?
Did we, for example, choose to use redux or not?
It's important
to set the goals here as well
which is the things that we want to improve
because of these decisions
and then split into the strategic decisions
for business, this is more than anything
which end up being constraints
be it in time, in resources, whatever
and then the technical decisions emanating
from these strategic decisions.
Finally, we'll dive a little bit deep into the implementation
I'll show a little bit of code
not to really understand it
but basically the goal here is to show you
how little code you need to actually do
the integration between two stacks
and finally the edge cases
we all have them, these are the edge cases
that take most of your time at work
so it's fair that I mention them
because not everything is always ideal
in a quick summary.
So why even react in the first place?
Basically as I said
we have a lot of state in our app
but most importantly some of it changes over time
and the center part of it pauses a video
which advances through time
there's a lot of things we track for the video
where the student is like
the question should be open, leave an audio
in the middle of the video should pop up
and video is very unpredictable
as soon as a student enters with a mobile phone
inside a tunnel for example
the internet must be gone so there are lots of little states
where you can end up with
and you don't really know how
when you get a lot of customer support
of different cases so development wise
and having lots of cases that you need to have in your head
in order to make changes
so this is very unmanageable after a while
and background, the people who already program with it
know that it's a very imperative way of programming
and then while react
it's not just a technical decision
we have done trainings internally
we have experimented and the team likes it
I think the second part is the most important
but it's also like if your team doesn't like it
you shouldn't even start
and for those who don't understand
what the concept of imperative and declarative code is
the one on the left
you give orders in time one after the other
to reach for example from
work to intake today
and on the right you have
basically just a screenshot of the journey itself
so on the left to go from my work
to intake there are many ways I could have followed
so imperatively maybe if there's a change in traffic
there will be many many cases
that you would have to account for
Google does that for us
so we don't have to worry
but you can agree that the right one is much more clear
which path I follow instead of just having to
accumulating the brain
all the steps I had to follow to arrive here
and also
did we end up using redux
I made it a goal of the top
for redux not to be something you need to understand
to understand the migration
I hope I have a country stat
but it's fair to say that we did end up using redux
mainly for the same reason I said before
redux is just a different way to handle state in react
a way to extract it from the components
and because we have a lot of rights and reads
it was something that we were very interested in
so
we have a lot of state across our apps
and the way that redux forces you to
extract it
really saves us a lot of time
and also because in our app
we have a lot of shared state between different applications
other applications for example
banking where each screen has its own state
you probably don't need redux as much
because that state doesn't need to live
over time or stay in memory in any case
you just move around the app
and the users are not so usual
they stay in a view for the longest time
so the benefits there are not so great
but for us it really
was very important
and more than this as well
another reason was that our state is very complex
there's a lot of nested stuff for example
an assignment has a video
the video has an unknown amount of questions
each questions can have many answers
there's just a lot of state that is nested
and if you try to do it in backbone
you're gonna lose some hair
and then another benefit that redux brings us
is the testability of our mutations to that state
not only that but it also
serves as a documentation of all the possible mutations
that we have so that even helps onboarding
new developers
and
before diving into the code and everything else
let's set the goals clear
because these are the goals that we're gonna rely on
whenever we have a crossroad
and we have to go one path for another one
first, the business goal
I'm one of the founders of the puzzle
it's something I
pay a lot of attention to
because we have a small team
so we have a view of what's going to happen in the future
and business is very important to make the technical decisions
so first of all
we don't want to disturb the roadmap
basically because it's quite full already
we have a lot of teachers
a lot of staff that we need to implement
but also we go over requirements
we all know GDPR is coming in May
so that's also something stuck in your roadmap right now
and it cannot be moved
and the technical goal was
how can we improve the overall team communication
with this change
for example, Align the Design team
and the Frontend team
and then as a result
increase the quality of our product in the end
which is what we all want for our teachers and students
the technical goal
was quite ambitious
which is how do you start using React and Redux
as easily as if you were starting
that from scratch
while still having the legacy code right there
with zero impact to your teachers and students
so they should not even notice
there's a technical change happening
but the developer experience that you have
when you're starting a new React and Redux application
is great and that's one of the reasons why we all
when we see it for the first time we say
this is much better than what I'm doing at work
so how can we accomplish the same benefits
without having to throw away everything we've done
for four years
and finally the design goal
which I mentioned in the business goal as well
which is how can we start using the same language
and the front-end team especially because
as we started this migration
was when we were forming our design team from scratch
so it was a great moment to stop
talk and align ourselves
and on top of all of this
there was in the roadmap a scheduled redesign
and rebranding of the whole company
so we should better align those things
because they're both quite disrupting
in terms of the time we need to invest
so technical decisions
sorry, statistical decisions
basically there are two questions that we have to ask ourselves
is can we do a full rewrite
and we all know the answer is no
otherwise we stop when we get boring
but the reasons why it's not possible
is firstly we take months
probably I'm wrong with this deadline already
it probably takes more than that
and also this is an idea of the education system
doesn't allow us to stop for such a long time
basically we have a lot of traffic
during the semesters so from September
to January
then there's a little break for Christmas
and then until June and December
we don't have teachers using the platform
but no students at all
and then in September we can double ourselves
in a couple of weeks
so there's no easy way to fit the rewrite
so that it doesn't basically take the whole time
where the teachers are at school
and the students are at school
which would be a missed opportunity to improve the product
or for the rewrite to end
right before maybe doubling ourselves
and if we have bugs which every rewrite has
they're gonna be very very incremented
and we're gonna have a very bad time
and it surprises you a lot
because just imagine you're a teacher
and it's summer, a Friday, afternoon
your students just have lunch in plate
in the yard
very strong sports sweating a lot
and then they come back
from lunch to your classroom
they're really nervous
and then you say I'm gonna do something cool
I'm gonna use videos so they are engaged
and then the platform fails on you
it's a very very tough situation to handle
especially if the teacher doesn't have a plan B
so we have to be very very reliable
because even if we have a bug
we only have less than one hour to fix it
or we will have rent
the one hour classroom of the teacher
so we have to have that in mind at all times
so rewrite doesn't sound so good
and then, as I said before
there are some fixed things in the roadmap
we cannot just put all the front end team
all the full stack developers on this
because we have a lot of stack GDPRs one
but other legal changes in the US as well
so those things already require
most of our team
so how can we do this with like one or two people
progressively, it's something that we really need to think about
and the second question is do you renovate
or do you rebuild
you can as well start introducing react little by little
but actually have the same product overall
or you can take this chance
and align every team in the company
doing the redesign, the rebranding, the technical changes
and rebuild parts of your app completely
we think it's a better opportunity
to align those teams
because the metric of success
if you are just making a technical change
is that the pro behaves the same way as before
it's not really so exciting
and in the meantime you will still get customer support request
bugs that you need to fix
so it's not a very good experience
if you have done it before, you probably know it
so we believe that it's much better to rebuild
maybe subsections of the app
but rebuild them from scratch, redesign
align them with our new branding
then actually just making technical changes in the background
which don't benefit the overall product
or the overall company
so these are two constraints
we cannot rewrite
and we are going to remake every part
that we do in React, we are going to rethink it from scratch
so technical decisions
this is partly the part where all your team gets together
and starts idealizing
about how cool it would be to have React
and read us already everywhere in your app
but it's not going to happen anytime soon
you don't see how long it's going to take
you wish the world would stop
in your own time
so you need to scratch your head
and start asking the hard questions
so the first one is
where do we insert React in our current stack
do we do a single build
let's think about this
then if we plan to use Redux
do we do it from the start
or do we wait until most of the state is out of backbone
and do it in Redux already
that's a fair question
and if we are doing this progressively
how do you handle those situations
in the backbone part and React part
that are actually the same
that sounds like a challenge
so we will have to deal with that as well
and then routing, like every application
from the application that is a single page admin
so do we add it from the start
or do we still rely on backbone router
and then later we do a project in the very end
when backbone doesn't create any of our views
and just redo the routing later
that's another question
but before answering this we need to analyze our architecture
where things are
not in your head
because maybe you've been working for two months in a feature
and you can't forget about the rest
so we need to sit down and analyze the whole code base
and in a front end app you basically have these five blocks
sometimes they are together
sometimes they are split
but constantly you have the routing layer
in a single page app
the business logic whatever it is
like handing user interactions
all the authorizations
all the different parts that your app has
like our VDA
the view layer
and then all the state that you accumulate
and the connection with the API
sometimes for example in backbone state an API
together because you do it through models and collections
which not only store state
but they also communicate with the API
so in our case it will be together
so let's find all of this
if we want to make it react we have to find all of these layers
in our app and know where they are
so that will help us answer the questions in the beginning
where are we going to act react
so let's analyze it because we're going to have to
not kill ourselves and then
find the problems as they come but do a good plan
for the future
so what are these parts in our current architecture
this is a super super simplified schema
of how our application is organized
you have an entry point and then
about 25 tenacious applications
for example the classrooms app
and the video app the classrooms app will have
for example the views for showing the classroom
to create a new one, to edit it
the videos app will have like for example all your content
that the teacher has accumulated
the video editor as well
all this kind of stuff
so let's analyze it
I'm going to go for example to the classroom apps
of application and analyze that one
from the entry point and notes down
I'm going to show code
you don't really need to understand it
you just need to know ok in this note
the routing is here, there's state here
there's views here or not
like all the layers that I said
that our funding application has
we need to identify in which note they leave
simple, you start a management application
and then you just call start
and then there's a callback that gets called
where you can start the subapp that your app
is composed with and then you do something very important
which is start listening to the URL changes
so the background can trigger
a different navigation as the URL changes
so in this layer
we basically have routing
it's a very core part of it
there are no routes but there's
this code knows about background history
so it does routing
the classroom app
this one basically has one responsibility
which is define all the routes that the app
cares about
connect them to a controller
that has some methods
basically this show here
with the show right there
and then this receives the parameters from the URL
you do for example some very basic
authentication or authorization here
and if that authorization clears
you can basically
move down to the next note
showing one classroom
so let's go down to that note
but first this layer
what does it do? that's routing
defines all the routes, it does business logic
very little one but it's authorization
and that's business logic and then there's state
because if you can see here
it accesses the session where you store
who's logged in at the moment
so that's already knowing about the state
let's go down to the show
classroom note
and basically
it does two things
it has a controller that gets instantiated
instantiated
and it does three things here
it's simplified with two but instantiate the model
and trigger the API request
then here you would add some listeners
to the view so that the clicks
everything that you want to listen to
and instantiate the view, give it the model
and show it and the view is very simple
it just has a template
very easy to understand, you don't actually need to know
background or marinate to understand this
it has a lot of business logic
because it has all the user interactions
it has the view layer, completely here
state
because it's a state that is holding the model
and then it has API request
because in backbone the models are the ones who connect
you don't have an API client unless you're architected
it that way
if you start from the beginning maybe you use models
and collections in school and later you regret it
when you actually realize that everything stays together
so
back to the initial question
what do we react in this
in this architecture
there are three options that we thought about
the first one
of course everywhere
this would be the rewrite
at least of that set application
first it requires redoing the whole routing layer
because as we saw
the routing layer is in those top two notes
here listening to backbone and here defining all the routes
so if you do this you're going to have to redo
the routing layer for the 25, 26
of apps even if you're trying to just migrate
the classroom app
so it's kind of a lot of work
and the routing layer looks simple until you have to change it
so you have to have the whole context
of the folder app in your head
to change it properly
and then migrating the whole routing layer
it has another drawback
that it's not so obvious it's everywhere in your code
where you're doing navigation
that has to change as well because if you're using a react router
for example that navigation needs to be done in react
router and we all know that imperative
and declarative code
so if you're going to use the link
the red red from react router
it doesn't look so nice
and it's going to be a lot of work
you're going to have to touch almost every file
of your application just to change the navigation
so option one
protect from the get go
option two
this is probably one that you will find
a lot of videos about on the internet
I will link to a top later
if you're interested but that will be maybe starting
from the lowest notes of your tree
react
to change the view layer
so it's very simple
it will require adding react
redact the react router at all
that link is to a talk
from Brian Florence
called I think react
don't rethink react something like that
but he goes to the typical to do app
and he starts changing little components
it's actually from backbone to react
so the ones who are trying to do that migration
it's kind of interesting
one of the business goals
is to not rebuild
not to renovate where we're building each model
where we're designing it from scratch
so this option is not something we can do
because this is perfect when you don't have buy-in
from your CTO
or there's too much stuff
and you don't have to make a technological decision
without disrupting anywhere else in the company
so for us
that we actually decided altogether
that we're going to rebuild its application from scratch
this doesn't make a lot of sense
we don't have
but if you were in a case where nobody actually buys
into react redact
or stopping everything to migrate
maybe this is an option for you
and one of the benefits as I said
is the deepest note we migrate
the more likely we'll have to still use backbone
as a state
and then maybe pass it down as props
so this is something that breaks the technical goal
that we're talking about
where we want to write the new code
as if it was a new code base
we're going to have to know where to put what
it's going to be a lot of context in your head
and that leads to bugs
guaranteed
so option 2 for us
rejected
and option 3
basically means
we're going to have 2 entry points
to the react app and to the backbone app
and as we migrate from the backbone app
to the react app we're going to move the setups there
this sounds cool but that requires a lot of
little
combinations there that we're going to talk about
first it requires doing just a writing layer
of that sort of application
that sounds cool because you can focus only
in one specific app which is quite simple by itself
but
to do that you will have to find some way
to make backbone history and real writer
talk to each other
and that's probably going to take a while
to understand how to do
you're going to have to understand very well how both work
and because we are migrating a note high
in the component 3
architecture
if you know react you already know this
sorry for the navigation
because we're basically making the cut
right here just as in react
the higher the component the more likely it's a container component
the one that owns the state
the higher you migrate the more likely you will not have
to use backbone state
you'll have to make it from scratch with react
so that goes with the technical goal
of writing react only knowing react
without knowing the backbone app
option 3
so you add the end to different
the project right
to different
yeah
no repository just folder structure
well I'll show that to you
so as I said we'll have to
somehow synchronize
the routers so
we can migrate entire cell applications
progressively it sounds like a huge task
but each cell application is quite reduced
we won't need to change other apps in the process
we won't have to change the writing layer
or the way they navigate through the app
we won't have to touch that so you won't have to
relearn what you did or what somebody else did
in order to make the changes without breaking anything
but somehow we have to sync
both routers and another benefit we can have
from this is because we are migrating high
in the component tree we can start adding
redux and use redux as a state container
you won't have to sync it
most likely you won't have to sync it with backbone
we'll see the edge cases later
and you will have also react router from the start
which is basically all the stack
it has the layers of a frontend application
it has routing, it has
business logic, it has views
it has the state and the API request
you can also separate that progressively
so by itself that app could leave
it does a less
full feature application of our company
not very useful but by itself
if you wanted you could cut the backbone app
and it will leave by itself
so that's on school because everything we make there
won't require us to think about the other apps
so it's like starting your own pet project again
with no legacy code, nothing to worry about
so let's dig deep into the code
how we solve the synchronization
between the routers
first how do you keep both apps really separated
so they don't know about each other
and for now let's assume
that each application is a full
like it covers the full screen
it's not like a sub app within a sub app
later we'll go into the edge case
where this doesn't happen
let's assume that the application covers the full app
so the first thing you need to do
is go from for example this
we had some regions that
backbone or marionette in this case uses
as a container for different views
that you can start inserting in them
we have header, main, footer and a modal region
so it's like most apps out there
so we change it from this to this
where we encapsulate the backbone app
there and we create a new node
completely separated in the html for react
then this already
kind of gives you a hint that whenever
the react page has to show
the backbone one has to hide somehow
so you can do this very
periodically like every time I show
like order the other one to hide
or you can start using react and the declarative nature of it
and create a component
that you wrap the whole react application with
and every time this one is rendered
it hides the backbone one
and every time this one gets unmounted from the DOM
it hides the backbone one
because we don't have two frameworks
we have three and we'll have a problem
where we wrap the whole react app with this
and it will magically switch
and I can promise you, you can try later everyone
the user does not see any kind of flipper
at all
so basically
you end up with this kind of architecture
you have a new entry point for react
that connects to the classroom app
and the rest of the legacy code
is leaving somewhere else
and to add the react entry point
you basically just have a file
defining the routes for react router
and that's it
and the application there
the component we created to hide the backbone part
you can actually put it above
if you want to, to not repeat every route
and just for the sake of the example you can see this
and we're connecting to the class
in the HTML that we
purposely created just for the react app
and the folder structure
like you were asking, we are not having to repos here
we're just having, basically
we had an app folder, we create a new one
parallel where we start putting everything
the entry point is the index.js file
and also here is an opportunity to change the wording
instead of calling it subapps
designer thinks about pages
so let's call it pages
it's going to be much more obvious when you talk to the designer
which page you're talking about
because when you do subapps, classroom show
it sounds kind of like crud
create a read update and designers don't talk that way
so let's just change our wording as well
the benefit of this folder structure
is in the end when you start moving things up
you will have to delete the app folder
for backbone and
the migration is done
another thing that is quite important
how do you handle the CSS
because a lot of the CSS has already been created
you can use the same
philosophy here of separating both apps
we decided first to use CSS modules
not add any other
fancier CSS, ings
implementation for one simple reason
not because they are bad, they are actually quite good
but to keep the better of entry low
for the designers to take ownership
of components everywhere
in JavaScript they have to start learning React
from the get go
and they start using their time for something
that they shouldn't be doing
they are good designers because
they are very good at designing
so they become front-end developers
and that's another position
maybe they don't like it
so as a rule we explicitly never reuse
the current CSS rules
we just create also in the folder structure
new CSS for the new application
and we have to finally kill the background app
we just kill the CSS from before
and we start worrying now
how are you going to manage the bundle size
don't worry there is a section for that as well
so also remember that we are redesigning
so the CSS is not going to be the same
there is going to be some common stuff
that you are very very tempted to reuse
but the rule is to not do it
and the new CSS looks quite different from the old one
and for the really interesting part
once we have both apps
living in HTML
differently we have the two entry points
each of them instances in the router
how do they talk to each other
because now there are two apps
that they don't actually know about each other at all
so the user doesn't have the power to move between them
basically
this is the situation that you start with
you have the URL for the browser
and you have background trying to modify it
and react rather trying to modify it
this is not cool
all of their races to change it
but here if you are a new developer
that knows about the react app
and the URL changes from somewhere magical
in the background area
it's going to be very confusing
so we are not going to do this
but there is a better version
thankfully react router is used in many platforms
not just the web
and even it's thought in a way
that it's very testable
so they have different routers
there is a browser one
which is the one that has access to the URL
and you move back and forth
it's just that
conceptually it's just that
so making it live in memory
it's just like using a normal router
it just doesn't have the privileges to modify the URL
but it's an array of routes that you have to navigate
so first thing
this is the way we are going to try to make it work
where
backbone is the ruler
is the one that has access to the URL
and it is responsible for
ok, we move to this URL
because which one to win
why backbone and not react router
because most of the app is written in backbone
so if you make the router be the one dominating
you're going to have to change a lot more code
so the 2D list to make this happen
is make sure react router does not
itself modify the URL bar
from the browser
sync both routers when the URL is changed
when somebody navigates, enters
whatever
also sync it when there's a silent navigation
whenever you change the URL without actually triggering
triggering a route change
and also when somebody navigates
from the react code
react is going to have an navigation as well
so you don't want to have backbone code in the react code
because that breaks the code that we said
that you should write just knowing react
if we start having imperative navigation of backbone
in our react views
we are kind of defeating the purpose
so we're going to have to find a way to do that
the first one
I said it before
this is for example the react app
I just erase some code for the sake of simplicity
but you instantiate
history is the package that react router uses internally
because we are also storing some of the URL
state in relapse we just created
but if you didn't want to do that
just know that history is the package within react router
and it has a method
called create browser history
which is the one that has the privileges to access the URL
so instead of doing this
just do it for the memory history one
ok
very simple change as one line
so the first step done
now it doesn't have privileges to change
second how do you
tell backbone to synchronize react router
basically you need some kind of node
in our idealistic
architecture from before
now we need some node in the middle
that is responsible for making this communication
from the right to the left
so let's look at this node
there is a subapp entry point
where there is a router
so it's something like this
basically you have a router
and marionette has a method called enroute
that gets called every time
a router is hit in the backbone part
so what you have to do is just
have a reference to the history that you are using
in the memory router from react
and just push the path
anytime any of the routes
of any of the subapplication is hit
this is going to get called
after history and then all the routes
that are defined in the react part
will also it's going to look if there's any
route matching that one as well
so if that's the case
if there's a route in react
defined there means that you're already migrated
so in this case when there's a match
you do literally nothing
you don't want to instantiate any backbone app
any backbone subapplication, any view, anything
so you do nothing, this is the final method
that does nothing
and this is going to cover most of the cases
as well every time somebody navigates
back and forth because all of these actions trigger
a change in the backbone router
so it's going to call the onroute
and then it's going to push it to the memory history
from react
but then there's another edge case
which is when you change a URL without triggering
a routing event
when would that happen
it's the same diagram as before
but it happens for example
imagine you are in the video editor
and you are creating a new video
and the user refreshes
after the first save they still remain
the same editor as before
otherwise they may be lost one hour of work
so you probably every time there's
the first API request to create the video
you suddenly change the URL
but you don't trigger a routing change
you want everything to be rendered
especially in a video editor where you need
everything to be living there
no render no fetching HTML
so this is an example
in this situation the onroute from the router
the history from react router
that something has changed
and basically we are lucky here
because we already had a class
called navigation helpers
with a method called navigate
where you pass route and some options
whether it triggers a routing change
or it replaces the previous route
for example in the previous case
it would be like a silent replace
so we had everything we wanted here
centralized in one point
so what we had to do is
replace it from the memory history
and if it's not just push it
so we covered
the third case
and now the fourth one
which is how do I avoid
using backbone history in my react code
imperative navigation with declarative views
and
this is the last of the arrows
that we didn't have to cover
and
navigating as I said
our class
thankfully we created
it feels like a failure to our initial purpose
so what we decided is
how can we implement some custom components
called backbone link
that have exactly the same API
as react routers link
but internally they call navigation helpers
so that's exactly what we did
we went from this
to this we could have called it the same
so that as a developer you didn't even know
it's made with navigation helpers
but it's kind of maybe a lying to yourself
so we prefer to explicitly
know that something's happening there
so that in the end we do a replace everywhere
and explicitly
make the changes
but it has exactly the same props
as a react router one
and you just have to use that in your views in react
and it's gonna work
and you have used the same structure
you would have used in a new app
and everything's working
and this is communicating with backbone
so it's kind of the full loop
and we have the four things
that we wanted to cover
now both apps are completely connected to each other
in an ideal world
where every step application is a full
covers a full screen
this works magical
so one of the ways
that probably some of you that like performance
are thinking about is how do you make this
still performant in terms of network
and as I said we work in schools so the network
is not always the best
in streaming video from our platform
and the rest of things are gonna work slow
so this is quite important
and we did something
that I think every one of you has done before
I didn't mention it before
there's a prerequisite for everything I'm showing today
which is using commonJS modules
or imports
in your codebase we didn't have that four years ago
so we did a step that I didn't find interesting to talk about
which is to migrate to commonJS
kind of importing files
but once you do that you can leverage the power of webpack
but before that we wanted to sit down
and set some goals of what we want to accomplish
because you can spend days and days actually tweaking the config
and earning like a little
kilobyte here, a little kilobyte there
but we wanted to set some goals and be very pragmatic about it
so we agreed with some bundle size limits
and we learned webpack
to the core
which is not that fun
and then we also added one step in our build process
which is webpack bundle analyzer
which gives you a very clear view of
this is not our app
a very clear view of
your component tree
and what things are covering a lot of space
you find things that
like momentJS carries a lot of stuff
this kind of things is very clear
when you have a UI that is open every time
you try to compile or you try to deploy
so it's just thrown
to the face of every developer in the company
so they are very aware of this and don't have to remember to go check it
so we added this
and this already added a lot of the information
we needed
first
we split every sub application into its own file
we have two types
of users, students and teachers
actually which subapps
get used more depends on the hour of the day
teachers don't edit videos during class time
they do it after
during class time it's students mostly watching the video
not doing anything else
you have a very clear case here
where splitting the subapplications has a lot of benefits
because they are used very independently
even if they share a lot of state
especially the reporting part of the teachers
and we also created a vendor bundle
in the beginning like
different frameworks and different vendors
but as we started migrating more subapplications
where it's very hard to avoid
loading both frameworks at the same time
then we joined that in one bundle
you don't have to use webpack, bundle analyzer
and start playing around
playing around with the hashes
configure the CDNs well
and then actually we improved the performance from before
where we didn't have bundle analyzer
and just measuring our performance
with a network of our office
which is not the right way to do
so I would recommend
increase visibility of bundle size to all developers
not just one that knows webpack
but maybe this year
they will learn webpack because they want to solve it
rather than actually having some task about learning webpack
which is a pain
so recap
we can now
with this structure
write react code that is completely unaware of backbone
with the caveat
that we are using backbone link and backbone redirect
which as I said you could have actually named
link and redirect and then there would be no caveat
but we just chose to make it very explicit
that something magical was happening below
backbone code can still call navigation helpers
just as before
so we have to make a change in the legacy code
for whatever reason we can still code the same way
some developers learned react
later than others
so we like a team
part of the team went forward and started migrating the first subapp
while the others were working on the old code
they didn't have to learn anything new
they didn't even know react was there
and then we just started moving and swapping the developers
so that they worked in different subapps
got a little bit more experience
and then we all now are quite confident with everything
and then react router
the other summary point that is very important
is only living in memory
backbone history rules
it's very important
and why is this better
it's a lot of talking
in the end what any developer asking a meeting
where somebody is proposing some weird idea
first
all the react application architecture
is set up from day one
there is no feared project
in the end where everyone says ok
but when we have to kill the backbone part
we are going to find some mysterious things
that we didn't think about
for example the routing layer
it looks simple but it has a lot of authorization
if I migrated every subapp
little by little I didn't have to get the whole context
we just have to literally delete the app folder
because we are separating both applications
change
create memory history
and replace backbone link for link
and backbone redirect with redirect
and that's it, the migration is done
and we can all sleep very well
and one side benefit from this
is every time there is a new hire
where new hires usually don't like
backbone or they worked on it
years ago and they are not
really excited about that technological part
and they don't learn it from the get go
but more learn it when they need to
which is more pleasant
and start working on the react stack first
and then as they start understanding the flow
of the whole product you find problems
you want to solve them and you start learning the backbone part
with actually a purpose
as a chore
so it's really beneficial for that
especially for example because we have a junior program
where we hire
students in the last year of university
where they do technical customer support
they already have a base
and we slowly bring them
into the code base so that when they graduate
they become full time
and this is very helpful because they can start
working on the newer code or making new stuff
redesigning stuff rather than
actually having to solve bugs in our
for your old full of edge cases code base
that it's quite hard to grab from the start
and you can actually damage their confidence even
when they don't know how to solve a bug
and it's actually the fault of the senior developers
who didn't do the right architecture
for example myself
in the beginning and I don't want to damage someone's career
because of my decision
and well
edge cases
everything sounds very ideal now
you want to implement it in your company as well
there are edge cases
first
when it's an application it's not a full page
we assumed this from the start
but in complex apps this doesn't happen all the time
sometimes you have for example
I'm just sharing an example we have a great book
from the lab of course all the navigation
on the top stuff like that
and the great book app has really really stayed heavy
we want to do it with redux from the start
or we're going to have a project to redo the great book
that we already did
so how do you handle this situation
because now
that application has to share
the same html as back when I married
so it cannot live there in the react app
unless you do some magical
zindex stuff that we're not going to do
it doesn't sound fun
so we're going to have to insert it
within the back one code
and normally this is a pain
that we're going to avoid because in back one
you declare which diffs are regions
and it does a lot of magic
a lot of functionality there
so if you mount a back one
like a marionet module and put a react one
and then mount marionet again maybe you forgot something
in the process and it started having some weird bugs
so how did we handle this
because we cannot no longer do this
with a great book app we need to do
that magical new note
remember here again
the goes from the beginning
we want to write a new code even this one
completely unaware of the back one part
using the whole stack
so redux and using react router
otherwise we would still defeat the purpose
so how did we do this
basically you have to create this snippet
I took from the internet as well ours is very similar
you don't have to read line by line
but you create a react view in a
back one that in the render
it just renders your react app
so it's kind of another entry point
to react app and because we're using redux
you also add the provider
the router and everything
but basically you have this kind of view
that you can start declaring different apps there
so it's a second entry point
now
we have the one that you can achieve
from the classroom application and then the new entry point
from the great book app
let's check
if we're comfortable with this solution first
you have two entry points
I don't know if that's good or bad
but what I know is that once we kill all the back one part
we're going to have to join them
it looks easy, it looks just like moving the route
on the first entry point
so it's not a big deal
but the big benefit
is that the great book app
still is completely unaware of the back one
can use the backbone link, backbone redirect
everything so the great book app
will not need a second iteration
once the migration is over
it's not a complicated one
it's not a user profile
and then
now we are having
a situation where idealistically redux contains some state
backbone contains another one
they're not the same but in real apps
this doesn't happen
especially in our situation where we share state among views
how do we handle this
so how do you synchronize the state
here for example there's experience Ilya
I did it in red booth
there's a package and github where they synchronize
with redux
we saw the package and we were scared by it
so we completely
tried to go any other way
before actually going to that
especially because I saw the last commit
was kind of far in time
so maybe you
it's working
I thought maybe you abandoned it for some reason
that it's not mentioned in the readme
so it was kind of scary
so what happens in a situation
where you have two sub-applications
again because of the roadmap
or the technical decisions you migrate one
to react and readux and the other one
cannot be migrated because if you do it together
it would take too much time
how do you do that? it's basically this situation
in this little diagram
for example videoator app shares state
which is the video itself with our media library
it's kind of common to navigate between the two
so this happening
which options do we have
option one
it does duplicate the state
it does the request by itself
and the readex part as well
so you duplicate the api request
when necessary
and keep both apps unaware
this is an easy solution
but in some cases
for example the gradebook
that api request does a lot of stuff
so you don't want to be navigating
and making the user wait all the time
or they're probably not going to use the gradebook at all
so for things that are simple
this is ideal
and then just schedule for that second subapp
to be the next one to be migrated
and maybe for like a month
you just have that duplication
but for a heavy api request
this option might lead to quite that of a ux
so option two
this is the one that they did at readbook
which is you completely synchronize both
so you probably have to think of something
low level like they did
where you can synchronize both technologies
and it would work everywhere
I just added the link
into the code
so what are the present cons of this
when the shell
the state changes in readbacks
we have to propagate the change to the corresponding background model
or collection
and vice versa
but this breaks our technical goal
unless we completely find a solution
or use a redbooks one
where it's completely isolated
like some kind of low level architecture layer
that handles all of this
if you don't do it properly
you don't have to modify each other
maybe in the react part
which is what we want to avoid
so if we can
let's reject this one
we can go back if actually it's the only option left
and option three
which is, I have to say, it's a disclaimer
the readbook app is mostly read only
the state, you don't have to modify it
so the likelihood of the state in the gradebook changing
in the gradebook on the side of readbacks
is low
and maybe if it happens
it's not really a big deal
so option three is to just synchronize
changes in the state in background
in this example the video editor was meeting back one
so a lot of changes, questions added
stuff like that
but then the gradebook was kind of a reporting of that only
of the video library in this case
so what would that be
it would just be the second point
whenever there's a state changing background
we trigger a specific reduction action
because that's the way you're mutating your state
maybe for that state, some others might live in the components
so
you just have to have a reference
to the store, redact store
and use the dispatch method on it
to launch one of the actions
you won't actually hard code the action
but for the sake of the slide, this is what you would do
so in your background code
you will have some awareness of the redact one
but the react code still lives happily
by itself
without knowing anything
which is exactly what we wanted
so our decision was
90% of the time
and we use option 2 only when the API requests
are kind of heavy
like stuff that the user doesn't want to
keep reloading or they're gonna spend 10 minutes
seeing all the reports of the students
and stuff like that
so we use this in the gradebook
but at the moment nowhere else
and if we can never
use option 3
or we'll have to make a call
to this man right here
and ask him to explain
where the redact and redbook reacts
where the redact was using exactly the last option
when the source of truth was back on
and the redact was just listening
ok, then we agreed on that
so I will probably call you and you will tell me I'm doomed
and then we'll have to go back to option 2
so that's a summary
of the edge cases
a summary of everything actually
we have both apps
completely separately
they can live on their own
if the background one was killed
only with the sub-applegations
that it has migrated to
and the background app still lives on its own
and we synchronize
the two routers
with a total of 19 lines of code
it's more complex about thinking
how to solve it than actually implementing the solution
it's just 19 lines of code
and the only caveat is we're using these two components
with different names but as I said before
you could actually name it
the same way as react router
and you won't have this caveat at all
the goal was accomplished
we can work independently
it's very easy to onboard new people
especially juniors
and then we are very aligned
with the design team
we don't have a constraint that doesn't allow us to redesign
some parts or some legacy code
that the design team needs to be aware of
because it limits the way we can change our application
we're creating a very very good foundation
for all the rebranding
all the style guide that we wanted to add
and with CSS modules being so low level
the designers can take ownership
we have a separate folder where we start moving
all the style guide
it basically limits the sketch file that our designers have
and they can actually go there and make small modifications
and it's really increased their productivity
and at the same time we all sleep well
because we don't fear that
last project for the migration
where we will not know exactly
how to do the surgery
we know that the three steps
are delete the app folder
change backbone link for link
backbone redirect for redirect
and create a browser
router instead of a memory router
so that takes five minutes
one developer who gets all the credit
but it's fine
yeah, so
I already said this, so basically that's it
I want to have some space for Q&A
and of course the pitch stock
here we are hiring full stack developers
if you are excited about this architecture
we are still in the process of migrating
we are here in Barcelona and we are looking
we have Nord in the back end
so full JavaScript if you are interested
you can contact me after
or just go to the website and contact any of my teammates
Aplausos