<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>AntJanus</title>
	<atom:link href="https://antjanus.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://antjanus.com</link>
	<description>AntJanus</description>
	<lastBuildDate>Sun, 22 Mar 2020 13:45:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.6</generator>
<site xmlns="com-wordpress:feed-additions:1">27408600</site>	<item>
		<title>How My VIM Setup and Open Source Code Ended Up In an AAA Video Game</title>
		<link>https://antjanus.com/blog/thoughts-and-opinions/how-my-vim-setup-and-open-source-code-ended-up-in-an-aaa-video-game/</link>
					<comments>https://antjanus.com/blog/thoughts-and-opinions/how-my-vim-setup-and-open-source-code-ended-up-in-an-aaa-video-game/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Sun, 22 Mar 2020 13:45:30 +0000</pubDate>
				<category><![CDATA[Thoughts and Opinions]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4313</guid>

					<description><![CDATA[<p>This post was originally posted on my dev.to blog account. I&#8217;m going to take you on a wild story that I tell everyone because I find it so exciting. It&#8217;s been taking up the top spot as a pinned tweet on my Twitter and I just want to get my personal obnoxious story-sharing out of [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/thoughts-and-opinions/how-my-vim-setup-and-open-source-code-ended-up-in-an-aaa-video-game/">How My VIM Setup and Open Source Code Ended Up In an AAA Video Game</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<blockquote class="wp-block-quote"><p>This post was <a href="https://dev.to/antjanus/how-my-vim-setup-and-open-source-code-ended-up-in-an-aaa-video-game-1if2">originally posted</a> on my dev.to blog account. </p></blockquote>



<p>I&#8217;m going to take you on a wild story that I tell <em>everyone</em> because I find it so exciting. It&#8217;s been taking up the top spot as a pinned tweet on my Twitter and I just want to get my personal obnoxious story-sharing out of the way with this article so I can stop annoying people with it <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<h2>The image</h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/06/dedsec-vim-setup.jpg" alt="code screenshot"/></figure>



<p>A few years back, I set it as my new banner image on LinkedIn when they introduced that feature on profiles. I thought it was kind of neat. I did not share that image anywhere else.</p>



<p>So what&#8217;s in it?</p>



<p>It&#8217;s my custom VIM setup that I used back then. In VIM, you can see that I have a project opened called <a href="https://github.com/AntJanus/popstar-cms">popstar-cms</a> and a file called <code>reader.js</code>. I mention this so that you know that the code written there is specifically my code.</p>



<p>Also note, I&#8217;m importing <a href="https://lodash.com">lodash</a> at the top and that this project at this point in time has no license file.</p>



<h2>The Ubisoft employee visit</h2>



<p>At some point in time, I checked who viewed my profile on LinkedIn. Among a bunch of recruiters, unknown names, and whoever else, there was a single Ubisoft employee but I&#8217;d have to pay LinkedIn for a premium membership to reveal who that person is.</p>



<p>I didn&#8217;t think much about it. All kinds of people view my profile. Maybe it was one of their web developers. Who knows.</p>



<h2>The Tweets</h2>



<p>Sometime later, I saw a tweet by John-David Dalton (creator of lodash). Around this time, it was quite a meme that Lodash was in <em>everything</em>. Everyone was using it and that was the joke so it didn&#8217;t come as a surprise that lodash would show up in a random video game called Watch Dogs 2:</p>



<p>{% twitter 800569316575997952 %}</p>



<p>I remember idly liking the tweet without inspecting it. I was using lodash as well and the joke held true. I thought it was funny.</p>



<p>And then Dalton took the time to figure out that it&#8217;s my project and tweeted @ me:</p>



<p>{% twitter 800609800048574464 %}</p>



<p>I was really surprised to see a tweet from him and I was beyond ecstatic to find out that my code ended up in an AAA game! I&#8217;ve heard of Watch Dogs and its sequel, I&#8217;ve never played it but I thought it was really really awesome. And of course, I told everyone about it.</p>



<p>Let&#8217;s not forget to <a href="https://twitter.com/PorlyP/status/800472188637900800">credit Paul</a> who took the original screenshot.</p>



<p>(note: the project that Dalton tweeted at me was the wrong one, the banner app was a fork off the previously mentioned popstar cms)</p>



<h2>The DedSec Screenshot</h2>



<p>The screenshot is of a monitor at the hideout of a hacker collective called DedSec in a game called Watch Dogs 2 which was created by Ubisoft Canada &#8212; and noooooow the random Ubisoft employee visit makes sense!</p>



<p>So before I leave this story alone (I mean, the big reveal already happened), I wanted to compare the two screenshots:</p>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/06/watchdogs2-dedsec.jpg" alt="watch dogs 2 screenshot of a monitor"/></figure>



<p>Ubisoft altered my original in a few ways:</p>



<ol><li>they removed my name and project name (which I&#8217;m truly bummed about)</li><li>the file tree just features a few copy/pastes of the <code>reader.js</code> and <code>parser.js</code> file listings</li><li>it looks like they selected only specific parts of each file buffer</li><li>under the file tree, we actually see a section of the <code>findFile</code> function</li><li>there are some random visualizations under the 2 buffers</li></ol>



<h2>Uhm, let&#8217;s talk about Reddit</h2>



<p>I was really excited about all of this at the time so I decided to share the story on Reddit and WOW. I did not expect people to be so crappy. Long story short, most people thought that the code in the DedSec screenshot had nothing to do with my screenshot which is just weird to me. I mean, they even copied my JSDoc code comment. Anyways…</p>



<p>A lesson for everyone: just don&#8217;t go on Reddit. If you want to be part of a good tech community, stay here on dev.to or go to Twitter (if you dare).</p>



<h2>Why mention the license?</h2>



<p>Ok, so people on Reddit did have one good point. Ubisoft used my copyrighted screenshot without permission and they published portions of my code which was free to view on Github, but wasn&#8217;t free to be used/copied/etc. in any way. I&#8217;m sure that this qualifies under fair use; however, I&#8217;m not a lawyer <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f937-200d-2640-fe0f.png" alt="🤷‍♀️" class="wp-smiley" style="height: 1em; max-height: 1em;" />. </p>



<p>I&#8217;m not mad about it, and geez, I won&#8217;t make a stink about it, but it <em>is</em> interesting to me and makes me wonder how many other assets companies use without letting the creator know, without crediting them, and literally erasing their name from the assets so they could use them.</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/thoughts-and-opinions/how-my-vim-setup-and-open-source-code-ended-up-in-an-aaa-video-game/">How My VIM Setup and Open Source Code Ended Up In an AAA Video Game</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/thoughts-and-opinions/how-my-vim-setup-and-open-source-code-ended-up-in-an-aaa-video-game/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4313</post-id>	</item>
		<item>
		<title>2019 Personal Retrospective On My Development Journey</title>
		<link>https://antjanus.com/blog/thoughts-and-opinions/yearly-review/2019-personal-retrospective-on-my-development-journey/</link>
					<comments>https://antjanus.com/blog/thoughts-and-opinions/yearly-review/2019-personal-retrospective-on-my-development-journey/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Fri, 13 Dec 2019 15:55:55 +0000</pubDate>
				<category><![CDATA[yearly review]]></category>
		<category><![CDATA[new year]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4286</guid>

					<description><![CDATA[<p>I always thought that as a developer, programming would either get less exciting with time but I prove myself wrong time and time again. In fact, I have been enjoying feeling like a beginner where putting time and effort into new technologies feels exciting and rewaring. So let me tell you about my year and [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/thoughts-and-opinions/yearly-review/2019-personal-retrospective-on-my-development-journey/">2019 Personal Retrospective On My Development Journey</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<hr class="wp-block-separator"/>



<p>I always thought that as a developer, programming would either get less exciting with time but I prove myself wrong time and time again. In fact, I have been enjoying feeling like a beginner where putting time and effort into new technologies feels exciting and rewaring. So let me tell you about my year and how things went. </p>



<p>I should probably mention that this is more for me and to reflect back on my own accomplishments rather than a guide or an article for others to follow.</p>



<h2>My 2019 Goals</h2>



<p>My goals for 2019 were actually rather simple: focus on writing an app and become an instructor. Did I accomplish either of these? Nope, not really.</p>



<p>But I did get pretty far with both, at least in my opinion.</p>



<h3>Building a side app</h3>



<p>I wanted to finish building an app I&#8217;ve been working on for quite a while called Skok. Skok is a photo management app. Here&#8217;s the kicker: it works. Here&#8217;s what you can do with it right now:</p>



<ol><li>scan a directory for photos and populate a database with them</li><li>look through a gallery of those photos</li><li>see the &#8220;photo of the day&#8221;</li><li>identify duplicate photos</li></ol>



<p>So what&#8217;s the problem? Polish and keeping it up to date. I just don&#8217;t have the drive to do it. Over my July goal of doing a <a href="https://dev.to/antjanus/30daysofcommits-retrospective-46pn">30 days of commits</a>, I refactored all of the ugly code, wrote a solid test coverage for the app but…then I got tired of it and went to do other things.</p>



<p>Life is very full right now (in good ways and not-so-good ways) and thus I dropped it when I got almost there.</p>



<p>By the way, if you want to see a quick walkthrough of that application, I have a <a href="https://www.youtube.com/watch?v=hh2GRmpy9kE">video about Skok</a> that I made early on in the year &#8212; before the big refactor that I did in the 30 days of commits.</p>



<h3>Becoming A Dev Instructor</h3>



<p>Did I become a full-time instructor anywhere? No. Did I become a part-time instructor? Also no. Wait but did I release videos on my YouTube channel with a course? Also no.</p>



<p>But I did keep <a href="https://www.youtube.com/user/WAJANUS/videos?view_as=subscriber">my YouTube channel</a> pretty busy. And I&#8217;ve been <a href="https://dev.to/antjanus">blogging</a> quite a bit, too. So I&#8217;ve been happy with where things went.</p>



<p>I made a lot of videos this year, more than any other (I think?) and they resulted in an amazing number of views. I&#8217;m up to 730 subscribers right now and I&#8217;m happy as heck with that.</p>



<h2>10 teeny-tiny developer resolutions.</h2>



<p>At the beginning of this year, I posted a fun article called <a href="https://dev.to/antjanus/10ish-teeny-tiny-resolutions-to-become-a-better-developer-in-2019-54f5">10ish Teeny-Tiny Resolutions to Become A Better Developer in 2019</a> so let me update on that real quick, too!</p>



<h3>1. Accessibility Course</h3>



<p>I took it! And I became a proponent of accessibility at work and have been helping build things out with accessibility in mind. From color contrast, to using aria labels, and more. It&#8217;s been tough and there still isn&#8217;t much to show for it but being aware of the issues and solutions has made it easier to bring it up at meetings and to push for it in code.</p>



<h3>2. Catch up with an ex-colleague</h3>



<p>Definitely did that. I reconnected with an old co-worker and we definitely chat quite a bit more than we did last year.</p>



<h3>3. Clean your keyboard</h3>



<p>I took out all of the keycaps from my keyboard, I cleaned everything out, and put it together. It was heinous.</p>



<h3>4. Watch someone use an OS you&#8217;re unfamiliar with</h3>



<p>I <em>kind</em> of did that. I&#8217;m using Linux + Windows full time right now but I rarely venture into the realm of MacOS. I <em>do</em> rotate browsers and I recently switched from Android to iOS to see where iOS has progressed to in the past few years</p>



<h3>5.Watch an online talk on a technology you have been interested in</h3>



<p>I watched a ton of GatsbyJS stuff</p>



<h3>6. Learn about RSI</h3>



<p>DONE <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3>7. Learn 1 new power-user feature of your code editor</h3>



<p>I switched entirely back to VIM. <em>But</em> I learned a new power feature in <code>tmux</code> which I also switched back to. I use the <code>ctrl+b d</code> to detach from a session. I use this so that I can save what I was working on for work, close out the terminal, and call it back up the next day.</p>



<h3>8. Learn Flexbox or CSS Grid</h3>



<p>Done! While I still need to look up the properties, I&#8217;ve got a pretty good grip on how things work and how to make a quick layout from scratch.</p>



<h3>9. Publish a package</h3>



<p>I published the <a href="https://www.npmjs.com/package/electron-transponder">electron-transponder</a> from all the work I did with Electron. I renamed it to <code>electron-communicator</code> but kept the package name anyways.</p>



<h3>10. Enjoy the new year</h3>



<p>I had a pretty decent year. <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f937.png" alt="🤷" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2>What did I <em>actually</em> do and learn in 2019?</h2>



<h3>React 100% forward</h3>



<p>At my job, we ended up rewriting major portions of our application in React. It&#8217;s been fun and helped me get used to the React paradigm. It turns out, following Reacty people and subscribing to React-related newsletters has its pay offs because jumping into it, I had no issue running around and doing what I needed to do. &#8212; even using Hooks once I sold everyone else on the team on them.</p>



<p>What I did find, unfortunately, is that React libraries are still not of the same caliber as Angular&#8217;s built-in features and libraries. Angular kind of found all of the weird and obscure edge-cases and built tooling around it. While React library owners still tend to rule with an iron fist and yell &#8220;You&#8217;re doing it wrong&#8221; or &#8220;Build it yourself&#8221;.</p>



<p>Two very good pieces of feedback that we&#8217;ve used as fuel to rip out 3rd-party libraries and handroll our own solutions.</p>



<h3>GatsbyJS All The Way</h3>



<p>It took me quite a while to get into Gatsby. It just did <em>not</em> make sense to me at first. When things finally clicked for me, I built two separate Gatsby blogs, then I <a href="https://github.com/csellis/gatsby-plugin-podcast-feed/pull/1">submitted a PR to a Gatsby plugin</a>, and had a lot of fun with it.</p>



<p>Despite the initial hard learning curve, when things got to work, it was very fun to add new functionality, make changes to my blog design, and to actually write. If you want to, check out my <a href="https://thoughtessays.antjanus.com/2019-10-24-grave-of-the-fireflies/">Thoughts on the Grave of the Fireflies movie</a> which forced me to add image support.</p>



<p>It also prompted me to write my <a href="https://nanowrimo.org">NaNoWriMo</a> in a format that would work with Gatsby so I could potentially write (or use, if it exists) a plugin to transform Gatsby content into an ebook. The very <em>wild</em> thing is that this is possible! I have…so much to say about Gatsby but that&#8217;ll be for another day.</p>



<h3>Writing</h3>



<p>One thing that surprised me this year is that without any goal to do so, I managed to write quite a few blog posts this year.I wrote around 18 posts (some questions) &#8212; which is a little out of my usual scope. And that&#8217;s just on <a href="https://dev.to/antjanus">my dev.to profile page</a>. </p>



<p>To add onto it, I wrote <a href="https://thoughtessays.antjanus.com/">2 shorts stories and 2 articles on my writing blog</a>. I edited good 15-20K words of a book I wrote a few years back. And I&#8217;m finishing up a 50K word NaNoWriMo in November (probably finished when you read this).</p>



<p>My total views on dev.to alone was around 60K views…which is pretty awesome <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3>Skok &amp; 30 Days of Commits</h3>



<p>In 2018, I did an event called the Shippening along with a few other developers. We decided to spend the time between Christmas and New Year&#8217;s to try to build a shippable product. Most people failed it…well, because 3 days isn&#8217;t a lot of time.</p>



<p>Anyways, I decided to use the Discord we started to do another events: 30 Days of Commits. The idea was to commit once a day on a project that you wanted to work on. I think it worked quite well!</p>



<p>I worked on my project Skok, published a node package out of it, and wrote tests to cover most of the features in the app. I was pretty happy with the outcome &#8212; though I completely abandoned the project! Again! </p>



<h3>Back To Linux…</h3>



<p>At the beginning of the year, I shifted all of my development to Linux. And now, at the end of it, I shifted all of my computer interactions to Linux and my Windows machine runs as a media server of sorts.</p>



<p>It&#8217;s pretty amazing. I got a new laptop, the Thinkpad T480, and I set up Ubuntu on it from scratch &#8212; which is actually weird for me because I&#8217;ve been predominantly an Arch user for the past several years.</p>



<p>As soon as I installed it, I switched to using i3. Then I got into ZSH (which I&#8217;ve been hesitant to use), I started to use VIM again and abandoned VS Code, then I got into Tmux…and I spiraled further and further into the Linux ecosystem.</p>



<h2>New Goals?</h2>



<p>Every year, I get less and less enthusiastic about goals, mostly because those goals only apply to the first month or two of the year and after that life goes off rails. Not necessarily in a bad way, life and goals simply change. </p>



<p>I still try to set some because when I lose my focus, it&#8217;s easier to go back to a list of <em>goals</em> rather than start from scratch. </p>



<p>Ok, here are a few ideas for (tech) goals:</p>



<ol><li>build a custom keyboard from scratch</li><li>try to build something in Rust</li><li>Webflow!</li></ol>



<h3>Custom Keyboard From Scratch</h3>



<p>This has been a low-key goal of mine ever since I got into mechanical keyboards. I&#8217;ll be getting my first one sometime soon. I was really intimidated by putting my own together until I got test switched in the mail and hooked up to my Arduino with a few spare wires.</p>



<p>I figure that adding switches to a PCB, soldering them in, and then putting the PCB in a case will be a nice weekend project.</p>



<h3>Rust</h3>



<p>Rust has been on my radar for a bit. I&#8217;ve been a fan of some of the newer languages and have tried them out and even built apps on top of them. I currently use Elixir at work and I still have production Golang running somewhere.</p>



<p>Rust has been the natural next step in my language-learning. I succeeded at doing some Rust exercises (can we please stop using the word <code>koan</code>? It&#8217;s been appropriated from a <a href="https://en.wikipedia.org/wiki/K%C5%8Dan">zen practice by the same name</a>). </p>



<p>Anyways, still a long way to go for me</p>



<h3>Webflow</h3>



<p>I honestly think this is where future is and unlike a lot of tools back in the day that tried to provide the no-code experience (Dreamweaver for instance), it lacked the <em>data</em> component. Webflow takes web design, web development, and data modeling and smashes it together to create a robust no-code web editor.</p>



<p>I&#8217;m psyched because I was super into Dreamweaver and Fireworks and Webflow is miles ahead of those. I was also a heavy Photoshop/Illustrator user and guess what? Webflow feels a lot like that, too. Finally, I did a bunch of work in Unity, Cinema 4D, and Blender…and again, Webflow captures the feel of those as well.</p>



<p>I stopped using all of the software above a while back because &#8220;code was the way&#8221; for so long that my specialization had no reason to broaden to use that software. Webflow changes that paradigm on its head <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2>My top 2019 Articles</h2>



<ul><li><a href="https://dev.to/antjanus/my-top-10-programming-proverbs-2a4d">My Top 10 Programming Proverbs</a></li><li><a href="https://dev.to/antjanus/switching-from-angular2-template-loader-to-ngtools-webpack-117g">Switching from angular2-template-loader to @ngtools/webpack </a> &#8211; this is more fun to read as my journey through Webpack/Angular hell <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </li><li><a href="https://dev.to/antjanus/the-definitive-react-hooks-cheatsheet-2ebn">The Definitive React Hooks Cheatsheet</a></li><li><a href="https://dev.to/antjanus/prototypes-dont-get-thrown-out----write-tracer-bullet-code-instead-2ncn">Prototypes Don&#8217;t Get Thrown Out &#8212; Write Tracer (Bullet) Code Instead</a></li><li><a href="https://dev.to/antjanus/my-personal-git-tricks-cheatsheet-23j1">My Personal Git Tricks Cheatsheet</a></li><li><a href="https://dev.to/antjanus/how-my-vim-setup-and-open-source-code-ended-up-in-an-aaa-video-game-1if2">How My VIM Setup and Open Source Code Ended Up In an AAA Video Game </a></li><li><a href="https://dev.to/antjanus/my-favorite-linux-tools-12be">My Favorite Linux Tools</a></li></ul>



<p>Links:</p>



<ul><li><a href="https://antjanus.com/blog/thoughts-and-opinions/yearly-review/how-did-2018-go-and-what-now/">2018 retrospective and goals</a></li><li><a href="https://dev.to/antjanus/yearly-retrospectives-looking-backward-and-forward-at-the-same-time-3pi1">my article on yearly retrospectives</a></li><li><a href="https://discord.gg/2NHFW5p">DevsWhoDev Discord</a></li></ul>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/thoughts-and-opinions/yearly-review/2019-personal-retrospective-on-my-development-journey/">2019 Personal Retrospective On My Development Journey</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/thoughts-and-opinions/yearly-review/2019-personal-retrospective-on-my-development-journey/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4286</post-id>	</item>
		<item>
		<title>My Favorite Linux Tools</title>
		<link>https://antjanus.com/blog/web-development-tutorials/my-favorite-linux-tools/</link>
					<comments>https://antjanus.com/blog/web-development-tutorials/my-favorite-linux-tools/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Mon, 05 Aug 2019 18:10:17 +0000</pubDate>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[productivity]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4280</guid>

					<description><![CDATA[<p>This post was originally posted on my dev.to account. It was migrated here for archival purposes. Checkout the original post for all kinds of awesome Linux discussions. I wanted to list a few utilities that either help my productivity on Linux or make working in Linux more pleasant in some way. I really enjoy setting [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/my-favorite-linux-tools/">My Favorite Linux Tools</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<blockquote class="wp-block-quote"><p>This post was <a href="https://dev.to/antjanus/my-favorite-linux-tools-12be">originally posted on my dev.to account</a>. It was migrated here for archival purposes. Checkout the original post for all kinds of awesome Linux discussions.</p></blockquote>



<p>I wanted to list a few utilities that either help my productivity on Linux or make working in Linux more pleasant in some way. </p>



<p>I really enjoy setting up tools so that they&#8217;re easier to use <em>when</em> I use them &#8212; so instead of just saying &#8220;this tool is great&#8221;, it&#8217;s also worth noting how some tools can be very powerful once you spend the time to set them up, even if you don&#8217;t use them often.</p>



<p>You might notice that most of these are terminal based utilities. I primarily interact with Linux via the terminal and almost everything that&#8217;s not terminal based is just the usual cross-platform applications (Discord, Opera, Slack, VSCode, etc.) so I&#8217;m not mentioning any of those.</p>



<blockquote class="wp-block-quote"><p>I <a href="https://dev.to/antjanus/what-are-your-favorite-linux-utility-productivity-tools-57al">asked the community</a> for everyone&#8217;s recommendations.</p></blockquote>



<h2><a href="https://neovim.io">NeoVIM</a></h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/06/nvim-screen.png" alt="neovim text editor screenshot"/></figure>



<p>From git messages to quick file changes (or full development), it&#8217;s totally worth setting up NeoVIM with at least syntax highlighting. I often reach for VIM when I don&#8217;t want to bother opening VSCode or when VSCode is just too much for a quick edit.</p>



<p>Why NeoVIM and not VIM? NeoVIM retains full backward compatibility with VIM and exposes some new features. Either one works! <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2><a href="https://www.zsh.org">ZSH</a></h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/06/zsh.png" alt="zsh shell screenshot"/></figure>



<p>I&#8217;ve had my bash config setup just the way I liked it but recently switched to ZSH. Why?</p>



<ol><li>it&#8217;s quick and easy to setup</li><li>you don&#8217;t have to be a power user to take advantage of it</li><li>zsh command highlighting makes things easier to read</li><li>theme support is much better than bash/terminal theme support</li><li>lots of plugins</li></ol>



<p>Make sure to check out <a href="https://github.com/robbyrussell/oh-my-zsh">oh-my-zsh</a> which gives you the theme support and plugin support.</p>



<h2><a href="https://developer.gnome.org/NetworkManager/stable/nmtui.html">nmtui</a></h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/06/nmtui.png" alt="nmtui network manager screenshot"/></figure>



<p>A TUI (terminal UI) for network management. I reach for it more so than any other built-in utilities because of how simple and straightforward it is. For some reason, I also trust it more. When a GUI network manager freezes, I&#8217;m always paranoid that the GUI froze &#8212; not that the network manager is doing its job. With NMTUI, there&#8217;s more trust on my part for sure.</p>



<p>I know, I know, it looks like it&#8217;s from the 80s BUT, it allows you to manage all of your saved wifi settings, your ethernet connections, and so much more. It is fully-featured and lacking nothing as far as I can tell.</p>



<h2><a href="https://dev.yorhel.nl/ncdu">ncdu</a></h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/06/ncdu.png" alt="ncdu disk usage utility screenshot"/></figure>



<p>NCDU is a terminal UI (an <code>ncurses</code> UI to be more specific) for the <code>du</code> command. What does <code>du</code> do? du is a <code>disk usage</code> utility. What&#8217;s cool about <code>ncdu</code> is that it scans everything in a folder or on your system and allows you to explore your file system with all of the computed size values. </p>



<p>This is <em>so</em> useful when you&#8217;re trying to figure out what&#8217;s taking up so much space on your drive, or when you&#8217;re trying to delete the space hogs.</p>



<h2><a href="https://hisham.hm/htop/">htop</a></h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/06/htop.png" alt="htop process viewer screenshot"/></figure>



<p>Another terminal utility. This one is an interactive process viewer. Think of it as your Activity Manager or Task Manager. It can filter, search, and sort through processes. It displays all of the relevant process information included full command path which started the process. This is so useful when trying to find runaway node processes.</p>



<p>You can then send commands to the processes but the only one I really use is the <code>kill</code> command to close stuck processes.</p>



<h2><a href="http://manpages.ubuntu.com/manpages/xenial/man1/notify-send.1.html">notify-send</a></h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/06/lmk.png" alt="notify-send terminal and notification example screenshot"/></figure>



<p><code>notify-send</code> is a utility that allows you to send notifications to yourself. This is super useful &#8212; so much so that I aliased it in my <code>.bashrc</code>:</p>



<pre class="wp-block-code"><code>alias lmk="notify-send 'Something happened!'"</code></pre>



<p>Might seem useless but if you&#8217;re running a long-running process, it&#8217;s great to have a notification system that lets you know when it&#8217;s done. So I tend to use <code>notify-send</code> in conjunction with other commands, like <code>npm install &amp;&amp; lmk</code>. </p>



<h2><a href="https://github.com/davatorium/rofi">Rofi</a></h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/06/rofi-1.png" alt="rofi application launcher screenshot"/></figure>



<p>Unlike others, this one isn&#8217;t a terminal application. This is an application launcher/window switcher/so much more. If you&#8217;re using something like i3, it is a perfect replacement for dmenu. If you&#8217;re using something else, it&#8217;s still a power tool.</p>



<p>What makes it special is that it handles command line utilities and GUI apps at the same time AND it&#8217;ll switch you over to a running instance of an app as well. On top of that, it&#8217;s insanely fast.</p>



<h2>Other notable tools</h2>



<p>I don&#8217;t want to go off to the deep end with every single tool I use so here are a few I&#8217;d check out:</p>



<ol><li><a href="https://github.com/sharkdp/bat">bat</a> &#8211; an alternative to <code>cat</code> with syntax highlighting and better display of file contents. Install and alias it to <code>cat</code></li><li><a href="https://notepadqq.com/s/">notepadqq</a> &#8211; inspired by the Windows-only Notepad++, a easy-to-use auto-draft-saving text editor</li><li><a href="https://orgmode.org">emacs org-mode</a> &#8211; Emacs is a powerful text editor and org-mode is a plain-text productivity/task-management tool</li><li><a href="https://github.com/brndnmtthws/conky">conky</a> &#8211; a desktop system monitoring tool &#8211; tells you CPU/RAM loads, active processes, etc. on your desktop</li><li><a href="https://github.com/HorlogeSkynet/archey4">Archey</a> &#8211; a cool utility that tells about your machine. It was used to generate the screenshot at the top of this post</li></ol>



<blockquote class="wp-block-quote"><p><strong>Note:</strong> If you use any of my screenshots for anything, please let me know and credit me somehow. Especially if it&#8217;s used as a texture for <a href="https://twitter.com/AntJanus/status/800825075880448000">computer hacker monitors in a AAA video game</a></p><p>Like my content? <a href="https://twitter.com">Follow me on Twitter</a> or just <a href="https://www.buymeacoffee.com/CKdpP4G">buy me a coffee</a></p></blockquote>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/my-favorite-linux-tools/">My Favorite Linux Tools</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/web-development-tutorials/my-favorite-linux-tools/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4280</post-id>	</item>
		<item>
		<title>Switching from angular2-template-loader to @ngtools/webpack</title>
		<link>https://antjanus.com/blog/web-development-tutorials/switching-from-angular2-template-loader-to-ngtools-webpack/</link>
					<comments>https://antjanus.com/blog/web-development-tutorials/switching-from-angular2-template-loader-to-ngtools-webpack/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Mon, 05 Aug 2019 15:53:56 +0000</pubDate>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[webpack]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4272</guid>

					<description><![CDATA[<p>Here is my journey...my blood, sweat, and tears that went into switching from angular2-template-loader to @ngtools/webpack and how you, too, can go through this as well</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/switching-from-angular2-template-loader-to-ngtools-webpack/">Switching from angular2-template-loader to @ngtools/webpack</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<hr class="wp-block-separator"/>



<blockquote class="wp-block-quote"><p>This post was originally posted on <a href="https://dev.to/antjanus/switching-from-angular2-template-loader-to-ngtools-webpack-117g">my dev.to account </a>and migrated here for archival purposes.</p></blockquote>



<p>I don&#8217;t usually write &#8220;utility&#8221; posts that describe a way to fix a very specific problem but I ran into something that doesn&#8217;t seem to have a good resolution path online. </p>



<p>A <em>huge</em> part of this article is all of the debugging/troubleshooting I&#8217;ve done to get everything to work. The entire project took me more than a week of focused work as well as bringing in another coder for pairing for several hours almost every day. I&#8217;ve had to switch from working on my laptop (which was getting overheated and stuttering at the constant recompiles) to my desktop which is currently heating my office way past comfortable temperatures. This was an excruciating process but…I did it! </p>



<h2>The Problem</h2>



<p>If you&#8217;re using Angular (or &#8220;Angular2+&#8221;), you might be using the <a href="https://github.com/TheLarkInn/angular2-template-loader">angular2-template-loader</a> which allows you to do some neat things such as <code>require</code> all of your Component templates and SASS files which you can then run through other loaders in Webpack.</p>



<p>You&#8217;ll send up with something like this for your components:</p>



<pre class="wp-block-preformatted prettyprint lang-js">@Component({
  template: require('./button.component.html'),
  styles: [require('./button.component.scss')]
})
export default ButtonComponent {}</pre>



<p>Whoa, check that out, we can use SCSS in our Angular components. That&#8217;s kind of the power of it. Angular2-template-loader will then load up the html/scss (or rather its post-processed versions) and inline them within the template itself.</p>



<p>The problem is that this effectively disallows AoT or Ahead-of-time compilation. So while the angular2-template-loader is very popular, often used in tutorials, and very easy to setup, it also creates a problematic solution for the AoT compiler.</p>



<h2>The AoT compiler</h2>



<p>AoT stands for &#8220;ahead of time&#8221;. The AOT compiler will look at the templates referenced in a component, parse them, and create the JavaScript logic to do what the templates ask it to do. </p>



<p>The best way for me to describe the AOT compiler is that instead of parsing through the HTML, figuring out where there are repeats, what components are referenced where, etc. at application boot time (when the browser loads the application), it happens during build time.</p>



<p>In our case at work, this process seems to take several seconds which is absolutely ridiculous. Plus, if you compile on application load, you have to include the compiler in your bundle. <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f641.png" alt="🙁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>But…angular2-template-loader doesn&#8217;t do AOT (it doesn&#8217;t claim it does!) and AOT can&#8217;t happen with it.</p>



<h2>The webpack loader alternative</h2>



<p>The immediate alternative I&#8217;ve found is the <a href="https://www.npmjs.com/package/@ngtools/webpack">@ngtools/webpack</a> package which not only does AOT but also serves as a TypeScript loader! It does some other things as well but I want to focus on this first.</p>



<p>First, we gotta replace the old <code>angular2-template-loader</code> and whatever <code>typescript</code> loader you&#8217;re using, this should look kind of like this at the end (and your TypeScript loader and your angular2-template-loader should be gone):</p>



<pre class="wp-block-preformatted prettyprint lang-js">// somewhere in your webpack config
rules: [
  {
    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
    loaders: [
       {
       loader: '@ngtools/webpack',
       },
    ],

  }
]</pre>



<p>You also need to your webpack plugins:</p>



<pre class="wp-block-preformatted prettyprint lang-js">import { AngularCompilerPlugin } from '@ngtools/webpack';

// and somewhere in your webpack config
plugins: [
    new AngularCompilerPlugin({
      tsConfigPath: './tsconfig.json',
      entryModule: './web/modern/main.ts#AppModule'
    }),
]</pre>



<p>Fantastic! The only problem? All those requires..</p>



<h2>Fixing the html requires</h2>



<p>The problem now is that we have tons of components that have that fancy <code>require</code> for templates and styles. What do we do now?</p>



<p>Here&#8217;s why I&#8217;m writing this so I can share/document this info and come back to it. Phew. So, <code>@ngtools/webpack</code> allows us to do similar requires but without the <code>require</code>.</p>



<p>Basically, we have to change</p>



<pre class="wp-block-preformatted prettyprint lang-js">@Component({
  selector: 'button-component',
  template: require('./button.component.html')
})</pre>



<p>into:</p>



<pre class="wp-block-preformatted prettyprint lang-js">@Component({
  selector: 'button-component',
  templateUrl: './button.component.html'
})</pre>



<p>Note that we&#8217;re still referencing a <code>templateUrl</code>, not a <code>template</code>. NgTools brings that template in and does AOT on it. So how do we do this change on a large scale? By using the Unix tool <code>grep</code> and then using plain ol&#8217; node to do the changes</p>



<h2>Grepping for all files</h2>



<p><code>Grep</code> is a unix tool present in Linux, macOS, and other systems. You can also get it on Windows. Unfortunately, Windows&#8217;s <code>Select-String</code> will not the do the job we need it do to today (though <a href="https://antjanus.com/blog/web-development-tutorials/how-to-grep-in-powershell/">go read about how to use Powershell&#8217;s Select-String like grep</a> if you&#8217;re into that).</p>



<p>With <code>grep</code> we can select all the files that need updating.</p>



<pre class="wp-block-preformatted prettyprint lang-sh">grep -rl 'Component({' /path/to/application</pre>



<p>The flag <code>-r</code> will make sure grep looks recursively through files in your application with the string <code>Component({</code> in it. </p>



<p>If you just run this by itself, you&#8217;ll get a long list of files that you need to update; however, we can use <code>node</code> to do the replacement for us.</p>



<h2>Change your files</h2>



<p>Here&#8217;s the thing, I tried <code>sed</code>, I really did. But it took so long to do one small operation that I figured I might as well write a <code>node</code> script for it.</p>



<p>First, we need a really complicated Regex that can do the correct substitution and replace <code>require('./template.component.html')</code> with just <code>./template.component.html</code>:</p>



<pre class="wp-block-preformatted prettyprint lang-js">/Component\(\{(.*\n)+.*template: require\(('.*\.html')\)(.*\n)+\}\)/</pre>



<p>Oh s***, wtf is that? Well, I hate to say this but this is our ticket to freedom. What this regex does is:</p>



<ol><li>look for the <code>Component({</code> string</li><li>it matches &#8220;however many newlines filled with characters&#8221; (that&#8217;s the <code>(.*\n)+</code>)</li><li>it finds the <code>template</code> string with the require. Note the extra parentheses</li><li>group matching allows us to identify just the HTML string via <code>('.*\.html')</code>. </li><li>and then we match for &#8220;however many newlines filled with characters&#8221;</li><li>and finally we match for the closing <code>})</code>.</li></ol>



<p>Basically anything that matches this pattern:</p>



<pre class="wp-block-preformatted prettyprint lang-js">@Component({
  something: else,
  doesnotmatter: whatshere,
  template: require('./path/to/template.html'),
  moreKeywords: withData
})</pre>



<p>It doesn&#8217;t matter how many keys are in that object or what data, as long as it has a template that requires an HTML file, we&#8217;ll match on it.</p>



<p>Let&#8217;s write the <code>node</code> script. It&#8217;ll need to read the path of a file as an argument, do the substitution, and write to that file with the changes. I&#8217;m going to skip the craziness of explaining this step by step so here&#8217;s the final JavaScript file:</p>



<pre class="wp-block-preformatted prettyprint lang-js">const path = require('path');
const fs = require('fs');

function run() {
  /*
   * Args which should look like ['node', 'path/to/this/script.js', '/path/tofile.ts']
   */
  const args = process.argv;
  const files = args.slice(2);

  files.forEach(file => {
    changeFile(file);
  });
}
function changeFile(relativeFilePath) {
  const filePath = path.resolve(__dirname, relativeFilePath);
  const fileString = fs.readFileSync(filePath).toString();
  const regex = /Component\(\{(.*\n)+.*template: require\(('.*\.html')\)(.*\n)+\}\)/;

  const match = fileString.match(regex);

  if (!match) {
    return;
  }

  const htmlPath = match[2];

  if (!htmlPath) {
    return;
  }

  const replacementLookup = `template: require(${htmlPath})`;
  const replacement = `templateUrl: ${htmlPath}`;
  const newFileString = fileString.replace(replacementLookup, replacement);

  fs.writeFileSync(filePath, newFileString);
}

run();</pre>



<p>Basically, this script will:</p>



<ol><li>read in script arguments to get the file paths</li><li>read the files one by one</li><li>use that fancy regex to find a match. match group 2 (3rd item in the array) will be our html url</li><li>do a replace on the file string where the original template value gets replace with the new one</li><li>save it!</li></ol>



<p><strong>Note</strong> This script is pretty handy. You can use it to update the <code>styles</code> as well if you run into that issue in the troubleshooting section. <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2>Put it all together</h2>



<p>Ok, so to put it altogether, we use one more unix tool, <code>xargs</code>. It&#8217;ll pipe the result of our grep into our node script which will then perform our replacement.</p>



<blockquote class="wp-block-quote"><p><strong>Caution</strong> This is a destructive action. Meaning that it&#8217;ll affect each file and run directly. I&#8217;m not responsible for whatever problems you might run into with these scripts. MAKE SURE that you&#8217;re using something like <code>git</code> and have committed all of your code changes up until this point so you can do a quick <code>git hard --reset</code> should you run into problems and get back to a working version of your project. PLEASE do make sure of this.</p></blockquote>



<pre class="wp-block-preformatted prettyprint lang-sh">grep -rl 'Component({' /path/to/application | xargs node replace.js</pre>



<p>The script will get each file as a separate argument so the xargs actually calls <code>node replace.js path/to/component1.ts path/to/component2.ts</code> and so on.</p>



<p>After this, you should be done!</p>



<h2>The results</h2>



<p>I want to share some preliminary benchmarks that I&#8217;ve done:</p>



<ol><li>initial load time in a dev environment dropped from 10 seconds to 3 seconds uncached</li><li>initial load time (cached) dropped from 8 seconds to 1.8 seconds in a dev environment</li><li>compiler time is way more resource intensive (my office is a sauna)</li></ol>



<p>I cannot wait to try this out in a production environment.</p>



<h2>Template problems?</h2>



<p>The compiler will call you out on your issues. I&#8217;ve mentioned it in <code>Potential issues</code> but it bears saying separately first: angular-cli will compile your templates. That means that it&#8217;ll check for variables, it&#8217;ll check for bindings, it&#8217;ll check for everything. And it <em>will</em> let you know if you messed up. Common issues that I&#8217;ve had to fix:</p>



<ol><li>referencing variables in the template that don&#8217;t exist in the component</li><li>calling a function with the wrong number of arguments</li><li>passing in a variable to a component which does not have an input to receive that data</li></ol>



<h2>Potential issues</h2>



<p>There were some issues I ran into during this conversion and I wanted to share how I was able to resolve them. Most of these have opened and/or closed issues on the <code>angular-cli</code> repo. :/ If you look up the errors directly, you can find those and follow the conversation. I wanted to provide you with how exactly <em>I</em> solved the problem and what other solutions were suggested.</p>



<h3><em>IMPORTANT NOTES:</em></h3>



<ol><li>MAKE SURE you&#8217;ve saved your work and committed it in Git &#8212; and NOT to your master branch. SERIOUSLY. I had to keep referring back to the master branch and the clean codebase</li><li>MAKE SURE you don&#8217;t try to change things ahead of time. Look at the potential issues that YOU experience</li><li>It&#8217;s ok if you have to undo some of the solutions</li><li>I can&#8217;t fix this for you</li></ol>



<h3>ERROR in : Cannot determine the module for class AppRootComponent in /path/to/component! Add AppRootComponent to the NgModule to fix it.</h3>



<p>I saw this come up in a few different places in issues and elsewhere. There are four solutions I&#8217;ve found to this issue:</p>



<h4>Possible solution 1</h4>



<p>You probably have bad import paths that webpack/node doesn&#8217;t care about but the compiler does. Most of the time, this is due to capitalization. Make sure if you&#8217;re importing a file that has capitalization in it (like <code>AppRootComponent.ts</code>) that you&#8217;re capitalizing correctly in your import path. You can actually do an import like <code>./path/to/approotcomponent</code>, and node/webpack won&#8217;t complain.</p>



<h4>Possible solution 2</h4>



<p>The other possibility is that you have components that either aren&#8217;t part of a module or are simply unimported but still in the working directory. Check for either of those situations and either put those components into modules or remove them.</p>



<h4>Possible solution 3</h4>



<p>Lastly, and this was my situation, you&#8217;re using components in your main module. Urgh, I hate this problem because I think it shouldn&#8217;t be causing these issues. Basically, if you have an <code>AppRootComponent</code> and you&#8217;re using it to bootstrap Angular, put it in another module first, import that module, and <em>then</em> bootstrap.</p>



<h4>Possible solution 4</h4>



<p>There&#8217;s another hidden error. As I was working through making everything work and through all of the other problems, I found out that I was still able to bootstrap <code>AppRootComponent</code> at the end of my journey, as long as it was part of my entry module (AppModule). So…I ended up reverting the solutions above once that happened.</p>



<h3>ERROR in path/to/component/button.component.ts.ButtonComponentComponent.html(1,21): : Expected 0 arguments, but got 1.</h3>



<p>This usually means that you have a typing issue in your template itself. There are several situation this shows up in:</p>



<ol><li>you&#8217;re calling a method or using a variable that was marked as <code>private</code> in your component</li><li>you have a typing issue. Eg. you&#8217;re passing the wrong number of arguments into a method (this was my situation!)</li></ol>



<h3>TypeError: Cannot read property &#8216;_ngToolsWebpackPluginInstance&#8217; of undefined</h3>



<p>This error occurred to me when using <a href="https://github.com/amireh/happypack">HappyPack</a> with <code>@ngtools/webpack</code>. They&#8217;re not compatible so just use <code>@ngtools/webpack</code> directly rather than with HappyPack</p>



<h3>Module not found: Error: Can&#8217;t resolve &#8216;./main.ts.ngfactory&#8217; in &#8216;/path/to/application/directory&#8217;</h3>



<p>Another strange problem that I don&#8217;t understand. Note that <code>main.ts</code> is my entry file so that name may be different for you (such as <code>app.ts</code>). There are three solutions that I&#8217;ve found to this:</p>



<ol><li>adjust your <code>rootDir</code> parameter in tsconfig <a href="https://github.com/angular/angular-cli/issues/13721">check out the relevant issue</a></li><li>install enhanced-resolve via <code>npm install enhanced-resolve@3.3.0</code> <a href="https://github.com/angular/angular-cli/issues/7151">here&#8217;s the relevant issue</a></li><li>you can add <code>.ngfactory</code> into the extensions that webpack needs to resolve in <code>extensions.resolve</code> in your webpack config</li></ol>



<p>If none of this works, go ahead and adjust the <code>@ngtools/webpack</code> config by not specifying the <code>entryModule</code> and specifying an absolute path to the <code>mainPath</code>.</p>



<pre class="wp-block-preformatted">{
  mainPath: path.resolve(__dirname, '/path/to/entry/file')
}</pre>



<p>This disables lazy route loading (automatic code splitting by route) which is a bummer but it was necessary in my case and the code splitting wasn&#8217;t an issue for me anyways because I use an Angular/AngularJS hybrid app where the router rests on the AngularJS side.</p>



<p>Phew, let&#8217;s keep going!</p>



<h2>Potential issues in more complicated build chains</h2>



<p>I wanted to split this section off because it&#8217;s more likely that it&#8217;s my own specific application architecture that causes these issues rather than something <code>ngtools/webpack</code> is responsible for.</p>



<h3>TypeError: library_1.default is undefined</h3>



<p>This issue basically means that a module is not available. It was an issue because the TypeScript compiler was compiling JavaScript files. Why is that a problem?</p>



<p>While Babel has no issue with this:</p>



<pre class="wp-block-preformatted prettyprint lang-js">import _ from 'lodash';</pre>



<p>TypeScript requires this syntax:</p>



<pre class="wp-block-preformatted prettyprint lang-js">import * as _ from 'lodash';</pre>



<p>What that meant for me was to switch to the TypeScript compiler entirely and adjust all of the import paths &#8212; I ripped out our Babel compiler and changed the <code>@ngtools/webpack</code> loader to match against all <code>.js</code> files. </p>



<p>Here&#8217;s the look up regex if you want to adjust the <code>replace.js</code> file I mentioned above: <code>/import ([a-z0-9A-Z_]+) from/g;</code>. I could write a whole article about the process so if you do get here, just comment below! And I&#8217;ll give you the step-by-step process.</p>



<p>But, make sure you don&#8217;t change the import paths for your own modules!</p>



<h3>Host should not return a redirect source file from <code>getSourceFile</code></h3>



<p>There&#8217;s <a href="https://github.com/angular/angular/issues/22524#issuecomment-468212447">an open issue</a> on Github for this error and it suggests patching the compiler… yeah. The patch <em>does</em> work (I&#8217;ve tried it) and it basically involves:</p>



<ol><li>looking up <code>./node_modules/@angular/compiler-cli/src/transformers/program.js</code></li><li>finding a line that starts with <code>if (this.hostAdapter.isSourceFile(sf.fileName)) {</code></li><li>and putting <code>if (sf['redirectInfo']) { sf = sf['redirectInfo'].redirectTarget; }</code> right before</li></ol>



<p>That essentially replaces a source file redirect with the actual file it redirected to. <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f937-200d-2640-fe0f.png" alt="🤷‍♀️" class="wp-smiley" style="height: 1em; max-height: 1em;" /> doesn&#8217;t mean much to me; however, if you don&#8217;t want to manually patch stuff in node_modules (even with the useful <code>postinstall</code> script included in the Github issue), you can do what I did and instead of step 3 where you set the redirect, you can log out the problematic files!</p>



<pre class="wp-block-preformatted prettyprint lang-js">if (sf['redirectInfo']) {
  console.log('SF: ', sf.fileName);
}</pre>



<p>And then tackle the problems that show up. In my case, the library <code>@turf/turf</code> was having some issues and namely, each module in <code>@turf/turf</code> was importing <code>@turf/helpers</code> and <em>that</em> was causing issues. I was able to solve those problems by:</p>



<ol><li>destructuring any imports from the problematic library</li><li>using/installing submodule of the library directly</li></ol>



<p>And I&#8217;m gonna also throw this in there: look for alternatives if it&#8217;s not a huge cost to you.</p>



<h3>SASS/SCSS not loading?</h3>



<p>I encountered this issue as well. There&#8217;s <a href="https://github.com/angular/angular-cli/issues/6252">a closed ticket</a> for it with not much information; however, if you&#8217;re wanting to use SASS (and haven&#8217;t before!), check out the thread for information on the SASS loader.</p>



<p>However, if you&#8217;ve used it before and things aren&#8217;t working now, you just need to change how you load your styles:</p>



<pre class="wp-block-preformatted prettyprint lang-js">// from
@Component({
    styles: [require('./path/to/component.scss')]
})

// to
@Component({
    styleUrls: ['./path/to/component.scss'] 
})</pre>



<h2>Additional Resources</h2>



<p>There were a few resources that helped me along the way:</p>



<ul><li><a href="https://blog.angularindepth.com/upgrading-a-project-without-cli-to-angular-6-b07b105adc02">Upgrading a project without cli to Angular 6</a></li></ul>



<h2>But Why?</h2>



<p>Why am I sharing this long-ass article that has no clear path to navigate through it? So you can understand my journey. How I&#8217;ve struggled, what I&#8217;ve seen, and where I had to look for answers.</p>



<p>I&#8217;m a new person today. I look in the mirror, and I don&#8217;t see the Antonin that I saw two weeks ago when I was preparing to make this loader change. I&#8217;m not the same developer.</p>



<p>These were trying times. My sanity has been tested. My perseverance has been tested. There were many nights when I wanted to shout at webpack, at Angular, at Angular-CLI. To blame <em>someone</em> for this but I couldn&#8217;t. Code just…works this way sometimes. And sometimes, issues aren&#8217;t reproducible and so they can&#8217;t be addressed by the open source maintainers. And yet, it worked out. It worked.</p>



<p>Check out the screenshot at the top of the article. Look at how many changes I&#8217;ve had to make! It was…a lot of work.</p>



<p>Despite all of that…I&#8217;m glad that <code>ngtools/webpack</code> exists and that <code>angular2-template-loader</code> existed when I first started transitioning to Angular. Without the ngtools, I wouldn&#8217;t have been able to cut down on our load time enough for us to move onto the next stage of our application development: rewriting everything in React.</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/switching-from-angular2-template-loader-to-ngtools-webpack/">Switching from angular2-template-loader to @ngtools/webpack</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/web-development-tutorials/switching-from-angular2-template-loader-to-ngtools-webpack/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4272</post-id>	</item>
		<item>
		<title>My Top 10 Programming Proverbs</title>
		<link>https://antjanus.com/blog/web-development-tutorials/my-top-10-programming-proverbs/</link>
					<comments>https://antjanus.com/blog/web-development-tutorials/my-top-10-programming-proverbs/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Mon, 05 Aug 2019 15:44:15 +0000</pubDate>
				<category><![CDATA[Development]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4270</guid>

					<description><![CDATA[<p>A little while back, I started a repo of funny (and insightful!) programming quotes and proverbs. These often take a shape of an existing proverbs (like Rome wasn't built in a day) and get translated to be tech-relevant and hopefully give you a good chuckle (like Facebook wasn't built in a day). Protip: You can [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/my-top-10-programming-proverbs/">My Top 10 Programming Proverbs</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>A little while back, I started <a href="https://github.com/AntJanus/programmers-proverbs">a repo</a> of funny (and insightful!) programming quotes and proverbs. These often take a shape of an existing proverbs (like <code>Rome wasn't built in a day</code>) and get translated to be tech-relevant and hopefully give you a good chuckle (like <code>Facebook wasn't built in a day</code>). Protip: You can put these into Slack as the loading/intro messages. <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<p>Without further ado, here are my favorites to brighten your day:</p>



<h2>When you reach wizened-engineer level, there are at least a hundred wizened engineers above you.</h2>



<hr class="wp-block-separator"/>



<h2>A deployed MVP is worth two prototyped.</h2>



<hr class="wp-block-separator"/>



<h2>Sleep on a force push.</h2>



<hr class="wp-block-separator"/>



<h2>Sometimes you have to cut legacy support to allow the new product to bloom.</h2>



<hr class="wp-block-separator"/>



<h2>Good test coverage + automated workflows = quiet cell phones and better sleep.</h2>



<hr class="wp-block-separator"/>



<h2>There is no test without first a failure</h2>



<hr class="wp-block-separator"/>



<h2>Anger and stubborness make bad allies in code review</h2>



<hr class="wp-block-separator"/>



<h2>With commit and deploy access comes great responsibility</h2>



<hr class="wp-block-separator"/>



<h2>Don&#8217;t put all your logic in one method basket</h2>



<hr class="wp-block-separator"/>



<h2>A foreach loop avoided is a CPU cycle earned.</h2>



<p><em>This post was <a href="https://dev.to/antjanus/my-top-10-programming-proverbs-2a4d">originally posted on dev.to</a> and has been moved to this blog for personal archival purposes</em></p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/my-top-10-programming-proverbs/">My Top 10 Programming Proverbs</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/web-development-tutorials/my-top-10-programming-proverbs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4270</post-id>	</item>
		<item>
		<title>The Definitive React Hooks Cheatsheet</title>
		<link>https://antjanus.com/blog/web-development-tutorials/front-end-development/the-definitive-react-hooks-cheatsheet/</link>
					<comments>https://antjanus.com/blog/web-development-tutorials/front-end-development/the-definitive-react-hooks-cheatsheet/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Fri, 10 May 2019 16:40:03 +0000</pubDate>
				<category><![CDATA[Front End]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[react]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4236</guid>

					<description><![CDATA[<p>React Hooks is the new hotness in the React world. I&#8217;m writing steadily more and more of them and I thought it would be useful to have a cheatsheet to refer back to which encompasses the basic hooks as well as the intricacies of useEffect. Check out the official Hooks API Reference for more in-depth [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/front-end-development/the-definitive-react-hooks-cheatsheet/">The Definitive React Hooks Cheatsheet</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>React Hooks is the new hotness in the React world. I&#8217;m writing steadily more and more of them and I thought it would be useful to have a cheatsheet to refer back to which encompasses the basic hooks as well as the intricacies of <code>useEffect</code>. Check out the official <a href="https://reactjs.org/docs/hooks-reference.html">Hooks API Reference</a> for more in-depth information.</p>



<p><strong>Table of Contents</strong></p>



<ul><li><a href="#useeffect-for-lifecycle-methods">useEffect for lifecycle methods</a></li><li><a href="#substitute-for-componentdidupdate-componentdidmount">componentDidUpdate + componentDidMount</a></li><li><a href="#substitute-for-componentdidmount-componentwillunmount">componentDidMount + componentWillUnmount</a></li><li><a href="#useeffect-for-side-effects">useEffect for general side effects</a></li><li><a href="#usestate">useState</a></li><li><a href="#usereducer">useReducer</a></li><li><a href="#building-your-own-hooks">Building Your Own Hooks</a></li></ul>



<h2 id="useeffect-for-lifecycle-methods">useEffect (for lifecycle methods)</h2>



<p><code>useEffect</code>, among other things, allows you to write your own side effects and trigger a re-render when needed. </p>



<p>But to make it simpler, useEffect also substitutes lifecycle methods. Let&#8217;s talk about them.</p>



<h3 id="substitute-for-componentdidupdate-componentdidmount">substitute for componentDidUpdate + componentDidMount</h3>



<p><strong>When does it run?</strong> On every render</p>



<p><strong>What&#8217;s the catch?</strong> It&#8217;s not just a <code>componentDidUpdate</code> replacement, it also runs on mount. So it&#8217;s not 1-to-1</p>



<p><strong>Important features?</strong> useEffect can take in a 2nd argument, you <em>have</em> to skip that argument. You can also return a function, we&#8217;ll cover that in the next section.</p>



<p><strong>Code sandbox playground:</strong> <a href="https://codesandbox.io/s/1r8nrzpl9j">Go play with it</a></p>



<p><strong>Syntax:</strong></p>



<pre class="wp-block-preformatted prettyprint lang-js">import { useEffect } from 'react';

useEffect(() =&gt; {
  // whatever runs here will run on each re-render
});</pre>



<h3 id="substitute-for-componentdidmount-componentwillunmount">substitute for componentDidMount + componentWillUnmount</h3>



<p><strong>When does it run?</strong> On component mount and unmount</p>



<p><strong>What&#8217;s the catch?</strong> The syntax is very close to the previous use case. It threw me off several times but it makes sense once you read the docs. If the effect runs more than once, make sure you passed in the 2nd argument</p>



<p><strong>Important features?</strong> This is an effect that runs only <em>once</em>. The mount logic goes in the body of the effect function, the unmount/cleanup logic goes into a function that you return from the effect.</p>



<p><strong>Code sandbox playground:</strong> <a href="https://codesandbox.io/s/xjrk36x244">Go play with it</a></p>



<p><strong>Syntax:</strong></p>



<pre class="wp-block-preformatted prettyprint lang-js">import { useEffect } from 'react';

useEffect(() =&gt; {
  // run mount logic here such as fetching some data

  return () =&gt; {
    // unmount logic goes here
  };
}, []); // note the empty array</pre>



<p>You can leave either the <code>mount</code> or <code>unmount</code> logic empty to work only off one of those lifecycle substitute. Meaning that:</p>



<ol><li>leave <code>mount</code> logic empty so that only <code>unmount</code> logic runs (substitute for just <code>componentWillUnmount</code>)</li><li>return nothing so that only <code>mount</code> logic runs (substitute for just <code>componentDidMount</code>)</li></ol>



<h2 id="useeffect-for-side-effects">useEffect for side effects</h2>



<p><code>useEffect</code>&#8216;s primary goal is to encompass any side effect you might want to use. A side effect is essentially <em>something</em> that you do within your component which affects the world at large. Whether that&#8217;s a network request, setting the document title, or what have you.</p>



<h3>Run when necessary</h3>



<p><strong>When does it run?</strong> when the component re-renders, <code>useEffect</code> will check dependencies. If the dependency values changed, useEffect will run the effect</p>



<p><strong>What&#8217;s the catch?</strong> React does a shallow comparison. If you use an object or an array that you mutate, React will think nothing changed. </p>



<p><strong>Important features</strong> useEffect skips running the effect when things don&#8217;t change. You don&#8217;t actually have to use the dependency values in the effect. You can pass in a prop value as a dependency.</p>



<p><strong>Code sandbox playground:</strong> <a href="https://codesandbox.io/s/j14zoq7095">Go play with it</a></p>



<p><strong>Syntax:</strong> </p>



<pre class="wp-block-preformatted prettyprint lang-js">import { useEffect } from 'react';

function SomeComponent(props) { 
    useEffect(() =&gt; {
      // logic runs only when dependency variables changed
    }, [arrOfDependency, values, props.id]); // array of values to check if they've changed
}</pre>



<p><strong>Potential use cases</strong> </p>



<p>Since the hook is more difficult to explain, I&#8217;d like to offer a list of use cases</p>



<ol><li>run a side effect (like a fetch) when a prop changes to get new data</li><li>run a resource-heavy calculation only when the calculation values change</li><li>update the page (like document title) when a value updates</li></ol>



<h2 id="usestate">useState</h2>



<p>State is probably <em>the</em> reason why people switch from stateless (functional) components to class components. <code>useState</code> allows us to have stateful components without classes.</p>



<p><strong>What does it return?</strong> Current state and a function that lets you set state</p>



<p><strong>What&#8217;s the catch?</strong> The state setting function will replace the previous state with the new one rather than merging them as class state would have. You need to merge your objects yourself before setting the state.</p>



<p><strong>Important features</strong> You can use as many <code>useState</code> hooks in your component as you want. Passing any value to <code>useState</code> will create the initial state. It&#8217;s also a convention to not call the variables <code>state</code> and <code>setState</code> but rather by contextual names (eg. <code>user</code> and <code>setUser</code>). <code>useState</code> accepts any value for state, it doesn&#8217;t have to be an object.</p>



<p><strong>Code Sandbox playground:</strong> <a href="https://codesandbox.io/s/53ovy28krn">Check out the useState examples</a></p>



<p><strong>Syntax:</strong> </p>



<pre class="wp-block-preformatted prettyprint lang-js">import { useState } from 'react';

// setup
const defaultValue = { name: "Antonin" };
const [state, setState] = useState(defaultValue);

// scenario 1 usage
// resulting state only contains key `user` with value 'antjanus'
setState({ user: 'antjanus' }); 

// scenario 2 usage
// resulting state contains key `name` with value 'A. Januska'
setState({ name: 'A. Januska' }); 

// scenario 3 usage
// resulting state is a merger between `{ name: 'A. Januska' }` and `{ user: 'antjanus'}`
setState({ ...state, user: 'antjanus'}); </pre>



<h2 id="usereducer">useReducer</h2>



<p><code>useReducer</code> is an alternative to <code>useState</code> and if you&#8217;ve used Redux in the past, this will look familiar.</p>



<p><strong>What are the arguments? What does it return?</strong> <code>useReducer</code> takes in a <code>reducer</code> function and the <code>initialState</code>. It returns the current <code>state</code> and a <code>dispatcher</code> (sound familiar?)</p>



<p><strong>How does it run?</strong> On state change, <code>dispatch</code> an object with a type and a data payload (read about <a href="https://github.com/redux-utilities/flux-standard-action">flux standard action</a> for more info). The <code>reducer</code> we passed into useReducer will receive the current state and the dispatched object. It returns the new state.</p>



<p><strong>What&#8217;s the catch?</strong> It&#8217;s a more complicated workflow but it works just like you&#8217;d expect if you&#8217;ve used Redux. </p>



<p><strong>Important features</strong> The reducer gets run on every dispatch. It gets access to the previous state. <code>useReducer</code> also includes a 3rd argument you can use to create the initial state</p>



<p><strong>Code Sandbox playground:</strong> <a href="https://codesandbox.io/s/zqj3j03jpl">Check out the useReducer example</a></p>



<p><strong>Syntax</strong></p>



<pre class="wp-block-preformatted prettyprint lang-js">import { useReducer } from 'react';

function reducer(currentState, action) {
  switch(action.type) {
     // handle each action type and how it affects the current state here
  }
}

function SomeComponent() {
  const [state, dispatch] = useReducer(reducer, initialState);

  dispatch({ type: 'ADD', payload: data }); // { type: 'ADD', payload: data } gets passed into the `reducer` as the `action` argument while `state` gets passed in as the `currentState` argument
}</pre>



<h2 id="building-your-own-hooks">Building Your Own Hooks</h2>



<p>A quick note on building your own hooks. It&#8217;s as easy as using the existing hooks and composing them together inside of a function that starts with <code>use</code>. Here&#8217;s a quick example of a <code>useUser</code> hook.</p>



<p><strong>What are the requirements?</strong> That the function starts with the keyword <code>use</code>. Eg. <code>useUser</code> or <code>useSomethingElse</code>.</p>



<p><strong>Important features:</strong> you can call any hooks within your custom hook and it works as expected.</p>



<p><strong>Code Sandbox playground:</strong> <a href="https://codesandbox.io/s/2wzponv3oy">Check out the custom hooks example</a></p>



<p><strong>Syntax:</strong> </p>



<pre class="wp-block-preformatted prettyprint lang-js">import { useEffect } from 'react';

function useUser(userId) {
  let [user, setUser] = useState(null);

  useEffect(() =&gt; {
    fetch(`/api/user/${userId}`)
        .then(data =&gt; data.toJSON())
        .then(data =&gt; setUser(data));
  }, [userId]);

  return user;
}

function SomeComponent(props) {
  const user = useUser(props.id);
}</pre>



<h2>What about the rest?</h2>



<p>There are other hooks you can use such as <code>useMemo</code>, <code>useCallback</code> and so on. I would say that those are more advanced hooks and if you understand the basic hooks, go ahead and check out <a href="https://reactjs.org/docs/hooks-reference.html">the official docs</a>.</p>



<p>I also understand there are some advanced usage examples for many of these (like passing useReducer&#8217;s <code>dispatch</code> down several levels).</p>



<p>If you find something incorrect or some extra information useful that isn&#8217;t included, let me know! And I&#8217;ll include it!</p>



<blockquote class="wp-block-quote"><p>Did you find the cheatsheet useful? <a href="https://www.buymeacoffee.com/CKdpP4G">Buy me a coffee</a> so I can keep doing this and produce more content! <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> You can also <a href="https://twitter.com/AntJanus">follow me on Twitter</a></p></blockquote>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/front-end-development/the-definitive-react-hooks-cheatsheet/">The Definitive React Hooks Cheatsheet</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/web-development-tutorials/front-end-development/the-definitive-react-hooks-cheatsheet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4236</post-id>	</item>
		<item>
		<title>Prototypes Don&#8217;t Get Thrown Out &#8212; Write Tracer (Bullet) Code Instead</title>
		<link>https://antjanus.com/blog/thoughts-and-opinions/prototypes-dont-get-thrown-out-write-tracer-bullet-code-instead/</link>
					<comments>https://antjanus.com/blog/thoughts-and-opinions/prototypes-dont-get-thrown-out-write-tracer-bullet-code-instead/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Mon, 25 Feb 2019 22:51:13 +0000</pubDate>
				<category><![CDATA[Thoughts and Opinions]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4226</guid>

					<description><![CDATA[<p>A few years back, I wrote an article called My Experience Running Development At A Startup and one neat thing I mentioned that got a good deal of comments has been the concept of &#8220;Tracers over Prototypes&#8221;. I discussed some problems with prototypes and spikes and how &#8220;tracers&#8221; are a better alternative. Three years later, [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/thoughts-and-opinions/prototypes-dont-get-thrown-out-write-tracer-bullet-code-instead/">Prototypes Don&#8217;t Get Thrown Out &#8212; Write Tracer (Bullet) Code Instead</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>A few years back, I wrote an article called <a href="https://antjanus.com/blog/thoughts-and-opinions/experience-running-development-startup/">My Experience Running Development At A Startup</a> and one neat thing I mentioned that got a good deal of comments has been the concept of &#8220;Tracers over Prototypes&#8221;. I discussed some problems with prototypes and spikes and how &#8220;tracers&#8221; are a better alternative.</p>



<p>Three years later, I&#8217;m now here to expand on this and discuss why prototypes and spikes are foot-guns rather than solutions and how tracer code is a better approach to problem-solving, especially in a fast-paced environment.</p>



<p>If you&#8217;ve read the <a href="https://amzn.to/2S03i9D">Pragmatic Programmer</a>, you&#8217;ll find this concept familiar, that&#8217;s where I learned about it as well.</p>



<h2>What&#8217;s a prototype? What&#8217;s a spike?</h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/02/nicolas-thomas-540353-unsplash-e1550681415880.jpg" alt="prototype"/></figure>



<p>Let&#8217;s get definition for these first. The idea of both a prototype and spike is to write disposable code in order to learn and in order to test an idea/library/whatever out.</p>



<p>For example, you might write a &#8220;prototype&#8221; rewrite of your product in another language. Fancy Elm? You might rewrite a difficult section of your current product in elm as a test and then analyze the results:</p>



<ol><li>Does it perform just as well?</li><li>What is the developer experience like?</li><li>Does it have community support necessary for long-term development?</li></ol>



<p>And so on. Based on your &#8220;test&#8221; results, you might either go with that decision and write a permanent solution based off lessons learned during the prototype development/spike or you might realize that this is not the right decision at this time.</p>



<p>A spike is a similar idea but might require less development and more research. Basically, it has more to do with spending time on an idea/decision and investigating it rather than creating a functional prototype.</p>



<h2>What&#8217;s great about prototypes?</h2>



<p>Prototypes can be fantastic. Why? Prototypes encourage taking hard shortcuts in order to get a working idea out and to be tested. </p>



<p>For example, if you wanted to create a prototype for an image gallery app, you might heavily rely on off-the-shelf products in order to get you to the finish line as quickly as possible. You might cut corners on testing, cut corners on the development experience and so on. </p>



<p>You&#8217;re testing the image app idea and the only thing that matters is having a final product to show users in order to get feedback. Do people want a gallery app? Does it have any advantages over existing solutions? How does it differentiate? What technical challenges do you foresee after building the prototype?</p>



<p>The biggest advantage over regular development is that you don&#8217;t have to care about the details, you only care about the idea you&#8217;re testing and getting there. This means you get to develop faster and spend less time yak shaving.</p>



<p>And then you throw it out. </p>



<blockquote class="wp-block-quote"><p>You take the knowledge you&#8217;ve acquired from development and feedback, and then you craft a long-term solution from scratch based on that information.</p></blockquote>



<h2>What&#8217;s terrible about them?</h2>



<p>That last part, the &#8220;throw it out part&#8221;. Let me show you something:</p>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/01/prototype-1.png" alt="github screenshot of landdox-prototype repository"/></figure>



<p>I&#8217;ve been working on a &#8220;prototype&#8221; for 4 years. There are nearly 14,000 commits, nearly a dozen contributors over the years, 1300 releases. We&#8217;re on major version 9.x (we don&#8217;t follow semver but each major bump is a HUGE feature or huge rewrite). </p>



<p>The problems with prototypes have more to do with &#8220;culture&#8221; than anything else but the problems (in my head) are insurmountable in most cases:</p>



<ol><li>prototypes often work and look &#8220;good enough&#8221; to encourage people to keep it instead of rewriting it</li><li>deadlines often push against the idea of rewriting prototypes</li><li>management sometimes doesn&#8217;t understand the idea of a &#8220;prototype&#8221; fully. If they see a functional product, they&#8217;re expecting &#8220;the final product&#8221; to take less time than the prototype took to develop.</li></ol>



<p>The reason I stuck with a &#8220;prototype&#8221; for 4 years is because when it was time to do a rewrite, it no longer made sense. Things were &#8220;good enough&#8221;, we were a startup, we were burning bootstrapped money, and I made the development decision not to rewrite but instead focus on delivering features to clients.</p>



<p>I see developers trapped in this time and time again. &#8220;I&#8217;m testing out an idea&#8221; more often than not turns to having crap code with cut corners making it to production.</p>



<p>So my rule is:</p>



<blockquote class="wp-block-quote"><p>Expect a prototype to become the basis for your final product. Expect your prototype to never be thrown away even though it should be.</p></blockquote>



<h3>An aside: what developers do to make prototypes to be more likely to be thrown away</h3>



<p>This is semi funny but after talking to other developers, reading articles, and listening to podcasts, I&#8217;ve found an interesting pattern. Developers will create a prototype a specific way in order for it to be more likely to be thrown out using methods such as:</p>



<ol><li>naming variables horrible things so that no one wants to work on the code base</li><li>using an unknown library/framework incompatible with existing products</li><li>writing it in a language no one else is comfortable using &#8212; thus making the prototype useless long term</li><li>naming the repository silly names (guess what? Naming something &#8220;prototype&#8221; apparently doesn&#8217;t work! <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f62d.png" alt="😭" class="wp-smiley" style="height: 1em; max-height: 1em;" />)</li><li>using jQuery for a single page application prototype</li><li>using PHP in a non-PHP shop for server/back-end prototype </li></ol>



<p>Don&#8217;t try the last one on me because I like PHP.</p>



<h3>An exception to my depressing rule</h3>



<p>If you have a culture centered around prototype development, then the downsides of prototypes don&#8217;t exist. I know some developers that are used to doing prototypes and spikes without the drawbacks of having to use them in production.</p>



<p>This can be fantastic. But it takes time and energy and investment to setup that culture.</p>



<h2>A better alternative &#8212; Tracer code</h2>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/02/rawpixel-788527-unsplash-e1550681691133.jpg" alt="building plans"/></figure>



<p>There&#8217;s a decent <a href="https://stackoverflow.com/questions/4047335/tracer-bullets-vs-prototypes">short discussion on tracer bullets</a> on StackOverflow but the gist is this:</p>



<blockquote class="wp-block-quote"><p>Tracer code is not disposable: you write it for keeps. It contains all the error checking that any piece of production code has. It simply is not fully functional.</p></blockquote>



<p>To break this down to the important components:</p>



<ol><li>tracer is not disposable.</li><li>tracer is written similarly to production code</li><li>a tracer doesn&#8217;t have to be fully functional</li><li>a tracer is meant to be the base for the final product</li></ol>



<p>You can already spot the differences and advantages.</p>



<p>Tracers are great for testing out ideas that you plan on having in the production environment. They&#8217;re different from prototypes in that you should be more &#8220;sure&#8221; in your idea. Tracers aren&#8217;t disposable. </p>



<p>In my mind, they&#8217;re supposed to be one of the final steps in building out a solution. A tracer ensures that your idea for a solution <em>will work</em> in a production environment. This is after you decide on architecture, after you ensure that your ideas are sound, and after you plan things out. But before you write any code.</p>



<h2>Good Tracer practices</h2>



<p>If you&#8217;re testing out a framework or a new language, you wouldn&#8217;t use a tracer. You&#8217;d use it to ensure that framework/language works for that one specific purpose in your application &#8212; and use that tracer as breaking ground for further development.</p>



<p>But here is my list of Tracer practices:</p>



<ol><li>stubbing out functionality is okay as long as you have a solid plan for extending that stub</li><li>you don&#8217;t necessarily have to have tests, but write code as if you did</li><li>the most important code you write are the interfaces/endpoints which other code interact with</li><li>don&#8217;t leave major changes for &#8220;later&#8221;</li></ol>



<p>The last one is especially important. When working on prototypes, it&#8217;s easy to leave things for &#8220;later&#8221;. If you&#8217;re planning on writing code that&#8217;ll live on in your codebase, you need to recognize when your code has gone awry and already needs a rewrite.</p>



<p>This is hard but these small rewrites pay off in the end. I&#8217;ve had this happen several times recently and while I was kicking myself in the butt for making an assumption that lead me to write code I had to rewrite, it was worth it because it saved me from writing legacy/bad/broken code before it even ships. </p>



<h2>Bad Tracer Practices</h2>



<p>Every practice has its issues and every practice has footguns. A footgun is essentially a &#8220;thing&#8221; that is seemingly designed to help you fail as badly or as quickly as possible. </p>



<p>So if you&#8217;re getting used to the idea of writing tracers, here&#8217;s what to watch out for:</p>



<h3>Tight coupling with existing code</h3>



<p>Tracers should ideally be semi-isolated systems that expose some interface or endpoint for other code to use. For example, if you&#8217;re writing a &#8220;tracer&#8221; focused on building out a helper toolbar for your app, it shouldn&#8217;t dive too deeply into existing code to modify store values, or state management, or change how services work which would impact the rest of your app. </p>



<p>It <em>can</em> rely on existing services, but you shouldn&#8217;t be making major changes to your main codebase. </p>



<h3>Vague focus</h3>



<p>Whilst prototypes encourage exploration, tracers are more focused. If you can&#8217;t identify the end-product of your effort, you shouldn&#8217;t be writing a tracer. You should probably do more research.</p>



<p>For example, a tracer shouldn&#8217;t be something &#8220;give management ability to increase conversion by changing things on the site&#8221;. No, it should be &#8220;create a feature wherein a manager can create an A/B test via simple CSS that is tracked via our analytics suite&#8221;.</p>



<p>Without a focus, you don&#8217;t really know what you&#8217;re writing. If you don&#8217;t know what you&#8217;re coding, you&#8217;re not writing a tracer.</p>



<h3>Fear of throwing away bad code</h3>



<p>This is that footgun I was referring to. Tracer are not meant to be thrown away but that doesn&#8217;t mean you can&#8217;t adjust course. Or bend the rules.</p>



<p>It&#8217;s happened to me several times before where scope changed over the course of coding a new feature. It&#8217;s not meant to happen, you should be pretty sure of what you&#8217;re trying to do beforehand, it doesn&#8217;t mean that you&#8217;d either finish a feature you no longer need, or try to avoid a rewrite just because this article says so. <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f937-200d-2640-fe0f.png" alt="🤷‍♀️" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2>A personal example</h2>



<p>This whole article is fairly vague. It&#8217;s hard to actually write code snippets that demonstrate the differences or to describe an exact feature where you&#8217;d apply one concept over another.</p>



<p>However, I have quite some experience writing both tracers and prototypes. Both in my personal projects and at work.</p>



<p>I have a couple of personal projects that I&#8217;d like to share some info about to demonstrate the difference between a prototype and a tracer.</p>



<h3>OMEN</h3>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/02/omen.png" alt="Omen screenshot"/></figure>



<p>OMEN was my markdown editing environment. Think IDE but for writers and in markdown, similar to Scrivener if you know it. I took the prototype approach, mainly because it made sense. I was working with a brand new stack: Angular 2 (which I had limited experience in), Electron (again, limited experience), and CodeMirror for editing (no experience).</p>



<p>All three technologies were new and before fully testing them out and learning about them, I took my limited experience and ran with it. I wanted to get <em>something</em> out.</p>



<p>So, I tirelessly worked on getting an MVP out. I picked an approach and immediately used it just to get that end-product that I could use to write a book (and I wrote a good 30K words in it!). I took really bad shortcuts. The developer experience sucked (and made me not want to return). My store had an architecture where I coded myself into a corner. And on top of it, CodeMirror wasn&#8217;t exactly what I needed.</p>



<p>I abandoned the project but learned SO MUCH about writing an editor. I really loved it and I took what I knew to my next project. I used my new-found Angular 2 knowledge to push our product at work to Angular 2. I learned enough about Electron where my next Electron use was pretty straightforward.</p>



<h3>Skok</h3>



<figure class="wp-block-image"><img src="https://antjanus.com/wp-content/uploads/2019/02/skok-screenshot.png" alt="Skok screenshot"/></figure>



<p>Skok was a recent project that I&#8217;m still working on. It&#8217;s a desktop photo manager app. I used a slightly different stack than with OMEN but I stuck to Electron.</p>



<p>And I did everything right because I took the time to research, plan it, and drill into my head that this isn&#8217;t to throw away. It made me acutely aware of places where I wanted to cut corners just to get that pre-Alpha out. Instead, I planned for the long-term.</p>



<p>I built a great architecture around Electron &lt;-&gt; React interactions, and I focused on the developer experience so that the project was pleasant to work with.</p>



<p>At the same time, I had a very tight focus on a minimal setup. My plan was: scan, display photos, and setup for more features. And I did. I got the initial photo indexing and photo viewing down very quickly and when I started working on more features, it was easy to plug them in.</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/thoughts-and-opinions/prototypes-dont-get-thrown-out-write-tracer-bullet-code-instead/">Prototypes Don&#8217;t Get Thrown Out &#8212; Write Tracer (Bullet) Code Instead</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/thoughts-and-opinions/prototypes-dont-get-thrown-out-write-tracer-bullet-code-instead/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4226</post-id>	</item>
		<item>
		<title>The Books That Made All The Difference To Me As A Developer</title>
		<link>https://antjanus.com/blog/reviews/the-books-that-made-all-the-difference-to-me-as-a-developer/</link>
					<comments>https://antjanus.com/blog/reviews/the-books-that-made-all-the-difference-to-me-as-a-developer/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Wed, 13 Feb 2019 17:24:34 +0000</pubDate>
				<category><![CDATA[Reviews]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4218</guid>

					<description><![CDATA[<p>This question pops up on every form of media out there. &#8220;What books should I read to be a better developer?&#8221;. I&#8217;ve answered this a ton of times. On Twitter, on Dev.To, Reddit, and everywhere else. I figured it might be a good idea to put the list in a single post I can always [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/reviews/the-books-that-made-all-the-difference-to-me-as-a-developer/">The Books That Made All The Difference To Me As A Developer</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>This question pops up on every form of media out there. &#8220;What books should I read to be a better developer?&#8221;. I&#8217;ve answered this a ton of times. On Twitter, on Dev.To, Reddit, and everywhere else.</p>



<p>I figured it might be a good idea to put the list in a single post I can always link to. </p>



<p><strong>Note:</strong> I <em>am</em> using Amazon affiliate links where I link to the books.</p>



<h2><a href="https://amzn.to/2ssYoDu">Clean Code: A Handbook of Agile Software Craftsmanship</a></h2>



<p>While this book might be considered quite old at this point, it&#8217;s still very much on point when it comes to creating maintainable code. Some of its principles I no longer agree with but it really drives the importance of planning out code and writing it so that it&#8217;s much easier to maintain in the future. A few bits that still stick with me:</p>



<ol><li>if a function has more than 2-3 arguments, split it up. That&#8217;s way too many arguments</li><li>keep functions short, easy to understand, and focused on a single goal</li><li>test driven development</li><li>use meaningful names</li></ol>



<p>There&#8217;s so much more to learn from the book and it has become a staple among programmer. </p>



<p>If you don&#8217;t feel like reading it or can&#8217;t/won&#8217;t pay for a copy, look up the book title and you&#8217;ll find plenty of videos and articles of people discussing the various important parts of the book</p>



<h2><a href="https://amzn.to/2Crujc4">The Pragmatic Programmer: From Journeman To Master</a></h2>



<p>I&#8217;m still about halfway through this book. This book is amazing for anyone starting out a career in development &#8212; and anyone well into it. I found it shows and explains various scenarios you&#8217;d find in the real world and then it discusses strategies to tackle them. It features tons of ideas about how to keep your code clearly separated, how to think about concurrency, how to address code that needs to clean itself up, and so on.</p>



<p>Probably my favorite part of the book is the discussion around what &#8220;prototypes&#8221; are for, how to use them, and so on. And then it discusses the idea of a &#8220;tracer bullet&#8221; (which I&#8217;ve discussed in my post <a href="https://antjanus.com/blog/thoughts-and-opinions/experience-running-development-startup/">My Experience Running Development At A Startup</a>) and totally won me over and changed how I do development.</p>



<h2><a href="https://amzn.to/2VW0bib">Game Programming Patterns</a> &#8211; <a href="http://gameprogrammingpatterns.com/contents.html">GMP free to read on the web</a></h2>



<p>Before I get into it, you might be thinking, but why <em>game</em> programming? I&#8217;m a web developer and this book is just as relevant to web devs as it is for game devs. This book is by far the best resource I&#8217;ve found that discusses common (and well-known) programming patterns &#8212; from their advantages, to their drawbacks, trade-offs, and their details. All neatly written to be easy to understand.</p>



<p>There are quite a few that I absolutely recommend reading about:</p>



<ol><li>Object pool</li><li>Dirty Flag</li><li>Singleton &#8212; because that&#8217;s how your node imports work!</li><li>Observer</li></ol>



<p>I also suggest reading the <code>game loop</code> and <code>update method</code> patterns if you&#8217;re into gaming.</p>



<h2><a href="https://amzn.to/2tj3gLZ">Non-Violent Communication</a></h2>



<p>This might seem off-beat but despite being a non-programming book, I found it extremely useful in terms of communication and applying empathy to my work. Not only that, but I found it useful in my interactions with my teammates and my other co-workers. It covers a few key concepts:</p>



<ol><li>how to ensure both parties are in full understanding of a concept</li><li>applying empathy in stressful situations</li><li>value of honesty</li><li>value of expressing your own needs</li></ol>



<p>All of those have been key in my career in one way or another. Here&#8217;s a dirty secret: my own team focused on communication with each other and with our manager heavily. Improved communication lead to greater job satisfaction (personally) but it also lead to better code, feature releases, better conversations around development roadmaps, and so much more. We didn&#8217;t use NVC but we did make big changes into how we&#8217;re organized</p>



<h2>Books I haven&#8217;t Read (Yet)</h2>



<p>I have a stack of books in my GoodReads that I want to read, and even a longer stack of books I keep in my head. I can&#8217;t personally vouch for these but I do see these come up over and over again on Twitter, here, and elsewhere:</p>



<h3><a href="https://amzn.to/2N2fv8E">CSS Secrets</a></h3>



<p>A book that made waves when it dropped, CSS Secrets by Lea Verou is a book focusing on techniques and tips and programmatic solutions to your CSS problems and how to practically write CSS. If you&#8217;re not sure this is for you, <a href="https://www.youtube.com/watch?v=8BXQ3zCihYM">check out one of her many talks</a>.</p>



<h3><a href="https://refactoringui.com/book/">Refactoring UI</a></h3>



<p>Refactoring UI by Adam Wathan and Steve Shoger has been making rounds on my radar and I think it&#8217;s a worthwhile book to look into. I haven&#8217;t personally had time to check it out but I&#8217;ve heard of Adam&#8217;s courses that people love and I have closely followed the development of <a href="https://tailwindcss.com/docs/what-is-tailwind/">Tailwind CSS</a> which is his CSS framework.</p>



<h2>Got any books you&#8217;d like to recommend?</h2>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/reviews/the-books-that-made-all-the-difference-to-me-as-a-developer/">The Books That Made All The Difference To Me As A Developer</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/reviews/the-books-that-made-all-the-difference-to-me-as-a-developer/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4218</post-id>	</item>
		<item>
		<title>How did 2018 Go, and What Now?</title>
		<link>https://antjanus.com/blog/thoughts-and-opinions/yearly-review/how-did-2018-go-and-what-now/</link>
					<comments>https://antjanus.com/blog/thoughts-and-opinions/yearly-review/how-did-2018-go-and-what-now/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Wed, 28 Nov 2018 04:57:01 +0000</pubDate>
				<category><![CDATA[Thoughts and Opinions]]></category>
		<category><![CDATA[yearly review]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4193</guid>

					<description><![CDATA[<p>It&#8217;s that time of the year again! What part you ask? It&#8217;s time for a end-of-the-year retrospective, a check-in wherein I look back at what I&#8217;ve done, how I&#8217;m doing with my goals that I set out at the beginning of the year, and most importantly, add a new post to my blog so that [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/thoughts-and-opinions/yearly-review/how-did-2018-go-and-what-now/">How did 2018 Go, and What Now?</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>It&#8217;s that time of the year again! What part you ask? It&#8217;s time for a end-of-the-year retrospective, a check-in wherein I look back at what I&#8217;ve done, how I&#8217;m doing with my goals that I set out at the beginning of the year, and most importantly, add a new post to my blog so that it doesn&#8217;t look like it&#8217;s dead.</p>



<p>Just kidding!</p>



<p>So first, this is a blog post in a pretty long series of personal updates that I started back in 2012 (and probably before that on my old blog). It has always given me the focus I needed to look back without judgement or bias, and organize my thoughts on what I&#8217;ve been up to.</p>



<p>Let&#8217;s review 2018 goals real quick.</p>



<h2>Original goals progress</h2>



<p>In summary:</p>



<ul><li>Website redesign</li><li>Hugo blog</li><li>ng-redux support</li><li>unity tutorials</li><li>finish several personal projects<ul><li>D20 Elixir bot</li><li>Slack proverbs</li><li>Quick pomodoro</li><li>Dashboard</li><li>Newsletter revival</li><li>app ideas repo</li></ul></li></ul>



<p>So, errr….I didn&#8217;t get any of this done. I spent some time on <code>ng-redux</code> and pushed out a 4.X release but that&#8217;s about it. I didn&#8217;t get a newsletter together, I didn&#8217;t work on Unity. I basically just abandoned all of my goals in various states of disarray.</p>



<p>I <em>do</em> have a newsletter setup but I don&#8217;t use it. I keep wanting to use it but given how long this article took to write, it&#8217;s obvious I&#8217;m unlikely to write in any sort of regular capacity using a newsletter. </p>



<p>I&#8217;ve been <em>thinking</em> about a redesign but never did it. In fact, I abandoned the idea of migrating my site away from WordPress. Too much work, not enough pay off. I briefly tried to make GatsbyJS work with Netlify on my <a href="https://antjan.us">antjan.us</a> domain but even that I struggled to keep working. </p>



<p>These days, I rarely ever dive into side projects. You might ask why. Well…</p>



<h3>Fulfillment at work</h3>



<p>One of the reasons I&#8217;ve always gravitated toward side projects has been the work environment. Either work was really stressful and thus I couldn&#8217;t enjoy development, or there was a technology I wanted to try but couldn&#8217;t, or I&#8217;d just plain find my job boring.</p>



<p>One of the biggest changes at my job since January has been hiring several developers. We&#8217;re a team of six right now. That&#8217;s a big dev team for a small startup. And instead of scrambling to push features out, we&#8217;ve become a machine moving ever-forward. We&#8217;ve been rewriting the original app I wrote: both back-end and front-end. And we&#8217;ve been rewriting it in technology that I&#8217;ve enjoyed using: Angular and Elixir.</p>



<h3>Angular</h3>



<p>I used to write my side projects in Angular or React. And that was fun but a production environment is truly fulfilling. It requires deep thought, organization, future-thinking, and requires a consensus among the team. That has been driving me forward with my front-end development without really pushing me away to learn/use something different.</p>



<p>Don&#8217;t get me wrong, I&#8217;ve written some React/Preact here and there but there&#8217;s nothing like writing a nice component in Angular that fits into a larger codebase which customers use every single day.</p>



<p>Writing for a production environment also means that this is part of my work and I don&#8217;t have to sacrifice my much-lacking free time to use this technology.</p>



<h3>Elixir</h3>



<p>The back-end work has been great too. For years, I&#8217;ve been on the fence about what new language to learn. I&#8217;ve been coding a Discord bot in Golang for the past year but that&#8217;s been about it. I&#8217;ve tried Elixir but failed. Then, one of our developers wanted to rewrite our codebase in it for its various advantages over JavaScript/Node. Our entire team rallied behind the effort and now, all new features go through our Elixir app.</p>



<p>Elixir is a lot of fun and doesn&#8217;t take a huge amount of time to learn. It&#8217;s the nuances of app development that really get you. The idea of separating apps, the idea that everything is a thread or something, that async stuff happens asynchronously but you don&#8217;t know that. Unlike in JS, where you have to manage asynchronicity.</p>



<p>There&#8217;s no way I could mount such a huge effort in my spare time to build an app that&#8217;d really test my skills and teach me how to use Elixir so this has been a ton of fun for me and has helped our development as well. We didn&#8217;t just write in Elixir for the writing in Elixir. We use its benefits to benefit our product.</p>



<h3>Team Work</h3>



<p>It might seem silly but team work and a positive developer experience can bring about fulfillment as well – even more so than the technology you might use. </p>



<p>We&#8217;ve switched to Docker at work and slowly reversed/fixed a lot of mistakes and holes in the workflow I&#8217;ve setup years ago. Right now, we have two separate apps that seamlessly interact locally and in production. We have a deployment workflow that smooths over any bumps along the way.</p>



<p>On top of that, we do dev meetings that really scratch the itch when it comes to progress, fixing and analyzing problems, and steering development in a positive direction.</p>



<p>All of this combined with awesome people on the development team.</p>



<p>I should mention that a lot of the &#8220;problems&#8221; we analyze and try to fix have to do with more than the Elixir/JS we write. We have been tackling project management, team structures, feature planning, and so on. So that satisfies the productivity junkie in me as well.</p>



<p>Things aren&#8217;t perfect but they&#8217;re definitely really good.</p>



<h2>Unexpected progress</h2>



<h3>Content</h3>



<p>The one thing I did that was unexpected was post several blog posts this year. I&#8217;ve been out of the blogging game for a while and writing anything was an accomplishment. I blame <a href="https://dev.to">Dev.to</a> for that, it&#8217;s a content/blogging platform for developers.</p>



<p>Scroll back through my feed and even check out my <a href="https://twitter.com/antjanus">Twitter</a> for some good content as well. I&#8217;m really active on there.</p>



<p>Outside of that, my Youtube channel is seeing some love with org-mode related videos and more.</p>



<h3>Org-mode</h3>



<p>I finally dove into org-mode. I killed off my old <code>.emacs</code> earlier this year and started from scratch. My config is super short and is used to enable some small options and include the bare minimum of packages I need for my daily use. </p>



<p>Over time, I learned Emacs and I learned to use it using its defaults, not via evil-mode, or thorugh spacemacs or other packages. What was great about that is that I&#8217;m writing this article via Emacs using absolute defaults. And it&#8217;s nice.</p>



<p>My &#8220;main&#8221; installation with its config works really well and I can always lean on generic emacs articles/youtube videos without having to worry about defaults having been messed with. </p>



<p>I still don&#8217;t use Emacs for development; however, Emacs + org-mode has pretty much replaced all of my todo apps, note-taking apps, etc.</p>



<h3>Engineering Notebook</h3>



<p>As part of migrating to org-mode, I&#8217;ve also started a software engineering notebook. I hope I can stick with it because it&#8217;s been pretty useful to look up error messages in my own personal notebook where I document solutions for problems I run into.</p>



<p>I hope to one day make it publicly available.</p>



<h2>New Goals?</h2>



<p>Confession time, I started writing this article <em>months</em> ago but I couldn&#8217;t finish it. Now that the year is coming to a close, I decided to update it. Originally, this section was empty with a quick explanation that I&#8217;m focusing on personal development goals (development as in personal growth) rather than tech goals.</p>



<p>A few things have changed since then so I figured I&#8217;d share:</p>



<h3>try to become a development instructor</h3>



<p>Between the YouTube videos I&#8217;ve been making, the Tweets I&#8217;ve been tweeting, and some encouragement from a friend, I found myself wanting to enter the game of teaching development rather than just consuming articles.</p>



<p>I&#8217;ve been on this path toward instructor-ship for a while and now it&#8217;s become a bigger goal for me.</p>



<h3>one side app</h3>



<p>I <em>do</em> miss side project development. One of my big issues has been focusing on one project and the idea that when I don&#8217;t have time to work on it, dependencies and the code goes to hell quickly.</p>



<p>I&#8217;m thinking of building a single app but I have three big ideas, each one with its own merits, each one having to do with a personal goal as well.</p>



<p>So here are the ideas:</p>



<ul><li>Skok &#8211; a photo management app whose main purpose is to take haphazardly put-together folders of photos and sort them out</li><li>Omen &#8211; my markdown editor that I started a couple of years back. But this time, I&#8217;d like to finish it!</li><li>Chislo &#8211; a super simple  budgetting/finance app</li></ul>



<figure class="wp-block-image is-resized"><img loading="lazy" src="https://antjanus.com/wp-content/uploads/2018/11/2018-personal.jpg" alt="" class="wp-image-4197" width="957" height="402" srcset="https://antjanus.com/assets/2018/11/2018-personal.jpg 3827w, https://antjanus.com/assets/2018/11/2018-personal-300x126.jpg 300w, https://antjanus.com/assets/2018/11/2018-personal-768x323.jpg 768w, https://antjanus.com/assets/2018/11/2018-personal-1024x430.jpg 1024w" sizes="(max-width: 957px) 100vw, 957px" /></figure>



<h2>2018 Personal</h2>



<h3>Goals Review</h3>



<p>So last year, I had a few goals, nothing special; however, I did not get to most of those. My 52 sprint idea did not work out whatsoever. </p>



<p>But here&#8217;s the final tally:</p>



<ul><li>[X] finish Season 1 of Indigo League review for PUCL</li><li>[X] vlogging/video creation</li><li>[X] chore completion</li><li>[X] back to working out &#8211; I&#8217;ve been semi-regularly running!</li><li>[X] productivity prioritization</li><li>[ ] get finance in order</li><li>[ ] publish NaNo 2014</li><li>[ ] publish NaNo 2016</li></ul>



<p>And some unexpected progress: </p>



<ul><li>a good deal of gaming I&#8217;ve been meaning to get to</li><li>way more fiction writing than I expected to do</li><li>NaNo (idk which year) editing – currently on Chapter 6 out of 14</li></ul>



<h3>TV Shows and Movies</h3>



<h4>TV Shows</h4>



<p>I watched quite a few fun TV shows but for some reason, I can&#8217;t recall most of them so here&#8217;s what I do remember watching:</p>



<ul><li>Supernatural</li><li>Rick &amp; Morty</li><li>Handmaid&#8217;s Tale</li><li>Naruto Shippuden</li><li>Dragon Ball Super</li><li>Disenchantment</li><li>Badlands</li><li>The New Legends of Monkey</li></ul>



<h4>Movies</h4>



<p>I remember which movies I watched even less than which TV shows. I rewatched a ton of stuff I liked a while back and reaffirmed that I still like those movies:</p>



<ul><li>DOOM</li><li>The Matrix trilogy</li><li>All of Harry Potter</li><li>Lord of the Rings and the Hobbit (both trilogies)</li><li>Star Wars: Han Solo story &#8211; loved it!</li><li>Beyond Skyline</li></ul>



<h3>Podcasts</h3>



<ul><li><a href="https://soundcloud.com/ngppodcast">New Game Plus</a></li><li><a href="https://www.puclpodcast.com/">PUCL Podcast</a></li><li><a href="https://www.facebook.com/nerdpokerpodcast">Nerd Poker</a></li><li>Changelog</li><li>Cortex</li></ul>



<h3>Books</h3>



<p>Finished:</p>



<ul><li>1Q84</li><li>Star Wars The New Jedi Order: Vector Prime</li><li>Insecure In Love</li></ul>



<p>Still reading:</p>



<ul><li>Non Violent Communication</li><li>A House Divided</li><li>Return Of The King</li></ul>



<h3>Music</h3>



<p>The past few years, I&#8217;ve posted individual songs, and while I <em>can</em> do that this year, I&#8217;d like to share the Spotify playlists that I&#8217;ve aggregated throughout the year:</p>



<ul><li><a href="https://open.spotify.com/user/antjanus/playlist/6egbboy2Szmp1yJLwdZ2Az?si=kNNsLuxIS72WI3aM_2JGqA">2018 Favorites</a></li><li><a href="https://open.spotify.com/user/antjanus/playlist/2lzzcu1qwbVCgvU453VuXJ?si=F5lZNXmST-GsnIa-sfHSUg">Secondary 2018 favorites</a> – to mix things up</li><li><a href="https://open.spotify.com/user/antjanus/playlist/1ltxzZnXNJAwgdEj9kg36V?si=jhaIXUhyTR2hKx6znFXfZw">2018 Explicit favorites</a> – I try to keep songs with any explicit lyrics in this playlist</li><li><a href="https://open.spotify.com/user/spotify/playlist/37i9dQZF1DZ06evO2VWEAK?si=-9WDpuZ7TCeCzDLN43bp4w">This is Tryo</a> &#8211; not my own playlist but this is the music I started my day off to</li></ul>



<h3>Games</h3>



<p>Playing/Played A Bunch/Finished: </p>



<ul><li>Overwatch</li><li>Stardew Valley</li><li>A Bird Story – finished</li><li>Sonic Forces (Switch)</li><li>Paladins (on Switch)</li><li>Chrono Trigger</li><li>Blockout II</li><li>Halo: Combat Evolved</li><li>Torchlight</li></ul>



<p>Somewhat played/barely any progress:</p>



<ul><li>Might &amp; Magic VII: For Blood and Honor</li><li>Hexen</li><li>Harry Poter And The Philosopher&#8217;s Stone</li><li>Diablo</li><li>Commander Keen</li><li>Super Mario Land 2</li></ul>



<h3>Personal Goals for 2019</h3>



<p>My biggest takeaway from life this year has been the importance of focusing one&#8217;s own development and how that solid foundation of &#8220;self&#8221; can translate outwardly as well. </p>



<p>But here are a few things I&#8217;d like to do:</p>



<h4>general life management</h4>



<p>That includes:</p>



<ul><li>finance management</li><li>chores</li><li>and other responsibilities</li></ul>



<p>I&#8217;ve considered writing an app but it&#8217;d be too broad for anyone else to use. My main issue is that to manage my own life, I have to have either a very complicated system in a single app or spread everything out across too many apps.</p>



<h4>continue running</h4>



<p>Possibly run a 7K (I&#8217;ve got a 5K down pretty easy!) but I don&#8217;t feel confident that I can hit a 10K just yet. I&#8217;m not training in any way and simply run when I have time and feel the need to. Running a 10K would be quite difficult.</p>



<h4>NaNoWriMo 2019</h4>



<p>I&#8217;m not sure what I&#8217;ll write but I definitely have the goal to write yet another book. My hope is to make a standalone novel that doesn&#8217;t plug into any universe, story, or book I&#8217;ve already written.</p>



<h4>Edit NaNoWriMo 2014/2016</h4>



<p>I&#8217;ve been editing this book for a LONG time; however, I made some true progress this year. I&#8217;m at least a third way through my final editing pass and after that I&#8217;ll be bracing myself for some awkward self-publishing.</p>



<p>The quite <em>wonderful</em> thing about this is that my 2018 NaNoWriMo is a sequel.</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/thoughts-and-opinions/yearly-review/how-did-2018-go-and-what-now/">How did 2018 Go, and What Now?</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/thoughts-and-opinions/yearly-review/how-did-2018-go-and-what-now/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4193</post-id>	</item>
		<item>
		<title>Keep Your Types And Interfaces Closer (In TypeScript)</title>
		<link>https://antjanus.com/blog/web-development-tutorials/front-end-development/keep-your-types-and-interfaces-closer-in-typescript/</link>
					<comments>https://antjanus.com/blog/web-development-tutorials/front-end-development/keep-your-types-and-interfaces-closer-in-typescript/#respond</comments>
		
		<dc:creator><![CDATA[Antonin Januska]]></dc:creator>
		<pubDate>Fri, 23 Nov 2018 07:11:19 +0000</pubDate>
				<category><![CDATA[Front End]]></category>
		<guid isPermaLink="false">https://antjanus.com/?p=4187</guid>

					<description><![CDATA[<p>I&#8217;ve been writing production TypeScript for a little over year and as a hobby for a couple of years longer than that. If you&#8217;ve never used TypeScript before, the quick way to describe it is that it&#8217;s ES2015+ and types thrown together. Ie. modern JavaScript with real typing. TypeScript is awesome and I love writing [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/front-end-development/keep-your-types-and-interfaces-closer-in-typescript/">Keep Your Types And Interfaces Closer (In TypeScript)</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;ve been writing production TypeScript for a little over year and as a hobby for a couple of years longer than that. If you&#8217;ve never used TypeScript before, the quick way to describe it is that it&#8217;s ES2015+ and types thrown together. Ie. modern JavaScript with real typing.</p>



<p>TypeScript is awesome and I love writing it and over time, I&#8217;ve noticed my own style and my own patterns emerge one of which I&#8217;d like to share and, hopefully, justify why I stick to those patterns.</p>



<h2>Local Interfaces &gt; Global Interfaces</h2>



<p>Interfaces in TypeScript are essentially object definitions that describe what an object should minimally look like. For example, if I had a <code>DatabaseConfig</code> interface, it might look something like this:</p>



<pre class="wp-block-code"><code>interface DatabaseConfig {
  host: string,
  port: number,
  password: string
}

function connectToDb(dbConfig: DatabaseConfig) {
  // database connection config
}</code></pre>



<p>What that basically means is that whenever you call the function <code>connectToDb</code>, you need to pass in an object that looks like the <code>DatabaseConfig</code> interface (along with the appropriate typings for its properties).</p>



<p>A pattern I picked up from a Golang styleguide article (I can&#8217;t remember which) was the idea of &#8220;local interfaces&#8221;, interfaces that describe exactly what I need from an object within that single file.</p>



<p>This <code>DatabaseConfig</code> interface, if shared, will grow exponentially to encompass the needs of every function that might touch this object. A <code>createDatabasePool</code> function might additionally look for a <code>poolSize</code> property on that config which will now be required by every function that references this interface, whether they use it or not. Imagine that we also had a function that would return a driver for that particular database so we might need a <code>type</code> property which no function cares about except the driver one.</p>



<p>Basically, sharing interfaces (or using what I call <code>global interfaces</code>) causes interfaces to bloat and to impose artificial requirements on properties that might not even be used by the function/code block/whatever that references the interface. It creates a strange &#8220;coupling&#8221; between possibly unrelated pieces of code.</p>



<p>Instead, what I suggest is writing interfaces local to a file which describe only the necessary properties required to be in the object by the code in that file. Eg. if you have a <code>createPool</code> function, you might write something like this:</p>



<pre class="wp-block-code"><code>interface PoolConfig {
  poolSize: number
}

export function createPool(config: PoolConfig, driver) {
  // uses config.poolSize somewhere in the code
}</code></pre>



<p>This way, we&#8217;re telling the developer working in that file that all we really need is <code>poolSize</code> and we don&#8217;t use anything else from that config object.</p>



<p>I&#8217;ve found this to be super useful in keeping with the idea that types are really just documentation that the computer can also view and utilize.</p>



<h2>Exceptions</h2>



<p>There are a couple of exceptions to this rule.</p>



<p>Those exceptions are that if you&#8217;re using object Models for your data, you might want to have those models available as interfaces as well to communicate to the developer (and the compiler) that you&#8217;re really requiring this model. </p>



<p>You might not care about the exact keys, you might care more about getting the actual Model (or something with the exact same shape).</p>



<p>The other exception to the rule is if you have complex objects that require keeping up with its complex shape. Imagine that you have an object that nests 5 levels deep. It&#8217;s more prudent to have a single interface that you import which describes this rather than writing out, quite uselessly, complex nested interfaces.</p>
<p>The post <a rel="nofollow" href="https://antjanus.com/blog/web-development-tutorials/front-end-development/keep-your-types-and-interfaces-closer-in-typescript/">Keep Your Types And Interfaces Closer (In TypeScript)</a> appeared first on <a rel="nofollow" href="https://antjanus.com">AntJanus</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://antjanus.com/blog/web-development-tutorials/front-end-development/keep-your-types-and-interfaces-closer-in-typescript/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4187</post-id>	</item>
	</channel>
</rss>
