<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Erin Bush</title>
  <id>http://erinbush.postach.io/feed.xml</id>
  <updated>2019-09-20T01:00:07.845000Z</updated>
  <link href="http://erinbush.postach.io/" />
  <link href="http://erinbush.postach.io/feed.xml" rel="self" />
  <generator>Werkzeug</generator>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Static Methods for Javascript Classes 🎈</title>
    <id>https://erinbush.postach.io/post/static-methods-for-javascript-classes</id>
    <updated>2019-09-20T01:00:07.845000Z</updated>
    <published>2019-09-17T19:00:27Z</published>
    <link href="https://erinbush.postach.io/post/static-methods-for-javascript-classes" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;The other day I started a new project at my job.  I was setting up the repo and adding all of our usual linters to hold ourselves to a consistent standard.  Once I had eslint set up with the latest versions, something popped up that I hadn’t had to think about in a while: static methods.&lt;/p&gt;
&lt;p&gt;We had a javascript class with a mix of intense methods and some that yes technically should be considered static methods.  &lt;/p&gt;
&lt;p&gt;As a refresher (from &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static&quot;&gt;MDN Web docs&lt;/a&gt;):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Static methods aren’t called on instances of the class.  Instead, they’re called on the class itself. These are often utility functions, such as functions to create or clone objects.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So what does this mean? Static methods hold logic that do not interact with an instance of the class (ie. &lt;code&gt;this&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Person {
    constructor (name) {
      this.name = name;
    }

    static sayHello (name) {
      alert(`Hello ${name}!`);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;sayHello&lt;/code&gt; is a static method because it does not involve an instance of Person (it does not call &lt;code&gt;this&lt;/code&gt;).  We can call &lt;code&gt;sayHello&lt;/code&gt; by doing something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Person.sayHello(‘Denzel’)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, if we want to add another method to our Person class, that calls &lt;code&gt;sayHello&lt;/code&gt;, we could need to call it as a property of the constructor.  Static methods are not directly accessible using the &lt;code&gt;this&lt;/code&gt; keyword from non-static methods.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Person {
    constructor(name) {
      this.name = name;
    }

    interact() {
        this.constructor.sayHello(this.name);
    }

    static sayHello(name) {
      alert(`Hello ${name}!`);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can however call a static method from inside another static method using &lt;code&gt;this&lt;/code&gt; as &lt;code&gt;this&lt;/code&gt; represents the class itself, not the instance.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Person {
    static interact(name) {
       this.sayHello(name);
    }

    static sayHello(name) {
      alert(`Hello ${name}!`);
    }
}

Person.interact(‘Denzel Washington’);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I hope that clarifies static methods!  I was blinding following the linter rules and neglected to realize how static methods truly work. For more information, check out this &lt;br /&gt;
reference&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">TIL about NPM check updates</title>
    <id>https://erinbush.postach.io/post/til-about-npm-check-updates</id>
    <updated>2019-02-25T19:44:53.124000Z</updated>
    <published>2019-02-25T19:17:18Z</published>
    <link href="https://erinbush.postach.io/post/til-about-npm-check-updates" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="npm" />
    <content type="html">&lt;p&gt;Do you need to update a bunch of packages? Do they all have a similar scope* or name? &lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm-check-updates&lt;/code&gt; checks the packages listed in your package.json file, and prints out a list of the packages that can be updated to the latest version.&lt;/p&gt;
&lt;p&gt;To install:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install -g npm-check-updates
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, run it in your project folder:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ncu 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You’ll get some output that looks a little something like this: &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;
https://thepracticaldev.s3.amazonaws.com/i/cj8dzofzcldlaeuki1ka.png
&quot; style=&quot;max-width: 400px; margin: auto;&quot;/&gt;&lt;/p&gt;
&lt;p&gt;If you want it to automatically bump the versions in your package.json file you can pass in the update parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ncu -u
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can also run it with a regex string if you are just curious about a certain scope or package:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ncu '/^@npm.*$/' -u
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Remember to run &lt;code&gt;npm install&lt;/code&gt; afterwards to actually install the packages since npm-check-updates will just update your &lt;code&gt;package.json&lt;/code&gt; file!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;*PS: &lt;a href=&quot;https://docs.npmjs.com/about-scopes&quot;&gt;scopes in npm&lt;/a&gt; are useful if you need to group packages by your organization.  In the following example &quot;npm&quot; is the scope.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@npm/package-name
&lt;/code&gt;&lt;/pre&gt;

&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Being Intentional With Git Commits</title>
    <id>https://erinbush.postach.io/post/being-intentional-with-git-commits</id>
    <updated>2019-02-23T22:20:34.593000Z</updated>
    <published>2019-02-23T21:46:41Z</published>
    <link href="https://erinbush.postach.io/post/being-intentional-with-git-commits" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="git" />
    <category term="commits" />
    <content type="html">&lt;div&gt;The other day I was poking around in a github repository and came across this commit message:&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;img src=&quot;https://cdn-images.postach.io/22a20ab7-bd49-49ab-8e3d-b9839f60a228/27bd312f-a50c-43f1-900c-35a164de4eec/8cb19f6b-0ccb-45c1-98a3-00f5db007f7c.png&quot; /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Not that I needed to know that much about what this person was committing at the time, but I couldn’t help but think how unhelpful this commit message would be if someone needed to understand the project. &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;At my work we started using &lt;a href=&quot;https://github.com/commitizen/cz-cli&quot;&gt;commitizen&lt;/a&gt; and it took a minute to get used to but after a few days, I could see how much value it was adding to the code base.  &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;First, because it breaks commits down into categories, it forces you to only add relevant files to one category.  Buh-bye editing 30 files and committing them all in one go.  I mean you still &lt;span style=&quot;font-style: italic;&quot;&gt;could&lt;/span&gt; do that but you will feel a slight pang of guilt every time you add a feature file in with your test files. &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;img src=&quot;https://cdn-images.postach.io/22a20ab7-bd49-49ab-8e3d-b9839f60a228/27bd312f-a50c-43f1-900c-35a164de4eec/b4475e93-ffee-4946-8881-a9e488ca9260.png&quot; /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;After using the tool for a few days, I started thinking about good stopping points in my work to commit so that I could make my messages make the most sense.  For example, when working on a feature that also included some refactor work, I would try to just do the refactor first, commit that, and then start working on the new functionality. Looking back at the commit messages when browsing files and seeing the type of change that was made, helps so much for granularity and for knowing what to expect from a certain commit.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;Secondly, while other people on the internet might have already been splitting their commit messages into shorter and longer descriptions (ie. subjects and bodies), I was not.  And I’ve realized, the longer description is so helpful for describing the nuances of the changes you have made.  Even if its just for you to go over before you make your pull request, it will help you understand why you did what you in a way more thorough way - provided you add a thorough description.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;At my work, we’ve gone a step further to create a custom command line tool that makes your pull requests for you on Github.  The pull request description is a list of your git commits.  At first, I was worried this wasn’t enough.  How could 100 character commit messages tell you everything you need to know about the code changes? But then, I had a lightbulb moment.  The commits already ARE supposed to tell you everything about the code changes.  I just wasn’t making my commits well enough.  Once I started breaking things down by commit category and providing better commit messages (mainly through the longer descriptions), my pull requests were back up to the level they used to be before when I would write the description myself and have subpar commit messages. &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;img src=&quot;https://cdn-images.postach.io/22a20ab7-bd49-49ab-8e3d-b9839f60a228/27bd312f-a50c-43f1-900c-35a164de4eec/2ca6708d-ef5b-4376-ae0b-62982de68ecb.png&quot; /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;I encourage everyone to set up commitizen and try it out for a few days.  I think it will make future you way happier when you are looking back at your code and thinking, &quot;What the heck was I thinking?&quot;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Free Website Template 💰</title>
    <id>https://erinbush.postach.io/post/free-website-template</id>
    <updated>2019-02-25T19:32:19.062000Z</updated>
    <published>2019-02-17T01:21:26Z</published>
    <link href="https://erinbush.postach.io/post/free-website-template" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="free" />
    <category term="template" />
    <content type="html">&lt;p&gt;A month ago I noticed a few people had cloned the repo for my personal website, so I built a website template for ya'll that you can download for freeeeee&lt;/p&gt;
&lt;p&gt;You can check out a live preview of it here: &lt;a href=&quot;www.erinbush.ca/rubiks&quot;&gt;&lt;br /&gt;
www.erinbush.ca/rubiks&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And can clone the repo here: &lt;a href=&quot;github.com/erin-bush/rubiks&quot;&gt;&lt;br /&gt;
github.com/erin-bush/rubiks&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/erin-bush/rubiks/raw/master/website_template_preview.gif&quot; alt=&quot;website preview&quot; style=&quot;max-width:100%;&quot;&gt;&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">A Practical Guide for Making your Monolith Accessible</title>
    <id>https://erinbush.postach.io/post/a-practical-guide-for-making-your-monolith-accessible</id>
    <updated>2019-02-15T22:40:12.599000Z</updated>
    <published>2019-02-15T22:32:23Z</published>
    <link href="https://erinbush.postach.io/post/a-practical-guide-for-making-your-monolith-accessible" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;When we set out on making our app accessible, I had a hard time finding out how other companies tackled this. We started at the very beginning of this process and really had no idea where to go. I hope this guide helps you out - no matter what stage of the accessibility journey you are on. &lt;/p&gt;
&lt;h1&gt;1. Give a lunch and learn on accessibility and start generating empathy.&lt;/h1&gt;
&lt;p&gt;You can check out the slides from the lunch and learn I gave here: &lt;br /&gt;
https://github.com/erin-bush/a11y-cat&lt;br /&gt;
.  Before I had given this lunch and learn, accessibility really wasn’t on anybody’s mind.&lt;/p&gt;
&lt;h1&gt;2. Don’t stop talking about accessibility&lt;/h1&gt;
&lt;p&gt;Make sure everyone at the company knows what accessibility is and why its important&lt;/p&gt;
&lt;h1&gt;3. Create a mega list of customers asking for compliance with standards.&lt;/h1&gt;
&lt;p&gt;We found that once we started tagging customer tickets, we had a surprising number of people having issues with our platform and struggling to make their content accessible.&lt;/p&gt;
&lt;h1&gt;4. If you have a huge app, drill down the most critical user paths that need help first.&lt;/h1&gt;
&lt;p&gt;For our application, we provide course creators with the tools to make their own online courses.  We found that our customers’ students were the ones affected the most by our lack of web accessibility and the student signup to course completion ended up being our critical paths.&lt;/p&gt;
&lt;h1&gt;5. Put in time outside of work to compile a list of all the known issues.&lt;/h1&gt;
&lt;p&gt;I recommend using the chrome plugin &lt;a href=&quot;https://chrome.google.com/webstore/detail/axe/lhdoppojpmngadmnindnejefpokejbdd&quot;&gt;aXe&lt;/a&gt; on every page on your site to generate a list of accessibility issues. Alternatively, you can use the built in chrome lighthouse  audits&lt;/p&gt;
&lt;p&gt;If you can get buy in from your company to do this, great!  We found that as no one knew where to start, and we didn’t yet have buy in from management, we had to take it upon ourselves to make a list of ways we can improve&lt;/p&gt;
&lt;p&gt;Note: There will still will be other things that need to be fixed that can’t be automatically tested - this is where manual QA testing process comes in later (see #9)&lt;/p&gt;
&lt;h1&gt;6. Continue to talk about it.&lt;/h1&gt;
&lt;p&gt;We found a good way was to keep bringing accessibility to the front of mind of the product team by giving devs a 5 minute fix that they can implement easily as they do their work and highlight a different fix every month.&lt;/p&gt;
&lt;h1&gt;7. Run an Accessibility Jam after work to fix all of the easy stuff as a group (offer lots of tequila)&lt;/h1&gt;
&lt;p&gt;We had a ton of things that needed to be solved after we had run the aXe plugin on our user’s critical paths.  As we weren’t getting assigned dev time to work on this, we decided to organize our own Accessibility Jam were we wrangled a bunch of developers, designers, and qa people to come to work on the massive list together (with tacos provided 🙂). Both pull requests and alcohol were flowing.&lt;/p&gt;
&lt;p&gt;Remember to publish the stats from the jam to keep people motivated!&lt;/p&gt;
&lt;h1&gt;8. Get the customer support team on board to gather more information from customers who write in about accessibility issues.&lt;/h1&gt;
&lt;p&gt;We found that videos were the most informative, but even just in depth descriptions of the problem and some information about the screen reader type and browser version they are using. &lt;/p&gt;
&lt;h1&gt;9. Get accessibility processes integrated into the company’s OKRs.&lt;/h1&gt;
&lt;p&gt;Our company operates around OKRs, and the next step after getting buy in from management was to find a way to integrate accessibility into our quarterly plans.  We tried to attack it from both the process side (checklists for developers, QA and designers) and from the implementation side but found that it would have been better to start with process in one quarter and then work on implementing in the next quarter.&lt;/p&gt;
&lt;h1&gt;10. Create a list of things devs, designers, and QAs need to accomplish to meet standards (ie. fix the pipeline first, then go back and fix the other stuff)&lt;/h1&gt;
&lt;p&gt;Once the OKRs were fleshed out we had to actually come up with our processes that enable our upcoming features to be accessible.  I recommend taking a look at the &lt;a href=&quot;http://accessibility.voxmedia.com/?_ga=2.119983240.1822308305.1547492490-14035422.154749249&quot;&gt;vox checklist&lt;/a&gt; as they break it down by role.&lt;/p&gt;
&lt;h1&gt;11. Create a company philosophy on accessibility&lt;/h1&gt;
&lt;p&gt;We have yet to do this but I believe it is integral to have accessibility written into the policy so that when we are questioning if we have time to work on something or not, we can refer back to the policy as law&lt;/p&gt;
&lt;h1&gt;12. Automate some accessibility checks.&lt;/h1&gt;
&lt;p&gt;We have yet to this step but there are a few tools that can help you automate your accessibility compliance checks:&lt;br /&gt;
1. Git plugin for your pull requests: &lt;a href=&quot;https://github.com/GoogleChromeLabs/lighthousebot&quot;&gt;lighthouse bot&lt;/a&gt; or &lt;a href=&quot;https://www.accesslint.com/&quot;&gt;accesslint&lt;/a&gt;&lt;br /&gt;
2. Precommit hook for sass: set up a precommit hook that runs &lt;a href=&quot;https://github.com/YozhikM/stylelint-a11y&quot;&gt;stylelint-a11y&lt;/a&gt; or add as a plugin to your code editor&lt;br /&gt;
3. &lt;a href=&quot;https://github.com/evcohen/eslint-plugin-jsx-a11y&quot;&gt;eslint jsx a11y plugin&lt;/a&gt;&lt;br /&gt;
4. Integrate dev checklist into github PR checklists: set up a PR template that includes the checklist items from the list you made in step 10&lt;/p&gt;
&lt;h1&gt;13. Add in an accessibility feedback link to get first hand information on issues.&lt;/h1&gt;
&lt;p&gt;At the bottom of the page, include an accessible link that allows people to give feedback directly, possibly in the form of a type form.&lt;/p&gt;
&lt;h1&gt;14. Fix fix fix!&lt;/h1&gt;
&lt;p&gt;Keep pushing to have old accessibility issues integrated into feature work that touches currently inaccessible parts of the code.&lt;/p&gt;
&lt;h1&gt;15. Get an audit (could also be done earlier) to get access to people who use screenreader and assistive technology all 👏 the 👏 time 👏 to find issues you can’t automate&lt;/h1&gt;
&lt;p&gt;There are a few companies that do this but one that we like is &lt;a href=&quot;https://www.makeitfable.com/&quot;&gt;Fable&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;16. Run a show and tell to update the rest of the company of your phenomenal efforts 🙌&lt;/h1&gt;
&lt;p&gt;Tons more resources available here: &lt;a href=&quot;https://a11yproject.com/resources&quot;&gt;https://a11yproject.com/resources&lt;/a&gt;&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">npm link/unlink clarity 🤙</title>
    <id>https://erinbush.postach.io/post/npm-link-unlink-clarity</id>
    <updated>2019-02-06T21:05:04.671000Z</updated>
    <published>2019-02-06T18:45:47Z</published>
    <link href="https://erinbush.postach.io/post/npm-link-unlink-clarity" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="til" />
    <category term="npm" />
    <content type="html">&lt;p&gt;I kept getting confused with the link/unlink order mostly because I was getting myself into weird situations with permission issues where I would have the package not available anymore. &lt;/p&gt;
&lt;p&gt;There are some good resources out there for linking but I was struggling at first to find the documentation for unlinking.  I’ve written down the exact steps for both so that future devs never struggle like I did.  &lt;/p&gt;
&lt;p&gt;Lets say we have an npm package that we are working on locally, lets call it &lt;em&gt;cowabunga&lt;/em&gt;.  Our project structure looks something like this: &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;
https://cdn-images.postach.io/22a20ab7-bd49-49ab-8e3d-b9839f60a228/37335009-c87c-41a2-bcc2-7990e729d390/273328fd-30ce-49c3-bbd2-97e7a9472de8.png
&quot; alt=&quot;cowabunga package folder structure&quot; style=&quot;width:300px; margin:auto;&quot;/&gt;&lt;/p&gt;
&lt;p&gt;And it’s &lt;em&gt;package.json&lt;/em&gt; file looks something like this: &lt;br /&gt;
&lt;script src=&quot;
https://gist.github.com/erin-bush/53e42a5e01ecf9e5edd95eddc819f657.js
&quot;&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;You’ll notice that this package has its own &lt;em&gt;node_modules&lt;/em&gt; folder - this is where I kept getting tripped up.  I would switch branches (where my package lived) and the node_modules folder would disappear.  When I would go to unlink, npm was throwing permissions errors that went something like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm ERR! enoent ENOENT: no such file or directory, access ‘my_project/node_modules/cowabunga/node_modules/react’&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In order to avoid this, you have to follow the linking/unlinking order otherwise npm will try to unlink folders that no longer exist.  Seems pretty basic but it was surprisingly tedious to figure out. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linking:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First, in the &lt;em&gt;cowabunga&lt;/em&gt; folder (where package.json is):&lt;br /&gt;
&lt;code&gt;npm link&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then in the project you want to include &lt;em&gt;cowabunga&lt;/em&gt; in:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm link cowabunga&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unlinking:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Before&lt;/em&gt; switching branches and/or removing any node modules from the package itself (in my project, this includes running &lt;em&gt;learn clean&lt;/em&gt; which removed the node_modules folders)&lt;/p&gt;
&lt;p&gt;First, in the project: &lt;br /&gt;
&lt;code&gt;npm unlink --no-save cowabunga&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Second, in the package:&lt;br /&gt;
&lt;code&gt;npm unlink&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Note: order is important!&lt;/p&gt;
&lt;p&gt;Where I kept running into issues is switching branches and then the symlink couldn’t find the package anymore so you were stuck in this weird state where you couldn’t link anything or unlink anything because the folders don’t exist.  When this happens, check out your original branch and start from the beginning with linking the package and the project.  &lt;/p&gt;
&lt;p&gt;🤙&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Bonus:&lt;/em&gt;&lt;br /&gt;
You can also run &lt;br /&gt;
&lt;code&gt;npm install -g i .&lt;/code&gt;&lt;br /&gt;
in your package folder to install it globally 🎉&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);

document.querySelectorAll('code').forEach(function(el) {
  el.setAttribute(&quot;style&quot;, &quot;background-color: #333333; color: #ffffff; padding: 10px; display: block; width: 100%;&quot;);
})

&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">TIL: The importance of importing a module explicitly with React Apollo</title>
    <id>https://erinbush.postach.io/post/til-the-importance-of-importing-a-module-explicitly-with-react-apollo</id>
    <updated>2019-01-22T17:30:44.870000Z</updated>
    <published>2019-01-18T19:28:56Z</published>
    <link href="https://erinbush.postach.io/post/til-the-importance-of-importing-a-module-explicitly-with-react-apollo" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="til" />
    <category term="today-i-learned" />
    <content type="html">&lt;p&gt;While trying to write some tests for a React component that makes use of Apollo, I was getting increasingly frustrated when I couldn’t actually access the component.  I had a big lightbulb moment when &lt;a href=&quot;https://stackoverflow.com/questions/41103597/how-make-unit-test-with-react-apollo-component&quot;&gt;this Stack Overflow&lt;/a&gt; told me to simply use the exported component instead of the default export.  I was testing the component as a whole and Apollo was adding some extra functionality on top that made testing a challenge, and in order to actually unit test my component, I don’t need the Apollo garnish.&lt;/p&gt;
&lt;p&gt;Here’s what I had:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// UsersImport.js

export class UsersImport extends Component { 
  ...
}

export default compose(

  ...
)(withApollo(UsersImport))
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;// UsersImport.spec.js

import UsersImport from './UsersImport'

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here’s what I actually needed to do:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// UsersImport.spec.js

import { UsersImport } from './UsersImport'

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That way, I have access to the first export (&lt;code&gt;UsersImport&lt;/code&gt;) and not the entire module that includes Apollo.&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Useful Github Shortcuts 💅</title>
    <id>https://erinbush.postach.io/post/useful-github-shortcuts</id>
    <updated>2019-01-22T17:33:13.612000Z</updated>
    <published>2019-01-16T16:55:41Z</published>
    <link href="https://erinbush.postach.io/post/useful-github-shortcuts" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;Inspired by &lt;a href=&quot;https://dev.to/_darrenburns/8-productivity-tips-for-github-44kn?utm_source=Newsletter+Subscribers&amp;amp;utm_campaign=bd8f7b0ddf-EMAIL_CAMPAIGN_2019_01_14_07_51&amp;amp;utm_medium=email&amp;amp;utm_term=0_d8f11d5d1e-bd8f7b0ddf-154820857&quot;&gt;this post&lt;/a&gt;, I made a handy table for all your github shortcuts.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Keyboard Shortcut&lt;/th&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Repository view&lt;/td&gt;
&lt;td&gt;Fuzzy file search - use arrows to navigate through files, enter to open the file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File view in pull request&lt;/td&gt;
&lt;td&gt;Jump to a function/symbol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File or directory view&lt;/td&gt;
&lt;td&gt;Convert URL to a permalink&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File view&lt;/td&gt;
&lt;td&gt;Show blame&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Anywhere&lt;/td&gt;
&lt;td&gt;Search all code in repository&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ctrl . + ctrl 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Adding a comment&lt;/td&gt;
&lt;td&gt;Insert the first &lt;a href=&quot;https://github.com/settings/replies&quot;&gt;saved reply&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;``` suggestion&lt;/code&gt; &lt;br&gt;&lt;code&gt;# make this change&lt;/code&gt; &lt;br&gt;&lt;code&gt;```&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Adding a comment&lt;/td&gt;
&lt;td&gt;Create a suggestion that someone can commit to their PR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;g&lt;/code&gt; + &lt;code&gt;p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Repository view&lt;/td&gt;
&lt;td&gt;Opens the pull request tab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pull request list view&lt;/td&gt;
&lt;td&gt;Filter by author&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opening a pull request&lt;/td&gt;
&lt;td&gt;Apply a label&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opening a pull request&lt;/td&gt;
&lt;td&gt;Add an assignee&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;
https://octodex.github.com/images/surftocat.png
&quot; alt=&quot;github octocat surfing&quot; style=&quot;width:300px; margin:auto;&quot;/&gt;&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">React Code Snippets✂️</title>
    <id>https://erinbush.postach.io/post/react-code-snippets</id>
    <updated>2019-01-15T21:57:22.188000Z</updated>
    <published>2019-01-15T21:32:57Z</published>
    <link href="https://erinbush.postach.io/post/react-code-snippets" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;Figured I should start walking the walk with this whole &quot;giving back to the dev community thing&quot; so I made a gist of the react Visual Studio Code snippets that I use regularly.  &lt;/p&gt;
&lt;p&gt;To install them in your VS Code, go to File &amp;gt; Preferences &amp;gt; User Snippets (or Code &amp;gt; Preferences for Mac) then select &lt;strong&gt;New Global Snippets File&lt;/strong&gt;.  You can then name it and copy-paste these snippets into that file. &lt;/p&gt;
&lt;script src=&quot;
https://gist.github.com/erin-bush/b04dd2ecb9eb031f9549a3a37d1f27cb.js
&quot;&gt;&lt;/script&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn-images.postach.io/22a20ab7-bd49-49ab-8e3d-b9839f60a228/480625ba-0be5-44d5-bb93-1e568b29db2d/1785edf1-5445-4d11-8b3d-01ffd9cb6c50.gif&quot; /&gt;&lt;/p&gt;
&lt;p&gt;To create your own code snippets you can follow the instructions &lt;a href=&quot;https://code.visualstudio.com/docs/editor/userdefinedsnippets&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Tech Specks Week #6💧</title>
    <id>https://erinbush.postach.io/post/tech-specks-week-6</id>
    <updated>2019-01-15T20:09:39.307000Z</updated>
    <published>2019-01-15T18:29:29Z</published>
    <link href="https://erinbush.postach.io/post/tech-specks-week-6" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;Over the last few weeks I’ve taken a bit of a break from the usual tech specks to relax over the Christmas break and also to think about my &lt;a href=&quot;https://erinbush.postach.io/post/goals-2019&quot;&gt;goals&lt;/a&gt; for the year.  I’m trying out a new format here on the blog, one detailed summary and a list of the other 4 articles I’ve read over the week.  If you are interested in the rest of the summaries, hop over to my &lt;a href=&quot;https://diy-developer.thinkific.com/courses/become-a-senior-dev&quot;&gt;course&lt;/a&gt; and check it out.  I’ll be updating it every week! &lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://blog.usejournal.com/how-to-apply-solid-principles-in-react-applications-6c964091a982&quot;&gt;#1 How to apply SOLID principles in React applications&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Single Responsibility Principle&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The component should have one and only one reason to change (like if the react component should update or not): should just be a header component or just a footer, shouldn’t do both unless its a wrapper&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Have functions passed in as props that handle data mutations. &lt;/p&gt;
&lt;p&gt;Have a presentation component that encapsulates html and styling of components.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/whtswrng/c9c4e0fc609893784f11432801e0fd8b.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;&lt;strong&gt;Open Closed Principle&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Software entities (classes, modules, functions, etc) should be open for extension but closed for modification&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Use component composition (displaying children nested in components) to reorder/change structure of the child elements without changing the parent. &lt;/p&gt;
&lt;p&gt;Shouldn’t have to change the &lt;em&gt;render&lt;/em&gt; function&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Liskov Substitution Principle&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If extending a component, it needs to act the same as the parent (initialized the same)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interface Segregation Principle&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We should not depend on things we don’t need &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Only pass in props that are used (not the whole object if you don’t need it - but not just limited to props)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dependency Inversion Principle&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We should depend on abstractions not concretions&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A high level module should not depend on low-level details, both should depend on abstraction (ie. create an interface to fetch data). &lt;/p&gt;
&lt;p&gt;Should have no knowledge of HTTP, SOAP or other protocols&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Other Articles&lt;/h1&gt;
&lt;h3&gt;#2 &lt;a href=&quot;https://medium.com/@Charles_Stover/cache-your-react-event-listeners-to-improve-performance-14f635a62e15&quot;&gt;Caching React&lt;/a&gt; listeners can help boost your application’s performance by cutting out render cycles&lt;/h3&gt;
&lt;h3&gt;#3 Learn how to &lt;a href=&quot;https://levelup.gitconnected.com/the-definite-guide-to-handling-errors-gracefully-in-javascript-58424d9c60e6&quot;&gt;handle errors&lt;/a&gt; in your application the right way.  I had to split this article into 3 sections in order to tackle a little bit every day.&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Side Note:&lt;/strong&gt; If you read the original article, you’ll notice that in one of the examples, they have a semi-colon in front of the self-invoking function.  If you are curious about what it is used for I recommend looking &lt;a href=&quot;https://stackoverflow.com/questions/7365172/semicolon-before-self-invoking-function&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Resources&lt;/h1&gt;
&lt;p&gt;For more information on logging for debugging purposes check out &lt;a href=&quot;https://www.npmjs.com/package/loglevel&quot;&gt;loglevel&lt;/a&gt;&lt;/p&gt;
&lt;script&gt;

var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');

link.rel = 'shortcut icon';

link.href = `https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6`;

document.getElementsByTagName('head')[0].appendChild(link);

&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">What I learned in a 3 hour meeting ⏰</title>
    <id>https://erinbush.postach.io/post/what-i-learned-in-a-3-hour-meeting</id>
    <updated>2019-01-12T01:17:50.509000Z</updated>
    <published>2019-01-12T00:47:19Z</published>
    <link href="https://erinbush.postach.io/post/what-i-learned-in-a-3-hour-meeting" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;This week, I was involved in a meeting that got a little heated, and the discussion ran on pretty long but I feel like overall it was a success.  I wanted to share the behavioural pieces I noticed the more senior people in the room did that enabled conversation to continue in a focused direction and allowed people to feel like they walked away with something accomplished.&lt;/p&gt;
&lt;h1&gt;Is it helpful to go around and say examples of ___?&lt;/h1&gt;
&lt;p&gt;At one point we were trying to define this super vague idea of an &quot;aha moment&quot; in our platform and all of us were struggling to pin it down. We went around in circles a little bit until we were able to each say our experience of an aha moment as a customer of the platform.  It caused us to zoom in for a brief moment instead of waxing philosophical for a long time. &lt;/p&gt;
&lt;h1&gt;What is the problem we are trying to solve?&lt;/h1&gt;
&lt;p&gt;At this time, the conversation had gotten pretty specific and a little off topic.  Once again trying to zoom in on what we were trying to solve and give to customers gave the conversation a focus.&lt;/p&gt;
&lt;h1&gt;Lets all give our summary of the meeting.&lt;/h1&gt;
&lt;p&gt;After spinning wheels for a little bit and running over time, we decided to call it for the day but first had everyone go around and state their main take-aways.  It ensured we were all on the same page and knew what to chew on for the next follow up meeting.&lt;/p&gt;
&lt;p&gt;That’s it!  I feel like these are all simple questions to think about and integrate into the next passionate discussion you have ✌️&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">My Reading List for 2018 📖</title>
    <id>https://erinbush.postach.io/post/my-2018-reading-list</id>
    <updated>2019-01-07T16:59:06.375000Z</updated>
    <published>2019-01-06T23:06:03Z</published>
    <link href="https://erinbush.postach.io/post/my-2018-reading-list" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;As mentioned in my last post, I made it to 71 book this year 🤓 Here’s the final list - If it has a star beside it, I highly recommend it:&lt;/p&gt;
&lt;p&gt;The Immortal Life of Henrietta Lacks - Rebecca Skloot&lt;br /&gt;
The Penelopiad - Margaret Atwood&lt;br /&gt;
Hiroshima - John Hersey ⭐&lt;br /&gt;
Boy Snow Bird - Helen Oyeyemi&lt;br /&gt;
The Orenda - Joseph Boyden&lt;br /&gt;
Full tilt - Dervla Murphy&lt;br /&gt;
Oryx and crake - Margaret Atwood ⭐&lt;br /&gt;
Let’s Pretend This Never Happened - Jenny Lawson&lt;br /&gt;
Braving the Wilderness - Brene Brown &lt;br /&gt;
Weapons of Math Destruction - Cathy O'Neil ⭐&lt;br /&gt;
Sh*t My Dad Says - Justin Halpern&lt;br /&gt;
The beauty myth -  Naomi Wolf&lt;br /&gt;
Dept. of speculation - Jenny Offill&lt;br /&gt;
Hope in the dark - Rebecca Solnit ⭐&lt;br /&gt;
A Room of One’s Own - Virginia Woolf&lt;br /&gt;
Barrelling Forward - Eva Crocker &lt;br /&gt;
The Year of the Flood - Margaret Atwood&lt;br /&gt;
Hunger - Roxanne Gay ⭐&lt;br /&gt;
Young Jane Young - Gabrielle Zevin&lt;br /&gt;
The Notorious RGB - Irin Camrom, Shana Knizhnik&lt;br /&gt;
The Clay Girl - Heather Tucker&lt;br /&gt;
MaddAddam - Margaret Atwood&lt;br /&gt;
The Red Parts - Maggie Nelson &lt;br /&gt;
Coralline - Neil Gaiman&lt;br /&gt;
Men Explain Things to Me - Rebecca Solnit&lt;br /&gt;
Heart Burn - Nora Ephron ⭐&lt;br /&gt;
The Circle - Dave Eggers &lt;br /&gt;
The Color Purple - Alice Walker&lt;br /&gt;
Bloomability - Sharon Creech&lt;br /&gt;
What Happened - Hilary Rodham Clinton &lt;br /&gt;
Modern Lovers - Emma Straub&lt;br /&gt;
The Alice Network - Kate Quinn&lt;br /&gt;
The Nest - Cynthia D’Aprix Sweeney&lt;br /&gt;
The Muse - Jessie Burton ⭐&lt;br /&gt;
Modern Romance - Aziz Ansari &lt;br /&gt;
Hygge: The Danish Art of Happiness - Marie Tourell Søderberge ⭐&lt;br /&gt;
The Nix - Nathan Hill ⭐&lt;br /&gt;
The Vagina Monologues - Eve Ensler&lt;br /&gt;
Stone Mattress: Nine Tales - Margaret Atwood ⭐&lt;br /&gt;
The Gypsy Moth Summer - Julia Fierro&lt;br /&gt;
Your Heart is the Size of Your Fist - Martina Scholtens ⭐&lt;br /&gt;
The Course of Love - Alain De Botton&lt;br /&gt;
The Hitchhikers Guide to the Galaxy - Douglas Adams&lt;br /&gt;
The Book of Joan - Lydia Yuknavitch&lt;br /&gt;
All We Leave Behind - Carol Off ⭐&lt;br /&gt;
Why I’m No Longer Talking to White People About Race - Reni Eddo-Lodge ⭐&lt;br /&gt;
The Argonauts - Maggie Nelson&lt;br /&gt;
Shrill - Lindy West&lt;br /&gt;
So You Want to Talk About Race - Ijeoma Oluo &lt;br /&gt;
The Power - Naomi Alderman ⭐&lt;br /&gt;
Shrewed - Elizabeth Renzetti ⭐&lt;br /&gt;
The Rosie Project - Graeme Simsion ⭐&lt;br /&gt;
The Fifth Season - NK Jemisin ⭐&lt;br /&gt;
Heart Berries - Theresa Marie Mailhot ⭐&lt;br /&gt;
The Obelysk Gate - NK Jemisin&lt;br /&gt;
The Rock Warriors Way - Arno Ilgner&lt;br /&gt;
Barbarian Days - William Finnegan&lt;br /&gt;
Crazy Rich Asians - Kevin Kwan&lt;br /&gt;
A Man Called Ove - Fredrik Backman ⭐&lt;br /&gt;
Between the World and Me - Ta-Nehisi Coates &lt;br /&gt;
Meaty - Samantha Irby &lt;br /&gt;
Like a Mother - Angela Garbes&lt;br /&gt;
The Nightingale - Kristin Hannah&lt;br /&gt;
This Will Be My Undoing - Morgan Jerkins ⭐&lt;br /&gt;
The Best Laid Plans - Terry Fallis&lt;br /&gt;
When Breath Becomes Air - Paul Kalanithi ⭐&lt;br /&gt;
The Goldfinch - Donna Tart&lt;br /&gt;
Hyperbole and a Half - Allie Brosh&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">2018 In Numbers 🍪</title>
    <id>https://erinbush.postach.io/post/my-2018-in-numbers</id>
    <updated>2019-01-07T16:59:21.675000Z</updated>
    <published>2019-01-06T22:40:36Z</published>
    <link href="https://erinbush.postach.io/post/my-2018-in-numbers" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;2018 was a great year!  I took a moment to reflect on all that I’ve accomplished in just 365 days:&lt;/p&gt;
&lt;p&gt;📄 12 blog posts published&lt;br /&gt;
🛩 5 trips&lt;br /&gt;
💻 1,821 Github contributions&lt;br /&gt;
👩‍🏫 1 conference attended&lt;br /&gt;
📖 71 books read&lt;br /&gt;
🎧 38,725 minutes listened on Spotify&lt;br /&gt;
📈 4 ETFs invested in&lt;br /&gt;
⚙️ 1 open source project contribution&lt;br /&gt;
☕️ too much coffee consumed&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">#GOALS #2019 👩‍💻</title>
    <id>https://erinbush.postach.io/post/goals-2019</id>
    <updated>2019-01-11T18:31:54.102000Z</updated>
    <published>2019-01-06T22:01:10Z</published>
    <link href="https://erinbush.postach.io/post/goals-2019" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;I’m a little late to the resolution game but over the last week I’ve been doing some serious reflection (while on a ski trip in Nelson, BC) and have realized I’ve come a long way from when I first started my developer journey almost 8 years ago.  This year a main theme for me is engaging in the developer community and sharing some of the skills I’ve been building over the last few years. &lt;/p&gt;
&lt;h1&gt;Build out my React knowledge&lt;/h1&gt;
&lt;p&gt;I learned react almost 2 years ago but working on a weird edge case made me realize I still have a ways to go with my React understanding before I can call myself an expert.  I don’t want to limit what React-related a I focus on but a good start would be on performance and a more in-depth look into higher order components&lt;/p&gt;
&lt;h1&gt;Continue to read a technical article a day&lt;/h1&gt;
&lt;p&gt;A few months ago I made a commitment to reading one technical article a day and started putting the summaries of articles into a newsletter-style course.  &lt;/p&gt;
&lt;h1&gt;Connect with the developer community more&lt;/h1&gt;
&lt;p&gt;I signed up for dev.to in the hopes to engage more with developers and to find more technical articles to read to expand my knowledge.  I also want to start attending local meet ups at least once every 3 months. &lt;/p&gt;
&lt;h1&gt;Be a thought leader in the company on accessibility measures and follow through on implementing automated and manual accessibility checks&lt;/h1&gt;
&lt;p&gt;This goal has been in the works for a while but I want to formally commit myself to pushing our company forward on all things accessibility related and to providing a decent accessible experience for all users of our application.&lt;/p&gt;
&lt;h1&gt;Master GraphQL subscriptions&lt;/h1&gt;
&lt;p&gt;This is a also to push me to learn more about GraphQL and all the cool opportunities it provides.  I see a real use case in our app for implementing subscriptions and I intend to follow through on it. &lt;/p&gt;
&lt;h1&gt;Understand Redux and explore React Context as an alternative&lt;/h1&gt;
&lt;p&gt;Redux is a magical black box to me right now and I would love to have a better understanding of its implementation and use cases.&lt;/p&gt;
&lt;h1&gt;Follow up&lt;/h1&gt;
&lt;p&gt;This is how these goals actually translated into my 7Geese personal OKRs for the quarter at Thinkific:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images.postach.io/22a20ab7-bd49-49ab-8e3d-b9839f60a228/6fe3c1d9-c633-465f-8bc0-4420535536e9/b7b9338c-ebc3-4d1d-83de-d5336f445980.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Here’s to another great year! 🍻 &lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">I Made an Online Course! 📚</title>
    <id>https://erinbush.postach.io/post/i-made-an-online-course</id>
    <updated>2019-01-15T18:43:44.133000Z</updated>
    <published>2018-12-21T22:47:58Z</published>
    <link href="https://erinbush.postach.io/post/i-made-an-online-course" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;Being a developer at Thinkific for almost 2 years, I decided it was high time to make my very own online course.  I’ll be moving my tech specs over to the course for the time being.  I’ll make one article summary available on the blog per week and the 4 other articles will be available in the course.  &lt;/p&gt;
&lt;p&gt;If you are interested in enrolling here is the link: &lt;a href=&quot;https://diy-developer.thinkific.com/&quot;&gt;diy-developer.thinkific.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This course came about from me wanting to help others work on their technical knowledge as well.  If you remember from my &lt;a href=&quot;https://erinbush.postach.io/post/goals&quot;&gt;goals blog post&lt;/a&gt; in September, I wanted to work on my technical expertise.  While I feel like we are never done learning new technical skills, I think an important next step is to share what I have learned and also help others work on their technical knowledge as well.&lt;/p&gt;
&lt;p&gt;Happy 2019 all! &lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Commenting over Requesting Changes ☠</title>
    <id>https://erinbush.postach.io/post/commenting-over-requesting-changes</id>
    <updated>2018-11-20T21:50:10.555000Z</updated>
    <published>2018-11-20T00:08:07Z</published>
    <link href="https://erinbush.postach.io/post/commenting-over-requesting-changes" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;div&gt;It took me 3 business days + a weekend to find the courage to stand up to my boss after he requested changes on my pull request.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;How? How does this happen? I am usually a very opinionated person who will definitely tell people how I feel about a situation - especially at work.  Its my job to have an opinion. &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;One of my goals for the year is about building technical confidence.  I’m reading one technical article a day in order to expand in depth and breadth of knowledge.  I attended a front end conference to do just the same thing.  I’m actively planning lunch and learns and discussions on how to bring what I’ve learned into our product.  So why, WHY, was it so hard to tell a senior dev that I disagreed with his tactic.  &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;To set the stage, in the past, this developer has never approved one of my PRs on first look.  Even for suggestions, he very liberally uses the &quot;request changes&quot; feature of the Github pull request method.  That’s fine.  That’s not the issue.  I love getting feedback.  Most of the time I agree with him that it could be done better.  90% of the time we end up going with his suggestion. &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;This time around, I read an article about the very issue we were talking about.  And while nothing is set in stone, I felt pretty confident that I had the right approach before I created my pull request.  Not expecting any suggestions on this little number, I made the PR and happily went along with my day.  &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;The email notification came in with a hefty subject of &quot;{Senior Dev} requests changes on your pull request&quot;.  Not surprised (remember, this happens every time), I go in and see his suggestion.  I craft a thoughtful response that I think very nicely summarizes why I think my approach is better, submit, and then see another comment come in that is his exact words, but rephrased.  He thought I didn’t understand his approach.  I understood, I just didn’t agree.  And this is where the waiting period began.  &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;I knew he thought I was going to make the changes, I knew he was expecting it.  I also know that he sometimes goes in after someone has done work and will refactor their changes.  I had this paralyzing fear that if I didn’t make his changes, he’ll just go back to it in a month and make the changes he wanted in the first place.&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;I’m not saying that I am always right.  I am NEVER saying that I always have the right approach, but in this situation I knew that I did not agree with his suggested changes. I am not going to make the changes.  Making the changes feels like loosing. &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;It just feels like I always walk away from PRs with my tail between my legs despite having grown as a developer (this is my 3rd year as a dev, I am far from beginner).  I should have an opinion.  I am paid to have an opinion.  But changing a power dynamic is hard.  And telling someone with 6+ more years of experience than you that you think they are wrong is also hard.  I know it was unprofessional to leave his comment and my PR sitting there for almost a week but I didn’t know how to start.  Isn’t &quot;request changes&quot; just that?  A request?  Its not &quot;mandate changes&quot;, its also not &quot;we have held a fair trial and the ruling is that there must be changes&quot;.  &lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;When I review someone’s pull request, maybe because I am still partially unsure, or maybe just constantly conditioned to be unsure, but if in someone’s pull request something is a little off but not a necessary change and there aren’t any obvious errors, I use the &quot;comment&quot; and not the &quot;request changes&quot;.  I feel this opens people up for discussion on something you, yourself is not fully sure of.  Why can’t we all start discussions about someones work instead of deciding they don’t know what they are doing?&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;My 2 cents &lt;span style=&quot;font-size: 13px; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; color: rgb(34, 34, 34); font-family: arial, sans-serif; font-variant-caps: normal; font-variant-ligatures: normal;&quot;&gt;✌️&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Tech Specks Week #5 ⛷️</title>
    <id>https://erinbush.postach.io/post/tech-specks-week-5</id>
    <updated>2018-12-31T04:47:58.191000Z</updated>
    <published>2018-11-13T19:16:48Z</published>
    <link href="https://erinbush.postach.io/post/tech-specks-week-5" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="techspecks" />
    <content type="html">&lt;h1&gt;&lt;a href=&quot;https://www.kitchensoap.com/2012/10/25/on-being-a-senior-engineer/&quot;&gt;#1 On Being a Senior Engineer [Part 1]&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Senior engineers should be &lt;em&gt;mature&lt;/em&gt; engineers&lt;/strong&gt;&lt;br /&gt;
- Seek out constructive criticism of their designs&lt;br /&gt;
- Understand the non-technical areas of how they are perceived&lt;br /&gt;
    - Doesn’t matter how smart you are if no one wants to work with you&lt;br /&gt;
    - Be the engineer everyone wants to work with&lt;br /&gt;
      - Should still offer feedback on code - it doesn’t have feelings and shouldn’t be your baby&lt;br /&gt;
- Do not shy away from making estimates and try to get better at making them&lt;br /&gt;
- Have an innate sense of anticipation&lt;br /&gt;
    * how long will this thing last before it needs to be rewritten? Is it readable? Am I making things easier?&lt;br /&gt;
&lt;em&gt; not every project will be glamorous&lt;br /&gt;
&lt;/em&gt; lift the skills and expertise of others around them&lt;br /&gt;
    * teaching to fish - requires patience and a perspective fo investment in the rest of the organization&lt;br /&gt;
&lt;em&gt; Make trade-offs explicit when making judgements and decisions&lt;br /&gt;
    * cannot be efficient and thorough at the same time - most projects exist on a n axis of optimality and brittleness - problems are either acute or chronic&lt;br /&gt;
    * immature engineers discover tradeoffs in hindsight, mature engineers spell them out at the onset of a project, accept them and recognize them as a part of good engineering&lt;br /&gt;
&lt;/em&gt; don’t practise CYAE (&quot;Cover Your Ass Engineering&quot;)&lt;br /&gt;
    * don’t through people under the bus if your work doesn’t work&lt;br /&gt;
&lt;em&gt; be empathetic&lt;br /&gt;
    * recognize that all stakeholders goals are different &lt;br /&gt;
    * see the project from other people’s perspective &lt;br /&gt;
&lt;/em&gt; don’t make empty complaints&lt;br /&gt;
    * express judgements based on empirical evidence and bring options for dealing with them&lt;br /&gt;
    * don’t go to your boss with a problem without at least one solution&lt;br /&gt;
* be aware of cognitive biases&lt;br /&gt;
    * we are unaware of when we are interpreting things differently in our own brains in ways that defy empirical data&lt;br /&gt;
    * self serving bias: if something is good, its because of something I did, if its bad, its someone else’s fault&lt;br /&gt;
    * fundamental attribution error: the bad results someone else got are because of who he is (sloppy, stupid…), if I get a bad result, its because of my context/situation&lt;br /&gt;
    * hindsight bias: tendency to view the past more simply than it was in reality&lt;br /&gt;
    * outcome bias: it a damaging outcome, the decisions that came to that action are judged to be very stupid/reckless&lt;br /&gt;
    * planning fallacy: being more optimistic about forecasting the time required for a project&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://www.kitchensoap.com/2012/10/25/on-being-a-senior-engineer/&quot;&gt;#2 On Being a Senior Engineer [Part 2]&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;10 Commandments of Egoless Programming&lt;br /&gt;
1. Understand that you will make mistakes - you should just try to find them early&lt;br /&gt;
2. You are not your code - don’t take things personally&lt;br /&gt;
3. Know matter how much &quot;Karate&quot; you know, someone else will always know more - ask them to teach you some moves&lt;br /&gt;
4. Don’t rewrite code without consultation - know the difference between &quot;fixing code&quot; and &quot;rewriting code&quot;&lt;br /&gt;
5. Treat people who know less then you with respect, deference and patience&lt;br /&gt;
6. The only constant in the world is change, be open to it and accept it with a smile&lt;br /&gt;
7. The only true authority stems from knowledge, not from position - if you want respect in an egoless environment, cultivate knowledge&lt;br /&gt;
8. Fight for what you believe, but gracefully accept defeat&lt;br /&gt;
9. Don’t be the &quot;coder in the corner&quot; - this person has no voice in an open, collaborative environment&lt;br /&gt;
10. Critique code instead of people - be kind to the coder, not to the code - make all of your comments positive and oriented to the code (site local standards, program specs, increased performance, etc)&lt;/p&gt;
&lt;p&gt;Novices Vs Experts&lt;br /&gt;
&lt;em&gt; Novices are deeply subject to local rationality and adhere to rigid rules or plans&lt;br /&gt;
&lt;/em&gt; Experts are context driven and do not see problems as one thing and solutions as another, they act wholistically&lt;/p&gt;
&lt;p&gt;Mature engineers know that how people feel (sometime irrationally) about technology is still important.  People’s experiences with technology influence their opinions about it.  Mature engineers understand this when making the case for using a specific technology as a solution.&lt;/p&gt;
&lt;p&gt;Mature engineers hold the success of the project much higher than the potential praise they might get for working on it.&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://uxplanet.org/designing-accessible-navigations-3b1a151d3bd7&quot;&gt;#3 Designing Accessible Navigations&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Navigation also involves moving from section to section in addition to switching pages.  To improve usability for everyone:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Allow users to skip content:&lt;/strong&gt; include skip links (only visible when tabbed to) that allows users to bypass navigation&lt;br /&gt;
* important because otherwise users are forced to tab through all of the navigation every time they come to the page&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Add an Accessibility Menu:&lt;/strong&gt;&lt;br /&gt;
&lt;em&gt; Reduces the amount of effort it takes for impaired users to access your content&lt;br /&gt;
&lt;/em&gt; an altogether different navigations to simplify an impaired individual’s experience&lt;br /&gt;
* Facebook provides dropdown that allow users to jump to different sections and includes a keyboard shortcut to access it anywhere&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consider Keyboard Shortcuts:&lt;/strong&gt;&lt;br /&gt;
&lt;em&gt; Offers users the opportunity to navigate the site and perform actions with one button - significantly reduces frustration&lt;br /&gt;
&lt;/em&gt; Lets users skip content they think is irrelevant&lt;br /&gt;
&lt;em&gt; Show users a modal with all the possible shortcuts&lt;br /&gt;
&lt;/em&gt; Add hotkeys for the main pages in your app&lt;br /&gt;
* Have a goal for adding shortcuts and don’t just add them randomly&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Properly Structure and Label Elements:&lt;/strong&gt;&lt;br /&gt;
&lt;em&gt; Apple’s VoiceOver supports Rotor which pops up a modal that shows the user all of your Headings, Articles, Links, Form Controls, Landmarks, and etc&lt;br /&gt;
&lt;/em&gt; Having all your sections have descriptive labels that can be used as landmarks and having proper type hierarchy allows users to confidently know what they are skipping &lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://www.lullabot.com/articles/flow-for-static-type-checking-javascript&quot;&gt;#4 Using Flow for Static Type Checking&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Static type checking: types are known at compile time&lt;br /&gt;
Dynamic type checking: types aren’t known until runtime (javascript)&lt;/p&gt;
&lt;p&gt;With a static type checker, bugs are caught earlier &lt;/p&gt;
&lt;p&gt;Implicit Type Coercion: in JS we can reassign values to a variable that are not the same type - if it was a number, you can reassign it a boolean&lt;/p&gt;
&lt;p&gt;Flow catches these types of errors.&lt;/p&gt;
&lt;p&gt;Even though JS doesn’t check type, its always in the developers mind to reason about the code. &lt;/p&gt;
&lt;p&gt;Why use Flow over TypeScript? Flow is easier to use, not a new language - just add &lt;code&gt;/* @flow*/&lt;/code&gt; to the top of a file.&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://uxdesign.cc/designing-for-accessibility-is-not-that-hard-c04cc4779d94&quot;&gt;#5 Designing for accessibility is not that hard&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Myth: making a website accessible is difficult and expensive - fixing a site that is already inaccessible may require some effort though.  Most problems aren’t hard to correct.&lt;/p&gt;
&lt;p&gt;Why design for accessibility? Need to create a better experience for all users regardless of ability, context or situation, which usually results in a better experience for everyone.&lt;br /&gt;
* studies show that accessible websites have better SEO, a bigger audience, faster download times, encourage good coding practises, and have better usability&lt;br /&gt;
Seven easy things you can do:&lt;br /&gt;
1. Add enough colour contrast - contrast ratio needs to be at least 4.5 to 1 (conformance level AA) - use WEbAim colour contrast checker&lt;br /&gt;
2. Don’t use colour alone to make critical information understandable - use text or patterns&lt;br /&gt;
3. Design usable focus states - if you remove the browser focus state, you need to replace it&lt;br /&gt;
4. Use labels or instructions with form fields and inputs - don’t use just placeholder text! and don’t make the label disappear when they focus on the input&lt;br /&gt;
5. Write useful alternative text for your images and other non-text content - try to describe what’s happening in the image and how it matters to the story rather than just saying &quot;picture&quot;.  If you definitely don’t need alt text because the picture is redundant, adding an empty &lt;code&gt;&amp;lt;alt&amp;gt;&lt;/code&gt; attribute will make screen readers skip it. &lt;br /&gt;
6. Use correct markup on your content - the components and structure of a page are what arranges an accessibility tree which powers screen readers&lt;br /&gt;
7. Support keyboard navigation - people who don’t have precise motor control (and power users!) rely on keyboards - pay attention to the tab order of elements - provide ARIA landmarks to make navigation easier&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Tech Specks Week #4 🏎</title>
    <id>https://erinbush.postach.io/post/tech-specks-week-4</id>
    <updated>2018-10-25T22:11:14.819000Z</updated>
    <published>2018-10-25T20:45:25Z</published>
    <link href="https://erinbush.postach.io/post/tech-specks-week-4" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="techspecks" />
    <content type="html">&lt;p&gt;More webpack and javascript fun! &lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://webpack.js.org/guides/caching/&quot;&gt;#1: Caching (with webpack)&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Need to configure webpack to ensure files produced by webpack can remain cached unless their contents has changed&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;can use build-specific chunk hashes -&amp;gt; filename: ’[name].[chunkhash].js'&lt;/li&gt;
&lt;li&gt;runtimeChunk: split out runtime code into separate chunks - also good practise to do a vendor chunk (eg lodash/react) -&amp;gt; cacheGroups&lt;/li&gt;
&lt;li&gt;adding one module in your app will change the module.id in vendor files - use the NamedModulePlugin to use the module path instead of a numerical identifier&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;a href=&quot;https://medium.freecodecamp.org/avoiding-the-async-await-hell-c77a0fb71c4c&quot;&gt;#2: How to escape async/await hell&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;What hell is: people write multiple statements one after the other and put an await before a function call&lt;br /&gt;
- Causes performance issues - many times one statement doesn’t depend on the previous one&lt;/p&gt;
&lt;p&gt;What if we don’t use the await keyword?&lt;br /&gt;
- We get an unresolved promise (which we can use later)&lt;br /&gt;
- The compiler won’t wait for the function to execute properly&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What can we do?&lt;/strong&gt;&lt;br /&gt;
- Get the promise and then wait for it in another line&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps to get out of hell&lt;/strong&gt;&lt;br /&gt;
1. Find statements which depend on the execution of other statements - make things as parallel as possible&lt;br /&gt;
2. Group-dependent statements in async functions&lt;br /&gt;
3. Execute these async functions concurrently - take advantage of the event loop to run these async non-blocking functions concurrently&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://developers.google.com/web/updates/2018/05/bigint&quot;&gt;#3: BigInt: arbitrary-precision integers in JavaScript&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Lets you store/operate on large integers even beyond &lt;/li&gt;
&lt;li&gt;Makes it possible to correctly perform integer arithmetic without overflowing (eg. financial technology)&lt;/li&gt;
&lt;li&gt;Usually represent large integer ids/timestamps as string because the ints lead to lots of bugs - BigInt fixes this&lt;/li&gt;
&lt;li&gt;Big Int could lead to BigDecimal! &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;js decimal problem &lt;code&gt;(0.1+ 0.2 !== 0.3)&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; 0.1+0.2
&amp;lt;- 0.30000000000000004
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Previously had to use libraries to do big int calculations - can now use native BigInt which will reduce load time, parse time, and compile time + have run time performance.  Still need to polyfill BigInt&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Number:&lt;/strong&gt;&lt;br /&gt;
- &lt;code&gt;Number&lt;/code&gt; type in js are represented as double-precision floats = limited precision&lt;br /&gt;
- Doing calculations on integers outside of the safe integer range (from Number.MIN_SAFE_INTEGER to Number.MAX_SAFE_INTEGER) potentially loses precision&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BigInt:&lt;/strong&gt;&lt;br /&gt;
- Can safely do things outside of the limit for Number&lt;br /&gt;
- To create a BigInt, add n to the end of any integer literal (eg. 123 -&amp;gt; 123n), can also use BigInt(123) === 123n&lt;br /&gt;
- Safe integer limits don’t apply to BigInt&lt;/p&gt;
&lt;p&gt;eg:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BigInt(Number.MAX_SAFE_INTEGER) + 2n; //will be accurate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A New Primitive:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    typeof 123n 
// -&amp;gt; &quot;bigint&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;BigInt is never strictly equal to a number (42n !== 42) - to compare them, will need to convert (42n === BigInt(42))&lt;/li&gt;
&lt;li&gt;When coerced to a boolean, BigInts follow the same logic as numbers (0n is falsey)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Operators:&lt;/strong&gt;&lt;br /&gt;
- BigInts support most common operators, bitwise operations (|, &amp;amp;, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;, and ^) perform bitwise arithmetic assuming a two’s complement representation for negative values (just like for numbers) - &lt;a href=&quot;https://en.wikipedia.org/wiki/Two%27s_complement&quot;&gt;Two’s Complement&lt;/a&gt;&lt;br /&gt;
- Unary - works to make bigint a negative but, unary + is not supported because asm.js expects +x to always produce either a number o an exception&lt;br /&gt;
- Can’t mix operations between bigint and numbers (Bigint(2) + 2.5 -&amp;gt; ??? results in a TypeError)&lt;br /&gt;
- &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; (unsigned right shift does not work for BigInt because they are always signed&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://githubengineering.com/removing-jquery-from-github-frontend/&quot;&gt;#4: Removing jQuery from Github Frontend&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt;&lt;br /&gt;
- Sometimes tech debt grows around dependencies that slowly loose value&lt;br /&gt;
- Some of the jQuery syntax doesn’t show intent properly - jQuery will select all of one type (did the author intend this?), and jQuery also silently skips expressions if they don’t match anything on the page&lt;br /&gt;
- jQuery is not compatible with Flow (or other static type checkers)&lt;br /&gt;
- Removing jQuery means you can rely on web standards more&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Incremental Decoupling:&lt;/strong&gt;&lt;br /&gt;
- Monitor number of jQuery calls&lt;br /&gt;
- Don’t allow importing jQuery into new code - use eslint to error &lt;br /&gt;
- Disable all subsequent eslint errors - shows devs its not up to coding standards&lt;br /&gt;
- People see the eslint disable in code reviews and prompts people to fix it&lt;br /&gt;
- Static type checking added confidence when refactoring code to vanilla js&lt;br /&gt;
- replace $.ajax with fetch()&lt;br /&gt;
- Incrementally remove jQuery modules that were no longer being used (creates a custom jQuery) - sped up JS&lt;br /&gt;
- Dropped old IE support and then didn’t have to worry about polyfills&lt;br /&gt;
- Only used JS as a progressive enhancement so that it would still work with JS disabled in the browser - then didn’t have to rewrite support in JS - could get rid of it altogether&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Custom Elements:&lt;/strong&gt;&lt;br /&gt;
- Component library native to the browser - nothing for the user to download, parse, compile&lt;br /&gt;
- Focussed on progressive enhancement when making elements&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Polyfills:&lt;/strong&gt;&lt;br /&gt;
- Use specific polyfills only when they are necessary for the user and not all the time (ie. to outdated browsers)&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://hackernoon.com/optimising-your-application-bundle-size-with-webpack-e85b00bab579&quot;&gt;#5: Optimize your Application Bundle Size with Webpack&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Use &lt;code&gt;webpack-bundle-analyzer&lt;/code&gt; to visualize how big your project dependencies are. &lt;/p&gt;
&lt;p&gt;First, install with &lt;code&gt;npm install webpack-bundle-analyzer&lt;/code&gt;.  Then, modify your &lt;code&gt;webpack.config.js&lt;/code&gt; by adding:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var BundleAnalyzerPlugin = require(‘webpack-bundle-analyzer’).BundleAnalyzerPlugin;

//…
plugins: [
  new BundleAnalyzerPlugin(),
  new webpack.DefinePlugin({
    ‘process.env.NODE_ENV’: ‘&quot;production&quot;’
  }),
]
//… 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However you start your server, it should serve you a new page at &lt;code&gt;http://localhost:8888&lt;/code&gt; that has your projects visualizations and should be for the production version of your code.&lt;/p&gt;
&lt;p&gt;When importing dependencies use:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import groupBy from ‘lodash/groupBy’
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;instead of:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import loads from ‘lodash'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Remove your source map for production to save on space by using: &lt;code&gt;devtool: ‘eval-source-map’&lt;/code&gt; instead of &lt;code&gt;devtool: ‘eval’&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;gz compression:&lt;/strong&gt; use &lt;code&gt;compression-webpack-plugin&lt;/code&gt; - compresses assets and generates .gz files&lt;br /&gt;
&lt;strong&gt;de-duplicating:&lt;/strong&gt; use &lt;code&gt;dedupe-plugin&lt;/code&gt; - removes duplicates of equal/similar files from output, has overhead for entire chunk but can reduce file size&lt;br /&gt;
&lt;strong&gt;minimizing JS:&lt;/strong&gt; use &lt;code&gt;uglifyjs-plugin&lt;/code&gt; - minimizes all JS output of chunks&lt;br /&gt;
&lt;strong&gt;only include what’s necessary from module:&lt;/strong&gt; use &lt;code&gt;ignore-plugin&lt;/code&gt; - import selective modules&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Tech Specks Week #3 😎</title>
    <id>https://erinbush.postach.io/post/tech-specks-week-3</id>
    <updated>2018-10-25T22:11:14.626000Z</updated>
    <published>2018-10-18T23:19:18Z</published>
    <link href="https://erinbush.postach.io/post/tech-specks-week-3" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="techspecks" />
    <content type="html">&lt;p&gt;I focussed this week on Webpack and some React-y things. Lots of learning going on over here. &lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://webpack.js.org/guides/lazy-loading/&quot;&gt;#1: Lazy Loading with Webpack (follow up to code splitting)&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;only load code when the user requires it - speeds up initial loading of the app (some blocks may never be loaded)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;button.onclick = e =&amp;gt; import(/* webpackChunkName: &amp;quot;print&amp;quot; */ './print').then(module =&amp;gt; {
  var print = module.default;
  print();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: when using import() on ES6 modules, you must reference the .default property as it’s the actual module object that will be returned when the promise is resolved&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://reacttraining.com/react-router/web/guides/code-splitting&quot;&gt;#2: React and Code Splitting&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Incrementally downloading the app&lt;/strong&gt;&lt;br /&gt;
- packages: webpack, babel-plugin-syntax-dynamic-import and react-loadable&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;babel-plugin-syntax-dynamic-import&lt;/strong&gt;&lt;br /&gt;
- syntax-only plugin meaning babel won’t do any transformation&lt;br /&gt;
- allows babel to parse dynamic imports so webpack can bundle them as a code split&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;react-loadable&lt;/strong&gt;&lt;br /&gt;
- higher-order component for loading components with dynamic imports&lt;br /&gt;
- makes code splitting easy!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Loadable from 'react-loadable';
import Loading from './Loading';

const LoadableComponent = Loadable({
  loader: () =&amp;gt; import('./Dashboard'),
  loading: Loading,
})

export default class LoadableDashboard extends React.Component {
  render() {
    return &amp;lt;LoadableComponent /&amp;gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then use LoadableDashboard and it will automatically be loaded and rendered when you use it in your application&lt;br /&gt;
- loading is a placeholder component to show while the real component is loading&lt;/p&gt;
&lt;p&gt;react-loadable also has suggestions for server-side rendering&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://www.sitepoint.com/file-bundling-and-http2/&quot;&gt;#3: File Bundling and HTTP/2: Rethinking Best Practices&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2: based on Google’s SPDY protocol&lt;/strong&gt; - intent is to improve page load latency and security&lt;br /&gt;
- binary protocol not text based (more compact, efficient to parse and less prone to errors)&lt;br /&gt;
- multiplexed: multiple files can be transferred on a single connection&lt;br /&gt;
- server push: allows the server to transfer resources to the client before they’re requested (pre-filling the cache&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2 and JS developers&lt;/strong&gt;&lt;br /&gt;
- concatenating multiple files into bundles makes it difficult for the browser to effectively cache our code&lt;br /&gt;
  - the whole bundle needs to be redownloaded if one line of code changes&lt;br /&gt;
- since HTTP/2 can multiplex (making requests inexpensive) we can split code into smaller bundles and make use of caching (better experience for users)&lt;/p&gt;
&lt;p&gt;web servers also have limits on how efficiently they can serve a large number of files (so we shouldn’t endlessly split files)&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://medium.com/webpack/webpack-http-2-7083ec3f3ce6&quot;&gt;#4 webpack and HTTP/2&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Still is protocol overhead for each request compared to a single concatenated file&lt;/li&gt;
&lt;li&gt;The compression of the single large file is better than many small files&lt;/li&gt;
&lt;li&gt;Servers are slower serving many small files than a single large file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Changing one module invalidates the cache for one bundle which is only a part of the complete application - the remaining application is still cached.  Need to find a balance.&lt;/p&gt;
&lt;p&gt;More bundles = better caching but less compression&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AggressiveSplittingPlugin (from webpack)&lt;/strong&gt;&lt;br /&gt;
- Splits the original chunks into smaller chunks (you specify the size)&lt;br /&gt;
- To combine similar modules, they are sorted alphabetically (by path) before splitting - modules in the same folder are probably related to each other and similar from compression point of view - with this sorting they end up in the same chunk&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We need to reuse the previously created chunks&lt;/strong&gt;&lt;br /&gt;
- When AgressiveSplittingPlugin finds a good chunk, it stores the chunk’s modules and has into records (web pack’s concept of state that is kept between compilations)&lt;br /&gt;
- AggressiveSplittingPlugin tries to restore the chunks from records before trying to spit the remaining modules (ensures reuse)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The application using this optimization will have multiple script tags to load each chunk in parallel&lt;/strong&gt;&lt;br /&gt;
- The browser can start executing older files in cache while waiting for the download of most recent files&lt;br /&gt;
- HTTP/2 Server push can be used to send these chunks to the client when the HTML page is requested - best to start pushing the most recent file first as older files are more likely already in the cache&lt;br /&gt;
  - The client can cancel push responses for files it already has, but this take a round trip&lt;br /&gt;
- When using code splitting for on demand loading, w ebpack handles the parallel requests for you&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9&quot;&gt;#5: 6 Reasons Why JavaScript’s Async/Await Blows Promises Away&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Async/await makes asynchronous code look and behave a little more like synchronous code.  Any async function returns a promise implicitly and the resolve value of the promise will be whatever you return from the function&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why is it better?&lt;/strong&gt;&lt;br /&gt;
1. Concise + clean (no more .then, no more nested code)&lt;br /&gt;
2. Error Handling: can handle synchronous and async errors with the same construct (try/catch) - previously, try/catch won’t handle errors inside the promise&lt;br /&gt;
3. Conditionals: simplifies cause it makes multiple promises easier&lt;br /&gt;
4. Intermediate Values: no more crazy nesting promises or using promise.all&lt;br /&gt;
5. Error stacks: especially in production environments with large promise chains&lt;br /&gt;
6. Debugging: much easier - promises were annoying because you couldn’t set breakpoints in arrow functions that return expressions (no body)&lt;br /&gt;
   - Doesn’t step through .then statements because it only goes through synchronous code&lt;br /&gt;
    - With async/await you can step through like its synchronous&lt;/p&gt;
&lt;p&gt;Harder things:&lt;br /&gt;
- More difficult to spot asynchronous code&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">I'm a Node.js Contributor!🏅</title>
    <id>https://erinbush.postach.io/post/i-m-a-node-js-contributor</id>
    <updated>2018-10-25T20:35:29.813000Z</updated>
    <published>2018-10-18T20:12:52Z</published>
    <link href="https://erinbush.postach.io/post/i-m-a-node-js-contributor" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;I attended the Node+JS Interactive conference last week in Vancouver.  I found that every session I went to sparked some kind of idea for ways we can improve our product and workflow at Thinkific, and also for some personal projects I want to get started on.  The only problem is deciding what I want to start first because there is so much 🙈&lt;/p&gt;
&lt;p&gt;There was a strong female speaker presence which was refreshing (although it shouldn’t be surprising since its 2018). I also appreciated that there were no all-male diversity panels and all of the female speakers were discussing technical topics, not &quot;what its like being a female developer 🙄&quot;.  So good job Node+JS Interactive (even though its 2018 and I shouldn’t have to be congratulating you on this).&lt;/p&gt;
&lt;p&gt;The last day of the conference they did a workshop where they had about 300 people contribute to the Node.js project.  I was v impressed with how streamlined it was - I built Node locally, ran the tests, got a tiny task to work on, submitted a PR and was approved all in about 2 hours. And now I can say that I contribute to the open source community 🙃 I’m very proud of my &lt;a href=&quot;https://github.com/nodejs/node/pull/23542&quot;&gt;pull request&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;The talks that got me the most jazzed were:&lt;/h1&gt;
&lt;h3&gt;Leaving the CDN Behind: Building a JavaScript SDK in a Serverless World - Daniel Brain&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Main Takeaways:&lt;/strong&gt; Dynamically compile relevant code used by a component and cache it for speed.  SDK is available at a url that specifies the component.   Stays evergreen so you don’t have to worry about versioning and maintaining older versions&lt;br /&gt;
&lt;a href=&quot;https://jsi2018.sched.com/event/F76S/leaving-the-cdn-behind-building-a-javascript-sdk-in-a-serverless-world-daniel-brain-paypal&quot;&gt;Slides&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Automated Performance Testing - Christian Bromann&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Main Takeaways:&lt;/strong&gt; You should come up with performance metrics for your app (ie. it should be interactive in less than 5 seconds) and integrate automated testing in your CI/CD workflow.  One option for tooling is WebDriver.&lt;br /&gt;
&lt;a href=&quot;https://schd.ws/hosted_files/jsi2018/4a/Automated%20Web-Performance%20Testing%20with%20WebDriver.pdf&quot;&gt;Slides&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=7EUTIBILQKg&quot;&gt;Video&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Machine Powered Refactoring: Leverage AST’s to Push your Legacy Code (&amp;amp; the Web) Forward - Amal Hussein&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Main Takeaways:&lt;/strong&gt; You can make custom linters and refactor old code using ASTs.  We just did a tiny little dive into the world of ASTs but it seems very powerful.  I can definitely see applications for creating custom accessibility linters that we’ve been meaning to build out to make accessibility a priority for developers.&lt;/p&gt;
&lt;h1&gt;Talks that I didn’t make it to that I still want to see&lt;/h1&gt;
&lt;h3&gt;Automated Accessibility Testing - Dylan Barrell&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7hRQPNvUp-A&quot;&gt;Video&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Bringing Javascript Back to Life - Joyee Cheung&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=XQIo9knnb2s&quot;&gt;Video&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;HTTP/2, One Frame At a Time - Irina Shestak&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ebR_XrAoW3k&amp;amp;t=818s&quot;&gt;Video&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Effective Agile Processess: It’s All About People - Bryan Hughes&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=MdExAEEisoE&amp;amp;t=0s&amp;amp;list=PLfMzBWSH11xaZvhv1X5Fq1H-oMdnAtG6k&amp;amp;index=20&quot;&gt;Video&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Into to Web Components &amp;amp; Polymer - John Riviello &amp;amp; Chris Lorenzo&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=YZK_inA_wNM&amp;amp;t=0s&amp;amp;list=PLfMzBWSH11xaZvhv1X5Fq1H-oMdnAtG6k&amp;amp;index=32&quot;&gt;Video&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;h1&gt;Talks that seem cool but don’t have videos yet&lt;/h1&gt;
&lt;h3&gt;Offline First: Making your App Awesome When the Network Isn’t - Teri Chadbourne&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://schd.ws/hosted_files/jsi2018/b9/Offline%20First%20Making%20Your%20App%20Awesome%20When%20the%20Network%20Isnt.pdf&quot;&gt;Slides&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Zero to Production with the Serverless Framework - Diana Lee&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://schd.ws/hosted_files/jsi2018/2f/Serverless%20Framework%20-%20Diana%20-%20BeApplied.pdf&quot;&gt;Slides&lt;/a&gt;&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Tech Specks Week #2 🐳</title>
    <id>https://erinbush.postach.io/post/tech-specks-week-2</id>
    <updated>2018-10-18T20:12:30.214000Z</updated>
    <published>2018-09-26T00:58:51Z</published>
    <link href="https://erinbush.postach.io/post/tech-specks-week-2" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="techspecks" />
    <content type="html">&lt;p&gt;I managed to hit 5 articles this week 🙌  I’m already finding a lot of value re-reading all of the blurbs on Fridays.  This week I focused on Webpack and some Async/Await fun.&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://www.sitepoint.com/beginners-guide-webpack-module-bundling/&quot;&gt;#1: A Beginner’s Guide to Webpack 4 and Module Bundling - Part 1&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Webpack: module bundler for JS but can be used for HTMl, CSS and images &lt;br /&gt;
   - can give you more control over the number of HTTP requests your app is making &lt;br /&gt;
   - can easily consume packages from nom&lt;br /&gt;
Can create an npm script for running webpack -&amp;gt; &lt;code&gt;npm run develop&lt;/code&gt;  (dev mode) or &lt;code&gt;npm run build&lt;/code&gt; for production &lt;br /&gt;
   - production is minified and file size is much smaller - optimizes for execution speed at runtime and output file size&lt;br /&gt;
   - dev mode optimizes for build speed and debugging&lt;/p&gt;
&lt;p&gt;ES Modules (split your program into many small, self-contained programs&lt;br /&gt;
   - importing modules from npm don’t uses a relative path but all of your own imports do need a relative path&lt;/p&gt;
&lt;p&gt;Tree Shaking&lt;br /&gt;
   * in dev mode, webpack includes whole packages but in production mode all of the unused modules are removed from bundle&lt;/p&gt;
&lt;p&gt;Loaders&lt;br /&gt;
   * let you run preprocessors (eg. babel) on files as they are imported - allows you to bundle resources beyond js&lt;br /&gt;
   * loaders can be chained to gather into a series of transforms &lt;/p&gt;
&lt;p&gt;CSS in JS&lt;br /&gt;
&lt;code&gt;import ‘./style.scss’&lt;/code&gt;&lt;br /&gt;
   * needs the &lt;code&gt;style-loader&lt;/code&gt; npm package which outputs the string tiny an embedded &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tag&lt;br /&gt;
   * Makes it easier to bundle assets together (images, css, HTML)&lt;br /&gt;
   * dead code elimination: when the JS component is no longer loaded, the CSS file will also not be loaded&lt;br /&gt;
   * css modules: local CSS with unique classes to avoid css overwriting&lt;br /&gt;
   * this allows us to decrease HTTP requests by bundling/splitting code cleverly&lt;/p&gt;
&lt;p&gt;Images (eg package: &lt;code&gt;file-loader&lt;/code&gt;)&lt;br /&gt;
   * store the source of images as strings inside js - preloads them and the browser doesn’t have to fetch them with separate requests later&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import imageExample from ‘./image-example’
img.src = imageExample
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;this will include an image where the src attribute contains a dataURI of the image itself&lt;/li&gt;
&lt;li&gt;background images in CSS are also processed by &lt;code&gt;file-loader&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;a href=&quot;https://www.sitepoint.com/beginners-guide-webpack-module-bundling/&quot;&gt;#2: A Beginner’s Guide to Webpack 4 and Module Bundling - Part 2&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Dependency Graph&lt;br /&gt;
- loaders build a tree of dependencies among your assets and compiles single static assets&lt;/p&gt;
&lt;p&gt;Code Splitting&lt;br /&gt;
- allows you to split code into bundles that can be loaded on demand or in parallel (faster load time)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;button.onclick = () =&amp;gt; {
  import(/* webpackChunkName: &amp;quot;chat&amp;quot; */ &amp;quot;./chat&amp;quot;).then(chat =&amp;gt; {
    chat.init()
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can import the webpack chunk when we click the button (lazy loading)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Plugins&lt;/strong&gt;&lt;br /&gt;
   * loaders operate transform on single files, plugins operate across larger chunks of code&lt;br /&gt;
   * help split code in clever ways and optimize for production&lt;br /&gt;
   * webpack plugin &quot;mode&quot; lets us use dev and production specific plugins (eg: UglifyJsPlugin)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Production&lt;/strong&gt;&lt;br /&gt;
   * need a config file for dev, and prod (webpack.common.js, webpack.dev.js, webpack.prod.js - use common file in both dev and prod file)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Split CSS&lt;/strong&gt;&lt;br /&gt;
   * best practise is to split CSS from JS when bundling for production (use ExtractTextWebpackPlugin) and add the css file to your html as a link&lt;br /&gt;
   * allows for parallel loading of JS and CSS so it will be faster &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Generating HTML&lt;/strong&gt;&lt;br /&gt;
   * html-webpack-plugin updates our index.html file to reference new file paths&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;br /&gt;
   * webpack-dev-server provides a simple web server with live reloading&lt;br /&gt;
   * HotModuleReplacement swaps module at runtime without the refresh&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2&lt;/strong&gt;&lt;br /&gt;
  * webpack gives you control over how assets are fetched as well&lt;br /&gt;
  * HTTP/2 allows multiple files to be delivered in a single request (so concatenation isn’t a silver bullet anymore)&lt;br /&gt;
  * Could be more performant to cache several small files&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://webpack.js.org/guides/code-splitting/&quot;&gt;#3: Code Splitting&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Code splitting allows you to split code into various bundles to load them on demand or in parallel&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3 Approaches:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Entry Points - manually split code using &lt;code&gt;entry&lt;/code&gt; configuration&lt;/li&gt;
&lt;li&gt;in the webpack.config.js file, list the modules by their js files&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;module.exports = {
    mode: ‘development’,
    entry: {    
        index: ‘./src/index.js’,
        another: ‘./src/another-module.js’
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pitfalls:&lt;br /&gt;
   * If there is duplicated modules between chunks, they will be included in both bundles&lt;br /&gt;
   * Can’t be used to dynamically split code&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Prevent Duplication - use the SplitCHunks to deduce and split chunks&lt;ul&gt;
&lt;li&gt;extract common dependencies into a separate chunk&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;optimization: {
    splitChunks: {
        chunks: ‘all
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;other code splitting modules: mini-css-extract-plugin (split css out of main app), bundle-loader (split code and lazy load the resulting bundles), promise-loader (similar to bundle-loader but uses promises)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dynamic Imports - Split code via inline function calls within modules&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;use import() syntax (uses promises so need the promise polyfill for older browsers)&lt;br /&gt;
return import(/&lt;em&gt; webpackChunkName: &quot;lodash&quot; &lt;/em&gt;/ 'lodash').then(_&lt;/li&gt;
&lt;li&gt;webpackChunkNAme in the component will cause our separate bundle to be named loads.bundle.js&lt;/li&gt;
&lt;li&gt;import() returns a promise so ti can be used with async functions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Prefetching/Preloading modules&lt;/strong&gt;&lt;br /&gt;
Use inline directives when declaring imports allows webpack to output &quot;Resource Hint&quot; which tells the browser that for prefetch (probably needed for nav sometime in the future) and preload (resource might be deemed in the current nav)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import(/* webpackPrefetch: true */ 'LoginModal');
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates: &lt;code&gt;&amp;lt;link rel=&quot;prefetch&quot; href=&quot;login-modal-chunk.js&quot;&amp;gt;&lt;/code&gt; (browser will prefetch)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Prefetch:&lt;/em&gt; webpack will add the prefetch hint once the parent chunk has been loaded&lt;/p&gt;
&lt;p&gt;Preload vs prefetch (browser support could be different!)&lt;br /&gt;
    * preload chunk loads in parallel to parent and prefetch loads after parent&lt;br /&gt;
    * preloaded has medium priority and is instantly downloaded, prefetch loads in browser idle time&lt;br /&gt;
    * preloaded instantly requested by parent, prefetch is used anytime in the future&lt;/p&gt;
&lt;p&gt;Bundle Analysis: &lt;br /&gt;
* useful to analyze code splits to check where modules end up (use like webpack-chart and webpack-visulizer or webpack-bundle-analyzer)&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function&quot;&gt;#4: Async Function&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;An async function operates asynchronously via the event loop - uses a promise to return its result&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function doesTheWork() {
    return new Promise(resolve =&amp;gt; {
        setTimeout(() =&amp;gt; {
            resolve(‘resolved’);
        }, 2000);
    });
}

async function asyncCall() {
    var result = await doesTheWork();
    console.log(result) // &quot;resolved&amp;quot;
}

asyncCall()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Async functions can contain an await expression that pauses the execution of the async function and waits for the passed Promise’s resolution, and then resumes the async function’s execution&lt;/p&gt;
&lt;p&gt;The await keyword is only valid inside async functions - you will get a SyntaxError otherwise&lt;/p&gt;
&lt;p&gt;Options:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//sequential start - takes 2 + 1 seconds

async function() {
    const slow = await resolveAfter2Seconds(); 

    // if the value of the expression following the 
   //await operator is not a Promise, it’s converted to a resolved Promise
    const fast = await resolveAfter1Second();
}

//concurrent start - takes 2 seconds total - this can also be done with Promise.all (might be better if you have
//to wait for more than 2 promises 

async function() {
    const slow = resolveAfter2Seconds();
    const fast = resolveAfter1Second();

    console.log(await slow);
    console.log(await fast); // doesn’t log until slow is done!
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The async function is implicitly wrapped in Promise.resolve so you don’t have to put an await on the return statement in an async function&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://javascript.info/async-await&quot;&gt;#5: Async/await&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;async:&lt;/strong&gt; a function will always return a promise (js will automatically wrap the return statement in a promise&lt;br /&gt;
&lt;strong&gt;await:&lt;/strong&gt; only works inside the async function - makes js wait until that promise is resolved, and then evaluates the expression&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the waiting doesn’t cost CPU resources because the engine can do other jobs in the meanwhile &lt;/li&gt;
&lt;li&gt;similar to promise.then but easier to read/write&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;// wait 3 seconds
await new Promise((resolve, reject) =&amp;gt; setTimeout(resolve, 3000));

await accepts thenables (any function that 

class methods can also be async:
class Waiter {
    async wait() {
        return await Promise.resolve(1);
    }
}

new Waiter().wait().then(alert); //1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Error Handling:&lt;br /&gt;
- &lt;code&gt;await Promise.reject(new Error(&quot;Whoops!&quot;))&lt;/code&gt;&lt;br /&gt;
- await waits for the promise to resolve then throws the error&lt;br /&gt;
- Can use in a try/catch as per usual&lt;br /&gt;
- if not in a regular try/catch, the promise is rejected and we can do something like: &lt;code&gt;f().catch(alert);&lt;/code&gt;&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Resolving Conflicts in Real Life 🔪</title>
    <id>https://erinbush.postach.io/post/resolving-conflicts-in-real-life</id>
    <updated>2018-09-25T23:02:00.309000Z</updated>
    <published>2018-09-25T16:13:14Z</published>
    <link href="https://erinbush.postach.io/post/resolving-conflicts-in-real-life" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;In any workplace, conflicts will arise.  However, in a workplace where you are one of 4 female developers on a team of 20, there will be lots of opportunities to say something about not okay situations, and the key is to not have it turn into a conflict.  Which, turns out, is really frickin hard. &lt;/p&gt;
&lt;p&gt;A few weeks ago, myself and the a few other female devs watched a webinar on resolving workplace conflict put on by &lt;a href=&quot;https://www.eventbrite.com/o/tech-ladies-11183594978&quot;&gt;Tech Ladies&lt;/a&gt;.  It was short and sweet but there were a few key takeaways that stayed with me.&lt;/p&gt;
&lt;h1&gt;Positions Vs Interests&lt;/h1&gt;
&lt;p&gt;Positions are someone’s solution to an issue.  Interests are someone’s concerns they want to resolve.  The key is to move everyone from positions to understanding all interests.  Its easier to find a good solution when you understand people’s objectives.&lt;/p&gt;
&lt;p&gt;“I&quot;-statements are also positions, eg: “When you offer everyone except me a donut, I feel left out&quot;.  (I found this interesting to learn because you hear so much about using them to not lay blame on others but its not an effective way of communicating during conflict).&lt;/p&gt;
&lt;h1&gt;Relationship Building&lt;/h1&gt;
&lt;p&gt;Often, its not about the solution, its about building relationships and getting on better terms. &lt;/p&gt;
&lt;p&gt;There are 3 types of mediation (two of which value relationships):&lt;br /&gt;
1. Evaluative: has a fast timeline and requires quick action.  Success criteria is the settlement itself.&lt;br /&gt;
2. Facilitative: opportunity to develop skills and resolve future conflict.  Success criteria is the settlement &lt;em&gt;and&lt;/em&gt; relationship building.&lt;br /&gt;
3. Transformative: the outcome is minor and the relationships are critical.  Success criteria is prevention and self management.&lt;/p&gt;
&lt;h1&gt;Separate People from the Problem&lt;/h1&gt;
&lt;p&gt;Dealing with problems is often aggravated by people misunderstanding each other or taking things personally.  Work on leaving negative emotions out by using clear communication, taking breaks to let people cool down, and discussing each others perceptions.&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Tech Specks Week #1 🐙</title>
    <id>https://erinbush.postach.io/post/tech-specks-week-1</id>
    <updated>2018-09-25T22:51:02.617000Z</updated>
    <published>2018-09-21T23:15:20Z</published>
    <link href="https://erinbush.postach.io/post/tech-specks-week-1" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="techspecks" />
    <content type="html">&lt;p&gt;A main element of my goals for the next year are to level up my technical knowledge both in terms of breadth and depth of particular topics.  I thought a fun, achievable step towards that goal is to read one technical article a day and write a quick summary of what I’ve learned from it.  So far I only had time for 4 articles this week, but I’m aiming for 5 a week.&lt;/p&gt;
&lt;p&gt;So here we are, the first in a series of weekly updates of short summaries of technical articles:&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://medium.freecodecamp.org/introducing-the-single-element-pattern-dfbd2c295c5d&quot;&gt;#1: Introducing the Single Element Pattern&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Reliability: not needing to open the file and look at the code to understand how it works. &lt;/p&gt;
&lt;p&gt;Rules for reliability: (really only works for primitive elements)&lt;br /&gt;
1. &lt;strong&gt;Render only one element&lt;/strong&gt;&lt;br /&gt;
2. &lt;strong&gt;Never break the app:&lt;/strong&gt;if missing proptypes, show as a warning instead of breaking rendering&lt;br /&gt;
3. &lt;strong&gt;Render all HTML attributes passed as props:&lt;/strong&gt; instead of passing an object that renders html props (such as &lt;code&gt;src&lt;/code&gt; and &lt;code&gt;alt&lt;/code&gt;), make these the prototypes for the react component and then just render the propose the primitive as {…props}&lt;br /&gt;
4. &lt;strong&gt;Always merge the styles passed as props:&lt;/strong&gt; use object spread to merge style and className props&lt;br /&gt;
5. &lt;strong&gt;Add all the event handlers passed as props:&lt;/strong&gt; always apply the event handler coming from the prop (your choice if it replaces the internal one or both are called)&lt;/p&gt;
&lt;p&gt;Suggestions: &lt;br /&gt;
1. Avoid adding custom props&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For example: if you have a rounded version of the same element, don’t add a prop that is &lt;code&gt;rounded&lt;/code&gt;, create a new element that is &lt;code&gt;ElementRounded&lt;/code&gt; that rounds the edges &lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Receive the underlying HTML element as a prop&lt;blockquote&gt;
&lt;p&gt;Make your element more flexible - rendering a button as an anchor tag&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;&lt;a href=&quot;https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf&quot;&gt;#2 How JS works: an overview of the engine, the runtime, and the call stack&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The JS engine: &lt;br /&gt;
- Google’s V8 engine is used in Chrome and Node.js &lt;br /&gt;
- Consists of two main components: the memory heap (where memory allocation happens) and the call stack (wirer your stack frames are as your code executes&lt;br /&gt;
Runtime: web APIs provide things like setTimeout (not provided by the engine) and is supplied by the browser (eg. DOM, AJAX and setTimeout)&lt;/p&gt;
&lt;p&gt;Call Stack: JS is single threaded so it has a single call stack (can only do one thing at a time)&lt;br /&gt;
- Call Stack is a data structure that recourses basically where in the program we are&lt;br /&gt;
- Stepping into a function puts at on the top of the stack and returning from a function we pop off the top of the stack&lt;br /&gt;
- Stack traces are the state of the call stack when the exception happened&lt;br /&gt;
- “blowing the stack&quot; - when the number of function calls in the stack exceeds the actual size of the call stack (recursively calling a function with no termination)&lt;/p&gt;
&lt;p&gt;Concurrency &amp;amp; the event loop:&lt;br /&gt;
What happens when you do a large resource intensive task that blocks the rest of the app from executing? browser may not be responsive for a long time + might prompt you to close the page&lt;br /&gt;
So how do we execute heavy code without blocking the UI? -&amp;gt; &lt;strong&gt;asynchronous callbacks&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;&lt;a href=&quot;https://getstream.io/blog/react-fragments/&quot;&gt;#3 React Fragments&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;JSX turns &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s and &lt;code&gt;&amp;lt;MyComponent&amp;gt;&lt;/code&gt; into &lt;code&gt;React.createElement(&lt;/code&gt;) calls so when there are multiple elements instead of a single one, it doesn’t know what tag name to render with.&lt;/p&gt;
&lt;p&gt;Solutions: &lt;br /&gt;
- wrap elements in a div &lt;br /&gt;
- use the render method to return an array of nodes (clunky + non-jsx-y)- the transpolar is putting together an array of &lt;code&gt;React.createElement()&lt;/code&gt; calls and affixing them to the parent element as children &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;render () {
    return [
       &amp;lt;p&amp;gt;hi&amp;lt;/p&amp;gt;
       &amp;lt;p&amp;gt;there!&amp;lt;/p&amp;gt;
     ]
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Best: React Fragment&lt;/strong&gt; - behaves like the array method&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  render () {
    return (
      &amp;lt;React.Fragment&amp;gt;
        &amp;lt;p&amp;gt;hi&amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;there!&amp;lt;/p&amp;gt;
      &amp;lt;/React.Fragment&amp;gt;
    )
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;OR: more concise syntax&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  render () {
    return (
      &amp;lt;&amp;gt;
        &amp;lt;p&amp;gt;hi&amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;there!&amp;lt;/p&amp;gt;
      &amp;lt;/&amp;gt;
    )
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;h1&gt;&lt;a href=&quot;https://css-tricks.com/understanding-react-setstate/&quot;&gt;#4 Understanding React’s &lt;em&gt;setState()&lt;/em&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;setState() is the only legitimate way to update state after the initial state setup (don’t update state directly because the component won’t re-render)  - component is re-rendered with that state -&amp;gt; this process is called ‘reconciliation’ (how React updates the DOM)&lt;br /&gt;
&lt;em&gt; React creates a new tree containing the reactive elements in the component and the updated state&lt;br /&gt;
&lt;/em&gt; This tree is used to figure out how the component’s UI should change (compares the updated tree with the previous tree)&lt;br /&gt;
* React only updates the part of the component that have changed (makes it fast fast) &lt;/p&gt;
&lt;p&gt;Can’t call setState multiple times in a row (eg. trying to increment a value 3 times in a row)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;handleIncrement = () =&amp;gt; {
    this.setState({ count: this.state.count + 1})
    this.setState({ count: this.state.count + 1})
    this.setState({ count: this.state.count + 1})
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is equivalent to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Object.assign(
    {},
    { count: this.state.count + 1 },
    { count: this.state.count + 1 },
    { count: this.state.count + 1 },
)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Object.assign is used to copy data from a source to a target object but if the data (being copied from the source to the target) all have the same keys, the last object wins.&lt;/p&gt;
&lt;p&gt;What &lt;em&gt;will&lt;/em&gt; work is using a function within setState() - React will queue the functions in the order they are made and update the entire state once it is done:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;handleIncrement = () =&amp;gt; {
    this.setState((prevState) =&amp;gt; ({ count: this.state.count + 1}))
    this.setState((prevState) =&amp;gt; ({ count: this.state.count + 1}))
    this.setState((prevState) =&amp;gt; ({ count: this.state.count + 1}))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Accessing previous state:&lt;br /&gt;
- can’t always trust this.state right after setState() has been called - should be treated asynchronously&lt;br /&gt;
- Need to use an updater - like what is in the previous example (using a function that has prevState as an argument)&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">#GOALS  👩‍💻</title>
    <id>https://erinbush.postach.io/post/goals</id>
    <updated>2018-09-25T22:36:37.925000Z</updated>
    <published>2018-09-17T20:04:21Z</published>
    <link href="https://erinbush.postach.io/post/goals" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;Now that it is solidly fall in Vancouver I thought I would mimic all the trees around here and shed some leaves in preparation for new things.  First up, change of season haircut, but after that, there are a bunch of things professionally that I want to change.  The main theme being immersing myself in the tech community and deepening my technical knowledge.  So here we are, my professional goals for the next year:&lt;/p&gt;
&lt;h1&gt;Build Technical Confidence&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Write (or participate in writing) a tech spec for each mid sized project I work on (larger than 1 week)&lt;/li&gt;
&lt;li&gt;Find 3 areas of the product (product == Thinkific) to improve and investigate possible solutions&lt;/li&gt;
&lt;li&gt;Present a lunch and learn on a technical topic&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Get More Involved in Tech Community&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Attend 1 meet up every 2 months &lt;/li&gt;
&lt;li&gt;Commit to participating in mentorship outside of Thinkific (either as a mentor or mentee)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Increase Technical Expertise&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Read 1 technical article a day and write a short summary paragraph on it&lt;/li&gt;
&lt;li&gt;Complete 1 short course every month (less than 5 hours)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thats it! Time to get reading…&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Becoming Enough 👏</title>
    <id>https://erinbush.postach.io/post/becoming-enough</id>
    <updated>2018-09-25T22:36:37.921000Z</updated>
    <published>2018-09-14T17:27:42Z</published>
    <link href="https://erinbush.postach.io/post/becoming-enough" />
    <author>
      <name>Erin Bush</name>
    </author>
    <content type="html">&lt;p&gt;Last night I went to a meet up on Imposter Syndrome that opened with a panel discussion.  I’ve been to other panels before and while they have always been informative, I found myself walking away from last night internalizing so many eye opening pieces of advice.  There is so much to apply to my life, not just in the workplace.  I scrambled to scribble down the major takeaways from the event as there was so much.  Here is what I found were the most valuable: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Imposter syndrome has a bodily aspect to it (make yourself smaller)&lt;/li&gt;
&lt;li&gt;Imposter syndrome is failing to internalizing your own achievements&lt;/li&gt;
&lt;li&gt;Society loves the wonderkid and you don’t see successes that incorporate a lot of failure (impossible to achieve overnight success)&lt;/li&gt;
&lt;li&gt;Behind the feeling of imposter syndrome is how we learned the idea of failure and our relationship with the learning process&lt;/li&gt;
&lt;li&gt;Don’t avoid writing code because you are scared to ask for help&lt;/li&gt;
&lt;li&gt;Everyone brings something to the table even if they don’t have traditional education&lt;/li&gt;
&lt;li&gt;Maybe Imposter Syndrome just one side of the human spectrum &lt;/li&gt;
&lt;li&gt;Imposter Syndrome is an internal/external thing - your reaction and other people’s reaction &lt;/li&gt;
&lt;li&gt;If you are looking for clues that you aren’t good enough, the world will definitely provide - change your focus to proof that you ARE doing a good job&lt;/li&gt;
&lt;li&gt;We get asked insurmountable things that feel impossible when we are starting out but everyone has that feeling&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;✨Advice✨&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Put your feelings and emotions on hold and put the projects and groups objectives before your own of inadequacy&lt;/li&gt;
&lt;li&gt;Remember that you are here for a reason and things didn’t just fall into your lap &lt;/li&gt;
&lt;li&gt;If you don’t know how you are doing - ask for feedback because it will be way more constructive than worrying &lt;/li&gt;
&lt;li&gt;Compare yourself today to where you were yesterday&lt;/li&gt;
&lt;li&gt;Coach people on what their value is - you can grow into positions &lt;/li&gt;
&lt;/ul&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
  <entry xml:base="http://erinbush.postach.io/feed.xml">
    <title type="text">Light Dusting 🚀</title>
    <id>https://erinbush.postach.io/post/light-dusting</id>
    <updated>2018-09-25T22:36:39.213000Z</updated>
    <published>2018-04-03T16:54:32Z</published>
    <link href="https://erinbush.postach.io/post/light-dusting" />
    <author>
      <name>Erin Bush</name>
    </author>
    <category term="march" />
    <category term="update" />
    <category term="springcleaning" />
    <content type="html">&lt;h1&gt;This month&lt;/h1&gt;
&lt;p&gt;Spring cleaning is in full force and I’ve had an interesting mix of trying to get some heads down time at work and getting inspired to dig into issues that resonate with me.  I gave a talk about how cool CSS is at the first ever &lt;a href=&quot;https://www.facebook.com/djangogirlsvancouver/&quot;&gt;Vancouver Django Girls&lt;/a&gt; event and tried to convince some women that software development is fun ✨ I celebrated &lt;a href=&quot;https://www.instagram.com/p/BgE4QWYF7OB/&quot;&gt;International Women’s Day&lt;/a&gt; at the most inclusive work environment I have ever been a part of (shoutout to Thinkific).  I also decided to recommit myself to blogging about my experiences as a web developer in 2018 and at the very least do a monthly newsletter style update.&lt;/p&gt;
&lt;h1&gt;I'm reading&lt;/h1&gt;
&lt;p&gt;A reflection on the &lt;a href=&quot;https://medium.com/comparethemarket/a-journey-from-junior-developer-to-technical-lead-b1af4d2419fb&quot;&gt;stages of being a software developer&lt;/a&gt;. A &lt;a href=&quot;https://github.com/kamranahmedse/developer-roadmap/blob/master/readme.md&quot;&gt;flow chart&lt;/a&gt; on how to further your dev skills. How to &lt;a href=&quot;https://gist.github.com/bastman/5b57ddb3c11942094f8d0a97d461b430&quot;&gt;cleanup&lt;/a&gt; my docker images.  What doors are opened by using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_HTML_sections_and_outlines&quot;&gt;HTML5 semantic elements&lt;/a&gt;.  Why we shouldn’t test &lt;a href=&quot;http://anthonysciamanna.com/2016/02/14/should-private-methods-be-tested.html&quot;&gt;private ruby methods&lt;/a&gt; and in contrast, if you have no choice but to test the private method, &lt;a href=&quot;https://mixandgo.com/blog/3-ways-of-testing-private-methods-in-rails&quot;&gt;how do you do it?&lt;/a&gt;  Google’s new &lt;a href=&quot;https://google.github.io/styleguide/jsguide.html&quot;&gt;javascript style guide&lt;/a&gt;.  Some interesting results from &lt;a href=&quot;https://insights.stackoverflow.com/survey/2018/?utm_source=Iterable&amp;amp;utm_medium=email&amp;amp;utm_campaign=dev-survey-2018-promotion&quot;&gt;Stack Overflow’s survey&lt;/a&gt; - particularly the gender-based results. A lack of interest in community building by the &lt;a href=&quot;https://medium.com/@pfthurley/tech-bro-culture-in-the-waterloo-region-hits-peak-arrogance-in-michael-litt-c5c8924992ad&quot;&gt;growing tech bro culture&lt;/a&gt; in my hometown. &lt;a href=&quot;http://gutsmagazine.ca/growing-season/&quot;&gt;Tending to yourself&lt;/a&gt; as gently as you would plants.  In celebration of March being Women’s History Month, a reminder for young women everywhere to &lt;a href=&quot;https://www.theglobeandmail.com/opinion/article-advice-for-young-women-be-large/&quot;&gt;be large&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;📚 Book Alert 📖 But her emails! A heartbreaking account of blatant misogyny and how messed up journalism in the 2016 election was: &lt;a href=&quot;https://www.goodreads.com/book/show/34114362-what-happened&quot;&gt;What Happened&lt;/a&gt; by Hillary Clinton.&lt;/p&gt;
&lt;h1&gt;I’m interested in&lt;/h1&gt;
&lt;p&gt;Becoming/being a mentor at &lt;a href=&quot;https://www.glassceilingdemolition.com/&quot;&gt;The Glass Ceiling Demolition Co&lt;/a&gt;.  Based in Vancouver with the goal to connect young women with experienced mentors in any field. &lt;/p&gt;
&lt;h1&gt;I’m listening&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.thisamericanlife.org/640/five-women&quot;&gt;#metoo&lt;/a&gt;: 5 women discuss sexual harassment from the same man. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’d like to credit this blog format to &lt;a href=&quot;http://www.annfriedman.com/&quot;&gt;Ann Friedman&lt;/a&gt;, who’s newsletters lovingly find their way into my inbox each week.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;🌟&lt;/p&gt;
&lt;script&gt;
var link = document.querySelector(&quot;link[rel*='icon']&quot;) || document.createElement('link');
link.rel = 'shortcut icon';
link.href = `
https://cdn-static.postach.io/391aae499baf0a5123bfb00d20249ad6
`;
document.getElementsByTagName('head')[0].appendChild(link);
&lt;/script&gt;</content>
  </entry>
</feed>
