Embroider from zero to route
splitting in 3.5 weeks. So a couple of months ago now I went
through an effort of porting our app over to to embroider, took about three
and a half weeks to, do the full thing. And I wrote up an article on it
afterwards, and most of this talk is kind of adapted from that article. So I'm gonna move relatively quickly
through the kind of slides and the meat of the information to leave
time for for questions because, you know, I could, could've just brought
up my article and read it to you all, but that doesn't seem like the
most interesting use of time here. I skipped my greeting. I was going to say greetings
from just becoming sunny Seattle. It's. It's not terribly, apocalyptically
hot out here anymore. Like it was a couple of weeks ago,
although it looks like our smoky season might be coming early. And so it might get terribly
apocalyptically smoky in a couple of weeks, but right
now it's beautiful and lovely. And and we're all enjoying
it while it lasts. Who am I'm Ben Demboski, I'm the CTO at
Rowan Patents, which is a company that does several different things, but the
software portion of it focuses on building software for patent attorneys to to help
automate their workflows and whatnot. I've used umber for about seven
years both professionally and for kind of side projects. And I've learned everything I know
about embroider in the process. Porting our app to it. I knew just a tiny bit about it
and some theoretical benefits we'd get from it before I dove into it. I'm currently suffering from some
amount of imposter syndrome because I'm by no means an embroider expert. Yet here I am you know,
giving a talk about it. More, some guy that stumbled his way
through the porting and learned a lot in the process, but, you know, I
guess that's enough to to share, to help you all stumble your way through
someday or you know, mayby then the, it'll thingsngs will be moved along. That they'll be, you know more,
guides and whatnot and less stumbling. And you can find me on Twitter and
discord either in either place at . So the app that we ported to, to embroider. So it's a multi window Ember
electron desktop app, and think of it kind of like an IDE. That's how we think of it as
an IDE for patent attorneys. Except for reasons. It, it, makes sense for their
productivity to have things in multiple windows rather than just
multiple panes within the same window. So the attorney will have multiple windows
open with different tool sets in them at the same time they can cross reference
and they're sinking data in between them. So a lot of the routes, a lot
of our Ember routes are only ever rendered in one window. So loading the entire app and every window
would be needlessly memory consumptive. I might've just made up that word,
consumptive, needlessly consuming memory. And also more than just our Ember code. We have a lot of third-party libraries
that are only used by code in, one window things to do natural language processing
type analysis and that sort of thing. So for us memory footprint
including code size is a big concern cause multiple windows. Multiplies the any, code that's loaded
and all the windows, you know, gets multiplied by however many windows are
open and it, can be a number of windows. And then I spit out some stats
on our app, just so if you're. I don't know, compare yours
to ours in terms of sizing, maybe the effort or something. So our goal in the porting was to was
to control the, code driven memory footprint with minimal engineering
efforts and to do that via tree shaking and, route splitting. And when I say tree shaking I
realized after I wrote up these slides that it's, more than. Tree shaking, but basically let's just
say modern JavaScript, bundling techniques for reducing the size of the bundle and
tree shaking is a notable one of those, but there's a there's others as well. We had previously using Ember auto
import and a whole bunch of manual Webpack configuration to explicitly
strip out code that we didn't need in certain windows and stuff had
achieved a pretty good amount of. Memory footprint managed code
driven memory, footprint management, but the minimal engineering
effort part was, not there. So we were looking for kind of a
set it and forget it type solution with minimal ongoing maintenance. So before getting into some of the
slightly nitty or grittier the, my overall impressions of embroider are
more or less the same as they were. When I wrote the article that I would
kind of classify as late stage alpha early stage beta quality software. So the core functionality is
solid, fairly severe bugs. Aren't that uncommon still the
documentation is somewhat minimal. Porting a complex app to
embroider can be pretty. Effort intensive and keeping it up to
date across new releases of embroider can also be somewhat effort intensive as
it's still in a state where regressions, you know, come up and can, require
some effort to figure out how to work around them or configure around them. But I did find that production
stability is very high. None of those things that keep me up
at night of, if I built it once in CI. And then I rebuild with
exactly the same code and the production bundle is different. You know, none of that stuff happens. What I've found is that once, you
know, once it's building and I've got it all lined up it's, very stable. It's just it's just as embroider changes. And and, evolve that introduces
some instability updating to those newer versions. The dev environment stability
I've, found to be pretty high. It's pretty stable. There's some minor hiccups, nothing
that I've found to be a major issue. And I think a lot of that is,
has to do with kind of source map flakiness, which often just refreshing
the window a couple of times. I'm not sure if that's really
embroiders fault or webpacks fault or. Chrome dev tools as well. So those are my high-level impressions. So I kind of really over-simplified
overview of, what embroider does. Is it is it takes your, Ember app and,
assembles it and all of the ad-ons into a kind of a vanilla, NodeJS project that's
kind of hidden or already resolved all the unique behaviors of Ember and Ember CLI. So it's, run the broccoli pipeline and
gotten all the add-ons to contribute their assets, but then it assembles it into
a kind of static node JS project with the package that JSON and node modules
put in the right place and whatnot. So that then. It can point a standard packager
like web pack is the current one that's supported, although the
working on support for, some others. But in theory, you should be
able to use anything Webpack or roll up or anything like that. But yeah, I can point Webpack at it. And then with some custom
loaders and whatnot. Then Webpack turns it
into a browser bundle. So one of the big goals is to leverage
everything that's been done out in the community, on, on bundlers rather
than Ember having to maintain our own bundler that kind of duplicates
a bunch of functionality that the broader community is working. And then the last step is it injects
the, bundled script, another web pack, generated resources back into your index
that HTML using some of those special rules that that, we have a number where
the root URL gets filled in, if you're hosting on a CDN and that sort of stuff. So that's kind of an overview
of what embroider does. And my reason for is, to provide some
context for some of the hard parts that I found according to embroider. So one of them was the package that
JSON dependencies, when embroiders assembling the vanilla node JS version
of the application, that relies heavily on information in the apps
and add-ons package dot JSON to set things up properly, to know which
packages to include and the kind of assembled, you know, vanilla JS package. So that Webpack will do the right thing
and so missing dependencies, but under Ember CLI it was fine because the package
was still a node modules, because it was a transitive dependency of some add
on, but your app didn't call it out as a dependency, even though it imported
it, that would work in Ember CLI. That would break under embroider. So there's a bunch of cases where yeah. We had to do some fiddling with
undeclared dependencies or tricks that we'd play with putting something
in peer dependencies instead of declaring our own dependency on it. That that that, took some doing to
get that all woanother one that's, ES6 that might be ES5 module compliant. I can never quite remember the
distinction between ES5 and ES6 modules. But the idea is that the Webpack static
analysis of the code is based on stricter module resolution rules than, embers
kind of runtime module loader or. Or the, way the code gets
transpiled into runtime modules. So a lot of slightly incorrect imports. For example, I think this one isn't
actually a problem, but the example of the sort of thing I'm talking
about is if a module has a bunch of named exports and you consume
it by importing a single default. Export and then accessing the name to
export as properties on the default export that's not actually correct because the
module isn't producing a default export, it's only producing, named exports. I think embroider, I think Webpack
might just give a warning on that one, but that's the sort of issue that we
ran into in a number of places where just imports weren't quite right. Statically analyzable components. So there's a whole section
in the embroider read-me's on kind of how to deal with. But, you know, sometimes in ember we
use the component helper and can play a little fast and loose where maybe
one component gets past an argument, that's the name of another component. And then internally uses the component
helper to invoke that component. And when moving to the
optimized embroider settings. So, so by default there's a baseline
of, embroider settings, but to get to, to a bunch of optimizations, including
route splitting need to enable a, higher bar of of settings that allows
embroider to do more static analysis. And one those is, a component so that it
embroider can understandand part of it is being able to tree shake components,
being able to look through the templates and see what components are and aren't
referenced so that it can leave out. Components that actually aren't
referenced anywhere you know, in an add on, for example. So it definitely took some fiddling,
cause there were places where we were playing little tricks with how we,
kind of dynamically invoked components that needed to clean up CSS and SAS. Like I say, in the article,
unfortunately I didn't keep notes on that when I was doing it. So I don't, I can't quite recall exactly
what the issues were there, but there was enough, differences between how Ember CLI. Kind of assemble CSS and embroider
assemble CSS that we ran into some styling issues and had
to shuffle some things around. And then the big one is third party
add ons because all those things that I just listed when they're
directly under my control in my code, I can go in and fix them. Third party, add on. Is, you know, I can't,
just fix it immediately. So in some cases contributing fixes and
other cases, finding work arounds through Webpack configs, or embroider configs
to to address all of those previous issues, but in the context of third
party, add ons and over in the article that I linked to at the beginning of,
of the presentation, I actually list out all the major ones that required
effort and explain what was needed. That's probably a little obsolete
now, because I know at least one or two of those have been
addressed since I wrote the article. But that can give you a sense of the
kinds of challenges that you've run into. And then also maybe flag some specific
ad-ons that you might, yknow, use that, that, areare problematic. Fortunately. Mentioned all the workarounds. So for the ones that, for the
problems that I ran into, so hopefully that'll help some folks out. Kind of my, this is my my last slide
before we, you know, turn it over to Q&A, but my experience getting support. So I found that the dev embroidered
discord channel was Pretty helpful. There's folks hanging out
there that can share their experiences and answer questions. Some of the kind of core drivers of,
embroider you know, Ed Faulkner and you know and Rob Jackson are there, you
know, but they're, busy folks, so can't reliably, you know get, support directly
from them, but the, channel, but they do pop in and out and answer questions. And so the, channel is I
found was pretty helpful. I found that bugs don't always
get addressed very quickly. Cause again, I think there's just a
lot, that's still being done on it, but I found that tpull requests to
get get attention pretty quickly. And it's relatively easy to
get some support from, er... Or from, you kother folks in terms of shepherding PR's through. Yeah, like I mentioned, the core team
was pretty helpful in providing advice for investigating and fixing bugs. And I found that the embroider code
base itself, as far as diving in to just investigate and figure out
how to work around something or contribute back a fix the embroider
code base looks kind of intimidating. It isn't too terribly hard to kind of
dig into and investigate issues once, you know, a little bit of time getting
comfortable with where the pieces are. But then my experience with the code
base was pretty pretty positive. And I did manage to contribute a few fixes
back for, issues that I was running into. So that's all that I had. Presentation wise. And like I said, I wanted to save time
for, any questions that folks have. So I'll open the floor to questions.