<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[I Am NotMyself]]></title><description><![CDATA[I enjoy playing guitar and building things with my brain.]]></description><link>https://iamnotmyself.com/</link><image><url>https://iamnotmyself.com/favicon.png</url><title>I Am NotMyself</title><link>https://iamnotmyself.com/</link></image><generator>Ghost 5.92</generator><lastBuildDate>Sat, 09 Nov 2024 19:24:30 GMT</lastBuildDate><atom:link href="https://iamnotmyself.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Beginner Theory: Learning the Fretboard Exercise I]]></title><description><![CDATA[<p>I have been reading <a href="https://www.guitarmusictheory.com/?ref=iamnotmyself.com">Desi Serna</a>&apos;s <a href="https://www.amazon.com/Fretboard-Theory-Volumes-Combined-progressions/dp/1542403227/?ref=iamnotmyself.com">Fretboard Theory</a> book. The very first thing he asks you to do in the first chapter is to learn the natural notes on the 6th and 5th strings.They look something like this:</p><p>E String:</p><ul><li><strong>EF-G-A-BC-D-E</strong> -&gt; up the neck</li><li><strong>E-D-CB-A-G-FE</strong></li></ul>]]></description><link>https://iamnotmyself.com/beginner-theory-learning-the-fretboard-exercise-i/</link><guid isPermaLink="false">63f3b7183f7922037df10eae</guid><category><![CDATA[Guitar]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Mon, 20 Feb 2023 18:10:38 GMT</pubDate><content:encoded><![CDATA[<p>I have been reading <a href="https://www.guitarmusictheory.com/?ref=iamnotmyself.com">Desi Serna</a>&apos;s <a href="https://www.amazon.com/Fretboard-Theory-Volumes-Combined-progressions/dp/1542403227/?ref=iamnotmyself.com">Fretboard Theory</a> book. The very first thing he asks you to do in the first chapter is to learn the natural notes on the 6th and 5th strings.They look something like this:</p><p>E String:</p><ul><li><strong>EF-G-A-BC-D-E</strong> -&gt; up the neck</li><li><strong>E-D-CB-A-G-FE</strong> &#xA0;&lt;- down the neck</li></ul><p>A String:</p><ul><li><strong>A-BC-D-EF-G-A</strong> &#xA0;-&gt; up the neck</li><li><strong>A-G-FE-D-CB-A</strong> &#xA0;&lt;- down the neck</li></ul><p><strong>Note:</strong> Notes separated by a dash are whole step notes.</p><p>The book moves on from there using these natural notes to teach the CAGED system. But you need to have the fundamental down first.</p><p>To try to get these notes under my fingers and recall them at will, I have been practicing playing each note and saying the name out loud going up and down the neck. This has been working to a degree and I am sure that I will get there eventually. </p><p>Yesterday I discovered a fun exercise to add using Rocksmith+ and wanted to share it. </p><p>Recently, a new list of songs was released with &quot;Simple&quot; charts called Easy single-note songs. I was dorking around with the song <a href="https://www.youtube.com/watch?v=o8pQLtHTPaI&amp;ref=iamnotmyself.com">The Story</a> by <a href="https://www.brandicarlile.com/?ref=iamnotmyself.com">Brandi Carlile</a> and realized I was playing pretty much only on the 6th and 5th strings.</p><p>So, I started calling out the notes as I played them as an exercise. I was tripped up a couple times remembering what a specific note was, so I turned on Riff Repeater for the whole song and enabled Note by Note. This gave me some time to figure out what the note was before I played it. </p><p>So the exercise became say the note name and play it in time so Note by Note did not stop the song. Then attempt to do the same just playing along with the song at speed until I could 100% it.</p>]]></content:encoded></item><item><title><![CDATA[How to play Guitar by David Fair of Half Japanese]]></title><description><![CDATA[<p>Someone on Mastodon suggested this article written by David Fair of the band Half Japanese on how to play guitar. I found it inspiring so I am copying it here verbatim as inspiration and easy access later.</p><h3 id="how-to-play-guitar">How to Play Guitar</h3><p><a href="https://www.allmusic.com/artist/david-fair-mn0000646155/biography?ref=iamnotmyself.com">David Fair</a> of <a href="https://open.spotify.com/artist/1YPYaJyUobMi0eABhZo92N?si=JG1r4OlrStOsZE1jgsajlw&amp;ref=iamnotmyself.com">Half Japanese</a></p><p>I taught myself to</p>]]></description><link>https://iamnotmyself.com/how-to-play-guitar-by-david-fair-of-half-japanese/</link><guid isPermaLink="false">63ea87793f7922037df10e81</guid><category><![CDATA[Guitar]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Mon, 13 Feb 2023 19:00:38 GMT</pubDate><content:encoded><![CDATA[<p>Someone on Mastodon suggested this article written by David Fair of the band Half Japanese on how to play guitar. I found it inspiring so I am copying it here verbatim as inspiration and easy access later.</p><h3 id="how-to-play-guitar">How to Play Guitar</h3><p><a href="https://www.allmusic.com/artist/david-fair-mn0000646155/biography?ref=iamnotmyself.com">David Fair</a> of <a href="https://open.spotify.com/artist/1YPYaJyUobMi0eABhZo92N?si=JG1r4OlrStOsZE1jgsajlw&amp;ref=iamnotmyself.com">Half Japanese</a></p><p>I taught myself to play guitar. It&apos;s incredibly easy when you understand the science of it. The skinny strings play the high sounds, and the fat strings play the low sounds. If you put your finger on the string farther out by the tuning end it makes a lower sound. If you want to play fast, move your hand fast and if you want to play slower move your hand slower. That&apos;s all there is to it. You can learn the names of notes and how to make chords that other people use, but that&apos;s pretty limiting. Even if you took a few years and learned all the chords you&apos;d still have a limited number of options. If you ignore the chords your options are infinite and you can master guitar playing in one day.</p><p>Traditionally, guitars have a fat string on the top and they get skinnier and skinnier as they go down. But the thing to remember is it&apos;s your guitar and you can put whatever you want on it. I like to put six different sized strings on it because that gives the most variety, but my brother used to put all of the same thickness on so he wouldn&apos;t have so much to worry about. What ever string he hit had to be the right one because they were all the same.</p><p>Tuning the guitar is kind of a ridiculous notion. If you have to wind the tuning pegs to just a certain place, that implies that every other place would be wrong. But that&apos;s absurd. How could it be wrong? It&apos;s your guitar and you&apos;re the one playing it. It&apos;s completely up to you to decide how it should sound. In fact I don&apos;t tune by the sound at all. I wind the strings until they&apos;re all about the same tightness. I highly recommend electric guitars for a couple of reasons. First of all they don&apos;t depend on body resonating for the sound so it doesn&apos;t matter if you paint them. As also, if you put all the knobs on your amplifier on 10 you can get a much higher reaction to effort ratio with an electric guitar than you can with an acoustic. Just a tiny tap on the strings can rattle your windows, and when you slam the strings, with your amp on 10, you can strip the paint off the walls.</p><p>The first guitar I bought was a Silvertone. Later I bought a Fender Telecaster, but it really doesn&apos;t matter what kind you buy as long as the tuning pegs are on the end of the neck where they belong. A few years back someone came out with a guitar that tunes at the other end. I&apos;ve never tried one. I guess they sound alright but they look ridiculous and I imagine you&apos;d feel pretty foolish holding one. That would affect your playing. The idea isn&apos;t to feel foolish. The idea is to put a pick in one hand and a guitar in the other and with a tiny movement rule the world.</p>]]></content:encoded></item><item><title><![CDATA[Learning Guitar the Hard Way]]></title><description><![CDATA[<p>I have been trying to learn guitar since I was around 15 year old. Back around 1990-ish, my father bought me a Kay hollow body electric from a friend of his. I bought some new strings and strung it upside down because I am left handed and then picked up</p>]]></description><link>https://iamnotmyself.com/learning-guitar-the-hard-way/</link><guid isPermaLink="false">63ea64c93f7922037df10c88</guid><category><![CDATA[Guitar]]></category><category><![CDATA[Rocksmith+]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Mon, 13 Feb 2023 18:11:30 GMT</pubDate><content:encoded><![CDATA[<p>I have been trying to learn guitar since I was around 15 year old. Back around 1990-ish, my father bought me a Kay hollow body electric from a friend of his. I bought some new strings and strung it upside down because I am left handed and then picked up a copy of Guitar World magazine.</p><p>I would sit in my room alone and learn riffs out of that magazine and imagine being on a stage playing thrash metal. It was what I was into at the time, but that is another story.</p><p>Some regrets that I have from that time in my life:</p><ol><li>I never learned to play a song all the way through. I would hyper focus on getting a riff perfect. I would play until I messed up then stop and start over again.</li><li>I never thought to convince my friends, who were all doing the same thing I was, to start a band and suggesting some of us picking up different instruments. I had a handful of people that I knew that all were trying to learn how to play guitar. None of us were really around musical people who knew what they were doing. <br><br>We all had our own guitar hero who we day dreamed about being one day and no real plan to get there. All it would have taken was one of us to say, &quot;Hey why don&apos;t you buy a bass, you buy a simple drum kit and let&apos;s start writing our own songs.&quot; If only we had discovered punk at that time and it&apos;s DIY ethos.</li><li>I was too cool to join band. No, not a band, band at school. You know that place where young musicians learn all the fundamentals of music, have infinite time to practice and give public performances? All for free-ish?<br><br>Yeah, that was a mistake. Here today I publically admit being cool was more important to me in high school than learning to actually create music.</li></ol><p>The fondest memories I have of playing guitar back then was joining friends on stage at school talent shows. I managed to piece together the main riffs from some Metalica songs that flowed nicely together and my friend played solos over them. </p><p>I then joined some other friends on stage to play the guitar riffs used in Fuck Shop by 2 Live Crew while they &quot;rapped&quot; about one of our teachers that we thought was good looking. Of course they changed the hook to say &quot;School Shop&quot; so none of the faculty would catch on but the entire school had that album and recognized it immediately. </p><p>I still day dream about how good that felt. I commonly tell people that I hate to practice I want to skip right to being on stage with a band playing songs. This memory is what drives that sentiment.</p><p>I ended up going through a couple pawn shop electric guitars and buying a nice Marshall amp by the time I hit college. Never knowing how to play an entire song or simply jamming regularly with other people.</p><p>I ended up selling it all to keep a car that I needed for a dead end job.</p><p>Jump to a few years later, I moved to Washington state in the middle of the 90s when the grunge scene was in full swing. A friend at work gave me a beat up acoustic for doing some web design work. I fiddle with it but mostly let it sit because the body was seperating and it didn&apos;t sound all that great. I was focused on making money and learning how to program.</p><p>Later I started a job near Olympia, Washington around the turn of the millennium. I had a little extra cash and some free time. So I picked up a left handed Fender bass at a pawn shop. Maybe bass would be easier to pick up, I thought. Once again I bought a magazine or maybe a book of songs and noodled.</p><p>The place where I was working had a set of managers that had mostly all gone to school together and played in bands together. They were a bit older than I was, but they wanted to put a band together and needed a bass player. So of course, I told them I had a bass and would love to play with them.</p><p>They invited me over one weekend. I plugged in and had no idea what I was doing. One of them pointed out that they were playing in the key of G and I should follow the I, IV, V. I just stared at him confused. It embarrased me so badly, I sold the bass and focused on my budding web development career.</p><p> Jump to around 2011 and I found a lefty Gibson Les Paul Standard on Amazon for a good price. I added it to my wishlist and started talking about it obsessively to my wife, Julia. She of course took the hint and bought it for me.</p><p>This time, I told myself, was going to be different. I was going to practice every day until I learned the guitar. Of course, I didn&apos;t know how to practice really or what to practice. So, all I accomplished was annoying Julia by twanging on it while we watched TV. She eventually got irritated with me and asked me to stop. So in the case it went.</p><p>Next, I decided I was going to do it right this time and signed up to take lessons from <a href="https://www.jamminmusicstudios.com/jon-balsley/?ref=iamnotmyself.com">Jon Balsey</a> here in Olympia. I looked him up and he was in a band that regularly played music in Portland. It was really important to me that I take lessons from someone who was actually doing what I wanted to be able to do.</p><p>Lessons started great. We clicked well. But I would simply not make time to practice. I used work and life as an excuse to not pick up the guitar and work on the the things that Jon showed me. Of course, that embarrassment from early was whispering in my ear. Telling me that I am waisting his time that I will never be any good. I eventually quit, not because I couldn&apos;t pay or because Jon was a bad teacher, but because I was worried I was waisting his time.</p><p>Later, I was working with a pretty accomplished musician named <a href="https://www.linkedin.com/in/carl-dexter-53314b88/?ref=iamnotmyself.com">Carl Dexter</a>. I told him about my desire to learn to play and that my motivation was playing with other people. He suggested that I come over to his studio and in exchange for teaching him how to program, he would teach me to play and do it by playing with me.</p><p>Once again, it started great. I figured out how to play parts of Twist of Cain by Danzig and we would jam on that song with him on drums while I played what I knew of it. He once asked me what was an other song I would like to learn, and I said Got the Time by Anthrax. He honestly said he didn&apos;t know if he could play something that fast. We were not clicking on music choice and once again that voice started whispering in my ear, &quot;You are wasting his time. You are not good enough. You are too old.&quot;</p><p>I ended up getting a new job and ghosting Carl. Not because he was mean or not helpful, but because I lacked faith in myself, felt foolish and worst of all was wasiting his time. He even made a valiant effort to reach out to me multiple times, but I used the excuse of work and life to push him away. That was really stupid of me. </p><p>In the last couple years, COVID pushed everyone to working from home. I had a pretty great job that paid well. My company got bought out by another and I had some bonus cash. So I used it to buy some dream guitars I have always wanted. I had the Gibson and I added a Fender Stratocaster and Taylor 314ce acoustic.</p><p>My wife and mother-in-law (who lived with us by that time) were a bit perplexed. Why was I buying these fancy guitars if I never actually played them. I had resigned myself to the idea that just owning them, hanging them on my wall and being able to look at them any time I wanted was enough.</p><p>Just being able to touch that dream I had at 15 deep in my soul was going to be enough to hang my hat on. I&apos;ll never reach that inspiration that I felt the first time I heard Slash play Sweet Child, the first time I heard Metallica&apos;s One or the crusing opening riff of Nirvana&apos;s Smells Like Teen Spirit. It is just not going to happen. </p><p>About that time, I got an invite to the <a href="https://www.ubisoft.com/en-us/game/rocksmith/plus?ref=iamnotmyself.com">Rocksmith+</a> beta. I accepted it and started messing around with the game and having fun with it. So, when the full game released I suscribed for a year.</p><p>I started playing it regularly. The game really does a nice job of simulating that feeling of playing in a band with other people. Something clicked for me. I started doing the lessons and exercises while also learning to play songs all the way through. HOLY FUCK that felt good. And I wasn&apos;t wasting anyones time.</p><p>My software engineer&apos;s mind kicked in and I started tracking my progress month to month in a <a href="https://docs.google.com/spreadsheets/d/1GNzyGKSPB47iA6PxOrv3WIuJbvhFGgqp11ZEk5f9DUs/edit?usp=sharing&amp;ref=iamnotmyself.com">spreadsheet</a>. I set goals for myself. I gave myself permission to fuck up and be bad. All the skills I learned in a 25 year career doing software development, I started to apply to learning how to play.</p><p>I stuck with it and five months in I decided to add lessons to what I am doing again. I reached out to a couple instructors that offered zoom lessons and setup lessons with <a href="https://learnguitarpdx.com/?ref=iamnotmyself.com">Rick Klaras</a> out of Portland for much the same reasons I selected Jon back in the day.</p><p>You might ask, why not contact Carl or Jon? Well you see that little voice in my head was still there. I needed to find someone I didn&apos;t know personally that I could ghost if I failed or died of embarrasment. I could not let these guys who tried to help me down yet again.</p><p> I picked up a copy of <a href="https://www.guitarmusictheory.com/?ref=iamnotmyself.com">Desi Serna</a>&apos;s <a href="https://www.amazon.com/Fretboard-Theory-Including-Progressions-Application-ebook/dp/B004ASNACS?ref=iamnotmyself.com">Fretboard Theory</a> book. This time I want to actually understand the insturment and the theory of music behind it. I am currently struggling to learn the natural notes on the 5th and 6th strings, so that I can play them backwards and forwards and find them easily. It might take me weeks to accomplish this feat. But that is ok, I have time and have learned a little patience. I&apos;ll get there.</p><p>The first lesson was a little rocky. I could not get my audio to cooperate so that Rick could hear me play. It was clear he was irked and started just plugging away to get through the lesson time. That little voice is in my head already, &quot;I am wasting his time. He thinks I am some fucking boomer dipshit. He is not really into teaching me.&quot;</p><p>But I am going to stick with it for the month. I have goals that I can achieve on my own. An instructor is an augmentation of that effort not the effort. Rick and I will either click or we wont. The way I am looking at it right now is there are other instructors, maybe I need to find the right one. But I want to give this a chance and see where it goes.</p><p>In the end, I am not quitting this time. This is the thing that is for me, all my own. I am not doing this for someone else, to make someone else happy. I can push myself to play and learn. I can rock out in Rocksmith+ and day dream about being on a stage. I can learn Ableton and start recording my own things.</p><p>I really don&apos;t give a fuck about wasiting other peoples time anymore. I have wasted enough of my own. This is who I am, insecurities and all. I am going to play this guitar every day if possible just to shut that voice in my head up. Whatever comes in the future, I am going to have my hands on the fretboard.</p>]]></content:encoded></item><item><title><![CDATA[Using Rocksmith+ to Learn Guitar]]></title><description><![CDATA[I have been using Rocksmith+ for the last few months to teach myself how to play Guitar. I thought it might be a good idea to write my practice down somewhere where it might be helpful to somebody else and I can point to when beginner questions come up.]]></description><link>https://iamnotmyself.com/using-rocksmith-to-learn-guitar/</link><guid isPermaLink="false">63dae1343f7922037df10c3d</guid><category><![CDATA[Guitar]]></category><category><![CDATA[Rocksmith+]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Wed, 01 Feb 2023 22:11:22 GMT</pubDate><content:encoded><![CDATA[<p>I have been using <a href="https://www.ubisoft.com/en-us/game/rocksmith/plus?ref=iamnotmyself.com">Rocksmith+</a> for the last few months to teach myself how to play Guitar. I thought it might be a good idea to write my practice down somewhere where it might be helpful to somebody else and I can point to when beginner questions come up.</p><p>I&apos;ll start by saying I keep a simple journal of my progress in the form of a google spreadsheet. I create one tab a month and track my progress for that month in it. The game does a good job of encouraging you, but I like being able to see all the progress I have made month to month in one place.</p><p><a href="https://docs.google.com/spreadsheets/d/1GNzyGKSPB47iA6PxOrv3WIuJbvhFGgqp11ZEk5f9DUs/edit?usp=sharing&amp;ref=iamnotmyself.com" rel="noopener nofollow ugc">Here</a> is a view only link to that spreadsheet. Feel free to steal if you like the idea.</p><h2 id="goals">Goals</h2><p>I start each month by listing out some goals I think I can accomplish in the given month. I try to format these as SMART goals. SMART being Specific, Measurable, Achievable, Relevant and Time bound.</p><p>The goals are around what I think will get me to progress to the next level of playing. As you can see, I am working on practicing regularly, breaking out of the Easy level of exercises, completing the basic learning path and getting a 100% on at least one song.</p><p>This month I added a couple out of game goals of working through the first chapter of the book <a href="https://www.amazon.com/Fretboard-Theory-Volumes-Combined-progressions/dp/1542403227/?ref=iamnotmyself.com" rel="noopener nofollow ugc">Fretboard Theory by Desi Serna</a> and having 4 lessons with an actual guitar instructor (for those things the game can&apos;t teach me like proper form).</p><h3 id="learning">Learning</h3><p>The next section of the spreadsheet I like to think of as eating my vegetables. I know that I do not have great finger dexterity, grip strength or pick hand coordination. So I spend a lot of time on the learning tab.</p><h3 id="exercises">Exercises</h3><p>I play each exercise type once a day. I start at 60% speed and play all the way through. I stick with that exercise at that speed until I can 100% the track at that speed. Then I mark it as green complete and create a new line where I bump the speed up by 10%.</p><p>I sometimes get stuck getting that last 1-2%, but this is eating veggies right? I should be able to do these exercises easily at some point, so doing this work is valuable in the long run no matter how long it takes me.</p><p>Again, I just run through them once a day.</p><h3 id="no-look-exercises">No Look Exercises</h3><p>Once I got out of the Easy exercises and into Intermediate my progress started to slow down. I had an idea while watching <a href="https://www.twitch.tv/chainbrain?ref=iamnotmyself.com">Chainbrain</a> on twitch to start the easy exercises and focus on not looking at my hands. Instead I try to feel where the frets are and shift both down and across the neck with my fingers not my eyes.</p><h3 id="lessons">Lessons</h3><p>I have taken a similar approach with the in game lessons. I started on the basic learning path. I watch the video then try to 100% the practice track. I do not move forward in the learning path until I have 100%ed the practice track. These are fundamental skills, so spending time on them enough to master a practice track seems worthwhile to me.</p><p>I got hung up on the Strumming Practice Track 1 for a few months. Switching from D to Dm in the open chord position was eating my face. So I slowed it down to 85% speed and progressed with it like I do the exercises. I 100%&apos;d it in the last week of January.</p><p>I am now working on Strumming Practice Track 2 at 60% speed.</p><h3 id="songs">Songs</h3><p>Finally, I do actually play songs in the game as well. I picked out some tracks that I was familiar with that are in E Standard at a Basic difficulty and have Rhythm charts. You can see the list of songs in the spreadsheet that I am working on. I tend to start at the top of my list and work my way down until I am done playing for the day.</p><p>The goal here has been to just have fun playing along to some songs that I like. I have gotten pretty far just playing at speed and doing the suggested practice sections after. But I think this month I might start doing the same thing I described above and slowing the songs down to focus on accuracy.</p><h2 id="daily-practice">Daily Practice</h2><p>So given all this what does a daily practice look like for me at the moment? Based on the 23 February tab, this is what I will do today.</p><ol><li>Intermediate Linear Playing 1 - No looking at hands</li><li>Intermediate Linear Playing 2 - 80% speed</li><li>Intermediate String Switching 1 - 90% speed (I skip no look because I am working on the same track in both)</li><li>Easy String Skipping 2 - No looking at hands</li><li>Intermediate String Skipping 1 - 70% speed</li><li>Easy Hammer-ons 2 - 100% speed</li><li>Easy Pull-offs 1 - No looking at hands</li><li>Intermediate Pull-offs 1 - 60% speed</li><li>Strumming Practice Track 2 - 60% speed (I might play this one 2-3 times)</li><li>I Hate Myself for Loving You - Joan Jett 1-2 times (just trying to get those last 4% on this song)</li><li>Never Miss a Beat - Kaiser Chiefs 1-2 times</li><li>The Hardest Button to Button - White Stripes - 1-2 times</li><li>Father of Mine - Everclear 1-2 times</li></ol><p>Anything beyond this is bonus or me putzing around looking for new songs to play.</p><h2 id="future">Future</h2><p>I will keep going on this path using R+ as a practice tool. I want to augment that with learning music theory. I&apos;ll work on that with my instructor and the book I mentioned. Beyond that I want to start recording my own music in my home studio.</p><p>I have this idea to take songs that I have 100%&apos;d in the game and start recording my own versions of them using Ableton paired with EZ Drummer and EZ Bass. Basically start creating my own backing tracks. This is something my instructor says he wants to work with me on. The goal being learning songs in R+, recreating them in Ableton and eventually creating my own music from what I have learned.</p><p>If this helps you or you are just looking for another beginner to shoot the shit with and stay motivated hit me up.</p>]]></content:encoded></item><item><title><![CDATA[Your Terminal and You: Dotfiles]]></title><description><![CDATA[<p>Have you ever watched a skilled engineer pull up a terminal, issue a few keystrokes and kick off a whole series of processes in seconds? It can be downright magical, some even wizard-like. A few are hard to distinguish from cackling necromancers raising processes from the dead.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" class="kg-image" alt="Souls" loading="lazy" width="7952" height="5304" srcset="https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=600&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ 600w, https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ 1000w, https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1600&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ 1600w, https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2400&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ 2400w" sizes="(min-width: 720px) 720px"><figcaption>Photo by <a href="https://unsplash.com/@rhett__noonan?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Rhett</a></figcaption></figure>]]></description><link>https://iamnotmyself.com/your-terminal-and-you-dotfiles/</link><guid isPermaLink="false">63850c043f7922037df10971</guid><category><![CDATA[bash]]></category><category><![CDATA[Guide]]></category><category><![CDATA[WSL]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Tue, 10 Nov 2020 16:00:00 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/11/IMG_2229.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/11/IMG_2229.jpg" alt="Your Terminal and You: Dotfiles"><p>Have you ever watched a skilled engineer pull up a terminal, issue a few keystrokes and kick off a whole series of processes in seconds? It can be downright magical, some even wizard-like. A few are hard to distinguish from cackling necromancers raising processes from the dead.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" class="kg-image" alt="Your Terminal and You: Dotfiles" loading="lazy" width="7952" height="5304" srcset="https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=600&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ 600w, https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ 1000w, https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=1600&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ 1600w, https://images.unsplash.com/photo-1502919280275-1bed9aca68ab?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2400&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ 2400w" sizes="(min-width: 720px) 720px"><figcaption>Photo by <a href="https://unsplash.com/@rhett__noonan?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Rhett Wesley</a> / <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Unsplash</a></figcaption></figure><p>I&apos;ll let you in on a little secret, engineers who are comfortable on the command line are not wizards, they are pack rats. They accumulate techniques and store them away in a toolbox and take it everywhere they go.</p><p>That engineer can sit down at any machine and within minutes reach into their toolbox and become productive.</p><p>Let&apos;s take a look at one technique that I use. It is not my technique, like all good pack rats I borrowed it from countless others and added them to my toolbox. </p><p>The technique I use, is fairly macOS focused. It will work on macOS, Linux and WSL on Windows. You can do similar things in PowerShell, I encourage you to take a look at <a href="https://baldbeardedbuilder.com/?ref=iamnotmyself.com">Michael Jolly</a>&apos;s <a href="https://github.com/builders-club/devtoolbox?ref=iamnotmyself.com">devtoolbox</a> project for examples.</p><p>Let&apos;s start by creating your toolbox in a way that you can access it from any machine. Head to <a href="https://github.com/new?ref=iamnotmyself.com">GitHub</a> and create a new repository called <strong>dotfiles</strong>. This is a common name for this kind of repository, remember it. You can find all kinds of great examples by looking at other peoples dotfiles repos.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/11/Screen-Shot-2020-11-09-at-8.54.01-AM.png" class="kg-image" alt="Your Terminal and You: Dotfiles" loading="lazy" width="741" height="848"><figcaption>Recommended settings for new dotfiles repository</figcaption></figure><p>If you want to allow others to use tools from your toolbox, consider adding an MIT license and making your repo public. Be sure to add a README file. It will be useful later when you want to start documenting things for others to consume. </p><p>Once you have created the repository, let&apos;s clone it to your machine. We will do this in a special place called your home directory located in your user directory. We will also give it a special name.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">cd ~
git clone git@github.com:NotMyself/dotfiles.git .dotfiles
</code></pre>
<!--kg-card-end: markdown--><p>Use git to clone the repository to a directory named <strong>.dotfiles</strong>. Notice the period in front of the directory name. This makes the directory a hidden one. Trying running these two commands to see what I mean.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">ls
ls -a
</code></pre>
<!--kg-card-end: markdown--><p>The first command lists the files and directories in the current directory. Notice that the <strong>.dotfiles</strong> directory is not displayed. The second command uses the <strong>-a</strong> flag to show all files and directories.</p><p>Here is what it looks like on my machine currently.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/11/Screen-Shot-2020-11-09-at-9.31.50-AM.png" class="kg-image" alt="Your Terminal and You: Dotfiles" loading="lazy" width="1337" height="962"><figcaption>running ls vs. ls -a</figcaption></figure><p>As you can see, I have a variety of dot files for various things. Can you spot my <strong>.dotfiles</strong> directory?</p><p>Next, you will need to wire up your <strong>.dotfiles</strong> directory in a way that your terminal application will use it. By default, macOS terminal uses <a href="http://zsh.sourceforge.net/?ref=iamnotmyself.com">zsh</a> as it&apos;s shell. So create a <strong>zsh</strong> directory in the <strong>.dotfiles</strong> directory and add a <strong>.zshrc</strong> file to it.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">cd ~/.dotfiles
mkdir zsh
touch ./zsh/.zshrc
</code></pre>
<!--kg-card-end: markdown--><p>When a new shell is started in a terminal application, zsh will look for a .zshrc file in the home directory of the current user. It will then execute that file. Of course, your file is located in the <strong>.dotfiles/zsh </strong>directory. </p><p>We can fix that by creating a <a href="https://en.wikipedia.org/wiki/Symbolic_link?ref=iamnotmyself.com">symbolic link</a> between the file&apos;s current location on disk and where zsh expects it to be. To do that, create an <strong>install</strong> script in your <strong>.dotfiles</strong> directory.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">echo &quot;#\!/usr/bin/env sh&quot; &gt; ./install
echo &quot;echo \&quot;Installing..\&quot;&quot; &gt;&gt; ./install
chmod +x ./install
./install
</code></pre>
<!--kg-card-end: markdown--><p>There is a bit of magic going on here, so let&apos;s break it down. The first command creates a file named <strong>install</strong> and adds a special value as the first line.<strong> </strong>This value is called a <strong>shebang</strong>. It is used to decide how a file will be executed. In this case, the shebang checks the local system environment for the configured shell. So this install script will execute in <strong>zsh</strong>.</p><p>The next command, adds a line to the install file that will write the text <strong>&quot;Installing...&quot;</strong> to the terminal when the install script is executed. We will use this to verify everything is working correctly.</p><p>Text files in macOS are not typically executable. So the next command explicitly set the install text file as executable. This only needs to be done once when you create a script file.</p><p>The final command executes the install script. The output on my machine looks like this.</p><figure class="kg-card kg-image-card"><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/11/Screen-Shot-2020-11-09-at-10.03.15-AM.png" class="kg-image" alt="Your Terminal and You: Dotfiles" loading="lazy" width="1337" height="962"></figure><p>Finally, add the command needed to create the symbolic link to the .zshrc file to the install script. Open the install script in a text editor and add the following line.</p><!--kg-card-begin: markdown--><pre><code class="language-bash"># shell settings
ln -sv /Users/bobby/.dotfiles/zsh/.zshrc ~/.zshrc
</code></pre>
<p>Note that your user directory name will be different than mine. Be sure to change the <strong>bobby</strong> value to the name of your user directory. If you are not sure what that name is run <code>echo ~</code> in your terminal to display the full path to your home directory.</p>
<!--kg-card-end: markdown--><p>This is a key concept in creating your toolbox. Instead of just looking up commands and running them once to set things up make a script file that does it so you do not have to look it up again. </p><p>I simply looked at my <a href="https://github.com/NotMyself/dotfiles/blob/master/install?ref=iamnotmyself.com">install script</a> in my <a href="https://github.com/notmyself/dotfiles?ref=iamnotmyself.com">dotfiles</a> repository to find the symlink command. See, I am not a wizard I am a pack rat.</p><p>At this point you should commit your changes to the Git repository. Now, run the install script.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">./install
</code></pre>
<p>You may recieve an error that a file named .zshrc already exists in your home directory. In that case, make a backup of that file for later review and run the install again.</p>
<pre><code class="language-bash">mv ~/.zshrc ~/.zshrc_backup
./install
</code></pre>
<p>You can now list the contents of your home directory and you should see the <strong>.zshrc</strong> file.</p>
<pre><code class="language-bash">ls -a ~
</code></pre>
<p>Remember though, this is a symbolic link to the file in our <strong>.dotfiles</strong> repository. Which basically makes it our entry point to setup our shell any way we want.</p>
<!--kg-card-end: markdown--><p>Now, let&apos;s make it do something interesting. Open the <strong>~/.dotfiles/zsh/.zshrc</strong> file in a text editor and add the following.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">for DOTFILE in `find /Users/bobby/.dotfiles/system`
do
  [ -f $DOTFILE ] &amp;&amp; source $DOTFILE
done
</code></pre>
<p>This script will execute each of the files located in the <strong>system</strong> directory in our <strong>.dotfiles</strong> directory. Making them available to the current shell.</p>
<p>I typically setup a series of files in the system folder: <strong>.alias</strong>, <strong>.env</strong>, <strong>.function</strong>, <strong>.path</strong>, and <strong>.prompt</strong>.</p>
<ul>
<li>.alias - contains a set of command aliases to commands that already exist on my machine.</li>
<li>.env - contains commands to add additional functionality into my terminal environment.</li>
<li>.function - contains a set of functions that are useful in my terminal environment.</li>
<li>.path - updates the $PATH to include any other binary sources on my machine.</li>
<li>.prompt - contains the configuration needed to setup my fancy shell prompt.</li>
</ul>
<!--kg-card-end: markdown--><p>Aliases can be very useful for common commands containing elaborate flags and values that you use regularly. Let&apos;s set up a few so you can see how easy it is. First, we need to set up the <strong>.alias</strong> file.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">cd ~/.dotfiles
mkdir system
touch system/.function</code></pre>
<!--kg-card-end: markdown--><p>Then add the following code to the <strong>.alias</strong> file.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">alias l=&quot;ls -la&quot;       # List in long format, include dotfiles
alias ld=&quot;ls -ld */&quot;   # List in long format, only directories
alias ..=&quot;cd ..&quot;
alias ...=&quot;cd ../..&quot;
alias ....=&quot;cd ../../..&quot;
</code></pre>
<p>These aliases are ones that I use for navigating around the file system. As you can see they are simply shortcuts for other commands.</p>
<!--kg-card-end: markdown--><p>Functions on the other hand allow you to do more complex tasks with a single command. Let&apos;s set you up with one of my favorite functions. Typically when I create a new directory using the <strong>mkdir</strong> command the very next thing I do is change directories into the one I just created. </p><p>Let&apos;s create a function that does this in one command instead of two. First, you need to create the <strong>.function</strong> file.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">cd ~/.dotfiles
touch system/.function
</code></pre>
<!--kg-card-end: markdown--><p>Next, add the following code to the .function file using a text editor.</p><!--kg-card-begin: markdown--><pre><code class="language-bash"># Create a new directory and enter it
function mk() {
  mkdir -p &quot;$@&quot; &amp;&amp; cd &quot;$@&quot;
}
</code></pre>
<p>Now when you wish to create a directory and enter it you can execute the command <code>mk foo</code>.</p>
<p>Commit these changes to your <strong>dotfiles</strong> repository.</p>
<!--kg-card-end: markdown--><p>And with that your toolbox is setup. Start collecting the tools that make you look like a wizard. You can take a look at my <a href="https://github.com/NotMyself/dotfiles?ref=iamnotmyself.com">dotfiles</a> repository for ideas. Or, search GitHub for <a href="https://github.com/search?q=dotfiles&amp;type=repositories&amp;ref=iamnotmyself.com">others</a>.</p>]]></content:encoded></item><item><title><![CDATA[Debugging .NET Core via Symbol Server on OSX in VSCode]]></title><description><![CDATA[<p>In a previous life, I was a heavy user of Visual Studio on Windows. But for the last few years I have been working exclusively on Mac OSX and using VSCode as my primary editor.</p><p>One feature of the full Visual Studio that I miss is integrating with a Symbol</p>]]></description><link>https://iamnotmyself.com/debugging-net-core-on-osx-in-vscode/</link><guid isPermaLink="false">63850c043f7922037df1096f</guid><category><![CDATA[.NET Core]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Thu, 25 Jun 2020 19:08:58 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/06/IMG_2167-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/06/IMG_2167-1.jpg" alt="Debugging .NET Core via Symbol Server on OSX in VSCode"><p>In a previous life, I was a heavy user of Visual Studio on Windows. But for the last few years I have been working exclusively on Mac OSX and using VSCode as my primary editor.</p><p>One feature of the full Visual Studio that I miss is integrating with a Symbol Server for debugging code that does not belong to me.</p><p>If you are not familiar with how a debugger works (at least in .NET), debugging information is stored in a symbol file separate from the executable that is being built by a compiler. All modern version of Microsoft compilers store that information in &#xA0;a program database file, or .pdb.</p><p>You might recognize those files from building a debug version of your applications. But did you know that Microsoft also produces symbol files for the .NET Core framework libraries as well?</p><p>And they make those symbols available via a Symbol Server. A symbol server enables debuggers to automatically retrieve the correct symbol files for a given library.</p><p>Micorsoft also makes their source code available via a Source Server. This allows a client to retrieve the exact version of the source code that were used to build an assembly.</p><p>Combining a Symbol and Source Server it is possible to debug right into any library you are using just like you do with your own code.</p><p>In full Visual Studio there is a deeply nested configration setting that you enable to make all this work. It is a bit more involved to get working in VSCode, let me outline the steps for you.</p><p>First, install the dotnet cli global tool for symbols.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">dotnet tool install -g \
    --add-source https://api.nuget.org/v3/index.json \
    dotnet-symbol
</code></pre>
<!--kg-card-end: markdown--><p>This will add everything that is needed to fetch symbols from the primary NuGet source. This happens to be where we get all of the .NET libraries from.</p><!--kg-card-begin: markdown--><p>We can use this tool now by issuing the command <code>dotnet symbol</code> from our terminals.</p>
<!--kg-card-end: markdown--><p>Next, we need to pull the symbols for the meta package we are using to build the application. </p><!--kg-card-begin: markdown--><pre><code class="language-bash">dotnet symbol --symbols \
  --output /tmp/symbols \
  /usr/local/share/dotnet/shared/Microsoft.AspNetCore.App/3.1.2/*
</code></pre>
<!--kg-card-end: markdown--><p>This will use the symbol tool to download the pdb symbol &#xA0;files to a temporary directory for all the dlls found in the AspNetCore meta package version 3.1.2 that is located on my local machine.</p><p>Once downloaded, we can copy them into the meta package directory.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">sudo cp /tmp/symbols/* \
  /usr/local/share/dotnet/shared/Microsoft.AspNetCore.App/3.1.2
</code></pre>
<!--kg-card-end: markdown--><p>Now that the symbols are in the right place, the debugger can use them to fetch source code and debug into the .NET Core framework. These steps only need to be completed once per .NET Core SDK you have installed. Any application you build from here out on that SDK will have the symbols available to it.</p><p>But if we jump into VSCode and attempt to debug an application, we will start seeing messages like this in the Debug Console.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">Loaded &apos;/src/sample/src/server/bin/Debug/netcoreapp3.1/Microsoft.IdentityModel.Protocols.dll&apos;.
Skipped loading symbols.
Module is optimized and the debugger option &apos;Just My Code&apos; is enabled.
</code></pre>
<!--kg-card-end: markdown--><p>This message is telling us that the debugger skipped loading external symbols because the &quot;Just My Code&quot; debugger option is enabled. </p><p>This is a feature of the debugger that allows us to focus our debugging session only on code that we have written. And that is probably the normal state we want to use.</p><p>But we can easily tell the debugger that we want to debug all the code we have symbols for by setting a flag in the launch.json file.</p><!--kg-card-begin: markdown--><pre><code class="language-json">{
   &quot;version&quot;: &quot;0.2.0&quot;,
   &quot;configurations&quot;: [
        {
            &quot;name&quot;: &quot;.NET Core Launch (web)&quot;,
            &quot;type&quot;: &quot;coreclr&quot;,
            &quot;request&quot;: &quot;launch&quot;,
            &quot;preLaunchTask&quot;: &quot;build&quot;,
            &quot;program&quot;: &quot;${workspaceFolder}/src/server/bin/Debug/netcoreapp3.1/server.dll&quot;,
            &quot;args&quot;: [],
            &quot;cwd&quot;: &quot;${workspaceFolder}/src/server&quot;,
            &quot;stopAtEntry&quot;: false,
            &quot;justMyCode&quot;: false,
            &quot;env&quot;: {
                &quot;ASPNETCORE_ENVIRONMENT&quot;: &quot;Development&quot;
            }
        }
    ]
}
</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>In this example, we have added the <code>justMyCode</code> property to the .NET Core Launch configuration and set it&apos;s value to false.</p>
<!--kg-card-end: markdown--><p>And just like that, we are debugging the .NET Core framework libraires on our local machine. </p>]]></content:encoded></item><item><title><![CDATA[Webpack Proxy Configuration for .NET Core 3 SPA Projects]]></title><description><![CDATA[<p>On August 5th of 2019, <a href="https://github.com/danroth27?ref=iamnotmyself.com">Daniel Roth</a> <a href="https://github.com/dotnet/aspnetcore/issues/12890?ref=iamnotmyself.com">announced</a> on the <a href="https://github.com/dotnet/aspnetcore?ref=iamnotmyself.com">aspnetcore</a> repository that Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices were being made obsolete in the coming .NET Core 3 release.</p><p>As you can see from the annourncement issue, there has been quite a bit of commentary from folks who</p>]]></description><link>https://iamnotmyself.com/webpack-proxy-configuration-for-net-core-3-spa-projects/</link><guid isPermaLink="false">63850c043f7922037df1096e</guid><category><![CDATA[.NET Core]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Sat, 29 Feb 2020 20:23:26 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/02/IMG_2062.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/02/IMG_2062.jpg" alt="Webpack Proxy Configuration for .NET Core 3 SPA Projects"><p>On August 5th of 2019, <a href="https://github.com/danroth27?ref=iamnotmyself.com">Daniel Roth</a> <a href="https://github.com/dotnet/aspnetcore/issues/12890?ref=iamnotmyself.com">announced</a> on the <a href="https://github.com/dotnet/aspnetcore?ref=iamnotmyself.com">aspnetcore</a> repository that Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices were being made obsolete in the coming .NET Core 3 release.</p><p>As you can see from the annourncement issue, there has been quite a bit of commentary from folks who have been relying on these services for various workflows.</p><p>I have been using the DevelopmentServer middleware quite heavily in my <a href="https://github.com/NotMyself/bivrost?ref=iamnotmyself.com">Bivrost</a> project for debugging purposes. The way it worked in .NET Core 2 is the middeware would shell out and start a webpack development server and proxy requests from the aspnetcore application to the SPA application.</p><p>This functionalty went away. So I had to figure out another way to setup my development workflow.</p><!--kg-card-begin: markdown--><h2 id="workaroundforwebpackbasedfrontendapps">Workaround for Webpack Based Frontend Apps</h2>
<p>This workaround is taken directly from <a href="https://github.com/notmyself/bivrost?ref=iamnotmyself.com">this application</a> that I work on in my spare time. I have removed all use of the SpaServices provided development server. Instead, I configure webpack to proxy requests to aspnetcore and setup vscode to launch both processes.</p>
<h3 id="startupcs">Startup.cs</h3>
<p>The startup configuration is here only to serve up the built webpack based SPA application for production purposes. The location of this path is <a href="https://github.com/NotMyself/bivrost/blob/master/src/server/appsettings.Production.json?ref=iamnotmyself.com">configurable</a> in the <code>appsettings.json</code> and is specific to your application.</p>
<pre><code class="language-csharp">public class Startup
  {
    public void ConfigureServices(IServiceCollection services)
    {
      //configures the root of the built spa files
      services.AddSpaStaticFiles(configuration =&gt;
      {
          configuration.RootPath = Configuration[&quot;Client&quot;];
      });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      //tells the application to serve them up for production use
      app.UseStaticFiles();
      app.UseSpaStaticFiles();
    }
  }
</code></pre>
<h3 id="vueconfigjswebpackconfigjs">vue.config.js || webpack.config.js</h3>
<p>This configuration can go in your vue.config.js or webpack.config.js. It will proxy all http requests to the provided url (including websockets/signalr). This is a fairly standard thing to do in the frontend world.</p>
<pre><code class="language-javascript">module.exports = {
  devServer: {
    proxy: &apos;http://localhost:5000/&apos;
  }
};
</code></pre>
<h3 id="vscodelaunchjson">.vscode/launch.json</h3>
<p>The vscode <code>launch.json</code> tells the editor how to launch your application for debugging. This setup creates 2 configurations a <strong>Client</strong> for starting the webpack based app using NPM and a <strong>Server</strong> for starting the backend using dotnet cli. Then I use a <strong>compound</strong> configuration that joins the two together. Simply select the compound configuration in vscode and click run.</p>
<p><img src="https://user-images.githubusercontent.com/73120/75614277-e3918280-5aeb-11ea-80ff-e9de3bd13bf8.png" alt="Webpack Proxy Configuration for .NET Core 3 SPA Projects" loading="lazy"></p>
<p>Note: The Client configuration does not attempt to connect a debugger, it just starts the app via NPM. I prefer to debug client-side code in my browser.</p>
<pre><code class="language-javascript">{
  &quot;version&quot;: &quot;0.2.0&quot;,
  &quot;compounds&quot;: [
    {
      &quot;name&quot;: &quot;Bivrost&quot;,
      &quot;configurations&quot;: [&quot;Server&quot;, &quot;Client&quot;]
    }
  ],
  &quot;configurations&quot;: [
    {
      &quot;type&quot;: &quot;node&quot;,
      &quot;request&quot;: &quot;launch&quot;,
      &quot;name&quot;: &quot;Client&quot;,
      &quot;runtimeExecutable&quot;: &quot;npm&quot;,
      &quot;runtimeArgs&quot;: [
        &quot;run-script&quot;,
        &quot;serve&quot;
      ],
      &quot;noDebug&quot;:true,
      &quot;cwd&quot;: &quot;${workspaceFolder}/src/client&quot;,
      &quot;skipFiles&quot;: [
        &quot;&lt;node_internals&gt;/**&quot;
      ]
    },
    {
      &quot;name&quot;: &quot;Server&quot;,
      &quot;type&quot;: &quot;coreclr&quot;,
      &quot;request&quot;: &quot;launch&quot;,
      &quot;preLaunchTask&quot;: &quot;build&quot;,
      // If you have changed target frameworks, make sure to update the program path.
      &quot;program&quot;: &quot;${workspaceFolder}/src/server/bin/Debug/netcoreapp3.1/server.dll&quot;,
      &quot;args&quot;: [],
      &quot;cwd&quot;: &quot;${workspaceFolder}/src/server&quot;,
      &quot;stopAtEntry&quot;: false,
      &quot;env&quot;: {
          &quot;ASPNETCORE_ENVIRONMENT&quot;: &quot;Development&quot;,
      }
    }
  ]
}
</code></pre>
<p>When the application is running in debug, your screen will look similar to this:</p>
<p><img src="https://user-images.githubusercontent.com/73120/75614294-1b98c580-5aec-11ea-8f55-ba4284a3fde6.png" alt="Webpack Proxy Configuration for .NET Core 3 SPA Projects" loading="lazy"></p>
<p>Note: There are two debug consoles one for the Client app and one for the Server app. You also have a drop-down menu in the debug controls at the top to select either process as well. You do have to stop them both.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Pop-Up Saturday: Vue.js, Vuex, Websockets, Vuetify]]></title><description><![CDATA[In this stream, we cover an overview of the Bivrost frontend, how websockets are managed using Vuex plugins and end with some conversion work using Vuetify. ]]></description><link>https://iamnotmyself.com/pop-up-saturday-vue-js-vuex-vuetify/</link><guid isPermaLink="false">63850c043f7922037df1096d</guid><category><![CDATA[Twitch.tv]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[Vuex]]></category><category><![CDATA[Vuetify]]></category><category><![CDATA[Websockets]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Sun, 23 Feb 2020 19:59:22 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/02/IMG_1543.jpg" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/9ax_uLZy348?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><!--kg-card-begin: markdown--><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/02/IMG_1543.jpg" alt="Pop-Up Saturday: Vue.js, Vuex, Websockets, Vuetify"><p>In this stream, we cover an overview of the Bivrost frontend, how websockets are managed using Vuex plugins and end with some conversion work using Vuetify.</p>
<p>Stream Channel: <a href="https://notmyself.livecoders.dev/?ref=iamnotmyself.com">https://notmyself.livecoders.dev/</a><br>
Repository: <a href="https://github.com/notmyself/bivrost?ref=iamnotmyself.com">https://github.com/notmyself/bivrost</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Implementing Websocket Plugins for Vuex]]></title><description><![CDATA[<p><a href="https://vuex.vuejs.org/?ref=iamnotmyself.com">Vuex</a> is a state management plugin for <a href="https://vuejs.org/?ref=iamnotmyself.com">Vue.js</a>. It allows you to centrally store all data needed for a Vue application and manage mutations (changes) to that data. </p><p>Out of the box it works really well for working with data from an API. But when working with realtime data</p>]]></description><link>https://iamnotmyself.com/implementing-websocket-plugins-for-vuex/</link><guid isPermaLink="false">63850c043f7922037df1096c</guid><category><![CDATA[Vue.js]]></category><category><![CDATA[Twitch.tv]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Fri, 14 Feb 2020 21:55:36 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/02/IMG_1507.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2020/02/IMG_1507.jpg" alt="Implementing Websocket Plugins for Vuex"><p><a href="https://vuex.vuejs.org/?ref=iamnotmyself.com">Vuex</a> is a state management plugin for <a href="https://vuejs.org/?ref=iamnotmyself.com">Vue.js</a>. It allows you to centrally store all data needed for a Vue application and manage mutations (changes) to that data. </p><p>Out of the box it works really well for working with data from an API. But when working with realtime data being pushed to the client over websockets, there isn&apos;t a good way to represent that flow in a clean way.</p><p>Here is an example. Say we have a Vue application that needs to connect to a SignalR hub to recieve chat messages and display them realtime.</p><ul><li>Where should you put the SignalR client construction logic?</li><li>Where should you put the logic to start the SignalR client connection?</li><li>How do you dispatch SignalR messages into the Vuex store?</li></ul><p>This post will cover each of these topics and the concepts outlined here can be used with any websockets library you want.</p><h3 id="setting-up-a-chat-store">Setting Up a Chat Store</h3><p>First, let&apos;s setup a Vuex store for handling our realtime chat data. I typically set up <a href="https://vuex.vuejs.org/guide/modules.html?ref=iamnotmyself.com">Vuex modules</a> for each specific domain my apps need to know about. A simple chat module looks like this.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">const state = {
  chatMessages: [],
  limit: 5
};

const getters = {
  displayMessages: state =&gt; state.chatMessages
};

const actions = {
  addMessage({ commit }, message) {
    commit(&apos;ADD_MESSAGE&apos;, message);
  },
  deleteMessage({ commit }, message) {
    commit(&apos;DELETE_MESSAGE&apos;, message);
  }
};

const mutations = {
  ADD_MESSAGE(state, message) {
    while (state.chatMessages.length &gt;= state.limit) {
      state.chatMessages.shift();
    }
    state.chatMessages.push(message);
  },
  DELETE_MESSAGE(state, message) {
    state.chatMessages = state.chatMessages.filter(m =&gt; m.id !== message.id);
  }
};

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations
};
</code></pre>
<!--kg-card-end: markdown--><p>This chat module will maintain an array of chat messages for display. The array is limted to five messsages. When a new message is added, the oldest messages is popped off the stack.</p><p><strong>Note:</strong> I am explicitly using namespaces in the module definition. Here is how you call a namespaced module using the Vuex store.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">store.dispatch(&apos;chat/addMessage&apos;, message);
</code></pre>
<!--kg-card-end: markdown--><p>This call will execute the <em>addMessage</em> action passing it the message object.</p><p>Using this module in your Vuex store is pretty simple.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">import Vue from &apos;vue&apos;;
import Vuex from &apos;vuex&apos;;

import chat from &apos;./modules/chat&apos;;

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    chat
  }
});

</code></pre>
<!--kg-card-end: markdown--><p>Import the chat module then pass it along to the Vuex store constructor.</p><p>Finally, instruct Vue to use the store in <em>main.js</em>.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">import Vue from &apos;vue&apos;;
import store from &apos;./store&apos;;
import App from &apos;./App.vue&apos;;

Vue.config.productionTip = false;

new Vue({
  store,
  render: h =&gt; h(App)
}).$mount(&apos;#app&apos;);
</code></pre>
<!--kg-card-end: markdown--><p>Note that the Vue instance has no knowledge of how the store is setup, it simply uses it as configured.</p><p>We now have a store that is capible of handling our chat message state and making that state available to any Vue component that wants to consume it.</p><h3 id="setting-up-a-websocket-plugin">Setting Up a Websocket Plugin</h3><p>Vuex has a nice <a href="https://vuex.vuejs.org/guide/plugins.html?ref=iamnotmyself.com">plugin model</a> that allows you to add functionality by hooking into a stores mutations. For each websocket connection we can create a plugin that manages the interaction between socket messages we care about and the store.</p><p>Here is the basic shell of the plugin we will be building over the next few sections.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">export default function createWebSocketPlugin() {
  return store =&gt; {
  
  };
}
</code></pre>
<!--kg-card-end: markdown--><p>The module simply exports a function that returns a function with a single parameter: the store itself. To wire it up to the Vuex store, import the plugin and hand it off to the Vuex store constructor plugins array.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">import Vue from &apos;vue&apos;;
import Vuex from &apos;vuex&apos;;

import chat from &apos;./modules/chat&apos;;
import chatSocket from &apos;./plugins/chat&apos;;

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    chat
  },
  plugins: [chatSocket()]
});

</code></pre>
<!--kg-card-end: markdown--><p>Now that the plugin is wired in, we can update it to create a websocket connection.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">import { HubConnectionBuilder } from &apos;@aspnet/signalr&apos;;

const client = new HubConnectionBuilder()
  .configureLogging(process.env.VUE_APP_SIGNALR_LOG_LEVEL)
  .withUrl(process.env.VUE_APP_SIGNALR_HUB_URL)
  .build();


export default function createWebSocketPlugin() {
  return store =&gt; {
      //subscribe to events
    client.start();
  };
}
</code></pre>
<!--kg-card-end: markdown--><p>Here we have imported a websocket library called SignalR. It is a popular way of communicating with .NET server applications, but any websocket library will do.</p><p>Then we create a client and start the connection after we have subscribed to any events. The plugin how has access to both a websocket client and the Vuex store.</p><h3 id="subscribing-to-connection-events">Subscribing to Connection Events</h3><p>Our client side Vue application need a way to monitor the connection state of the websocket to ensure it does not try to use a closed connection. Let&apos;s subscribe to our first event by handling the connection status of the websocket.</p><p>First, update the chat vuex module to keep track of the connection state as well as actions and mutations for updating it.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">const state = {
  connected: false,
  error: null,
  chatMessages: [],
  limit: 5
};

const getters = {
  displayMessages: state =&gt; state.chatMessages
};

const actions = {
  addMessage({ commit }, message) {
    commit(&apos;ADD_MESSAGE&apos;, message);
  },
  deleteMessage({ commit }, message) {
    commit(&apos;DELETE_MESSAGE&apos;, message);
  },
  connectionOpened({ commit }) {
    commit(&apos;SET_CONNECTION&apos;, true);
  },
  connectionClosed({ commit }) {
    commit(&apos;SET_CONNECTION&apos;, false);
  },
  connectionError({ commit }, error) {
    commit(&apos;SET_ERROR&apos;, error);
  }
};

const mutations = {
  ADD_MESSAGE(state, message) {
    while (state.chatMessages.length &gt;= state.limit) {
      state.chatMessages.shift();
    }
    state.chatMessages.push(message);
  },
  DELETE_MESSAGE(state, message) {
    state.chatMessages = state.chatMessages.filter(m =&gt; m.id !== message.id);
  },
  SET_CONNECTION(state, message) {
    state.connected = message;
  },
  SET_ERROR(state, error) {
    state.error = error;
  }
};

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations
};
</code></pre>
<!--kg-card-end: markdown--><p>We have added a flag to indicate connection status and an error to the state. By default the connection is not available and there is no error state. We have added actions for opening and closing the connection as well as populating the error.</p><p>Now we update the plugin to subscribe to connection events and push them to the store.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">import { HubConnectionBuilder } from &apos;@aspnet/signalr&apos;;

const client = new HubConnectionBuilder()
  .configureLogging(process.env.VUE_APP_SIGNALR_LOG_LEVEL)
  .withUrl(process.env.VUE_APP_SIGNALR_HUB_URL)
  .withAutomaticReconnect()
  .build();

export default function createWebSocketPlugin() {
  return store =&gt; {
    client.on(&apos;stateChanged&apos;, (oldState, newState) =&gt; {
      if (oldState !== newState &amp;&amp; newState !== &apos;Connected&apos;)
        store.dispatch(&apos;chat/connectionClosed&apos;);
      else store.dispatch(&apos;chat/connectionOpened&apos;);
    });

    client
      .start()
      .then(() =&gt; {
        store.dispatch(&apos;chat/connectionOpened&apos;);
      })
      .catch(err =&gt; {
        store.dispatch(&apos;chat/connectionError&apos;, err);
      });
  };
}

</code></pre>
<!--kg-card-end: markdown--><p>Here we are subscribing to the <em>stateChanged</em> event. If the state is anything other than &quot;Connected&quot; we dispatch a closed action to the store otherwise the opened action.</p><p>We also handle the <em>start </em>promise states calling the appropriate actions.</p><h3 id="subscribing-to-chat-events">Subscribing to Chat Events</h3><p>The websocket server I am connecting to will raise <em>receiveChatMessage</em> events for each chat message sent to the server. We can easily subscribe to this event in our plugin.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">client.on(&apos;receiveChatMessage&apos;, message =&gt; {
  store.dispatch(&apos;chat/addMessage&apos;, message);
});
</code></pre>
<!--kg-card-end: markdown--><p>The event handler dispatches the <em>addMessage</em> action passing along the received message.</p><h3 id="subscribing-to-mutations">Subscribing to Mutations</h3><p>Our plugin is successfully managing it&apos;s own connection state and pushing messages into the Vuex store. But the application will need to send chat messages as well.</p><p>To accomplish that the plugin needs to subscribe to mutations and handle the ones it cares out.</p><!--kg-card-begin: markdown--><pre><code class="language-javascript">store.subscribe((mutation, state) =&gt; {
  if (state.chat.connected &amp;&amp; mutation.type === &apos;chat/SEND_MESSAGE&apos;)
    client.invoke(&apos;SendMessage&apos;, null, message);
});
</code></pre>
<!--kg-card-end: markdown--><p>Here we subscribe to all mutations. Then check the websocket connection state and mutation type before sending the message to the server.</p><h3 id="wrapping-up">Wrapping Up</h3><p>This post has described the technique that I have used in my Twitch streaming application <a href="https://github.com/notmyself/bivrost?ref=iamnotmyself.com">Bivrost</a>. If you would like to see how all of this is wired up in an acual application check out the <em>src/client/src/store</em> directory.</p>]]></content:encoded></item><item><title><![CDATA[Bivrost: Managing State with Vuex]]></title><description><![CDATA[In this stream we do some hacking on Bivrost my Vue.js/ASP.NET Core Twitch bot and overlay system. We learn some good techniques on Vuex.]]></description><link>https://iamnotmyself.com/bivrost-managing-state-with-vuex/</link><guid isPermaLink="false">63850c043f7922037df1096b</guid><category><![CDATA[Twitch.tv]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[.NET Core]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Thu, 18 Jul 2019 00:08:40 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/07/IMG_1552.jpg" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/rigdgUXGh54?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/07/IMG_1552.jpg" alt="Bivrost: Managing State with Vuex"><p>In this stream we do some hacking on Bivrost my Vue.js/ASP.NET Core Twitch bot and overlay system. We learn some good techniques on Vuex.<br><br>Stream Channel: <a href="https://notmyself.livecoders.dev/?ref=iamnotmyself.com">https://notmyself.livecoders.dev/</a><br>Project: <a href="https://github.com/NotMyself/bivrost/projects/1?ref=iamnotmyself.com">https://github.com/NotMyself/bivrost/projects/1</a><br>Repository: <a href="https://github.com/NotMyself/bivrost?ref=iamnotmyself.com">https://github.com/NotMyself/bivrost</a></p>]]></content:encoded></item><item><title><![CDATA[There's No Place Like Home]]></title><description><![CDATA[The reports of my death are greatly exaggerated. Join me for a catch-up session. We will discuss some upcoming events, what's new at Auth0 and a project I have been working on called Bivrost.]]></description><link>https://iamnotmyself.com/theres-no-place-like-home/</link><guid isPermaLink="false">63850c043f7922037df1096a</guid><category><![CDATA[Twitch.tv]]></category><category><![CDATA[Auth0]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[.NET Core]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Thu, 11 Jul 2019 00:46:40 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/07/rueben-mcchristian-xJSodSLmlGE-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card"><iframe width="459" height="344" src="https://www.youtube.com/embed/oA7bCYHe86c?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/07/rueben-mcchristian-xJSodSLmlGE-unsplash.jpg" alt="There&apos;s No Place Like Home"><p>The reports of my death are greatly exaggerated. Join me for a catch-up session. We will discuss some upcoming events, what&apos;s new at Auth0 and a project I have been working on called Bivrost.</p><p></p><p>Photo by <a href="https://unsplash.com/@ruebshoots?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Rueben McChristian</a> on <a href="https://unsplash.com/search/photos/olympia?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p><p></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Securing Vue.js with Auth0]]></title><description><![CDATA[In this stream, we cover updating a Vue.js application to use an external identity provider to authenticate using OpenID Connect and OAuth 2.]]></description><link>https://iamnotmyself.com/securing-vue-js-with-auth0/</link><guid isPermaLink="false">63850c043f7922037df10969</guid><category><![CDATA[Twitch.tv]]></category><category><![CDATA[Auth0]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Thu, 28 Feb 2019 02:39:03 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/02/yanny-mishchuk-1289477-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="480" height="270" src="https://www.youtube.com/embed/s2fMHRgR1y4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>Securing Vue.js with Auth0</figcaption></figure><!--kg-card-begin: markdown--><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/02/yanny-mishchuk-1289477-unsplash.jpg" alt="Securing Vue.js with Auth0"><p>In this stream, we cover updating a Vue.js application to use an external identity provider to authenticate using OpenID Connect and OAuth 2.</p>
<p>Stream Channel: <a href="https://notmyself.livecoders.dev/?ref=iamnotmyself.com">https://notmyself.livecoders.dev/</a><br>
Project: <a href="https://github.com/NotMyself/securing-vue/projects/1?ref=iamnotmyself.com">https://github.com/NotMyself/securing-vue/projects/1</a><br>
Repository: <a href="https://github.com/NotMyself/securing-vue?ref=iamnotmyself.com">https://github.com/NotMyself/securing-vue</a><br>
Completed: <a href="https://github.com/NotMyself/securing-vue/tree/complete?ref=iamnotmyself.com">https://github.com/NotMyself/securing-vue/tree/complete</a></p>
<!--kg-card-end: markdown--><p>Photo by <a href="https://unsplash.com/photos/InL80ungGDU?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Yanny Mishchuk</a> on <a href="https://unsplash.com/search/photos/olympia-washington?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>]]></content:encoded></item><item><title><![CDATA[Building A Twitch Screen-Scraper With Node]]></title><description><![CDATA[Twitch.tv's API does not offer a way to fetch scheduled events. In this stream, we take a stab at writing a screen-scraper to fetch event information for a given stream team.]]></description><link>https://iamnotmyself.com/building-a-twitch-screen-scraper-with-node/</link><guid isPermaLink="false">63850c043f7922037df10968</guid><category><![CDATA[Node.js]]></category><category><![CDATA[Twitch.tv]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Mon, 18 Feb 2019 19:32:50 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/02/korey-moore-774047-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="480" height="270" src="https://www.youtube.com/embed/9KLW5GpdgC8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>Building A Twitch Screen-Scraper With Node Part 1</figcaption></figure><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="480" height="270" src="https://www.youtube.com/embed/cFRklBGKIRk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>Building A Twitch Screen-Scraper With Node Part 2</figcaption></figure><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/02/korey-moore-774047-unsplash.jpg" alt="Building A Twitch Screen-Scraper With Node"><p>Twitch.tv&apos;s API does not offer a way to fetch scheduled events. In this stream, we take a stab at writing a screen-scraper to fetch event information for a given stream team.</p><p>Stream Channel: <a href="https://notmyself.livecoders.dev/?ref=iamnotmyself.com">https://notmyself.livecoders.dev/</a><br></p><p>Photo by <a href="https://unsplash.com/photos/aGI2sHN0gKg?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Korey Moore</a> on <a href="https://unsplash.com/search/photos/olympia-washington?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>]]></content:encoded></item><item><title><![CDATA[How Do I Verify a JWT Token If I Am Not Using Express?]]></title><description><![CDATA[In this popup stream, I show how you can verify a jwt token for any framework you want to use by hand.]]></description><link>https://iamnotmyself.com/how-do-i-verify-a-jwt-token-if-i-am-not-using-express/</link><guid isPermaLink="false">63850c043f7922037df10967</guid><category><![CDATA[Node.js]]></category><category><![CDATA[Twitch.tv]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Wed, 13 Feb 2019 02:47:03 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/02/danielle-calicdan-1108262-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/w_hG7drbdwo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/02/danielle-calicdan-1108262-unsplash.jpg" alt="How Do I Verify a JWT Token If I Am Not Using Express?"><p>In this popup stream, I show how you can verify a jwt token for any framework you want to use by hand.</p><p>Stream Channel: <a href="https://notmyself.livecoders.dev/?ref=iamnotmyself.com" rel="nofollow">https://notmyself.livecoders.dev/</a><br>Twitter: <a href="https://twitter.com/NotMyself?ref=iamnotmyself.com">https://twitter.com/NotMyself</a><br></p><p>Photo by <a href="https://unsplash.com/photos/mv5i_eOOxvg?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Danielle Calicdan</a> on <a href="https://unsplash.com/search/photos/olympia-washington?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>]]></content:encoded></item><item><title><![CDATA[Broxburn: Setting Up Continuous Deployment With Zeit Now]]></title><description><![CDATA[In this session we will cover dockerizing the app and setting up continuous deployment.]]></description><link>https://iamnotmyself.com/broxburn-setting-up-continuous-deployment-with-zeit-now-part-1/</link><guid isPermaLink="false">63850c043f7922037df10966</guid><category><![CDATA[.NET Core]]></category><category><![CDATA[React]]></category><category><![CDATA[Twitch.tv]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Import 2022-11-28 19:29]]></category><dc:creator><![CDATA[Bobby Johnson]]></dc:creator><pubDate>Sat, 02 Feb 2019 00:02:42 GMT</pubDate><media:content url="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/02/taylor-young-702974-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/q6aS4Nh-4Pw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><figure class="kg-card kg-embed-card"><iframe width="480" height="270" src="https://www.youtube.com/embed/OUqMYtASrpA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><img src="https://s3-us-west-1.amazonaws.com/iamnotmyself-com/2019/02/taylor-young-702974-unsplash.jpg" alt="Broxburn: Setting Up Continuous Deployment With Zeit Now"><p>Having set up the basic application structure in the previous session, in this session we will cover setting up continuous deployment on Zeit Now. Now bot will detect commits to the source control repository and trigger a build producing a deployable version of the application.</p><p>Stream Channel: <a href="https://notmyself.livecoders.dev/?ref=iamnotmyself.com" rel="nofollow">https://notmyself.livecoders.dev/</a><br>Github Repository: <a href="https://github.com/NotMyself/zeitcore?ref=iamnotmyself.com">https://github.com/NotMyself/zeitcore</a><br>Twitter: <a href="https://twitter.com/NotMyself?ref=iamnotmyself.com">https://twitter.com/NotMyself</a><br></p><p>Photo by <a href="https://unsplash.com/photos/kIZNwQ5bgGA?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Taylor Young</a> on <a href="https://unsplash.com/search/photos/olympia-washington?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>]]></content:encoded></item></channel></rss>