From a37eaa2d34d7c0d19675ed01a42bf9dfc63e3831 Mon Sep 17 00:00:00 2001 From: Spencer Lepine <60903378+spencerlepine@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:13:00 -0500 Subject: [PATCH] cleanup: minor article edits and Dev.to/Medium files (#3) * cleanup: minor article edits and Dev.to/Medium files * Optimised images with calibre/image-actions --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- README.md | 9 +- architecture.png | Bin 192620 -> 132265 bytes {blog => content}/authors.yml | 0 .../index.devto | 172 +++++++++++ .../index.md | 189 ++++++++++++ .../index.medium | 17 +- .../thumbnail.jpg | Bin .../building-llama-as-a-service/index.devto | 192 ++++++++++++ content/building-llama-as-a-service/index.md | 240 +++++++++++++++ .../building-llama-as-a-service/index.medium | 19 +- .../building-llama-as-a-service/thumbnail.jpg | Bin .../creating-custom-git-commands/index.devto | 11 +- .../creating-custom-git-commands/index.md | 36 ++- .../creating-custom-git-commands/index.medium | 11 +- .../thumbnail.jpg | Bin .../index.devto | 158 ++++++++++ .../index.md | 160 ++++++++++ .../index.medium | 32 +- .../thumbnail.jpg | Bin .../index.devto | 160 ++++++++++ .../index.md | 174 +++++++++++ .../index.medium | 17 +- .../thumbnail.jpg | Bin .../index.devto | 103 +++++++ .../index.md | 119 ++++++++ .../index.medium | 17 +- .../thumbnail.jpg | Bin .../index.devto | 25 +- .../index.md | 102 +++++++ .../index.medium | 77 +++++ .../thumbnail.jpg | Bin .../index.devto | 107 +++++++ .../index.md | 116 ++++++++ .../index.medium | 19 +- .../thumbnail.jpg | Bin .../software-engineering-workflow/index.devto | 115 ++++++++ .../software-engineering-workflow/index.md | 113 +++++++ .../index.medium | 17 +- .../thumbnail.jpg | Bin .../index.devto | 129 ++++++++ .../index.md | 136 +++++++++ .../index.medium | 19 +- .../thumbnail.jpg | Bin .../index.devto | 154 ++++------ .../index.md | 278 ++++++++++++++++++ .../index.medium | 222 ++++++++++++++ .../thumbnail.jpg | Bin docs/intro.md | 47 --- docusaurus.config.js | 15 +- package.json | 2 +- sidebars.js | 33 --- src/pages/markdown-page.md | 7 - 52 files changed, 3252 insertions(+), 317 deletions(-) rename {blog => content}/authors.yml (100%) create mode 100644 content/building-a-readme-crawler-with-node-js/index.devto create mode 100644 content/building-a-readme-crawler-with-node-js/index.md rename blog/building-a-readme-crawler-with-node-js/building-a-readme-crawler-with-node-js.md => content/building-a-readme-crawler-with-node-js/index.medium (95%) rename {blog => content}/building-a-readme-crawler-with-node-js/thumbnail.jpg (100%) create mode 100644 content/building-llama-as-a-service/index.devto create mode 100644 content/building-llama-as-a-service/index.md rename blog/building-llama-as-a-service/index.md => content/building-llama-as-a-service/index.medium (96%) rename {blog => content}/building-llama-as-a-service/thumbnail.jpg (100%) rename {blog => content}/creating-custom-git-commands/index.devto (84%) rename {blog => content}/creating-custom-git-commands/index.md (59%) rename {blog => content}/creating-custom-git-commands/index.medium (83%) rename {blog => content}/creating-custom-git-commands/thumbnail.jpg (100%) create mode 100644 content/git-project-configuration-with-husky-and-eslint/index.devto create mode 100644 content/git-project-configuration-with-husky-and-eslint/index.md rename blog/git-project-configuration-with-husky-and-eslint/git-project-configuration-with-husky-and-eslint.md => content/git-project-configuration-with-husky-and-eslint/index.medium (87%) rename {blog => content}/git-project-configuration-with-husky-and-eslint/thumbnail.jpg (100%) create mode 100644 content/manyshiba-the-worlds-greatest-twitter-bot/index.devto create mode 100644 content/manyshiba-the-worlds-greatest-twitter-bot/index.md rename blog/manyshiba-the-worlds-greatest-twitter-bot/manyshiba-the-worlds-greatest-twitter-bot.md => content/manyshiba-the-worlds-greatest-twitter-bot/index.medium (94%) rename {blog => content}/manyshiba-the-worlds-greatest-twitter-bot/thumbnail.jpg (100%) create mode 100644 content/portfolio-site-continuous-integration-github-action/index.devto create mode 100644 content/portfolio-site-continuous-integration-github-action/index.md rename blog/portfolio-site-continuous-integration-github-action/portfolio-site-continuous-integration-github-action.md => content/portfolio-site-continuous-integration-github-action/index.medium (90%) rename {blog => content}/portfolio-site-continuous-integration-github-action/thumbnail.jpg (100%) rename blog/preparing-for-my-amazon-front-end-engineer-interview/preparing-for-my-amazon-front-end-engineer-interview.md => content/preparing-for-my-amazon-front-end-engineer-interview/index.devto (90%) create mode 100644 content/preparing-for-my-amazon-front-end-engineer-interview/index.md create mode 100644 content/preparing-for-my-amazon-front-end-engineer-interview/index.medium rename {blog => content}/preparing-for-my-amazon-front-end-engineer-interview/thumbnail.jpg (100%) create mode 100644 content/quickly-open-github-repo-in-browser-from-terminal/index.devto create mode 100644 content/quickly-open-github-repo-in-browser-from-terminal/index.md rename blog/quickly-open-github-repo-in-browser-from-terminal/quickly-open-github-repo-in-browser-from-terminal.md => content/quickly-open-github-repo-in-browser-from-terminal/index.medium (83%) rename {blog => content}/quickly-open-github-repo-in-browser-from-terminal/thumbnail.jpg (100%) create mode 100644 content/software-engineering-workflow/index.devto create mode 100644 content/software-engineering-workflow/index.md rename blog/software-engineering-workflow/software-engineering-workflow.md => content/software-engineering-workflow/index.medium (91%) rename {blog => content}/software-engineering-workflow/thumbnail.jpg (100%) create mode 100644 content/typescript-development-set-up-for-vscode/index.devto create mode 100644 content/typescript-development-set-up-for-vscode/index.md rename blog/typescript-development-set-up-for-vscode/typescript-development-set-up-for-vscode.md => content/typescript-development-set-up-for-vscode/index.medium (88%) rename {blog => content}/typescript-development-set-up-for-vscode/thumbnail.jpg (100%) rename blog/what-i-learned-during-100-days-of-code/what-i-learning-during-100-days-of-code.md => content/what-i-learned-during-100-days-of-code/index.devto (80%) create mode 100644 content/what-i-learned-during-100-days-of-code/index.md create mode 100644 content/what-i-learned-during-100-days-of-code/index.medium rename {blog => content}/what-i-learned-during-100-days-of-code/thumbnail.jpg (100%) delete mode 100644 docs/intro.md delete mode 100644 sidebars.js delete mode 100644 src/pages/markdown-page.md diff --git a/README.md b/README.md index 049aa75..017969d 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ articles to [Medium](https://medium.com/@spencerlepine) and [Dev.to](https://dev ## 💻 Local Development ```sh -$ npm install -$ npm start +$ yarn install +$ yarn start ``` This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. @@ -17,7 +17,7 @@ This command starts a local development server and opens up a browser window. Mo ## 🏗️ Production Build ```sh -$ npm run build +$ yarn run build ``` This command generates static content into the `build` directory and can be served using any static contents hosting service. @@ -43,7 +43,8 @@ This command generates static content into the `build` directory and can be serv ## ⏳ Development -Clean up files, remove doc folder, renamne blog to content?? Move architecture picture Fix twitter preview images +- [feature] Fix twitter preview images +- [article] Add images to #100daysofCode article from twitter ### Dev.to Articles diff --git a/architecture.png b/architecture.png index 361d6ff7ef22381bb19a57dd8f0300ea030ab3df..f0523e1774332fa40f337a6e5c4bba9a8022a807 100644 GIT binary patch literal 132265 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 rnRKFEDMN!}FK9BwSO7A^^GrXPg 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 ND%-;3RB?j58n%OdsUxSjmf3<@~{dtDw2bd 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

f^sAAHgp3h$do`Y>lA_*yw_C$a4#HFpy zt{&Flc>jg4TnA6b@hrCE+MsFlb+~k7f=0if(K4M`NM0>-j9)G;ewi;D!i9~8#5`(b zVxSqXp6nj(0Z#%1BN(v7$!T*8t&Ir9l33Uf`?4* z@kqj)u@aa5dP#v4GI=BW$T$LS05|<&Pzuf+Wg1pd0wkJf5q~1QD*Jm?RA8ZENf^$J zi_J8a(%G$BB_aFZuXkcjDcf@oQjt?qOv>D^*iv2q!RcIFu`c%WC|IgsQQE>W*Ztzrl!It{I%`*-$U$|C*nHD>xP%W7Rcvm1)wH zuW@+B(thBRleFZK0CUR>Zj1x=AQcjm$`SD84QrH5Y;$&}s={u5mr?6RpgH;I^$&n&l67!N00DNpSTYv9VyTu zvR^2|!+hhA|8;$A0qjvS=72RCplLTMlJWc0!_F0Ogo7HvwPbgDddL#zRVn*yL(fQ% zKuVmi&E&PLwTfs()1T%re{RcFa`nWYIDWI$9?$0UXJrYfm#46$Vm|S14$dR*s&kQr z;V(|smJk|On_Z+oNa`X(ms7u6(x8bVjzV4ut7kubyF z9kJ-8&aV3M(49L=`^^@@S9K%lOVge{R%$74vjUghw2#9Ugk6o zFahAl3uxPY#ShvzCqI4Vv)oMgA|?E%RvpiqR_TS&b1%vn`sl^y!+Xn@#5%iDq?a0& zJiQTSd7MA7Vp)1GX?35uT0CKFmD|~dpn-p0Gz0}uBAxe`pTCdbKX9k37NTyXVOBJ? z3%Jzkp`WWL@R*q$q^F?wm~y!tp4}9Q))y!R2iihGT!+rOl6Ks3D24wa%u*)XWy3S3 z17lKUd3~kQp5o4~&-42h=_jUXlccf_|?|o5Ir5hV1*~ zzA_^^EC@Ja_n?B;4sZodj@fcu!s4^EI-Fw^Uaw1M_s-HcS}hiWvWX33IDetdJ2X$K zSh==BE#KMI=PTjxW<2kk{s5mw$jN*VWS9H2=7mKOfTis~i#%YxTTp;Sem)Nv^ODR8 z1N`!LhV}7ROHxFFi}=H;v9cmO$DZKASJ#>syW(FFO;{ZWep5GM<)S_w$dxaRQf3#idb zm6_$i>1udt>I_4}NJP6AXs|`{Pg|O~(G()^;%F-JeTLu(=xXqMjOnw6>c=hU%%nT( zGrJ>`bAHIt3wuN$S7t4)a$^|vRbz4?tZbh$A*k?K_t)`3IwNrJu+;HiD(hJvm=qiVzL2JdpA86BM440#q2hwG~id?)#3wfPC98G3zMX8mDq* zxW{VLqEq27UFstcnxh=(nin4U$1XwmfIJUw%2!{XPgEe4g|-CjELUEu7gF2ri8E8=lQOOx?fLxZ~d9!>Y1mf?YxO$~3m!h$SM5?{zX$H=<7 zb%gg#O-mTH6|Wo|8+r~IYlt-N{>``&Y5dyy^x^KD?744+{~Z_r2d@U$W3(K-;jxR5 z8Xd~X0AHl=p-K}0OHoV58img@Q^u;o%+Wj>dvw*L!L*>hGR>Jb*#2ta-8HuWA1aZ( zjC!puj=5B$Ce#f?N({F6rJpMJkN%Y_D2r%I~*UZf=8)$uF7Qve*;T2cy literal 192620 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%0A#*Hmv^DUVPM^idw`f>NyNuV=|UHS39~ zcVC$520>%m020y%vxm%pNc zV?(qEDw3aBdy5ODhmn!|m0j=Zd+=D&#q?JU


9#kd#%*H#!YihZKRVpzIWCu?l< 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�D|L+ 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

k|NzKP*A!- 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 diff --git a/blog/authors.yml b/content/authors.yml similarity index 100% rename from blog/authors.yml rename to content/authors.yml diff --git a/content/building-a-readme-crawler-with-node-js/index.devto b/content/building-a-readme-crawler-with-node-js/index.devto new file mode 100644 index 0000000..2808f2c --- /dev/null +++ b/content/building-a-readme-crawler-with-node-js/index.devto @@ -0,0 +1,172 @@ +--- +title: Building a README Crawler With Node.js +description: An Overview of the Node.js README Web Crawler project and how I created it. # Dev.to +tags: 'crawler, nodejs, repositories' # Dev.to (Max 3) +canonical_url: null # Dev.to +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +Building a README Crawler with Node.js + +An Overview of the Node.js README Web Crawler project and how I created it. + +A recent project of mine was this Node.js [web crawler](https://github.com/spencerlepine/readme-crawler). Working on that led to this idea for another crawler. I wanted a way to navigate through GitHub and search for obvious typos. I had this idea after stumbling across silly typos on numerous portfolio pages. Perhaps I could help fix these errors and ensure these portfolio/sites are more presentable. + +If you’re interest in the final product, you can find the package [here](https://www.npmjs.com/package/readme-crawler), as well as the [GitHub Repo](https://github.com/spencerlepine/readme-crawler). + +The goal was to create a process for automatically navigating through repositories and creating a method for spell-checking what is found. Doing that manually is time consuming, so the computer will execute that process for us. A [web crawler](https://www.cloudflare.com/learning/bots/what-is-a-web-crawler/) will systematically browse different pages across the internet. The purpose of this specific crawler would be scraping GitHub only. + +Here's the breakdown of this problem: + - Fetch the HTML data from a URL + - Look at the README file displayed in that DOM + - Export README and details README for later use + - Generate a list of repository links in displayed in README + +To execute the algorithm, we will use [Node.js](https://nodejs.org/) (for the JavaScript runtime) and [node-fetch](https://www.npmjs.com/package/node-fetch) (for network requests). This means we will run the code locally from the command line. +For this project, we will have an output folder to store all the README data, as well as a list (queue) of repository URLs to visit. +Before diving into the code, it is important to plan the input and output of the algorithm. For this web crawler, we will start at a valid GitHub repository page, which would be one URL string. After visiting each page with a README, we will export the data into a new file. +Now lets cover the process of requesting a repository page from a URL. For this, we only care about saving the README file that is displayed, and we will ignore any other links that GitHub displays (such as the navbar). We will send a URL request with node-fetch, and retrieve the result of a HTML string. If we convert the HTML string to a DOM Tree, we can search for a specific element. GitHub stores the README file under a div with the class "markdown-body". We can use a library called 'jsdom' to use Browser API methods, and return a specific node. + +```js +const fetchReadMeDOMFromRepoURL = async function (url) { + let destinationDOM; + + await fetch(url) + .then((response) => { + return response.text(); + }) + .then((data) => { + const { document } = new JSDOM(data).window; + const readmeNode = document.querySelector(".markdown-body"); + destinationDOM = readmeNode; + }) + .catch((err) => { + console.warn("Could not fetch url: " + url); + }); + + return destinationDOM; +}; +``` + +Now that we have access to a local node displaying the README content, we can export that data. +Instead of using a spell checker at this stage, I decided to handle that separately and resort to a command-line alternative. This meant the README file could be exported to file locally, and then we process spell checking files after the crawler stops running. +With a README DOM node we will convert it from HTML to a markdown file. Websites give the browser HTML code to display. + +```js +const exportRepoDOM = async function (readmeNode, repoURL, outputFolderPath) { + if (readmeNode) { + const { name, owner, href } = parseGitHubUrl(repoURL); + const folderDestination = `${outputFolderPath}${owner}-${name}/`; + + if (!fs.existsSync(folderDestination)) { + fs.mkdirSync(folderDestination); + } + + const markdown = turndownService.turndown(readmeNode.outerHTML); + createMarkdownFile(markdown, folderDestination); + + const info = `URL=${href}\nGIT_URL=${href}.git\nREPO_NAME=${name}\nOWNER=${owner}\n`; + createInfoFile(info, folderDestination); + } +}; +``` +Before we are finished with this README, we have to traverse the DOM node to find any other GitHub repository links. This will allow us to follow pages and crawl GitHub. Keep in mind though, there could be a README without any links, and we might want to navigate through GitHub some other way. +Since we are using jsdom, we can use the built-in getElementsByTagName method. We only want to save valid GitHub links, so we can use a helper function to test with regex. With that, we can create a list of links found. + +```js +const getLinksFromDOM = function (jsDOM, isUsableLink) { + const validLinks = []; + + const linkElements = (jsDOM && jsDOM.getElementsByTagName("a")) || []; + for (let i = 0; i < linkElements.length; i++) { + const thisElement = linkElements[i]; + const thisUrl = thisElement.href; + + if (isUsableLink(thisUrl)) { + validLinks.push(thisUrl); + } + } + return validLinks; +}; +``` + +Great, so far we retrieve README content from a URL and use that to generate a list of new URLs. If we want to continue searching and finding README files, we can follow the links and repeat entire process. This will recursively crawl the GitHub repositories, allowing us to gather data. +To keep track of the new URLs to visit, each link needs to be stored in a queue, or in terms of data structures, a (stack)[https://www.geeksforgeeks.org/stack-data-structure/]. To implement this, I append all the items of the new list to a file. Whenever the program is ready to fetch the next link, we can pull and remove the first line of the queue file and return it for a new URL string. The link queue will be stored in a file where we append/delete line by line. This was done to avoid storing an array in memory to avoid crashing, and to allow pausing the crawler and any point. + +```js +const saveLinkToQueue = function (linkStr, outputFolderPath, outputFileName) { + + const filePath = outputFolderPath + outputFileName; + if (fs.existsSync(filePath)) { + fs.appendFile(filePath, linkStr + "\r\n", function (err) { + if (err) throw err; + }); + } else { + fs.writeFile(filePath, linkStr + "\r\n", function (err) { + if (err) throw err; + }); + } +}; +``` + +All of these modules together will download README files in an organized output folder. After running the web crawler, we can run a spell checker on the exported data. To do this, I used a package called ‘[yaspeller](https://www.npmjs.com/package/yaspeller)’. Each time I want to correct a README, I can generate a file with all common typos and errors. + +```sh +yaspeller -e ".md" ./ --find-repeat-words --ignore-digits --ignore-urls --only-errors &> "spellcheck.txt" +``` + +And that's it! I now have a way to look through hundreds of repositories. I can spell check tons of README files and help people remove possibly embarrassing typos. There are many ways to expand on this. You could analyze the languages used, the diction, create a Graph, or even run the data through machine learning algorithms. + +```js +run() { + const repositoriesFolder = this.outputFolderPath + "repositories/"; + const linkQueueFile = "linkQueue.txt"; + + const linkListCallback = async function (linkList) { + const outputFolderPath = this.outputFolderPath; + if (this.followReadMeLinks) { + await linkList.forEach(async (link) => { + await saveLinkToQueue(link, outputFolderPath, linkQueueFile); + }); + } + }.bind(this); + + let nextURL =await getNextLinkFromQueue(this.outputFolderPath, linkQueueFile + + while (nextURL) { + fetchAndProcessRepo(nextURL, repositoriesFolder, linkListCallback); + nextURL = await getNextLinkFromQueue(this.outputFolderPath, linkQueueFile); + } + } +``` + + +This project is also available on [npm](https://www.npmjs.com/package/readme-crawler). Install the package and try it yourself! + +```js +import ReadMeCrawler from 'readme-crawler'; + +var crawler = new ReadMeCrawler({ + startUrl: 'https://github.com/jnv/lists', + followReadMeLinks: true, + outputFolderPath: './output/' + }); + + crawler.run(); + +``` + +Not only was this project fun, but I was able to learn about using Node.js and other npm packages. I spent many hours reading about the 'fs' module, and thinking of different ways to process/store the data. I also tried working with executing commands with Node.js, to run the spell checker synchronously on each result. However, It was difficult to pipe the stdout correctly, and I realized that spell checking was a separate concern apart from web crawling anyways. +Overall, this was a great learning experience and problem solving exercise. + +--- + +View the source code on [GitHub](https://github.com/spencerlepine/readme-crawler). + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/building-a-readme-crawler-with-node-js/index.md b/content/building-a-readme-crawler-with-node-js/index.md new file mode 100644 index 0000000..1fe923f --- /dev/null +++ b/content/building-a-readme-crawler-with-node-js/index.md @@ -0,0 +1,189 @@ +--- +title: Building a README Crawler With Node.js +slug: building-a-web-crawler-with-node-js +tags: [GitHub, Repositories, WebCrawler, Node.js] +authors: [spencerlepine] +date: 2021-08-14T12:00 +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +Building a README Crawler with Node.js + +An Overview of the Node.js README Web Crawler project and how I created it. + +A recent project of mine was this Node.js [web crawler](https://github.com/spencerlepine/readme-crawler). Working on that led to this idea for another crawler. I wanted a way to +navigate through GitHub and search for obvious typos. I had this idea after stumbling across silly typos on numerous portfolio pages. Perhaps I could help fix these errors and +ensure these portfolio/sites are more presentable. + +If you’re interest in the final product, you can find the package [here](https://www.npmjs.com/package/readme-crawler), as well as the +[GitHub Repo](https://github.com/spencerlepine/readme-crawler). + +The goal was to create a process for automatically navigating through repositories and creating a method for spell-checking what is found. Doing that manually is time consuming, so +the computer will execute that process for us. A [web crawler](https://www.cloudflare.com/learning/bots/what-is-a-web-crawler/) will systematically browse different pages across +the internet. The purpose of this specific crawler would be scraping GitHub only. + +Here's the breakdown of this problem: + +- Fetch the HTML data from a URL +- Look at the README file displayed in that DOM +- Export README and details README for later use +- Generate a list of repository links in displayed in README + +To execute the algorithm, we will use [Node.js](https://nodejs.org/) (for the JavaScript runtime) and [node-fetch](https://www.npmjs.com/package/node-fetch) (for network requests). +This means we will run the code locally from the command line. For this project, we will have an output folder to store all the README data, as well as a list (queue) of repository +URLs to visit. Before diving into the code, it is important to plan the input and output of the algorithm. For this web crawler, we will start at a valid GitHub repository page, +which would be one URL string. After visiting each page with a README, we will export the data into a new file. Now lets cover the process of requesting a repository page from a +URL. For this, we only care about saving the README file that is displayed, and we will ignore any other links that GitHub displays (such as the navbar). We will send a URL request +with node-fetch, and retrieve the result of a HTML string. If we convert the HTML string to a DOM Tree, we can search for a specific element. GitHub stores the README file under a +div with the class "markdown-body". We can use a library called 'jsdom' to use Browser API methods, and return a specific node. + +```js +const fetchReadMeDOMFromRepoURL = async function (url) { + let destinationDOM; + + await fetch(url) + .then(response => { + return response.text(); + }) + .then(data => { + const { document } = new JSDOM(data).window; + const readmeNode = document.querySelector('.markdown-body'); + destinationDOM = readmeNode; + }) + .catch(err => { + console.warn('Could not fetch url: ' + url); + }); + + return destinationDOM; +}; +``` + +Now that we have access to a local node displaying the README content, we can export that data. Instead of using a spell checker at this stage, I decided to handle that separately +and resort to a command-line alternative. This meant the README file could be exported to file locally, and then we process spell checking files after the crawler stops running. +With a README DOM node we will convert it from HTML to a markdown file. Websites give the browser HTML code to display. + +```js +const exportRepoDOM = async function (readmeNode, repoURL, outputFolderPath) { + if (readmeNode) { + const { name, owner, href } = parseGitHubUrl(repoURL); + const folderDestination = `${outputFolderPath}${owner}-${name}/`; + + if (!fs.existsSync(folderDestination)) { + fs.mkdirSync(folderDestination); + } + + const markdown = turndownService.turndown(readmeNode.outerHTML); + createMarkdownFile(markdown, folderDestination); + + const info = `URL=${href}\nGIT_URL=${href}.git\nREPO_NAME=${name}\nOWNER=${owner}\n`; + createInfoFile(info, folderDestination); + } +}; +``` + +Before we are finished with this README, we have to traverse the DOM node to find any other GitHub repository links. This will allow us to follow pages and crawl GitHub. Keep in +mind though, there could be a README without any links, and we might want to navigate through GitHub some other way. Since we are using jsdom, we can use the built-in +getElementsByTagName method. We only want to save valid GitHub links, so we can use a helper function to test with regex. With that, we can create a list of links found. + +```js +const getLinksFromDOM = function (jsDOM, isUsableLink) { + const validLinks = []; + + const linkElements = (jsDOM && jsDOM.getElementsByTagName('a')) || []; + for (let i = 0; i < linkElements.length; i++) { + const thisElement = linkElements[i]; + const thisUrl = thisElement.href; + + if (isUsableLink(thisUrl)) { + validLinks.push(thisUrl); + } + } + return validLinks; +}; +``` + +Great, so far we retrieve README content from a URL and use that to generate a list of new URLs. If we want to continue searching and finding README files, we can follow the links +and repeat entire process. This will recursively crawl the GitHub repositories, allowing us to gather data. To keep track of the new URLs to visit, each link needs to be stored in +a queue, or in terms of data structures, a (stack)[https://www.geeksforgeeks.org/stack-data-structure/]. To implement this, I append all the items of the new list to a file. +Whenever the program is ready to fetch the next link, we can pull and remove the first line of the queue file and return it for a new URL string. The link queue will be stored in a +file where we append/delete line by line. This was done to avoid storing an array in memory to avoid crashing, and to allow pausing the crawler and any point. + +```js +const saveLinkToQueue = function (linkStr, outputFolderPath, outputFileName) { + const filePath = outputFolderPath + outputFileName; + if (fs.existsSync(filePath)) { + fs.appendFile(filePath, linkStr + '\r\n', function (err) { + if (err) throw err; + }); + } else { + fs.writeFile(filePath, linkStr + '\r\n', function (err) { + if (err) throw err; + }); + } +}; +``` + +All of these modules together will download README files in an organized output folder. After running the web crawler, we can run a spell checker on the exported data. To do this, +I used a package called ‘[yaspeller](https://www.npmjs.com/package/yaspeller)’. Each time I want to correct a README, I can generate a file with all common typos and errors. + +```sh +yaspeller -e ".md" ./ --find-repeat-words --ignore-digits --ignore-urls --only-errors &> "spellcheck.txt" +``` + +And that's it! I now have a way to look through hundreds of repositories. I can spell check tons of README files and help people remove possibly embarrassing typos. There are many +ways to expand on this. You could analyze the languages used, the diction, create a Graph, or even run the data through machine learning algorithms. + +```js +run() { + const repositoriesFolder = this.outputFolderPath + "repositories/"; + const linkQueueFile = "linkQueue.txt"; + + const linkListCallback = async function (linkList) { + const outputFolderPath = this.outputFolderPath; + if (this.followReadMeLinks) { + await linkList.forEach(async (link) => { + await saveLinkToQueue(link, outputFolderPath, linkQueueFile); + }); + } + }.bind(this); + + let nextURL =await getNextLinkFromQueue(this.outputFolderPath, linkQueueFile + + while (nextURL) { + fetchAndProcessRepo(nextURL, repositoriesFolder, linkListCallback); + nextURL = await getNextLinkFromQueue(this.outputFolderPath, linkQueueFile); + } + } +``` + +This project is also available on [npm](https://www.npmjs.com/package/readme-crawler). Install the package and try it yourself! + +```js +import ReadMeCrawler from 'readme-crawler'; + +var crawler = new ReadMeCrawler({ + startUrl: 'https://github.com/jnv/lists', + followReadMeLinks: true, + outputFolderPath: './output/', +}); + +crawler.run(); +``` + +Not only was this project fun, but I was able to learn about using Node.js and other npm packages. I spent many hours reading about the 'fs' module, and thinking of different ways +to process/store the data. I also tried working with executing commands with Node.js, to run the spell checker synchronously on each result. However, It was difficult to pipe the +stdout correctly, and I realized that spell checking was a separate concern apart from web crawling anyways. Overall, this was a great learning experience and problem solving +exercise. + +--- + +View the source code on [GitHub](https://github.com/spencerlepine/readme-crawler). + +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/building-a-readme-crawler-with-node-js/building-a-readme-crawler-with-node-js.md b/content/building-a-readme-crawler-with-node-js/index.medium similarity index 95% rename from blog/building-a-readme-crawler-with-node-js/building-a-readme-crawler-with-node-js.md rename to content/building-a-readme-crawler-with-node-js/index.medium index 8874ed5..4144a67 100644 --- a/blog/building-a-readme-crawler-with-node-js/building-a-readme-crawler-with-node-js.md +++ b/content/building-a-readme-crawler-with-node-js/index.medium @@ -1,9 +1,7 @@ --- title: Building a README Crawler With Node.js -slug: building-a-web-crawler-with-node-js -tags: [GitHub, Repositories, WebCrawler, Node.js] -authors: [spencerlepine] -date: 2021-08-14T12:00 +description: An Overview of the Node.js README Web Crawler project and how I created it. +publish_status: "draft" --- ![Blog Post Thumbnail](./thumbnail.jpg) @@ -165,8 +163,9 @@ Overall, this was a great learning experience and problem solving exercise. View the source code on [GitHub](https://github.com/spencerlepine/readme-crawler). -Also find me here: -* [Twitter (@spencerlepine)](https://twitter.com/SpencerLepine) -* [GitHub (@spencerlepine)](https://github.com/spencerlepine) -* [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) -* [YouTube (Spencer Lepine)](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/building-a-readme-crawler-with-node-js/thumbnail.jpg b/content/building-a-readme-crawler-with-node-js/thumbnail.jpg similarity index 100% rename from blog/building-a-readme-crawler-with-node-js/thumbnail.jpg rename to content/building-a-readme-crawler-with-node-js/thumbnail.jpg diff --git a/content/building-llama-as-a-service/index.devto b/content/building-llama-as-a-service/index.devto new file mode 100644 index 0000000..a1a6884 --- /dev/null +++ b/content/building-llama-as-a-service/index.devto @@ -0,0 +1,192 @@ +--- +title: Building Llama as a Service (LaaS) +description: Creating the world’s first Llama as a Service, the random image API you didn't realize you needed. # Dev.to +tags: 'nodejs, mongodb, heroku' # Dev.to (Max 3) +canonical_url: null # Dev.to +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +This is a walkthrough of the development process and system design engineering for the Llama as a Service. LaaS is a website and public API that can serve random Llama images. It will respond with a single image URL, or even a list. + +- Visit the [LaaS website](https://llama-as-a-service.netlify.app/) for a demo +- View the source code on [GitHub](https://github.com/orgs/llama-as-a-service/repositories) +- View the walkthrough [YouTube video](https://www.youtube.com/watch?v=uDQUA_JTMJk) + +### What I Learned + +For this project, there is a frontend built with [React](https://reactjs.org/) hosted on [Netlify](https://www.netlify.com/), connected to the backend. + +I built each API with Node.js, Express, and Docker. Services connected to a NoSQL [MongoDB](https://www.mongodb.com/) database. + +Each service is in an independent repository to maintain separation of concerns. It would have been possible to build this in a monorepo, but it was good practice. + +Each repository uses [GitHub Actions](https://docs.github.com/en/actions) to build, and test the code on every push. Express API was deployed to [Heroku](https://www.heroku.com/) when the main branch was pushed. + +With each app containerized with [Docker](https://www.docker.com/), this allows it to be run on any other developer's machine also running Docker. Although I had automated deployments to Heroku without this, I decided to upload each service to a container registry. + +Each repository also used a GitHub Actions workflow to automatically tag and version updates and releases. It would then build and publish the most up to date Docker image, and release it to the [GitHub Container Registry](https://ghcr.io/). + +For future use, this makes it crazy easy to deploy a Kubernetes cluster to the cloud, with a simple `docker pull ghcr.io/OWNER/IMAGE_NAME` command. However, that was beyond the scope of this project because of zero budget. + +To manage the environment variables, I was able to share Secrets to the GitHub Action workflows, which are encrypted, and can be shared across an entire organization (meaning multiple repos could access the variables). This allowed me to deploy my code securely to Heroku, without ever hard-coding the API keys. + +Another tool I used was [Artillery](https://www.artillery.io/) for load testing on my local machine. + +Instead of npm, I tried using `yarn` for the package manager, and it was WAY faster in GitHub Actions even without caching enabled. + +Although they did not make it into production, I experimented with the [RabbitMQ](https://www.rabbitmq.com/) message broker, Python (Django, Flask), Kubernetes + minikube, [JWT](https://jwt.io/), and [NGINX](https://www.nginx.com/). This was a hobby project, but I intended to learn about microservices along the way. + +### Demonstration +Here is a screen shot of the [LaaS](https://llama-as-a-service.netlify.app/) website. + +![Frontend Screenshot](https://user-images.githubusercontent.com/60903378/179845930-8bd90991-42da-400b-8983-543030be0502.png) + +If you would like to try out the API, simply made a GET request to the following endpoint: + +`https://llama-as-a-service-images.herokuapp.com/random` +### Creating an API +First, I started with a simple API built with Node.js and Express, containerized with Docker. I set up GitHub Actions for CI to build and test it on each push. This will later connect to the database, to respond with image URLs. + +![Images API](https://user-images.githubusercontent.com/60903378/179846653-c04f2636-75a0-47a0-9789-d58a0cd3928e.png) + +Although this API doesn’t NEED to scale to millions of users, it was a valuable exercise for building and scaling a system. I aimed for a minimum latency of 300ms with 200 RPS. +### Image Database +With an API ready to connect to the database, it was time to choose between a NoSQL or SQL database. + +The answer is obvious for this use case. Let’s walk through the data we have, and the use cases. + +We are going to store one single table with image URLs. This could easily be done in either database, but there is one key factor. We need a way to randomly pull a list of images from the database. + +A SQL database makes it simple to query a random row, however, this is not horizontally scalable, and with a large data set, we are replicating the ENTIRE database to each new node. + +On the other hand, NoSQL databases are horizontally scalable; which leads me to Cassandra, but unfortunately it is very difficult to pull random selections from this type of NoSQL database. + +Finally, I settled with MongoDB, which has a built-in `$sample` method to pull from the records. + +![Mongo Database](https://user-images.githubusercontent.com/60903378/179846661-8e20b67d-6d28-4971-939b-a7d347f15ee4.png) + +Once I got the MongoDB database running locally with Docker, I created a quick script to seed the database. + +Now it’s time to connect the API to the database. + +### Connecting API to the Database +Next, I used the `mongoose` Node.js API to connect to the local MongoDB. + +I created two endpoints; one to upload an image URL, and another to retrieve a random list of images. + +![API Database Connection](https://user-images.githubusercontent.com/60903378/179846674-642b4412-3385-4b0a-9640-036225ce1423.png) + + +### Endpoint Load Testing +To experiment with scaling the API, I wanted to do load testing. Keep in mind that this API does not have much logic, meaning caching, or optimizing the code's performance, will have a huge impact. + +I found a tool for load testing called [Artillery](https://www.artillery.io/). Following [this guide](https://blog.appsignal.com/2021/11/10/a-guide-to-load-testing-nodejs-apis-with-artillery.html) I installed Artillery and began research for the test configuration. + +The API currently has the `/random` endpoint to return an image URL (a string), with very little computation. Let’s stress test this to see the current traffic limit. + + +The random list endpoint is what we need to optimize. For the starting algorithm though, I seeded 100 image records into the database, and then pulled the ENTIRE list from the database each request. The API would then choose 25 random elements to return. Let’s benchmark how this performs with load testing. + +With the first run, API, the limit on the `/random?count=25` endpoint was 225 RPS over 15 seconds, with 99% of the response times were under 300ms. We can improve this. + +![Load Testing Latency Chart](https://user-images.githubusercontent.com/60903378/179846688-33198d9a-f9fa-4611-ba15-7161f2bf87ce.png) + +![Load Testing](https://user-images.githubusercontent.com/60903378/179846696-e82bfe4e-b9b9-4114-9b59-48785b945021.png) + +### Optimizing the Endpoint +We have many records of image URLs in the database. Somehow, we need to efficiently transform these into a list, pulling random selections from the database. + +![Random Database Query](https://user-images.githubusercontent.com/60903378/179846759-e5654196-093c-41a2-a5aa-06029ca5c47a.png) + +Let’s optimize the query for pulling documents from the database. Using a special mongodb query, we can drastically reduce the computational load for a single request. Running locally in postman, `random?count=25` endpoint went from ~150ms for a single request, to \<50ms. + +This is the only code we need for this endpoint, compared to the previous 20 lines and O(n^2) space. + +![Random Query Code](https://user-images.githubusercontent.com/60903378/179846772-fdcf54a1-34eb-42a1-a4cd-8b05ba783a7f.png) + +With the new query, the endpoint maintains 99% sub-300ms response time with a max of 440 RPS over 15 seconds. + +![Latency Improvements Chart](https://user-images.githubusercontent.com/60903378/179846777-3518451f-33f2-4638-b4d9-c614db7d52e5.png) + + +### Horizontally Scaling the API +With the containerized Node.js/Express API, I could run multiple containers, scaling to handle more traffic. Using a tool called [minikube](https://github.com/kubernetes/minikube), we can easily spin up a local [Kubernetes](https://github.com/kubernetes/kubernetes) cluster to horizontally scale Docker containers. It was possible to keep one shared instance of the database, and many APIs were routed with an internal Kubernetes load balancer. + +Horizontally scaling the API to two instances, the random endpoint maintains 99% sub-300ms response time with a max of 650 RPS over 15 seconds. Three API Instances => 99% sub-300ms response time with a max of 1000 RPS over 15 seconds. Five API Instances => 99% sub-300ms response time with a max of 1200 RPS over 15 seconds. + +In practice, five instances were the limit of scaling the API horizontally. Even with more instances, the traffic was never sub 300ms response time. Note, this is dependent on the hardware of my local machine, and not accounting for cross-network latency in the real world. + +With scaling, we can achieve higher throughput, allowing more traffic to flow, and resiliency, where a failed node can simply be replaced. + +![API Horizontal Scale](https://user-images.githubusercontent.com/60903378/179846784-c605f7e8-856a-4d8d-b1ff-e9ad16d34c33.png) + +Since the image responses are intended to be random, we cannot cache the responses. It would be possible to scale the database with a slave/master system, but without a large data set, it is not worth the time to test. The bottleneck is most likely the API and connections to the database, versus MongoDB not handling read requests. It may be possible to improve the read times with a REDIS database, using in-memory caching, but that is overkill for this project. +### Setting up Authentication +After playing around with load testing, I wanted to explore [JSON Web Tokens](https://jwt.io/) and build an API to handle authentication. + +This auth API will generate tokens, which will be sent back to the client as headers. The tokens headers are stored client-side (e.g. cookies, local storage), and sent to the backend each request. + +If we expand the backend, we could include the authentication logic in each microservice. + +![API Coupled Services](https://user-images.githubusercontent.com/60903378/179846797-c965ec7f-4076-4ed7-9b2e-4909004fec6e.png) + + +Not practical. Instead, we can decouple the logic into its own service as shown below: + +![API Auth Gateway](https://user-images.githubusercontent.com/60903378/179846807-6f650b2d-165f-4345-8f93-34633b2f3cc4.png) + +### Creating a Gateway API +Instead of exposing the users directly to each microservice, we should route ALL traffic from the clients to the Gateway API. For this, I chose the same tech stack of Node.js/Express. Using a library, I was able to set up a proxy to the other services. In the future, this could be very useful to standardize requests to the backend, track usage, forward data to a logging microservice, talk to a message broker, and more. + +### Environment Variables and Configuration +Most of the system built, I needed to simplify the process for configuring the Docker containers locally, and how environment variables would be shared to each. Keep in mind, each service needed to access these in GitHub Actions as well, during deployment. + +I used the `docker-compose` files to easily spin up the containers locally. I used default values for the environment variables for local development, and kept the config files separated so it was easy to follow. + +This step was just a process of carefully writing the Docker and docker-compose files, and setting up GitHub Actions Secrets. The code could not run without having all env variables, could be hard to debug locally or lead to ambiguity for other developers. + + +### A Simple Frontend +I would talk about building the frontend, but it is just a single page React app I built quickly. It does use a CSS library called [Bulma](https://bulma.io/), which is similar to tailwind and worth checking out. I did spend a day implementing a login/signup page, but this was just for the learning experience, and not what I wanted in the final product. + +### GitHub Actions Testing and Deployment +With most of the code written, it was time to deploy the app. This was actually a bumpy road because I was not sure how to approach this. I was keeping each component in its own repository on my personal GitHub Account, which was getting hard to keep track of. + +My solution was to create the [Llama as a Service](https://github.com/llama-as-a-service) GitHub Organization, which also allowed me to store organization-wide secrets that any repository could access. + +Using GitHub Actions, I created workflows to build and test code on every push, and deploy to main branch Heroku (and Netlify for the frontend). + +I also created a workflow to tag and version every update, and release the Docker image to the [GitHub Container Registry](https://ghcr.io/). These packages could be private to the organization, or public. I did not end up using these published containers, but it was really dope to see everything automated. + +### Deploying to Production + +So after deploying the gateway API, frontend, and backend, I hoped all the services would be connected in production. For some reason the [http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware) was causing problems, and it was not worth redesigning the whole system. I was not ready to work with deploying a Kubernetes Cluster, so I did not use the GHCR Docker packages for deploying. + +Instead, I just stripped away the extra services that I had been working on, and stuck with a simple system to deploy. For the final product, there is the frontend deployed on Netlify, which connects to the API on Heroku, with talks to the MongoDB Atlas database (in the cloud). + +![Application Architecture Diagram](https://user-images.githubusercontent.com/60903378/179846810-754daa79-2639-4550-a7dd-e0be88ef71bf.png) + +### View the Source Code +If you wish to view all of the source code for this project, you can look through each repository here: + +- GitHub Organization: [github.com/llama-as-a-service](https://github.com/llama-as-a-service) +- All the GHCR Packages: [github.com/orgs/llama-as-a-service/packages](https://github.com/orgs/llama-as-a-service/packages) +- Frontend - [github.com/llama-as-a-service/frontend](https://github.com/llama-as-a-service/frontend) +- Images API - [github.com/llama-as-a-service/images-service](https://github.com/llama-as-a-service/images-service) +- Authentication API - [github.com/llama-as-a-service/auth-service](https://github.com/llama-as-a-service/auth-service) +- Gateway API - [github.com/llama-as-a-service/gateway-service](https://github.com/llama-as-a-service/gateway-service) + + +If you want to have a repository with Node.js, Express, and Docker set up with GitHub Actions, check out the [boilerplate repository here](https://github.com/llama-as-a-service/express-docker-boilerplate) + +If you are interested in more projects by me, you can check out the [ManyShiba Twitter bot](https://spencerlepine.github.io/blog/manyshiba-the-worlds-greatest-twitter-bot), or more on my website. + +--- + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/building-llama-as-a-service/index.md b/content/building-llama-as-a-service/index.md new file mode 100644 index 0000000..22111eb --- /dev/null +++ b/content/building-llama-as-a-service/index.md @@ -0,0 +1,240 @@ +--- +title: Building Llama as a Service (LaaS) +slug: building-llama-as-a-service +tags: [Express, Docker, MongoDB, Node.js, Heroku, GitHub Actions] +authors: [spencerlepine] +date: 2022-07-12T12:00 +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +This is a walkthrough of the development process and system design engineering for the Llama as a Service. LaaS is a website and public API that can serve random Llama images. It +will respond with a single image URL, or even a list. + +- Visit the [LaaS website](https://llama-as-a-service.netlify.app/) for a demo +- View the source code on [GitHub](https://github.com/orgs/llama-as-a-service/repositories) +- View the walkthrough [YouTube video](https://www.youtube.com/watch?v=uDQUA_JTMJk) + +### What I Learned + +For this project, there is a frontend built with [React](https://reactjs.org/) hosted on [Netlify](https://www.netlify.com/), connected to the backend. + +I built each API with Node.js, Express, and Docker. Services connected to a NoSQL [MongoDB](https://www.mongodb.com/) database. + +Each service is in an independent repository to maintain separation of concerns. It would have been possible to build this in a monorepo, but it was good practice. + +Each repository uses [GitHub Actions](https://docs.github.com/en/actions) to build, and test the code on every push. Express API was deployed to [Heroku](https://www.heroku.com/) +when the main branch was pushed. + +With each app containerized with [Docker](https://www.docker.com/), this allows it to be run on any other developer's machine also running Docker. Although I had automated +deployments to Heroku without this, I decided to upload each service to a container registry. + +Each repository also used a GitHub Actions workflow to automatically tag and version updates and releases. It would then build and publish the most up to date Docker image, and +release it to the [GitHub Container Registry](https://ghcr.io/). + +For future use, this makes it crazy easy to deploy a Kubernetes cluster to the cloud, with a simple `docker pull ghcr.io/OWNER/IMAGE_NAME` command. However, that was beyond the +scope of this project because of zero budget. + +To manage the environment variables, I was able to share Secrets to the GitHub Action workflows, which are encrypted, and can be shared across an entire organization (meaning +multiple repos could access the variables). This allowed me to deploy my code securely to Heroku, without ever hard-coding the API keys. + +Another tool I used was [Artillery](https://www.artillery.io/) for load testing on my local machine. + +Instead of npm, I tried using `yarn` for the package manager, and it was WAY faster in GitHub Actions even without caching enabled. + +Although they did not make it into production, I experimented with the [RabbitMQ](https://www.rabbitmq.com/) message broker, Python (Django, Flask), Kubernetes + minikube, +[JWT](https://jwt.io/), and [NGINX](https://www.nginx.com/). This was a hobby project, but I intended to learn about microservices along the way. + +### Demonstration + +Here is a screen shot of the [LaaS](https://llama-as-a-service.netlify.app/) website. + +![Frontend Screenshot](https://user-images.githubusercontent.com/60903378/179845930-8bd90991-42da-400b-8983-543030be0502.png) + +If you would like to try out the API, simply made a GET request to the following endpoint: + +`https://llama-as-a-service-images.herokuapp.com/random` + +### Creating an API + +First, I started with a simple API built with Node.js and Express, containerized with Docker. I set up GitHub Actions for CI to build and test it on each push. This will later +connect to the database, to respond with image URLs. + +![Images API](https://user-images.githubusercontent.com/60903378/179846653-c04f2636-75a0-47a0-9789-d58a0cd3928e.png) + +Although this API doesn’t NEED to scale to millions of users, it was a valuable exercise for building and scaling a system. I aimed for a minimum latency of 300ms with 200 RPS. + +### Image Database + +With an API ready to connect to the database, it was time to choose between a NoSQL or SQL database. + +The answer is obvious for this use case. Let’s walk through the data we have, and the use cases. + +We are going to store one single table with image URLs. This could easily be done in either database, but there is one key factor. We need a way to randomly pull a list of images +from the database. + +A SQL database makes it simple to query a random row, however, this is not horizontally scalable, and with a large data set, we are replicating the ENTIRE database to each new +node. + +On the other hand, NoSQL databases are horizontally scalable; which leads me to Cassandra, but unfortunately it is very difficult to pull random selections from this type of NoSQL +database. + +Finally, I settled with MongoDB, which has a built-in `$sample` method to pull from the records. + +![Mongo Database](https://user-images.githubusercontent.com/60903378/179846661-8e20b67d-6d28-4971-939b-a7d347f15ee4.png) + +Once I got the MongoDB database running locally with Docker, I created a quick script to seed the database. + +Now it’s time to connect the API to the database. + +### Connecting API to the Database + +Next, I used the `mongoose` Node.js API to connect to the local MongoDB. + +I created two endpoints; one to upload an image URL, and another to retrieve a random list of images. + +![API Database Connection](https://user-images.githubusercontent.com/60903378/179846674-642b4412-3385-4b0a-9640-036225ce1423.png) + +### Endpoint Load Testing + +To experiment with scaling the API, I wanted to do load testing. Keep in mind that this API does not have much logic, meaning caching, or optimizing the code's performance, will +have a huge impact. + +I found a tool for load testing called [Artillery](https://www.artillery.io/). Following +[this guide](https://blog.appsignal.com/2021/11/10/a-guide-to-load-testing-nodejs-apis-with-artillery.html) I installed Artillery and began research for the test configuration. + +The API currently has the `/random` endpoint to return an image URL (a string), with very little computation. Let’s stress test this to see the current traffic limit. + +The random list endpoint is what we need to optimize. For the starting algorithm though, I seeded 100 image records into the database, and then pulled the ENTIRE list from the +database each request. The API would then choose 25 random elements to return. Let’s benchmark how this performs with load testing. + +With the first run, API, the limit on the `/random?count=25` endpoint was 225 RPS over 15 seconds, with 99% of the response times were under 300ms. We can improve this. + +![Load Testing Latency Chart](https://user-images.githubusercontent.com/60903378/179846688-33198d9a-f9fa-4611-ba15-7161f2bf87ce.png) + +![Load Testing](https://user-images.githubusercontent.com/60903378/179846696-e82bfe4e-b9b9-4114-9b59-48785b945021.png) + +### Optimizing the Endpoint + +We have many records of image URLs in the database. Somehow, we need to efficiently transform these into a list, pulling random selections from the database. + +![Random Database Query](https://user-images.githubusercontent.com/60903378/179846759-e5654196-093c-41a2-a5aa-06029ca5c47a.png) + +Let’s optimize the query for pulling documents from the database. Using a special mongodb query, we can drastically reduce the computational load for a single request. Running +locally in postman, `random?count=25` endpoint went from ~150ms for a single request, to \<50ms. + +This is the only code we need for this endpoint, compared to the previous 20 lines and O(n^2) space. + +![Random Query Code](https://user-images.githubusercontent.com/60903378/179846772-fdcf54a1-34eb-42a1-a4cd-8b05ba783a7f.png) + +With the new query, the endpoint maintains 99% sub-300ms response time with a max of 440 RPS over 15 seconds. + +![Latency Improvements Chart](https://user-images.githubusercontent.com/60903378/179846777-3518451f-33f2-4638-b4d9-c614db7d52e5.png) + +### Horizontally Scaling the API + +With the containerized Node.js/Express API, I could run multiple containers, scaling to handle more traffic. Using a tool called [minikube](https://github.com/kubernetes/minikube), +we can easily spin up a local [Kubernetes](https://github.com/kubernetes/kubernetes) cluster to horizontally scale Docker containers. It was possible to keep one shared instance of +the database, and many APIs were routed with an internal Kubernetes load balancer. + +Horizontally scaling the API to two instances, the random endpoint maintains 99% sub-300ms response time with a max of 650 RPS over 15 seconds. Three API Instances => 99% sub-300ms +response time with a max of 1000 RPS over 15 seconds. Five API Instances => 99% sub-300ms response time with a max of 1200 RPS over 15 seconds. + +In practice, five instances were the limit of scaling the API horizontally. Even with more instances, the traffic was never sub 300ms response time. Note, this is dependent on the +hardware of my local machine, and not accounting for cross-network latency in the real world. + +With scaling, we can achieve higher throughput, allowing more traffic to flow, and resiliency, where a failed node can simply be replaced. + +![API Horizontal Scale](https://user-images.githubusercontent.com/60903378/179846784-c605f7e8-856a-4d8d-b1ff-e9ad16d34c33.png) + +Since the image responses are intended to be random, we cannot cache the responses. It would be possible to scale the database with a slave/master system, but without a large data +set, it is not worth the time to test. The bottleneck is most likely the API and connections to the database, versus MongoDB not handling read requests. It may be possible to +improve the read times with a REDIS database, using in-memory caching, but that is overkill for this project. + +### Setting up Authentication + +After playing around with load testing, I wanted to explore [JSON Web Tokens](https://jwt.io/) and build an API to handle authentication. + +This auth API will generate tokens, which will be sent back to the client as headers. The tokens headers are stored client-side (e.g. cookies, local storage), and sent to the +backend each request. + +If we expand the backend, we could include the authentication logic in each microservice. + +![API Coupled Services](https://user-images.githubusercontent.com/60903378/179846797-c965ec7f-4076-4ed7-9b2e-4909004fec6e.png) + +Not practical. Instead, we can decouple the logic into its own service as shown below: + +![API Auth Gateway](https://user-images.githubusercontent.com/60903378/179846807-6f650b2d-165f-4345-8f93-34633b2f3cc4.png) + +### Creating a Gateway API + +Instead of exposing the users directly to each microservice, we should route ALL traffic from the clients to the Gateway API. For this, I chose the same tech stack of +Node.js/Express. Using a library, I was able to set up a proxy to the other services. In the future, this could be very useful to standardize requests to the backend, track usage, +forward data to a logging microservice, talk to a message broker, and more. + +### Environment Variables and Configuration + +Most of the system built, I needed to simplify the process for configuring the Docker containers locally, and how environment variables would be shared to each. Keep in mind, each +service needed to access these in GitHub Actions as well, during deployment. + +I used the `docker-compose` files to easily spin up the containers locally. I used default values for the environment variables for local development, and kept the config files +separated so it was easy to follow. + +This step was just a process of carefully writing the Docker and docker-compose files, and setting up GitHub Actions Secrets. The code could not run without having all env +variables, could be hard to debug locally or lead to ambiguity for other developers. + +### A Simple Frontend + +I would talk about building the frontend, but it is just a single page React app I built quickly. It does use a CSS library called [Bulma](https://bulma.io/), which is similar to +tailwind and worth checking out. I did spend a day implementing a login/signup page, but this was just for the learning experience, and not what I wanted in the final product. + +### GitHub Actions Testing and Deployment + +With most of the code written, it was time to deploy the app. This was actually a bumpy road because I was not sure how to approach this. I was keeping each component in its own +repository on my personal GitHub Account, which was getting hard to keep track of. + +My solution was to create the [Llama as a Service](https://github.com/llama-as-a-service) GitHub Organization, which also allowed me to store organization-wide secrets that any +repository could access. + +Using GitHub Actions, I created workflows to build and test code on every push, and deploy to main branch Heroku (and Netlify for the frontend). + +I also created a workflow to tag and version every update, and release the Docker image to the [GitHub Container Registry](https://ghcr.io/). These packages could be private to the +organization, or public. I did not end up using these published containers, but it was really dope to see everything automated. + +### Deploying to Production + +So after deploying the gateway API, frontend, and backend, I hoped all the services would be connected in production. For some reason the +[http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware) was causing problems, and it was not worth redesigning the whole system. I was not ready to work with +deploying a Kubernetes Cluster, so I did not use the GHCR Docker packages for deploying. + +Instead, I just stripped away the extra services that I had been working on, and stuck with a simple system to deploy. For the final product, there is the frontend deployed on +Netlify, which connects to the API on Heroku, with talks to the MongoDB Atlas database (in the cloud). + +![Application Architecture Diagram](https://user-images.githubusercontent.com/60903378/179846810-754daa79-2639-4550-a7dd-e0be88ef71bf.png) + +### View the Source Code + +If you wish to view all of the source code for this project, you can look through each repository here: + +- GitHub Organization: [github.com/llama-as-a-service](https://github.com/llama-as-a-service) +- All the GHCR Packages: [github.com/orgs/llama-as-a-service/packages](https://github.com/orgs/llama-as-a-service/packages) +- Frontend - [github.com/llama-as-a-service/frontend](https://github.com/llama-as-a-service/frontend) +- Images API - [github.com/llama-as-a-service/images-service](https://github.com/llama-as-a-service/images-service) +- Authentication API - [github.com/llama-as-a-service/auth-service](https://github.com/llama-as-a-service/auth-service) +- Gateway API - [github.com/llama-as-a-service/gateway-service](https://github.com/llama-as-a-service/gateway-service) + +If you want to have a repository with Node.js, Express, and Docker set up with GitHub Actions, check out the +[boilerplate repository here](https://github.com/llama-as-a-service/express-docker-boilerplate) + +If you are interested in more projects by me, you can check out the [ManyShiba Twitter bot](https://spencerlepine.github.io/blog/manyshiba-the-worlds-greatest-twitter-bot), or more +on my website. + +--- + +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/building-llama-as-a-service/index.md b/content/building-llama-as-a-service/index.medium similarity index 96% rename from blog/building-llama-as-a-service/index.md rename to content/building-llama-as-a-service/index.medium index f0b22a7..007f72e 100644 --- a/blog/building-llama-as-a-service/index.md +++ b/content/building-llama-as-a-service/index.medium @@ -1,9 +1,7 @@ --- title: Building Llama as a Service (LaaS) -slug: building-llama-as-a-service -tags: [Express, Docker, MongoDB, Node.js, Heroku, GitHub Actions] -authors: [spencerlepine] -date: 2022-07-12T12:00 +description: Creating the world’s first Llama as a Service, the random image API you didn't realize you needed. +publish_status: "draft" --- ![Blog Post Thumbnail](./thumbnail.jpg) @@ -181,12 +179,13 @@ If you wish to view all of the source code for this project, you can look throug If you want to have a repository with Node.js, Express, and Docker set up with GitHub Actions, check out the [boilerplate repository here](https://github.com/llama-as-a-service/express-docker-boilerplate) -If you are interested in more projects by me, you can check out the [ManyShiba Twitter bot](https://www.spencerlepine.com/blog/manyshiba-the-worlds-greatest-twitter-bot), or more on my website. +If you are interested in more projects by me, you can check out the [ManyShiba Twitter bot](https://spencerlepine.github.io/blog/manyshiba-the-worlds-greatest-twitter-bot), or more on my website. --- -Also find me here: -* [Twitter (@spencerlepine)](https://twitter.com/SpencerLepine) -* [GitHub (@spencerlepine)](https://github.com/spencerlepine) -* [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) -* [YouTube (Spencer Lepine)](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/building-llama-as-a-service/thumbnail.jpg b/content/building-llama-as-a-service/thumbnail.jpg similarity index 100% rename from blog/building-llama-as-a-service/thumbnail.jpg rename to content/building-llama-as-a-service/thumbnail.jpg diff --git a/blog/creating-custom-git-commands/index.devto b/content/creating-custom-git-commands/index.devto similarity index 84% rename from blog/creating-custom-git-commands/index.devto rename to content/creating-custom-git-commands/index.devto index f0a5105..8c66a32 100644 --- a/blog/creating-custom-git-commands/index.devto +++ b/content/creating-custom-git-commands/index.devto @@ -55,8 +55,9 @@ Use this script or create your own, and follow these steps to set up the custom Viola! This script will accept one command line argument of the destination repo URL. It will automatically open the new project in VSCode in one command. -Also find me here: - - [Twitter](https://twitter.com/SpencerLepine) - - [GitHub](https://github.com/spencerlepine) - - [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) - - [YouTube](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/creating-custom-git-commands/index.md b/content/creating-custom-git-commands/index.md similarity index 59% rename from blog/creating-custom-git-commands/index.md rename to content/creating-custom-git-commands/index.md index bee8169..617b5cb 100644 --- a/blog/creating-custom-git-commands/index.md +++ b/content/creating-custom-git-commands/index.md @@ -9,22 +9,26 @@ date: 2021-08-15T12:00 ![Blog Post Thumbnail](./thumbnail.jpg) -Every time I clone a repository from GitHub, I always run the same set of commands. This is prone to typos and simply inconvenient. There is a simple solution of combining each step into a single command that automatically runs everything for us. +Every time I clone a repository from GitHub, I always run the same set of commands. This is prone to typos and simply inconvenient. There is a simple solution of combining each +step into a single command that automatically runs everything for us. In this example, I need to clone a GitHub repository, move into the new directory, and then open the project in VSCode. Instead of multiple commands: + ```sh git clone https://github.com/spencerlepine/readme-crawler cd readme-crawler code . ``` + It would great to run one command: + ```sh clone https://github.com/spencerlepine/readme-crawler ``` -To achieve this, we can create a script in the ```~/bin``` directory. Make sure this path matches up with your configuration for the terminal (e.g. ```PATH=$PATH:$HOME/bin```). +To achieve this, we can create a script in the `~/bin` directory. Make sure this path matches up with your configuration for the terminal (e.g. `PATH=$PATH:$HOME/bin`). Let’s create a custom script to combine the git commands. @@ -43,22 +47,24 @@ Let’s create a custom script to combine the git commands. Use this script or create your own, and follow these steps to set up the custom command: -- Navigate to usr/local/bin -> ```cd ~/../../usr/local/bin``` -- Run ```vim clone``` - - *Paste the script* +- Navigate to usr/local/bin -> `cd ~/../../usr/local/bin` +- Run `vim clone` + - _Paste the script_ - Save the file: - - *press ‘ESC’ - - *press ‘SHIFT’ + ‘:’ - - *type ‘wq’ + ENTER + - \*press ‘ESC’ + - \*press ‘SHIFT’ + ‘:’ + - \*type ‘wq’ + ENTER - Create an executable - - ```chmod +x clone``` + - `chmod +x clone` - Run the command! - - ```clone https://github.com/spencerlepine/manyshiba-bot.git``` + - `clone https://github.com/spencerlepine/manyshiba-bot.git` Viola! This script will accept one command line argument of the destination repo URL. It will automatically open the new project in VSCode in one command. -Also find me here: - - [Twitter](https://twitter.com/SpencerLepine) - - [GitHub](https://github.com/spencerlepine) - - [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) - - [YouTube](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/creating-custom-git-commands/index.medium b/content/creating-custom-git-commands/index.medium similarity index 83% rename from blog/creating-custom-git-commands/index.medium rename to content/creating-custom-git-commands/index.medium index e5cff8e..f876258 100644 --- a/blog/creating-custom-git-commands/index.medium +++ b/content/creating-custom-git-commands/index.medium @@ -54,8 +54,9 @@ Use this script or create your own, and follow these steps to set up the custom Viola! This script will accept one command line argument of the destination repo URL. It will automatically open the new project in VSCode in one command. -Also find me here: - - [Twitter](https://twitter.com/SpencerLepine) - - [GitHub](https://github.com/spencerlepine) - - [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) - - [YouTube](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/creating-custom-git-commands/thumbnail.jpg b/content/creating-custom-git-commands/thumbnail.jpg similarity index 100% rename from blog/creating-custom-git-commands/thumbnail.jpg rename to content/creating-custom-git-commands/thumbnail.jpg diff --git a/content/git-project-configuration-with-husky-and-eslint/index.devto b/content/git-project-configuration-with-husky-and-eslint/index.devto new file mode 100644 index 0000000..215642d --- /dev/null +++ b/content/git-project-configuration-with-husky-and-eslint/index.devto @@ -0,0 +1,158 @@ +--- +title: Git Project Configuration With Husky and ESLint +description: Git conventions using pre-commit hooks and enforcing code styles. # Dev.to +tags: 'linter, husky, workflow' # Dev.to (Max 3) +canonical_url: null # Dev.to +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +Working on a project with Git and GitHub is relatively simple. When a project starts to grow however, it is crucial to write clean code that other developers can read. Follow this article to learn how to set up linting and pre-commit hooks for your repository. + +Let’s walk through the steps for a one-time setup to configure [husky](https://github.com/typicode/husky) pre-commit and pre-push hooks, [ESLint](https://eslint.org/) with code styles conventions, [prettier](https://prettier.io/) code formatter, and [lint-staged](https://github.com/okonet/lint-staged). Husky automatically runs a script on each commit or push. This is useful for linting files to enforce code styles that keeps the entire code base following conventions. + +## Walkthrough + +Install the dependencies: +``` +npm install husky@4.3.8 lint-staged@10.5.4 prettier@2.8.8 --save-dev +``` +``` +yarn add husky@4.3.8 lint-staged@10.5.4 prettier@2.8.8 --dev +``` + +### Package.json Updates + +Add the following to your `package.json` to configure all three packages: + +```json +{ + "name": "@spencer/example-package", + // ... + "scripts": { + "format": "prettier --write ." + }, + "prettier": { + "printWidth": 180, + "tabWidth": 2, + "singleQuote": true, + "semi": true, + "trailingComma": "es5", + "bracketSpacing": true, + "arrowParens": "avoid", + "proseWrap": "always", + "requirePragma": false, + "insertPragma": false, + "endOfLine": "lf", + "jsxBracketSameLine": true + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "**/*.(js|jsx|ts|tsx|json|css|md)": [ + "prettier --write" + ] + } +} +``` + +### Configure ESLint (optional) + +First, install this package +``` +npm install eslint-config-prettier +``` + +Then, run `npm init @eslint/config` to create a config file and choose preferred code styles. + +Alternatively, use this example file. In the root directory, create `.eslintrc`: + +```json +{ + "extends": [ + "eslint:recommended" + ], + "plugins": [ + "prettier" + ], + "parserOptions": { + "ecmaVersion": 2017 + }, + "env": { + "es6": true + }, + "rules": { + "no-console": "off", + "no-unused-vars": "off", + "react/prop-types": "off", + "quotes": [ + 2, + "double", + { + "avoidEscape": true + } + ] + } +} +``` + +## Everything in action + +After making changes, commit the files, and see `lint-staged` automatically run, triggered by the pre-commit hook. + +```sh +my-project$ git commit -m 'example commit message' +✔ Preparing lint-staged... +✔ Running tasks for staged files... +✔ Applying modifications from tasks... +✔ Cleaning up temporary files... +[example-branch 4bc4030] add new husky setup + 4 files changed, 59 insertions(+), 44 deletions(-) +``` + +All files have been linted and automatically fixed with `prettier`, or denied if too many errors were thrown. Now we can push the "clean" code. +```sh +my-project$ git push origin example-branch +# npx lint-staged +# ... (no errors found) +# npm test +# ... (PASS) +Enumerating objects: 7, done. +Counting objects: 100% (7/7), done. +Delta compression using up to 8 threads +Compressing objects: 100% (4/4), done. +Writing objects: 100% (4/4), 375 bytes | 375.00 KiB/s, done. +Total 4 (delta 3), reused 0 (delta 0), pack-reused 0 +remote: Resolving deltas: 100% (3/3), completed with 3 local objects. +To https://github.com/spencerlepine/my-project.git + 4bc4030..b558038 example-branch -> example-branch +``` + +## Boilerplate + +See a working example here: [GitHub repository](https://github.com/spencerlepine/husky-boilerplate). + +## Notes + +A useful trick is the `-–no-verify` flag to SKIP the pre-commit or pre-push hook. +Use this option to skip the husky script in case you force a commit/push. + +```sh +my-project$ git push origin my-branch --no-verify +# husky will not run "npm test" +... pushing to GitHub +``` + +When `husky` released v7, it had some major changes to the configuration. There are many articles and Stack Overflow answers about husky, but some of them are misleading if they were using v4. + +Hope this article helped! Interested in more, check out more articles [here](https://spencerlepine.github.io/blog). + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/git-project-configuration-with-husky-and-eslint/index.md b/content/git-project-configuration-with-husky-and-eslint/index.md new file mode 100644 index 0000000..34e7346 --- /dev/null +++ b/content/git-project-configuration-with-husky-and-eslint/index.md @@ -0,0 +1,160 @@ +--- +title: Git Project Configuration With Husky and ESLint +slug: git-project-configuration-with-husky-and-eslint +tags: [Git, Husky, ESLint, Workflow, GitHub] +authors: [spencerlepine] +date: 2022-03-20T12:00 +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +Working on a project with Git and GitHub is relatively simple. When a project starts to grow however, it is crucial to write clean code that other developers can read. Follow this +article to learn how to set up linting and pre-commit hooks for your repository. + +Let’s walk through the steps for a one-time setup to configure [husky](https://github.com/typicode/husky) pre-commit and pre-push hooks, [ESLint](https://eslint.org/) with code +styles conventions, [prettier](https://prettier.io/) code formatter, and [lint-staged](https://github.com/okonet/lint-staged). Husky automatically runs a script on each commit or +push. This is useful for linting files to enforce code styles that keeps the entire code base following conventions. + +## Walkthrough + +Install the dependencies: + +``` +npm install husky@4.3.8 lint-staged@10.5.4 prettier@2.8.8 --save-dev +``` + +``` +yarn add husky@4.3.8 lint-staged@10.5.4 prettier@2.8.8 --dev +``` + +### Package.json Updates + +Add the following to your `package.json` to configure all three packages: + +```json +{ + "name": "@spencer/example-package", + // ... + "scripts": { + "format": "prettier --write ." + }, + "prettier": { + "printWidth": 180, + "tabWidth": 2, + "singleQuote": true, + "semi": true, + "trailingComma": "es5", + "bracketSpacing": true, + "arrowParens": "avoid", + "proseWrap": "always", + "requirePragma": false, + "insertPragma": false, + "endOfLine": "lf", + "jsxBracketSameLine": true + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "**/*.(js|jsx|ts|tsx|json|css|md)": ["prettier --write"] + } +} +``` + +### Configure ESLint (optional) + +First, install this package + +``` +npm install eslint-config-prettier +``` + +Then, run `npm init @eslint/config` to create a config file and choose preferred code styles. + +Alternatively, use this example file. In the root directory, create `.eslintrc`: + +```json +{ + "extends": ["eslint:recommended"], + "plugins": ["prettier"], + "parserOptions": { + "ecmaVersion": 2017 + }, + "env": { + "es6": true + }, + "rules": { + "no-console": "off", + "no-unused-vars": "off", + "react/prop-types": "off", + "quotes": [ + 2, + "double", + { + "avoidEscape": true + } + ] + } +} +``` + +## Everything in action + +After making changes, commit the files, and see `lint-staged` automatically run, triggered by the pre-commit hook. + +```sh +my-project$ git commit -m 'example commit message' +✔ Preparing lint-staged... +✔ Running tasks for staged files... +✔ Applying modifications from tasks... +✔ Cleaning up temporary files... +[example-branch 4bc4030] add new husky setup + 4 files changed, 59 insertions(+), 44 deletions(-) +``` + +All files have been linted and automatically fixed with `prettier`, or denied if too many errors were thrown. Now we can push the "clean" code. + +```sh +my-project$ git push origin example-branch +# npx lint-staged +# ... (no errors found) +# npm test +# ... (PASS) +Enumerating objects: 7, done. +Counting objects: 100% (7/7), done. +Delta compression using up to 8 threads +Compressing objects: 100% (4/4), done. +Writing objects: 100% (4/4), 375 bytes | 375.00 KiB/s, done. +Total 4 (delta 3), reused 0 (delta 0), pack-reused 0 +remote: Resolving deltas: 100% (3/3), completed with 3 local objects. +To https://github.com/spencerlepine/my-project.git + 4bc4030..b558038 example-branch -> example-branch +``` + +## Boilerplate + +See a working example here: [GitHub repository](https://github.com/spencerlepine/husky-boilerplate). + +## Notes + +A useful trick is the `-–no-verify` flag to SKIP the pre-commit or pre-push hook. Use this option to skip the husky script in case you force a commit/push. + +```sh +my-project$ git push origin my-branch --no-verify +# husky will not run "npm test" +... pushing to GitHub +``` + +When `husky` released v7, it had some major changes to the configuration. There are many articles and Stack Overflow answers about husky, but some of them are misleading if they +were using v4. + +Hope this article helped! Interested in more, check out more articles [here](https://spencerlepine.github.io/blog). + +Also find me here: + +- [Twitter](https://twitter.com/SpencerLepine) +- [GitHub](https://github.com/spencerlepine) +- [LinkedIn](https://www.linkedin.com/in/spencerlepine/) +- [YouTube](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) diff --git a/blog/git-project-configuration-with-husky-and-eslint/git-project-configuration-with-husky-and-eslint.md b/content/git-project-configuration-with-husky-and-eslint/index.medium similarity index 87% rename from blog/git-project-configuration-with-husky-and-eslint/git-project-configuration-with-husky-and-eslint.md rename to content/git-project-configuration-with-husky-and-eslint/index.medium index 5589650..76c90ec 100644 --- a/blog/git-project-configuration-with-husky-and-eslint/git-project-configuration-with-husky-and-eslint.md +++ b/content/git-project-configuration-with-husky-and-eslint/index.medium @@ -1,9 +1,7 @@ --- title: Git Project Configuration With Husky and ESLint -slug: git-project-configuration-with-husky-and-eslint -tags: [Git, Husky, ESLint, Workflow, GitHub] -authors: [spencerlepine] -date: 2022-03-20T12:00 +description: Git conventions using pre-commit hooks and enforcing code styles. +publish_status: "draft" --- ![Blog Post Thumbnail](./thumbnail.jpg) @@ -33,7 +31,7 @@ Add the following to your `package.json` to configure all three packages: "scripts": { "format": "prettier --write ." }, - "prettier": { + "prettier": { "printWidth": 180, "tabWidth": 2, "singleQuote": true, @@ -60,7 +58,7 @@ Add the following to your `package.json` to configure all three packages: } ``` -## Configure ESLint (optional) +### Configure ESLint (optional) First, install this package ``` @@ -100,7 +98,7 @@ Alternatively, use this example file. In the root directory, create `.eslintrc`: } ``` -#### Everything in action +## Everything in action After making changes, commit the files, and see `lint-staged` automatically run, triggered by the pre-commit hook. @@ -132,12 +130,15 @@ To https://github.com/spencerlepine/my-project.git 4bc4030..b558038 example-branch -> example-branch ``` -#### Boilerplate +## Boilerplate + See a working example here: [GitHub repository](https://github.com/spencerlepine/husky-boilerplate). -#### Notes +## Notes + A useful trick is the `-–no-verify` flag to SKIP the pre-commit or pre-push hook. Use this option to skip the husky script in case you force a commit/push. + ```sh my-project$ git push origin my-branch --no-verify # husky will not run "npm test" @@ -146,10 +147,11 @@ my-project$ git push origin my-branch --no-verify When `husky` released v7, it had some major changes to the configuration. There are many articles and Stack Overflow answers about husky, but some of them are misleading if they were using v4. -Hope this article helped! Interested in more, check out more articles [here](https://www.spencerlepine.com/blog). +Hope this article helped! Interested in more, check out more articles [here](https://spencerlepine.github.io/blog). -Also find me here: - - [Twitter](https://twitter.com/SpencerLepine) - - [GitHub](https://github.com/spencerlepine) - - [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) - - [YouTube](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) \ No newline at end of file +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/git-project-configuration-with-husky-and-eslint/thumbnail.jpg b/content/git-project-configuration-with-husky-and-eslint/thumbnail.jpg similarity index 100% rename from blog/git-project-configuration-with-husky-and-eslint/thumbnail.jpg rename to content/git-project-configuration-with-husky-and-eslint/thumbnail.jpg diff --git a/content/manyshiba-the-worlds-greatest-twitter-bot/index.devto b/content/manyshiba-the-worlds-greatest-twitter-bot/index.devto new file mode 100644 index 0000000..15ae378 --- /dev/null +++ b/content/manyshiba-the-worlds-greatest-twitter-bot/index.devto @@ -0,0 +1,160 @@ +--- +title: ManyShiba - The World's Greatest Twitter Bot +description: Exploration of building a custom Twitter Bot. # Dev.to +tags: 'twitter, nodejs, bot' # Dev.to (Max 3) +canonical_url: null # Dev.to +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +ManyShiba is the greatest Twitter bot ever created. Bless your soul with a daily photo of the almighty Shiba. Be uplifted by the spirit of this holy and sacred creature to free your soul. + +For so long, I felt that something was missing in my life. After being blessed by the presence of a divine Shiba Inu dog, I had my answer. I could cleanse my soul each day by reminding myself of this divine being. But that couldn’t be it, there had to be some way I could bless EVERYONE. + +Behold - your new favorite Twitter bot - [@ManyShiba](https://twitter.com/manyshiba). (source code: [GitHub](https://github.com/spencerlepine/manyshiba-bot)) + +### So what exactly is the ManyShiba Bot? + +This is a simple Node.js app connected to the Twitter API. The app is deployed on [Heroku](https://dashboard.heroku.com/) and connected to the Twitter developer account. + +Each time the script runs, a new dog image will be fetched from the [Shibe.online](https://shibe.online/) API. That image will then be uploaded and posted on the Twitter feed. + +### Technologies: +To build this app, there were three technologies I worked with. + + - [Node.js](https://nodejs.org/) + - [Shibe.online API](https://shibe.online/) + - [twit](https://www.npmjs.com/package/twit) + +Node is a popular Javascript runtime environment that can easily run on Heroku. Heroku is a PaaS and great tool to deploy a small app for free. + +The Shibe.online API is a third party service to retrieve a link for dog pictures. Since there are many random photos to use in that database, it is the perfect resource for finding many new photos. + +Finally, the twit library is a Twitter API Client for Node that simplifies the REST requests. Since this app will only be posting tweets, there are on advanced requests being made to the Twitter API. + +With each of these tools, we can have a functioning Twitter bot. Here are the steps for code: + +- Save the Twitter API configuration +- Initialize the Twit Client with the configuration +- Fetch a random image from Shibe.online +- Convert the image from a URL to base64 +- Tweet the image + +After registering a [Twitter App](https://developer.twitter.com/), make sure to enable Read/Write permissions in the App settings. Create an `.env` file in the root of the project based on `.env.example`. We can use this data in our file with an object like this: + +```js +const config = { + consumer_key: process.env.TWITTER_API_KEY, + consumer_secret: process.env.TWITTER_API_SECRET, + access_token: process.env.TWITTER_API_ACCESS_TOKEN, + access_token_secret: process.env.TWITTER_API_ACCESS_TOKEN_SECRET, +} +``` + +In `app.js` we can import `twit` and pass along the config obj: + +```js +import twit from 'twit'; +... +const twitterClient = new twit(config); +``` + +Before we tweet anything, we first need to generate the content to post. This is where we will retrieve an image from the Shibe.online API. Note, the Shibe endpoint will return a list of image URLs stored on a third party server. We must download this image, because posting an image URL does not actually display it on the feed. + +```js +const API_ENDPOINT = 'http://shibe.online/api/shibes?count=1&urls=true&httpsUrls=false'; +... +const fetchRandomImage = async (tweetFunction) => { + const resultList = await fetch(API_ENDPOINT).then(res => res.json()); + const newImage = resultList[0]; + return newImage +} +``` + +After retrieving a URL from Shibe.online, we must fetch the image as well. We can convert the data from the image URL and convert it to a base64 string in memory. Since we are saving the image data, a Tweet will always load the image since it does not depend on the third party image database anymore. + +Note, you can use any library for HTTP requests like [axios](https://axios-http.com/). This example uses the `http` and `node-fetch` libraries available on [npm](https://www.npmjs.com/). + +```js +import fetch from 'node-fetch'; +import http from 'http'; +... +const urlToBase64 = async (imgUrl, tweetFunction) => { + await http.get(imgUrl, async (httpRes) => { + httpRes.setEncoding('base64'); + // Exclude -> "data:" + httpRes.headers["content-type"] + ";base64,"; + let body = ""; + await httpRes.on('data', (data) => { + body += data; + }); + await httpRes.on('end', () => { + tweetFunction(body); + }); + }).on('error', (e) => { + console.log(`Got error: ${e.message}`); + }); +} + +const fetchRandomImage = async (tweetFunction) => { + ... + await urlToBase64(newImage, tweetFunction); +} +``` + +With a base64 string, we need to upload it as media context to Twitter. After uploading it, we have access to a `media_id`. This media_id can be attached to the actual Tweet, which will cause the image to render on the feed. For this project, there is no text context attached to this Tweet. + +```js +... +const tweetImage = (tweetContent) => { + if (tweetContent) { + twitterClient.post('media/upload', { media_data: tweetContent }, function (err, data, response) { + // now we can assign alt text to the media, for use by screen readers and + // other text-based presentations and interpreters + var mediaIdStr = data.media_id_string + var altText = "Shiba Inu" + var meta_params = { media_id: mediaIdStr, alt_text: { text: altText } } + + twitterClient.post('media/metadata/create', meta_params, function (err, data, response) { + if (!err) { + // now we can reference the media and post a tweet (media will attach to the tweet) + var params = { status: '', media_ids: [mediaIdStr] } + + twitterClient.post('statuses/update', params, function (err, data, response) { + console.log(data) + }) + } + }) + }) + } +} + +fetchRandomImage(tweetImage); +``` + +With each step tied together, we can retrieve Shiba images and generate Tweets with media content. To see the source code, head over to the [GitHub repository](https://github.com/spencerlepine/manyshiba-bot). + +With a working Twitter bot, I could run the script with Node on my local machine. However, it wouldn’t be automated if I had to run it manually. To solve this, I decided to deploy everything onto Heroku. This service allows node servers to run not just simple static files. + +With [Heroku Scheduler](https://devcenter.heroku.com/articles/scheduler), you can configure script executions. Make sure to add this script to your `package.json` file: + +```js +{ + ... + “scripts”: { + “start”: “node app.js” + } +} +```` + +Adding a setting to execute the script on a timer makes the bot automated. I decided to let the bot create a daily Tweet with this tool. Our ManyShiba bot is now fully functional! + +--- + +View the source code on [GitHub](https://github.com/spencerlepine/manyshiba-bot). + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/manyshiba-the-worlds-greatest-twitter-bot/index.md b/content/manyshiba-the-worlds-greatest-twitter-bot/index.md new file mode 100644 index 0000000..6ac647e --- /dev/null +++ b/content/manyshiba-the-worlds-greatest-twitter-bot/index.md @@ -0,0 +1,174 @@ +--- +title: ManyShiba - The World's Greatest Twitter Bot +slug: manyshiba-the-worlds-greatest-twitter-bot +tags: [GitHub, Twitter, NodeJS. Bot] +authors: [spencerlepine] +date: 2021-09-01T12:00 +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +ManyShiba is the greatest Twitter bot ever created. Bless your soul with a daily photo of the almighty Shiba. Be uplifted by the spirit of this holy and sacred creature to free +your soul. + +For so long, I felt that something was missing in my life. After being blessed by the presence of a divine Shiba Inu dog, I had my answer. I could cleanse my soul each day by +reminding myself of this divine being. But that couldn’t be it, there had to be some way I could bless EVERYONE. + +Behold - your new favorite Twitter bot - [@ManyShiba](https://twitter.com/manyshiba). (source code: [GitHub](https://github.com/spencerlepine/manyshiba-bot)) + +### So what exactly is the ManyShiba Bot? + +This is a simple Node.js app connected to the Twitter API. The app is deployed on [Heroku](https://dashboard.heroku.com/) and connected to the Twitter developer account. + +Each time the script runs, a new dog image will be fetched from the [Shibe.online](https://shibe.online/) API. That image will then be uploaded and posted on the Twitter feed. + +### Technologies: + +To build this app, there were three technologies I worked with. + +- [Node.js](https://nodejs.org/) +- [Shibe.online API](https://shibe.online/) +- [twit](https://www.npmjs.com/package/twit) + +Node is a popular Javascript runtime environment that can easily run on Heroku. Heroku is a PaaS and great tool to deploy a small app for free. + +The Shibe.online API is a third party service to retrieve a link for dog pictures. Since there are many random photos to use in that database, it is the perfect resource for +finding many new photos. + +Finally, the twit library is a Twitter API Client for Node that simplifies the REST requests. Since this app will only be posting tweets, there are on advanced requests being made +to the Twitter API. + +With each of these tools, we can have a functioning Twitter bot. Here are the steps for code: + +- Save the Twitter API configuration +- Initialize the Twit Client with the configuration +- Fetch a random image from Shibe.online +- Convert the image from a URL to base64 +- Tweet the image + +After registering a [Twitter App](https://developer.twitter.com/), make sure to enable Read/Write permissions in the App settings. Create an `.env` file in the root of the project +based on `.env.example`. We can use this data in our file with an object like this: + +```js +const config = { + consumer_key: process.env.TWITTER_API_KEY, + consumer_secret: process.env.TWITTER_API_SECRET, + access_token: process.env.TWITTER_API_ACCESS_TOKEN, + access_token_secret: process.env.TWITTER_API_ACCESS_TOKEN_SECRET, +}; +``` + +In `app.js` we can import `twit` and pass along the config obj: + +```js +import twit from 'twit'; +... +const twitterClient = new twit(config); +``` + +Before we tweet anything, we first need to generate the content to post. This is where we will retrieve an image from the Shibe.online API. Note, the Shibe endpoint will return a +list of image URLs stored on a third party server. We must download this image, because posting an image URL does not actually display it on the feed. + +```js +const API_ENDPOINT = 'http://shibe.online/api/shibes?count=1&urls=true&httpsUrls=false'; +... +const fetchRandomImage = async (tweetFunction) => { + const resultList = await fetch(API_ENDPOINT).then(res => res.json()); + const newImage = resultList[0]; + return newImage +} +``` + +After retrieving a URL from Shibe.online, we must fetch the image as well. We can convert the data from the image URL and convert it to a base64 string in memory. Since we are +saving the image data, a Tweet will always load the image since it does not depend on the third party image database anymore. + +Note, you can use any library for HTTP requests like [axios](https://axios-http.com/). This example uses the `http` and `node-fetch` libraries available on +[npm](https://www.npmjs.com/). + +```js +import fetch from 'node-fetch'; +import http from 'http'; +... +const urlToBase64 = async (imgUrl, tweetFunction) => { + await http.get(imgUrl, async (httpRes) => { + httpRes.setEncoding('base64'); + // Exclude -> "data:" + httpRes.headers["content-type"] + ";base64,"; + let body = ""; + await httpRes.on('data', (data) => { + body += data; + }); + await httpRes.on('end', () => { + tweetFunction(body); + }); + }).on('error', (e) => { + console.log(`Got error: ${e.message}`); + }); +} + +const fetchRandomImage = async (tweetFunction) => { + ... + await urlToBase64(newImage, tweetFunction); +} +``` + +With a base64 string, we need to upload it as media context to Twitter. After uploading it, we have access to a `media_id`. This media_id can be attached to the actual Tweet, which +will cause the image to render on the feed. For this project, there is no text context attached to this Tweet. + +```js +... +const tweetImage = (tweetContent) => { + if (tweetContent) { + twitterClient.post('media/upload', { media_data: tweetContent }, function (err, data, response) { + // now we can assign alt text to the media, for use by screen readers and + // other text-based presentations and interpreters + var mediaIdStr = data.media_id_string + var altText = "Shiba Inu" + var meta_params = { media_id: mediaIdStr, alt_text: { text: altText } } + + twitterClient.post('media/metadata/create', meta_params, function (err, data, response) { + if (!err) { + // now we can reference the media and post a tweet (media will attach to the tweet) + var params = { status: '', media_ids: [mediaIdStr] } + + twitterClient.post('statuses/update', params, function (err, data, response) { + console.log(data) + }) + } + }) + }) + } +} + +fetchRandomImage(tweetImage); +``` + +With each step tied together, we can retrieve Shiba images and generate Tweets with media content. To see the source code, head over to the +[GitHub repository](https://github.com/spencerlepine/manyshiba-bot). + +With a working Twitter bot, I could run the script with Node on my local machine. However, it wouldn’t be automated if I had to run it manually. To solve this, I decided to deploy +everything onto Heroku. This service allows node servers to run not just simple static files. + +With [Heroku Scheduler](https://devcenter.heroku.com/articles/scheduler), you can configure script executions. Make sure to add this script to your `package.json` file: + +```js +{ + ... + “scripts”: { + “start”: “node app.js” + } +} +``` + +Adding a setting to execute the script on a timer makes the bot automated. I decided to let the bot create a daily Tweet with this tool. Our ManyShiba bot is now fully functional! + +--- + +View the source code on [GitHub](https://github.com/spencerlepine/manyshiba-bot). + +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/manyshiba-the-worlds-greatest-twitter-bot/manyshiba-the-worlds-greatest-twitter-bot.md b/content/manyshiba-the-worlds-greatest-twitter-bot/index.medium similarity index 94% rename from blog/manyshiba-the-worlds-greatest-twitter-bot/manyshiba-the-worlds-greatest-twitter-bot.md rename to content/manyshiba-the-worlds-greatest-twitter-bot/index.medium index 96d8895..9a468a8 100644 --- a/blog/manyshiba-the-worlds-greatest-twitter-bot/manyshiba-the-worlds-greatest-twitter-bot.md +++ b/content/manyshiba-the-worlds-greatest-twitter-bot/index.medium @@ -1,9 +1,7 @@ --- title: ManyShiba - The World's Greatest Twitter Bot -slug: manyshiba-the-worlds-greatest-twitter-bot -tags: [GitHub, Twitter, Node.js. Bot] -authors: [spencerlepine] -date: 2021-09-01T12:00 +description: Exploration of building a custom Twitter Bot. +publish_status: "draft" --- ![Blog Post Thumbnail](./thumbnail.jpg) @@ -153,8 +151,9 @@ Adding a setting to execute the script on a timer makes the bot automated. I dec View the source code on [GitHub](https://github.com/spencerlepine/manyshiba-bot). -Also find me here: -* [Twitter (@spencerlepine)](https://twitter.com/SpencerLepine) -* [GitHub (@spencerlepine)](https://github.com/spencerlepine) -* [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) -* [YouTube (Spencer Lepine)](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/manyshiba-the-worlds-greatest-twitter-bot/thumbnail.jpg b/content/manyshiba-the-worlds-greatest-twitter-bot/thumbnail.jpg similarity index 100% rename from blog/manyshiba-the-worlds-greatest-twitter-bot/thumbnail.jpg rename to content/manyshiba-the-worlds-greatest-twitter-bot/thumbnail.jpg diff --git a/content/portfolio-site-continuous-integration-github-action/index.devto b/content/portfolio-site-continuous-integration-github-action/index.devto new file mode 100644 index 0000000..4825b0b --- /dev/null +++ b/content/portfolio-site-continuous-integration-github-action/index.devto @@ -0,0 +1,103 @@ +--- +title: Portfolio Site Continuous Integration GitHub Action +description: Automating steps to deploy static files for my personal website. # Dev.to +tags: 'github, automation, repository' # Dev.to (Max 3) +canonical_url: null # Dev.to +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +After learning about GatsbyJS and building a static Portfolio site and blog, I searched for systems to deploy this website. At this point, I had purchased the domain name through AWS Route53, but I still needed somewhere to host the static files. + +I chose to deploy the site through Digital Ocean Droplet. This was a remote Ubuntu virtual machine with an IP address I could route to. Once I installed apache web server software and connected domain name, the website was live. + +There was still one problem with this deployment process. Updating the website took several steps. After local development, I needed to build/generate the static files with Gatbsy locally, and push them to the GitHub repo. Then, I would ssh into the Ubuntu Droplet, clone the updated repo again, and replace the static files for apache to serve. + +Steps to deploy were repetitive. Having to remember terminal commands and finding passwords was inconvenient. I was unable to build the static files on the remote Ubuntu machine with limited hardware specs. + +One improvement I made was writing a script to delete and copy new files when deploying on Digital Ocean. This addition did not solve everything, as I hard-coded my github username and repository name. + +```sh +# RUN the script: +# sudo ./syncBuild.sh portfolio-site + +GITHUB_LINK="https://github.com/spencerlepine/$1.git" + +git clone "$GITHUB_LINK" +echo -e "$GREEN successfully cloned repo$NC \n" + +echo "Removing the current public folder" +rm -r -d public +echo "Moving into the github repo folder" +cd $1 +echo "Moving public folder contents OUT of repo folder" +mv public .. +echo -e "$GREEN Successfully copy news files $NC \n" +echo "Moving back into parent directory" +cd .. + +echo "Deleting leftover github repo files" +rm -d -r "$1" + +echo "Restarting apache server" +systemctl restart apache2 + +echo -e "$GREEN Public folder sync complete! $NC" + +echo "Visit: spencerlepine.com" + +# "syncBuild.sh" 52L, 956C +``` +Although this process took less than 10 minutes, switching between the IDE, GitHub, the terminal, and the browser was annoying. It would be better to automate this process. To do that, we can use a GitHub action that will trigger on every repository update. A handy feature of GitHub repositories is the ability to store secrets/environment variables. We can use this to store passwords directly connected to the repository, so all credentials needed for the project are stored in one place. + + Let’s create the GitHub workflow file: +``` +name: CI + +on: + push: + branches: [ master ] + +jobs: + + deploy: + name: Deploy + runs-on: ubuntu-latest + steps: + - name: Deploy Static Files + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + passphrase: ${{ secrets.PASSPHRASE }} + port: ${{ secrets.PORT }} + script_stop: true + script: | + # change directory to where website files are stored + # clone the repository + # remove the current public folder w/ static files + # enter the repo folder + # extract the public folder from the repo folder + # remove the leftover GitHub repo files + # restart the web server + echo “Visit deployed site: spencerlepine.com” +``` + +### Conclusion +This GitHub action will use another [ssh-action](https://github.com/appleboy/ssh-action) action to handle the remote ssh connection. After storing the connection credentials in the GitHub repository secrets, this can securely/dynamically connect to the remote Ubuntu machine. The last key for this action job is the script, or verbatim Ubuntu commands that will be run. For the sake of brevity, I have only written pseudo-code for the deployment steps. + +With this file saved in the `.github` folder in the project, GitHub can execute the action and connect to our remote server autonomously. After adding a blog post or updating the website, the only step required is pushing the code to GitHub (which I would do anyways). Now, the GitHub workflow will handle all of the steps to connect to the host server, delete old static files, and download the fresh static files. + +The continuous integration for this website is completely automated now. This saves me time and effort. No need to worry about forgetting how to deploy later on. + +--- + +View the source code on [GitHub](https://github.com/spencerlepine/spencerlepine.com). + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/portfolio-site-continuous-integration-github-action/index.md b/content/portfolio-site-continuous-integration-github-action/index.md new file mode 100644 index 0000000..74280c5 --- /dev/null +++ b/content/portfolio-site-continuous-integration-github-action/index.md @@ -0,0 +1,119 @@ +--- +title: Portfolio Site Continuous Integration GitHub Action +slug: portfolio-site-continuous-integration-github-action +tags: [GitHub, Actions, Repositories, ssh, Ubuntu, DigitalOcean] +authors: [spencerlepine] +date: 2021-10-11T12:00 +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +After learning about GatsbyJS and building a static Portfolio site and blog, I searched for systems to deploy this website. At this point, I had purchased the domain name through +AWS Route53, but I still needed somewhere to host the static files. + +I chose to deploy the site through Digital Ocean Droplet. This was a remote Ubuntu virtual machine with an IP address I could route to. Once I installed apache web server software +and connected domain name, the website was live. + +There was still one problem with this deployment process. Updating the website took several steps. After local development, I needed to build/generate the static files with Gatbsy +locally, and push them to the GitHub repo. Then, I would ssh into the Ubuntu Droplet, clone the updated repo again, and replace the static files for apache to serve. + +Steps to deploy were repetitive. Having to remember terminal commands and finding passwords was inconvenient. I was unable to build the static files on the remote Ubuntu machine +with limited hardware specs. + +One improvement I made was writing a script to delete and copy new files when deploying on Digital Ocean. This addition did not solve everything, as I hard-coded my github username +and repository name. + +```sh +# RUN the script: +# sudo ./syncBuild.sh portfolio-site + +GITHUB_LINK="https://github.com/spencerlepine/$1.git" + +git clone "$GITHUB_LINK" +echo -e "$GREEN successfully cloned repo$NC \n" + +echo "Removing the current public folder" +rm -r -d public +echo "Moving into the github repo folder" +cd $1 +echo "Moving public folder contents OUT of repo folder" +mv public .. +echo -e "$GREEN Successfully copy news files $NC \n" +echo "Moving back into parent directory" +cd .. + +echo "Deleting leftover github repo files" +rm -d -r "$1" + +echo "Restarting apache server" +systemctl restart apache2 + +echo -e "$GREEN Public folder sync complete! $NC" + +echo "Visit: spencerlepine.com" + +# "syncBuild.sh" 52L, 956C +``` + +Although this process took less than 10 minutes, switching between the IDE, GitHub, the terminal, and the browser was annoying. It would be better to automate this process. To do +that, we can use a GitHub action that will trigger on every repository update. A handy feature of GitHub repositories is the ability to store secrets/environment variables. We can +use this to store passwords directly connected to the repository, so all credentials needed for the project are stored in one place. + + Let’s create the GitHub workflow file: + +``` +name: CI + +on: + push: + branches: [ master ] + +jobs: + + deploy: + name: Deploy + runs-on: ubuntu-latest + steps: + - name: Deploy Static Files + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.USERNAME }} + key: ${{ secrets.KEY }} + passphrase: ${{ secrets.PASSPHRASE }} + port: ${{ secrets.PORT }} + script_stop: true + script: | + # change directory to where website files are stored + # clone the repository + # remove the current public folder w/ static files + # enter the repo folder + # extract the public folder from the repo folder + # remove the leftover GitHub repo files + # restart the web server + echo “Visit deployed site: spencerlepine.com” +``` + +### Conclusion + +This GitHub action will use another [ssh-action](https://github.com/appleboy/ssh-action) action to handle the remote ssh connection. After storing the connection credentials in the +GitHub repository secrets, this can securely/dynamically connect to the remote Ubuntu machine. The last key for this action job is the script, or verbatim Ubuntu commands that will +be run. For the sake of brevity, I have only written pseudo-code for the deployment steps. + +With this file saved in the `.github` folder in the project, GitHub can execute the action and connect to our remote server autonomously. After adding a blog post or updating the +website, the only step required is pushing the code to GitHub (which I would do anyways). Now, the GitHub workflow will handle all of the steps to connect to the host server, +delete old static files, and download the fresh static files. + +The continuous integration for this website is completely automated now. This saves me time and effort. No need to worry about forgetting how to deploy later on. + +--- + +View the source code on [GitHub](https://github.com/spencerlepine/spencerlepine.com). + +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/portfolio-site-continuous-integration-github-action/portfolio-site-continuous-integration-github-action.md b/content/portfolio-site-continuous-integration-github-action/index.medium similarity index 90% rename from blog/portfolio-site-continuous-integration-github-action/portfolio-site-continuous-integration-github-action.md rename to content/portfolio-site-continuous-integration-github-action/index.medium index 5678fc4..682a237 100644 --- a/blog/portfolio-site-continuous-integration-github-action/portfolio-site-continuous-integration-github-action.md +++ b/content/portfolio-site-continuous-integration-github-action/index.medium @@ -1,9 +1,7 @@ --- title: Portfolio Site Continuous Integration GitHub Action -slug: portfolio-site-continuous-integration-github-action -tags: [GitHub, Actions, Repositories, ssh, Ubuntu, DigitalOcean] -authors: [spencerlepine] -date: 2021-10-11T12:00 +description: Automating steps to deploy static files for my personal website. +publish_status: "draft" --- ![Blog Post Thumbnail](./thumbnail.jpg) @@ -96,8 +94,9 @@ The continuous integration for this website is completely automated now. This sa View the source code on [GitHub](https://github.com/spencerlepine/spencerlepine.com). -Also find me here: -* [Twitter (@spencerlepine)](https://twitter.com/SpencerLepine) -* [GitHub (@spencerlepine)](https://github.com/spencerlepine) -* [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) -* [YouTube (Spencer Lepine)](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/portfolio-site-continuous-integration-github-action/thumbnail.jpg b/content/portfolio-site-continuous-integration-github-action/thumbnail.jpg similarity index 100% rename from blog/portfolio-site-continuous-integration-github-action/thumbnail.jpg rename to content/portfolio-site-continuous-integration-github-action/thumbnail.jpg diff --git a/blog/preparing-for-my-amazon-front-end-engineer-interview/preparing-for-my-amazon-front-end-engineer-interview.md b/content/preparing-for-my-amazon-front-end-engineer-interview/index.devto similarity index 90% rename from blog/preparing-for-my-amazon-front-end-engineer-interview/preparing-for-my-amazon-front-end-engineer-interview.md rename to content/preparing-for-my-amazon-front-end-engineer-interview/index.devto index 1b3def2..2a8b1ee 100644 --- a/blog/preparing-for-my-amazon-front-end-engineer-interview/preparing-for-my-amazon-front-end-engineer-interview.md +++ b/content/preparing-for-my-amazon-front-end-engineer-interview/index.devto @@ -1,9 +1,8 @@ --- title: Preparing for My Amazon Front End Engineer Interview -slug: preparing-for-my-amazon-front-end-engineer-interview -tags: [Job Search, Amazon, AWS, LeetCode, Interviews] -authors: [spencerlepine] -date: 2022-11-20T12:00 +description: My experience and advice for the Amazon Front End Engineer interview. +tags: 'job search, interview, amazon' # Dev.to (Max 3) +canonical_url: null # Dev.to --- ![Blog Post Thumbnail](./thumbnail.jpg) @@ -12,7 +11,7 @@ After my recent interviews with Amazon for the Front End Engineer role, I though TL;DR - practice LeetCode, practice vanilla JS, always verbalize your thought process, prepare stories to share in the STAR framework, and be confident (or fake it). -If you are interested in general advice for landing your first role in tech, I wrote another article about that: [How I Became a Software Engineer at 20 With No CS Degree](https://sppencerlepine.com/blog-TODO) +If you are interested in general advice for landing your first role in tech, I wrote another article about that: [How I Became a Software Engineer at 20 With No CS Degree](https://spencerlepine.github.io/blog/todo) For the Amazon FEE interviews, you can find a lot of material online, since thousands of people are applying to these roles. In this article I will share the resources that helped me and give advice on what to study. @@ -68,10 +67,12 @@ I will not go into detail about the specific problems I was given. You should fi All of this is biased to my experience, and you should look beyond just this article. Every new day you study, every hour you invest more time, your skills will sharpen. Focus on what you can control. I hope you got some value from the article. If you are interested in reading more about my job searching and landing my first role as a software engineer, checkout out these articles: - - [How I Became a Software Engineer at 20 With No CS Degree](https://sppencerlepine.com/blog-TODO) - - [My Coding Bootcamp Experience at Hack Reactor](https://sppencerlepine.com/blog-TODO) - -Follow my journey and connected with me here: -- LinkedIn: [/in/spencer-lepine](https://www.linkedin.com/in/spencer-lepine/) -- Twitter: [@SpencerLepine](https://twitter.com/spencerlepine) -- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) \ No newline at end of file + - [How I Became a Software Engineer at 20 With No CS Degree](https://spencerlepine.github.io/blog/todo) + - [My Coding Bootcamp Experience at Hack Reactor](https://spencerlepine.github.io/blog/todo) + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/preparing-for-my-amazon-front-end-engineer-interview/index.md b/content/preparing-for-my-amazon-front-end-engineer-interview/index.md new file mode 100644 index 0000000..c07c4bc --- /dev/null +++ b/content/preparing-for-my-amazon-front-end-engineer-interview/index.md @@ -0,0 +1,102 @@ +--- +title: Preparing for My Amazon Front End Engineer Interview +slug: preparing-for-my-amazon-front-end-engineer-interview +tags: [Job Search, Amazon, AWS, LeetCode, Interviews] +authors: [spencerlepine] +date: 2022-11-20T12:00 +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +After my recent interviews with Amazon for the Front End Engineer role, I thought I should share my experience and advice. I got numerous requests on LinkedIn about my interview +experience, so I decided to document everything to pass along. + +TL;DR - practice LeetCode, practice vanilla JS, always verbalize your thought process, prepare stories to share in the STAR framework, and be confident (or fake it). + +If you are interested in general advice for landing your first role in tech, I wrote another article about that: +[How I Became a Software Engineer at 20 With No CS Degree](https://spencerlepine.github.io/blog/todo) + +For the Amazon FEE interviews, you can find a lot of material online, since thousands of people are applying to these roles. In this article I will share the resources that helped +me and give advice on what to study. + +Study Material & Resources: + +Remember, your competition will get their hands on any information that helps them perform better in an interview. You should too. Get exposure to all the material you can, +read/explore these resources to learn as much as possible: + +- Article: [Amazon Front-End Engineer Interview Prep](https://www.interviewkickstart.com/companies/amazon-front-end-engineer-interview-prep) +- Article: [Understanding Amazon’s Front-End Engineering Interview](https://xjamundx.medium.com/understanding-amazons-front-end-engineering-interview-5e9f38b58058) +- Article: [How I Landed a Front-End Engineering Job at Amazon](https://xjamundx.medium.com/how-i-got-a-front-end-engineering-job-at-amazon-807e26c33915) +- Study Topic: [Amazon front end interview questions](https://www.frontendinterviewhandbook.com/companies/amazon-front-end-interview-questions) +- LeetCode Post: [Amazon Virtual Onsite - FrontEnd Engineer II Offer](https://leetcode.com/discuss/interview-question/694045/amazon-virtual-onsite-frontend-engineer-ii-offer) +- Google search: [“reddit amazon front end engineer”](https://www.google.com/search?q=reddit+amazon+front+end+engineer) +- Youtube Video: [Amazon Front End Interview Prep | Software Engineer](https://www.youtube.com/watch?v=rMWDtxJQIbQ) +- Youtube Video: [Amazon Frontend Interview Experience 2022 | Frontend Engineer 2](https://www.youtube.com/watch?v=jI4WfkudBb8) +- Youtube Video: [Amazon Interview Experience | Software Engineer](https://www.youtube.com/watch?v=baT3OzbOg5s&ab_channel=KeepOnCoding) +- Youtube Video: + [Rejected by Amazon - Frontend and Software Engineer - Full Loop Interview Exp with no degree at all](https://www.youtube.com/watch?v=gTIS4waIpG4&ab_channel=CodePhony) +- Youtube Video: [Amazon Behavioral Interview Questions | Leadership Principles Explained](https://www.youtube.com/watch?v=6p1m2nCE7jE&ab_channel=Exponent) + +### Soft skills & Behavioral Questions: + +First, let’s touch upon soft skills and behavioral preparation. You must learn about the STAR framework, as well as the leadership principles. My advice would be to prepare one +story per LP, as you will need to share concise answers for behavioral questions. You can practice telling a story (conflict with coworker, time you applied advice from a peer…) in +the STAR framework. STAR gives you structure to describe what happened with context and outcomes. + +Every interview could start with a few behavioral questions. If you try to wing it and think of stories in the moment, it likely will leave a bad impression. + +An important theme is that technical skills can easily be taught, soft skills cannot. A valuable candidate has great personality and collaboration skills with the team. If you were +hiring someone, that is what you would look for. Many people have talent. What sets you apart is how you present/market yourself, being memorable/leaving an impression. It is +essential to communicate well or have story-telling skills. + +### Technical Skills & Coding Challenges: + +Now let’s talk about technical skills and the coding challenges. You may be curious about exactly what I studied to prepare for this interview. + +Essentials to study: + +- LeetCode problems +- Vanilla JS practice (practice building simple widgets) +- Frontend system design basics + +I would recommend practicing LeetCode style problems and exercise a problem solving process. Think about the input/output of the problem. Think briefly about edge +cases/constraints. Write some pseudo-code first, then attempt the problem. A huge focus should be verbalizing your through process the entire time. Avoid going silent for too long, +the interviewer is trying to understand how you work through the challenge. + +Recording myself to solve LeetCode problems helped me a ton (like this [video](https://www.youtube.com/watch?v=rwEaDpdZuQg)). It can be uncomfortable and you might be bad to start, +but you will always improve. + +In FEE interviews, you likely can solve coding problems in any language you prefer. Although you will need to know vanilla JS, you could solve a few problems in Python if +preferred. + +Specific to the Amazon interview, they will likely test your frontend skills building a small widget with plain HTML/CSS/JS. You may need to brush up on the DOM methods and syntax. +I recommend building several small widgets to practice. Make sure you understand selectors, event listeners, and modifying styles with JS. If you are unsure what kinds of widgets I +am talking about, look through [this](https://www.frontendinterviewhandbook.com/companies/amazon-front-end-interview-questions] page. + +Something to note, they don’t always use an IDE for these interviews. This allows you to focus on the concept and the design. You save time since you aren’t fixing little bugs to +get an HTML page rendered. + +Lastly, for the front end system design, make sure you understand the basics. Get familiar with state management, performance optimizations, and accessibility. This +[playlist](https://www.youtube.com/playlist?list=PLI9W87-Dqn7j_x6QtR6sUjycJR7nQLBqT) has TONS of detailed videos. + +I will not go into detail about the specific problems I was given. You should find plenty of these in the links I shared above. This article should provide enough momentum to get +started, and you will know best to study for. + +### Conclusion + +All of this is biased to my experience, and you should look beyond just this article. Every new day you study, every hour you invest more time, your skills will sharpen. Focus on +what you can control. + +I hope you got some value from the article. If you are interested in reading more about my job searching and landing my first role as a software engineer, checkout out these +articles: + +- [How I Became a Software Engineer at 20 With No CS Degree](https://spencerlepine.github.io/blog/todo) +- [My Coding Bootcamp Experience at Hack Reactor](https://spencerlepine.github.io/blog/todo) + +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/preparing-for-my-amazon-front-end-engineer-interview/index.medium b/content/preparing-for-my-amazon-front-end-engineer-interview/index.medium new file mode 100644 index 0000000..7088de2 --- /dev/null +++ b/content/preparing-for-my-amazon-front-end-engineer-interview/index.medium @@ -0,0 +1,77 @@ +--- +title:Preparing for My Amazon Front End Engineer Interview +description: My experience and advice for the Amazon Front End Engineer interview. +publish_status: "draft" +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +After my recent interviews with Amazon for the Front End Engineer role, I thought I should share my experience and advice. I got numerous requests on LinkedIn about my interview experience, so I decided to document everything to pass along. + +TL;DR - practice LeetCode, practice vanilla JS, always verbalize your thought process, prepare stories to share in the STAR framework, and be confident (or fake it). + +If you are interested in general advice for landing your first role in tech, I wrote another article about that: [How I Became a Software Engineer at 20 With No CS Degree](https://spencerlepine.github.io/blog/todo) + +For the Amazon FEE interviews, you can find a lot of material online, since thousands of people are applying to these roles. In this article I will share the resources that helped me and give advice on what to study. + +Study Material & Resources: + +Remember, your competition will get their hands on any information that helps them perform better in an interview. You should too. Get exposure to all the material you can, read/explore these resources to learn as much as possible: + +- Article: [Amazon Front-End Engineer Interview Prep](https://www.interviewkickstart.com/companies/amazon-front-end-engineer-interview-prep) +- Article: [Understanding Amazon’s Front-End Engineering Interview](https://xjamundx.medium.com/understanding-amazons-front-end-engineering-interview-5e9f38b58058) +- Article: [How I Landed a Front-End Engineering Job at Amazon](https://xjamundx.medium.com/how-i-got-a-front-end-engineering-job-at-amazon-807e26c33915) +- Study Topic: [Amazon front end interview questions](https://www.frontendinterviewhandbook.com/companies/amazon-front-end-interview-questions) +- LeetCode Post: [Amazon Virtual Onsite - FrontEnd Engineer II Offer](https://leetcode.com/discuss/interview-question/694045/amazon-virtual-onsite-frontend-engineer-ii-offer) +- Google search: [“reddit amazon front end engineer”](https://www.google.com/search?q=reddit+amazon+front+end+engineer) +- Youtube Video: [Amazon Front End Interview Prep | Software Engineer](https://www.youtube.com/watch?v=rMWDtxJQIbQ) +- Youtube Video: [Amazon Frontend Interview Experience 2022 | Frontend Engineer 2](https://www.youtube.com/watch?v=jI4WfkudBb8) +- Youtube Video: [Amazon Interview Experience | Software Engineer](https://www.youtube.com/watch?v=baT3OzbOg5s&ab_channel=KeepOnCoding) +- Youtube Video: [Rejected by Amazon - Frontend and Software Engineer - Full Loop Interview Exp with no degree at all](https://www.youtube.com/watch?v=gTIS4waIpG4&ab_channel=CodePhony) +- Youtube Video: [Amazon Behavioral Interview Questions | Leadership Principles Explained](https://www.youtube.com/watch?v=6p1m2nCE7jE&ab_channel=Exponent) + +### Soft skills & Behavioral Questions: + +First, let’s touch upon soft skills and behavioral preparation. You must learn about the STAR framework, as well as the leadership principles. My advice would be to prepare one story per LP, as you will need to share concise answers for behavioral questions. You can practice telling a story (conflict with coworker, time you applied advice from a peer…) in the STAR framework. STAR gives you structure to describe what happened with context and outcomes. + +Every interview could start with a few behavioral questions. If you try to wing it and think of stories in the moment, it likely will leave a bad impression. + +An important theme is that technical skills can easily be taught, soft skills cannot. A valuable candidate has great personality and collaboration skills with the team. If you were hiring someone, that is what you would look for. Many people have talent. What sets you apart is how you present/market yourself, being memorable/leaving an impression. It is essential to communicate well or have story-telling skills. + +### Technical Skills & Coding Challenges: + +Now let’s talk about technical skills and the coding challenges. You may be curious about exactly what I studied to prepare for this interview. + +Essentials to study: + - LeetCode problems + - Vanilla JS practice (practice building simple widgets) +- Frontend system design basics + +I would recommend practicing LeetCode style problems and exercise a problem solving process. Think about the input/output of the problem. Think briefly about edge cases/constraints. Write some pseudo-code first, then attempt the problem. A huge focus should be verbalizing your through process the entire time. Avoid going silent for too long, the interviewer is trying to understand how you work through the challenge. + +Recording myself to solve LeetCode problems helped me a ton (like this [video](https://www.youtube.com/watch?v=rwEaDpdZuQg)). It can be uncomfortable and you might be bad to start, but you will always improve. + +In FEE interviews, you likely can solve coding problems in any language you prefer. Although you will need to know vanilla JS, you could solve a few problems in Python if preferred. + +Specific to the Amazon interview, they will likely test your frontend skills building a small widget with plain HTML/CSS/JS. You may need to brush up on the DOM methods and syntax. I recommend building several small widgets to practice. Make sure you understand selectors, event listeners, and modifying styles with JS. If you are unsure what kinds of widgets I am talking about, look through [this](https://www.frontendinterviewhandbook.com/companies/amazon-front-end-interview-questions] page. + +Something to note, they don’t always use an IDE for these interviews. This allows you to focus on the concept and the design. You save time since you aren’t fixing little bugs to get an HTML page rendered. + +Lastly, for the front end system design, make sure you understand the basics. Get familiar with state management, performance optimizations, and accessibility. This [playlist](https://www.youtube.com/playlist?list=PLI9W87-Dqn7j_x6QtR6sUjycJR7nQLBqT) has TONS of detailed videos. + +I will not go into detail about the specific problems I was given. You should find plenty of these in the links I shared above. This article should provide enough momentum to get started, and you will know best to study for. + +### Conclusion + +All of this is biased to my experience, and you should look beyond just this article. Every new day you study, every hour you invest more time, your skills will sharpen. Focus on what you can control. + +I hope you got some value from the article. If you are interested in reading more about my job searching and landing my first role as a software engineer, checkout out these articles: + - [How I Became a Software Engineer at 20 With No CS Degree](https://spencerlepine.github.io/blog/todo) + - [My Coding Bootcamp Experience at Hack Reactor](https://spencerlepine.github.io/blog/todo) + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/preparing-for-my-amazon-front-end-engineer-interview/thumbnail.jpg b/content/preparing-for-my-amazon-front-end-engineer-interview/thumbnail.jpg similarity index 100% rename from blog/preparing-for-my-amazon-front-end-engineer-interview/thumbnail.jpg rename to content/preparing-for-my-amazon-front-end-engineer-interview/thumbnail.jpg diff --git a/content/quickly-open-github-repo-in-browser-from-terminal/index.devto b/content/quickly-open-github-repo-in-browser-from-terminal/index.devto new file mode 100644 index 0000000..004430d --- /dev/null +++ b/content/quickly-open-github-repo-in-browser-from-terminal/index.devto @@ -0,0 +1,107 @@ +--- +title: Quickly Open GitHub Repo in Browser From Terminal +description: Create custom Git commands to open the repository web page in the browser. +tags: 'git, workflow, terminal' # Dev.to (Max 3) +canonical_url: null # Dev.to +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +I work a lot with the Git CLI and GitHub repository cloned on my local machine. I need a fast way to open the repository web page in the browser. Here is how I solved this, specifically on macOS. + +To start, the the quickest way to get the remote url is the following bash command: + +```sh +git remote -v | awk '/origin.*push/ {print $2}' | xargs open +``` + +That command alone is not very helpful, since it will be difficult to memorize and type out repeatedly. + +Instead, we can create a user-friendly command to use in the macOS terminal. By creating a custom named script in the `bin` directory, the terminal will execute it when the command is used. + +First, navigate to the bin directory: + +```sh +$ cd ~/../../usr/local/bin + +# Make sure this path matches up with your +# configuration for the terminal (e.g. PATH=$PATH:$HOME/bin) +``` + +Now create the script file, here I named the command `repo-open`: + +```sh +$ vim repo-open +``` + +Now paste the script contents into the file editor: + +```sh + #!/bin/bash + +git remote -v | awk '/origin.*push/ {print $2}' | xargs open +``` + +Save the file: + +- press ‘ESC’ +- press ‘SHIFT’ + ‘:’ +- type ‘wq’ + ENTER + +Create the executable: +```sh +$ chmod +x repo-open +``` +That’s it! Now you can run the new script in the terminal. If we are in a directory with a `.git` folder, we can run `repo-open`, and it will open the remote URL in the default browser. + +```sh +$ repo-open +# opens new page in the browser +``` + +Optionally, you can dig a little deeper into writing these scripts. Here are a few examples for Mac and Windows: + +Bash script for Mac: +```sh +function gbrowse { + gbrowsevar=$(git config --get remote.origin.url) + printf "${gbrowsevar}" + start $gbrowsevar +} +``` + +Script for Windows: +```sh +# GIT: open remote repository using Google Chrome +function gbrowse { + NC='\033[0m' # No Color + SB='\033[1;34m' # Sky Blue + PP='\033[1;35m' # Purple + gbrowsevar=$(git config --get remote.origin.url) + printf "\n${PP}→ ${SB}gbrowse:${NC} Chrome\n" + printf "${gbrowsevar}\n" + start chrome $gbrowsevar +} + +# GIT: open remote repository using Firefox +function fbrowse { + NC='\033[0m' # No Color + SB='\033[1;34m' # Sky Blue + PP='\033[1;35m' # Purple + fbrowsevar=$(git config --get remote.origin.url) + printf "\n${PP}→ ${SB}fbrowse:${NC} Firefox\n" + printf "${fbrowsevar}\n" + start firefox $fbrowsevar +} +``` + +--- + +That’s all for today, I hope this article was helpful. If you have any questions, feel free to connect with me. + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/quickly-open-github-repo-in-browser-from-terminal/index.md b/content/quickly-open-github-repo-in-browser-from-terminal/index.md new file mode 100644 index 0000000..83777af --- /dev/null +++ b/content/quickly-open-github-repo-in-browser-from-terminal/index.md @@ -0,0 +1,116 @@ +--- +title: Quickly Open GitHub Repo in Browser From Terminal +slug: quickly-open-github-repo-in-browser-from-terminal +tags: [Git, Workflow, GitHub, Scripts, Terminal, Commands] +authors: [spencerlepine] +date: 2022-10-22T12:00 +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +I work a lot with the Git CLI and GitHub repository cloned on my local machine. I need a fast way to open the repository web page in the browser. Here is how I solved this, +specifically on macOS. + +To start, the the quickest way to get the remote url is the following bash command: + +```sh +git remote -v | awk '/origin.*push/ {print $2}' | xargs open +``` + +That command alone is not very helpful, since it will be difficult to memorize and type out repeatedly. + +Instead, we can create a user-friendly command to use in the macOS terminal. By creating a custom named script in the `bin` directory, the terminal will execute it when the command +is used. + +First, navigate to the bin directory: + +```sh +$ cd ~/../../usr/local/bin + +# Make sure this path matches up with your +# configuration for the terminal (e.g. PATH=$PATH:$HOME/bin) +``` + +Now create the script file, here I named the command `repo-open`: + +```sh +$ vim repo-open +``` + +Now paste the script contents into the file editor: + +```sh + #!/bin/bash + +git remote -v | awk '/origin.*push/ {print $2}' | xargs open +``` + +Save the file: + +- press ‘ESC’ +- press ‘SHIFT’ + ‘:’ +- type ‘wq’ + ENTER + +Create the executable: + +```sh +$ chmod +x repo-open +``` + +That’s it! Now you can run the new script in the terminal. If we are in a directory with a `.git` folder, we can run `repo-open`, and it will open the remote URL in the default +browser. + +```sh +$ repo-open +# opens new page in the browser +``` + +Optionally, you can dig a little deeper into writing these scripts. Here are a few examples for Mac and Windows: + +Bash script for Mac: + +```sh +function gbrowse { + gbrowsevar=$(git config --get remote.origin.url) + printf "${gbrowsevar}" + start $gbrowsevar +} +``` + +Script for Windows: + +```sh +# GIT: open remote repository using Google Chrome +function gbrowse { + NC='\033[0m' # No Color + SB='\033[1;34m' # Sky Blue + PP='\033[1;35m' # Purple + gbrowsevar=$(git config --get remote.origin.url) + printf "\n${PP}→ ${SB}gbrowse:${NC} Chrome\n" + printf "${gbrowsevar}\n" + start chrome $gbrowsevar +} + +# GIT: open remote repository using Firefox +function fbrowse { + NC='\033[0m' # No Color + SB='\033[1;34m' # Sky Blue + PP='\033[1;35m' # Purple + fbrowsevar=$(git config --get remote.origin.url) + printf "\n${PP}→ ${SB}fbrowse:${NC} Firefox\n" + printf "${fbrowsevar}\n" + start firefox $fbrowsevar +} +``` + +--- + +That’s all for today, I hope this article was helpful. If you have any questions, feel free to connect with me. + +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/quickly-open-github-repo-in-browser-from-terminal/quickly-open-github-repo-in-browser-from-terminal.md b/content/quickly-open-github-repo-in-browser-from-terminal/index.medium similarity index 83% rename from blog/quickly-open-github-repo-in-browser-from-terminal/quickly-open-github-repo-in-browser-from-terminal.md rename to content/quickly-open-github-repo-in-browser-from-terminal/index.medium index a8ae2e3..1b67d5a 100644 --- a/blog/quickly-open-github-repo-in-browser-from-terminal/quickly-open-github-repo-in-browser-from-terminal.md +++ b/content/quickly-open-github-repo-in-browser-from-terminal/index.medium @@ -1,9 +1,7 @@ --- title: Quickly Open GitHub Repo in Browser From Terminal -slug: quickly-open-github-repo-in-browser-from-terminal -tags: [Git, Workflow, GitHub, Scripts, Terminal, Commands] -authors: [spencerlepine] -date: 2022-10-22T12:00 +description: Create custom Git commands to open the repository web page in the browser. +publish_status: "draft" --- ![Blog Post Thumbnail](./thumbnail.jpg) @@ -98,8 +96,11 @@ function fbrowse { --- -That’s all for today, I hope this article was helpful. If you have any questions, feel free to connect with me. You can find my profiles here: -* [Twitter (@spencerlepine)](https://twitter.com/SpencerLepine) -* [GitHub (@spencerlepine)](https://github.com/spencerlepine) -* [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) -* [YouTube (Spencer Lepine)](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) \ No newline at end of file +That’s all for today, I hope this article was helpful. If you have any questions, feel free to connect with me. + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/quickly-open-github-repo-in-browser-from-terminal/thumbnail.jpg b/content/quickly-open-github-repo-in-browser-from-terminal/thumbnail.jpg similarity index 100% rename from blog/quickly-open-github-repo-in-browser-from-terminal/thumbnail.jpg rename to content/quickly-open-github-repo-in-browser-from-terminal/thumbnail.jpg diff --git a/content/software-engineering-workflow/index.devto b/content/software-engineering-workflow/index.devto new file mode 100644 index 0000000..8fd2733 --- /dev/null +++ b/content/software-engineering-workflow/index.devto @@ -0,0 +1,115 @@ +--- +title: Software Engineering Workflow +description: Collection of software and resources I use for work. # Dev.to +tags: 'workflow, tools, software engineer' # Dev.to (Max 3) +canonical_url: null # Dev.to +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +This is a collection of resources and my general workflow for Software Engineering. Note: workstation is running MacOS. + +### **Dependencies/Libraries:** + +* [Homebrew](https://brew.sh/) - package manager for linux-based OSs. +* [Git](https://git-scm.com/downloads) - version control, manage files during project development +* [Node.js](https://nodejs.org/en/download/) + [Nvm](https://github.com/nvm-sh/nvm) - runtime for javascript without a browser +* [Npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - large organization of libraries/packages available to use in projects. +* [Python 3](https://www.python.org/downloads/) - python language interpreter for python ^3.0.0. +* [MySQL](https://www.mysql.com/products/workbench/) - SQL database software for development +* [Redis](https://redis.io/) - real time data storage with different data structures in a cache +* [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) - manager for Heroku apps from the command line +* [Amazon CLI](https://aws.amazon.com/cli/) - manager for AWS services from the command line + + +### **Communication:** + +* [Slack](https://slack.com/) +* [Zoom](https://zoom.us/) + + +### **Recording:** + +* [OBS](https://obsproject.com/) +* [Zoom Meeting Recording](https://zoom.us/) + + +### **Other Software:** + +* [Chrome](https://www.google.com/chrome/) - main browser with debugging tools +* [Postman](https://www.postman.com/) - API platform for easy endpoint testing +* [Flux](https://justgetflux.com/) - screen eye strain assistance +* [GIMP](https://www.gimp.org/) - photo editing software + + +### **Toy problems:** + +* [ExcaliDraw](https://excalidraw.com/) +* [LeetCode](https://leetcode.com/) +* [CyberDojo](https://cyber-dojo.org/creator/home) +* [TopCoder](https://www.topcoder.com/) +* [Coderbyte](https://coderbyte.com/) +* [HackerRank](https://www.hackerrank.com/) + + +### **Note taking:** + +* [Notion](https://www.notion.so/) + + +### **IDE:** + +[VSCode](https://code.visualstudio.com/download): +* MacOS Quick Action: Open Folder from finder -> [Configure Quick Action](https://stackoverflow.com/questions/64040393/open-a-folder-in-vscode-through-finder-in-macos) +* [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) Extension - Integrates ESLint JavaScript into VS Code. +* [Bracket Pair Colorizer](https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer) Extension - A customizable extension for colorizing matching brackets +* [Open In Default Browser](https://marketplace.visualstudio.com/items?itemName=peakchen90.open-html-in-browser) Extension - A VSCode extension to fast open html file in browser +* [Stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) Extension - Modern CSS/SCSS/Less linter +* settings.json: + + ```json + { + "editor.lightbulb.enabled": false, + "editor.parameterHints.enabled": false, + "editor.renderWhitespace": "all", + "editor.snippetSuggestions": "none", + "editor.tabSize": 2, + "editor.wordWrap": "off", + "emmet.showExpandedAbbreviation": "never", + "files.trimTrailingWhitespace": true, + "javascript.suggest.enabled": false, + "javascript.updateImportsOnFileMove.enabled": "never", + "javascript.validate.enable": false, + "eslint.alwaysShowStatus": true, + "explorer.confirmDelete": false, + "python.pythonPath": "/usr/bin/python3", + "workbench.editorAssociations": { + "*.ipynb": "jupyter.notebook.ipynb" + }, + "[javascript]": { + "editor.defaultFormatter": "vscode.typescript-language-features" + }, + "css.validate": false, + "window.zoomLevel": 2, + "editor.hover.sticky": false, + "editor.formatOnPaste": true, + "editor.formatOnSave": true, + "editor.defaultFormatter": "vscode.json-language-features", + "workbench.iconTheme": "material-icon-theme", + "security.workspace.trust.untrustedFiles": "open", + "liveshare.allowGuestTaskControl": true, + "liveshare.allowGuestDebugControl": true, + "liveshare.anonymousGuestApproval": "accept", + "python.defaultInterpreterPath": "/usr/bin/python3", + "editor.largeFileOptimizations": false, + } + ``` + +## **Interested in working together?** + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/software-engineering-workflow/index.md b/content/software-engineering-workflow/index.md new file mode 100644 index 0000000..281a0e2 --- /dev/null +++ b/content/software-engineering-workflow/index.md @@ -0,0 +1,113 @@ +--- +title: Software Engineering Workflow +slug: software-engineering-workflow +tags: [Workflow, Tools, Software Engineer] +authors: [spencerlepine] +date: 2021-08-13T12:00 +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +This is a collection of resources and my general workflow for Software Engineering. Note: workstation is running MacOS. + +### **Dependencies/Libraries:** + +- [Homebrew](https://brew.sh/) - package manager for linux-based OSs. +- [Git](https://git-scm.com/downloads) - version control, manage files during project development +- [Node.js](https://nodejs.org/en/download/) + [Nvm](https://github.com/nvm-sh/nvm) - runtime for javascript without a browser +- [Npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - large organization of libraries/packages available to use in projects. +- [Python 3](https://www.python.org/downloads/) - python language interpreter for python ^3.0.0. +- [MySQL](https://www.mysql.com/products/workbench/) - SQL database software for development +- [Redis](https://redis.io/) - real time data storage with different data structures in a cache +- [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) - manager for Heroku apps from the command line +- [Amazon CLI](https://aws.amazon.com/cli/) - manager for AWS services from the command line + +### **Communication:** + +- [Slack](https://slack.com/) +- [Zoom](https://zoom.us/) + +### **Recording:** + +- [OBS](https://obsproject.com/) +- [Zoom Meeting Recording](https://zoom.us/) + +### **Other Software:** + +- [Chrome](https://www.google.com/chrome/) - main browser with debugging tools +- [Postman](https://www.postman.com/) - API platform for easy endpoint testing +- [Flux](https://justgetflux.com/) - screen eye strain assistance +- [GIMP](https://www.gimp.org/) - photo editing software + +### **Toy problems:** + +- [ExcaliDraw](https://excalidraw.com/) +- [LeetCode](https://leetcode.com/) +- [CyberDojo](https://cyber-dojo.org/creator/home) +- [TopCoder](https://www.topcoder.com/) +- [Coderbyte](https://coderbyte.com/) +- [HackerRank](https://www.hackerrank.com/) + +### **Note taking:** + +- [Notion](https://www.notion.so/) + +### **IDE:** + +[VSCode](https://code.visualstudio.com/download): + +- MacOS Quick Action: Open Folder from finder -> [Configure Quick Action](https://stackoverflow.com/questions/64040393/open-a-folder-in-vscode-through-finder-in-macos) +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) Extension - Integrates ESLint JavaScript into VS Code. +- [Bracket Pair Colorizer](https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer) Extension - A customizable extension for colorizing matching + brackets +- [Open In Default Browser](https://marketplace.visualstudio.com/items?itemName=peakchen90.open-html-in-browser) Extension - A VSCode extension to fast open html file in browser +- [Stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) Extension - Modern CSS/SCSS/Less linter +- settings.json: + + ```json + { + "editor.lightbulb.enabled": false, + "editor.parameterHints.enabled": false, + "editor.renderWhitespace": "all", + "editor.snippetSuggestions": "none", + "editor.tabSize": 2, + "editor.wordWrap": "off", + "emmet.showExpandedAbbreviation": "never", + "files.trimTrailingWhitespace": true, + "javascript.suggest.enabled": false, + "javascript.updateImportsOnFileMove.enabled": "never", + "javascript.validate.enable": false, + "eslint.alwaysShowStatus": true, + "explorer.confirmDelete": false, + "python.pythonPath": "/usr/bin/python3", + "workbench.editorAssociations": { + "*.ipynb": "jupyter.notebook.ipynb" + }, + "[javascript]": { + "editor.defaultFormatter": "vscode.typescript-language-features" + }, + "css.validate": false, + "window.zoomLevel": 2, + "editor.hover.sticky": false, + "editor.formatOnPaste": true, + "editor.formatOnSave": true, + "editor.defaultFormatter": "vscode.json-language-features", + "workbench.iconTheme": "material-icon-theme", + "security.workspace.trust.untrustedFiles": "open", + "liveshare.allowGuestTaskControl": true, + "liveshare.allowGuestDebugControl": true, + "liveshare.anonymousGuestApproval": "accept", + "python.defaultInterpreterPath": "/usr/bin/python3", + "editor.largeFileOptimizations": false + } + ``` + +## **Interested in working together?** + +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/software-engineering-workflow/software-engineering-workflow.md b/content/software-engineering-workflow/index.medium similarity index 91% rename from blog/software-engineering-workflow/software-engineering-workflow.md rename to content/software-engineering-workflow/index.medium index b11803a..f98db9c 100644 --- a/blog/software-engineering-workflow/software-engineering-workflow.md +++ b/content/software-engineering-workflow/index.medium @@ -1,9 +1,7 @@ --- title: Software Engineering Workflow -slug: software-engineering-workflow -tags: [Workflow, Tools, Software Engineer] -authors: [spencerlepine] -date: 2021-08-13T12:00 +description: Collection of software and resources I use for work. +publish_status: "draft" --- ![Blog Post Thumbnail](./thumbnail.jpg) @@ -108,8 +106,9 @@ This is a collection of resources and my general workflow for Software Engineeri ## **Interested in working together?** -Let’s connect! Find me on any of my socials linked below: - -* [Twitter (@spencerlepine)](https://twitter.com/SpencerLepine) -* [GitHub (@spencerlepine)](https://github.com/spencerlepine) -* [YouTube (Spencer Lepine)](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/software-engineering-workflow/thumbnail.jpg b/content/software-engineering-workflow/thumbnail.jpg similarity index 100% rename from blog/software-engineering-workflow/thumbnail.jpg rename to content/software-engineering-workflow/thumbnail.jpg diff --git a/content/typescript-development-set-up-for-vscode/index.devto b/content/typescript-development-set-up-for-vscode/index.devto new file mode 100644 index 0000000..085d44c --- /dev/null +++ b/content/typescript-development-set-up-for-vscode/index.devto @@ -0,0 +1,129 @@ +--- +title: TypeScript Development Set Up for VSCode +description: Brief walkthrough for TypeScript development in VSCode. # Dev.to +tags: 'typescript, vscode, workflow' # Dev.to (Max 3) +canonical_url: null # Dev.to +--- + +![](./thumbnail.jpg) + +Looking to set up VSCode for a TypeScript project? This article will walk through the initial configuration steps for just that. + +This walk-through assumes you have the already have the following installed: + +- [VSCode](https://code.visualstudio.com/) +- [Node.js](https://nodejs.org/en/download/) +- [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) + +To begin, let’s install the `typescript` module globally: + +```sh +$ npm install -g typescript +$ tsc --version +``` + +Great! Now we can code our `.ts` files. A small issue remains. In order to compile those files to `.js`, we must run `tsc` or `npm run build` manually. To avoid this, we can auto-compile __on save__ in our IDE. + +## Configure Auto-Compile on Save + +Using the build tasks in VSCode, you can trigger auto-compile on save. This can be done through the settings search bar, or the application's menu bar in macOS. + +### Option 1: + +- Enter `CMD+SHIFT+P` +- Select: `Tasks: Configure Default Build Task` +- Choose: `tsc: watch - tsconfig.json` + +### Option 2: + +- Find tabs: in OS VSCode menu bar +- Click: `Terminal` (open dropdown) +- Select: `Configure Default Build Task` +- Choose: `tsc watch` option + +Now during development, anytime you save the `.ts` files, it will generate `.js` output automatically. + +## Hiding Compiler Output In Editor File Tree + +After running `tsc build`, it will populate the directory with compiled files. You may find `.js`, `.js.map`, or `.d.ts.` files, which could be useful to explore when learning. However, these can clutter up the file tree in the IDE. + +There is an easy was to hide these files in the workspace, without deleting them from the file system. + +To configure the following VSCode settings, it can be done in the global `settings.json` file, or for the projects workspace + +To set up a workspace, Do `"CMD+SHIFT+P" => "Preferences: Open Workspace Settings"`. This creates the `/.vscode/settings.json` file in the project directory. Note, you include the `.vscode` folder in the git history, unless a team is not sharing these settings. + +To find the settings file do `"CMD+SHIFT+P" => "Preferences: Open User Settings (JSON)"` or `"CMD+SHIFT+P" => "Preferences: Open Workspace Settings"`. + +Add the following options for file ignoring to the VSCode `settings.json`: +```json +{ + "files.exclude": { + "**/.git": true, + "**/.DS_Store": true, + "**/*.js.map": true, + "**/*.js": {"when": "$(basename).ts"} + } +} +``` + +Or + +```json +{ + "files.exclude": { + "**/.git": true, + "**/.DS_Store": true, + "**/*.d.ts": { + "when": "$(basename).ts" + }, + "**/*.js": { + "when": "$(basename).ts" + }, + "**/*.js.map": { + "when": "$(basename)" + } + } +} + ``` + + +## Using .gitignore + +When using git for your TypeScript project, you are not committing the compiled JavaScript code. You most likely will ignore the files generated, so you can configure that in the `.gitignore`. Be aware of needed files however, for example a `jest.config.js` file. + +Keeping the source `.ts` files, a `.gitignore` file may look like this: + +```diff +*.js +!jest.config.js +*.d.ts +node_modules +!lambda/*.js +``` + +## Configure Format On Save + +Optionally, you can avoid wasting time on formatting with `formatOnSave`. Add the following key to your `settings.json` file to enable: + +```json +"[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + } +``` + +## Conclusion + +That's it! You can now begin development for your new TypeScript project, with auto-compile and format-on-save enabled. The main purpose of this article was to document the setup project for my own use, and strengthen my understanding by teaching. + +--- + +That’s all for today, I hope this article was helpful. If you have any questions, feel free to connect with me. + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/typescript-development-set-up-for-vscode/index.md b/content/typescript-development-set-up-for-vscode/index.md new file mode 100644 index 0000000..60eafd7 --- /dev/null +++ b/content/typescript-development-set-up-for-vscode/index.md @@ -0,0 +1,136 @@ +--- +title: TypeScript Development Set Up for VSCode +slug: typescript-development-set-up-for-vscode +tags: [Workflow, VSCode, TypeScript] +authors: [spencerlepine] +date: 2022-10-24T12:00 +--- + +![](./thumbnail.jpg) + +Looking to set up VSCode for a TypeScript project? This article will walk through the initial configuration steps for just that. + +This walk-through assumes you have the already have the following installed: + +- [VSCode](https://code.visualstudio.com/) +- [Node.js](https://nodejs.org/en/download/) +- [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) + +To begin, let’s install the `typescript` module globally: + +```sh +$ npm install -g typescript +$ tsc --version +``` + +Great! Now we can code our `.ts` files. A small issue remains. In order to compile those files to `.js`, we must run `tsc` or `npm run build` manually. To avoid this, we can +auto-compile **on save** in our IDE. + +## Configure Auto-Compile on Save + +Using the build tasks in VSCode, you can trigger auto-compile on save. This can be done through the settings search bar, or the application's menu bar in macOS. + +### Option 1: + +- Enter `CMD+SHIFT+P` +- Select: `Tasks: Configure Default Build Task` +- Choose: `tsc: watch - tsconfig.json` + +### Option 2: + +- Find tabs: in OS VSCode menu bar +- Click: `Terminal` (open dropdown) +- Select: `Configure Default Build Task` +- Choose: `tsc watch` option + +Now during development, anytime you save the `.ts` files, it will generate `.js` output automatically. + +## Hiding Compiler Output In Editor File Tree + +After running `tsc build`, it will populate the directory with compiled files. You may find `.js`, `.js.map`, or `.d.ts.` files, which could be useful to explore when learning. +However, these can clutter up the file tree in the IDE. + +There is an easy was to hide these files in the workspace, without deleting them from the file system. + +To configure the following VSCode settings, it can be done in the global `settings.json` file, or for the projects workspace + +To set up a workspace, Do `"CMD+SHIFT+P" => "Preferences: Open Workspace Settings"`. This creates the `/.vscode/settings.json` file in the project directory. Note, you +include the `.vscode` folder in the git history, unless a team is not sharing these settings. + +To find the settings file do `"CMD+SHIFT+P" => "Preferences: Open User Settings (JSON)"` or `"CMD+SHIFT+P" => "Preferences: Open Workspace Settings"`. + +Add the following options for file ignoring to the VSCode `settings.json`: + +```json +{ + "files.exclude": { + "**/.git": true, + "**/.DS_Store": true, + "**/*.js.map": true, + "**/*.js": { "when": "$(basename).ts" } + } +} +``` + +Or + +```json +{ + "files.exclude": { + "**/.git": true, + "**/.DS_Store": true, + "**/*.d.ts": { + "when": "$(basename).ts" + }, + "**/*.js": { + "when": "$(basename).ts" + }, + "**/*.js.map": { + "when": "$(basename)" + } + } +} +``` + +## Using .gitignore + +When using git for your TypeScript project, you are not committing the compiled JavaScript code. You most likely will ignore the files generated, so you can configure that in the +`.gitignore`. Be aware of needed files however, for example a `jest.config.js` file. + +Keeping the source `.ts` files, a `.gitignore` file may look like this: + +```diff +*.js +!jest.config.js +*.d.ts +node_modules +!lambda/*.js +``` + +## Configure Format On Save + +Optionally, you can avoid wasting time on formatting with `formatOnSave`. Add the following key to your `settings.json` file to enable: + +```json +"[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + } +``` + +## Conclusion + +That's it! You can now begin development for your new TypeScript project, with auto-compile and format-on-save enabled. The main purpose of this article was to document the setup +project for my own use, and strengthen my understanding by teaching. + +--- + +That’s all for today, I hope this article was helpful. If you have any questions, feel free to connect with me. + +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/typescript-development-set-up-for-vscode/typescript-development-set-up-for-vscode.md b/content/typescript-development-set-up-for-vscode/index.medium similarity index 88% rename from blog/typescript-development-set-up-for-vscode/typescript-development-set-up-for-vscode.md rename to content/typescript-development-set-up-for-vscode/index.medium index a2cdfaf..3029280 100644 --- a/blog/typescript-development-set-up-for-vscode/typescript-development-set-up-for-vscode.md +++ b/content/typescript-development-set-up-for-vscode/index.medium @@ -1,9 +1,7 @@ --- title: TypeScript Development Set Up for VSCode -slug: typescript-development-set-up-for-vscode -tags: [Workflow, VSCode, TypeScript] -authors: [spencerlepine] -date: 2022-10-24T12:00 +description: Brief walkthrough for TypeScript development in VSCode +publish_status: "draft" --- ![](./thumbnail.jpg) @@ -120,8 +118,11 @@ That's it! You can now begin development for your new TypeScript project, with a --- -That’s all for today, I hope this article was helpful. If you have any questions, feel free to connect with me. You can find my profiles here: -* [Twitter (@spencerlepine)](https://twitter.com/SpencerLepine) -* [GitHub (@spencerlepine)](https://github.com/spencerlepine) -* [LinkedIn](https://www.linkedin.com/in/spencer-lepine/) -* [YouTube (Spencer Lepine)](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +That’s all for today, I hope this article was helpful. If you have any questions, feel free to connect with me. + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/blog/typescript-development-set-up-for-vscode/thumbnail.jpg b/content/typescript-development-set-up-for-vscode/thumbnail.jpg similarity index 100% rename from blog/typescript-development-set-up-for-vscode/thumbnail.jpg rename to content/typescript-development-set-up-for-vscode/thumbnail.jpg diff --git a/blog/what-i-learned-during-100-days-of-code/what-i-learning-during-100-days-of-code.md b/content/what-i-learned-during-100-days-of-code/index.devto similarity index 80% rename from blog/what-i-learned-during-100-days-of-code/what-i-learning-during-100-days-of-code.md rename to content/what-i-learned-during-100-days-of-code/index.devto index ba360c3..912919e 100644 --- a/blog/what-i-learned-during-100-days-of-code/what-i-learning-during-100-days-of-code.md +++ b/content/what-i-learned-during-100-days-of-code/index.devto @@ -1,9 +1,8 @@ --- title: What I Learned During 100DaysOfCode -slug: what-i-learned-during-100-days-of-code -tags: [Git, Scripts, Terminal, Commands, GitHub] -authors: [spencerlepine] -date: 2021-06-26T12:00 +description: Summary for a 100 day coding challenge. # Dev.to +tags: 'junior engineer, challenge, learning' # Dev.to (Max 3) +canonical_url: null # Dev.to --- ![Blog Post Thumbnail](./thumbnail.jpg) @@ -12,8 +11,9 @@ I recently completed a popular challenge on Twitter named #100DaysOfCode. There In my case, it was not my first time coding when I started this. However, the challenge helped me stay dedicated and build upon each skill I learned. -Day 1–10: The Challenge Begins! -=============================== +To see the original README journal, see [this repository](https://github.com/spencerlepine/100-days-of-code) + +## Day 1–10: The Challenge Begins! It all started with a ton of useful lessons on ES6 skills. There was a lot of new syntax and tricks that I never knew about. Since I started learning Javascript before ES6 was released, there were quite a few features I needed to practice. @@ -29,8 +29,7 @@ To wrap up this part of the challenge, there were some coding challenges from Cy [spencerlepine/cyber-dojo-exercises - GitHub](https://github.com/spencerlepine/cyber-dojo-exercises) -Day 11–20: Just Getting Started -=============================== +## Day 11–20: Just Getting Started At this point, there was some great momentum and I was always feeling more motivated to learn. The Scrimba React course had a lot of great lessons on all the basics of React. @@ -50,8 +49,7 @@ After discovering the behemoth of AWS products, I wasted no time working to set Just before reaching day 20, a worked on an in-browser [Chess React](https://github.com/spencerlepine/react-chess) app. This was just another opportunity to practice Javascript and apply knowledge. -Day 21–30: Gaining Momentum! -============================ +## Day 21–30: Gaining Momentum! With a solid understanding of React, it was time to double down on more computer science fundamentals. It was exciting to build toy projects, but that wouldn’t be enough. @@ -63,8 +61,7 @@ Alongside CS50 was more material about React memo and Context API — write a co Day 29 was the day I started working on Galvanize basic prep lessons. -Day 31–40: Diving Deeper -======================== +## Day 31–40: Diving Deeper CS50 included some lessons about data structures and SQL. I worked on some really good challenges for the CS50 Fiftyville assignment. @@ -76,8 +73,7 @@ With MongoDB connected to React, I was able to work on a MERN app that could rea Day 36 was when I began the QuickCar react app. Connected it to a backend MongoDB Atlas server. Add reducer + actions for post/fetch from frontend. Save the data in redux state. I created forms and routes with components connected to the Redux state using useSelectors. -Day 41–50: Working on QuickCart -=============================== +## Day 41–50: Working on QuickCart As I worked through some lessons for Galvanize basic prep, I also started lessons on [freeCodeCamp](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/). Got a better understanding of Regex from that. @@ -87,8 +83,7 @@ I revisited my AWS account. Started basic portfolio site using React — Set up With a working site, it would be really nice to have a blog hosted on the domain. I attempted to set up a blog. Researched Gatsby, GraphCMS, ButterCMS, GraphQL. Queries were not working. Unable to route to posts. This was a difficult concept to navigate, but along the way I learned a lot about apache and setting up ssl. -Day 51–60: A Working Blog! -========================== +## Day 51–60: A Working Blog! Gatsby.js was the answer. Instead of using a headless CMS, I settled with local md files to use for an article. During this challenge, I spent many hours working with the ‘mdx’ plugin. I tried to connect a CMS through queries and GraphQL, but it was very difficult. @@ -98,8 +93,7 @@ Flatiron wasn’t the only school that I was preparing for though. I completed m The last major assignment on hand was working through more of the freeCodeCamp Javascript fundamentals material. -Day 51–60: Coding Bootcamp! -=========================== +## Day 51–60: Coding Bootcamp! No, I didn’t start a coding bootcamp, but I was getting ready! I got accepted into Flatiron (they didn’t do a TAA anymore), accepted into General Assembly, and I was studying to pass my Hack Reactor technical assessment. My target was in August, which was over 100 days from this point. @@ -113,8 +107,7 @@ With all that work done, I began Hack Reactor premium prep. The technical admiss This is where I began working testing. Test driven development is integral to Software Engineering. I was able to appreciate my code much more after practicing it. -Day 71–80: Hack Reactor and Firebase -==================================== +## Day 71–80: Hack Reactor and Firebase At this point, I was making really good progress in my Hack Reactor prep work. I was able to learn the basic methodology of testing my code. Whenever I worked on Javascript challenges, it was important to practice writing tests and get used to the upfront setup. @@ -126,8 +119,7 @@ One of the most important themes of this week was practicing problem solving. Ha Now that I was able to write small tests for a challenge, I wanted to work on writing tests for a real project. I started learning how to use Enzyme and Jest for React test-driven-development. The process is tedious at the start, but it will ensure the code is more robust. This was difficult for me at first, because I wasn’t sure if my React test was written incorrectly, or I needed to pass the test now instead. There were lots of features to read Docs about, like redirecting, testing contexts/store, and tons more. -Day 81–90: Test Driven Development and APIs -=========================================== +## Day 81–90: Test Driven Development and APIs The TDD practice with React was the birth of Woofer. I wanted to work on a project and build it from the ground up writing tests. I did my best to write a test FIRST before writing code. This project did not go very far during my challenge, since there were other priorities. It was going to take a long time to complete the idea, and it was just good practice to implement testing. @@ -141,8 +133,7 @@ I stepped away from the deep rabbit hole of React TDD. I went back to QuickCart One feature I had been eager to add to the grocery app was “searching products”. With an empty form, users could manually input EVERY detail about a product, but nobody would want to use that. By connecting to the OpenFoodFacts API, I could search a dump of thousands of grocery products. This was an open source dump that anybody can contribute to. They also feature nutrition score data, so it can help users see healthier options. -Day 91–100: The Final Stretch -============================= +## Day 91–100: The Final Stretch After learning so much with Javascript and best-practices for writing code, it was time to USE these skills. I continued working through Hack Reactor prep material. I learned about higher order functions, scopes, and hoisting. There were lessons about terminal commands and important dev tools like homebrew. It was time to upgrade my developer workflow, and get familiar with industry standard software. @@ -154,22 +145,11 @@ The next Hack Reactor prep section was about Git and GitHub. This was a REALLY u More work on Mocha and Chai testing was done. Getting familiar with different libraries and how they have similar functions. -**Challenge Complete!** -======================= - -After 100 days of coding, I was able to explore new features and concepts relating to Javascript and software development. The dedication allowed me to keep my momentum and build upon what I learned the previous day. - -Interested in working together? -------------------------------- - -Let’s connect! Find me on any of my socials linked below: +## Conclusion -* [Twitter (@spencerlepine)](https://twitter.com/SpencerLepine) -* [GitHub (@spencerlepine)](https://github.com/spencerlepine) -* [YouTube (Spencer Lepine)](https://www.youtube.com/channel/UCBL6vAHJZqUlyJp-rcFU55Q) +Challenge complete! After 100 days of coding, I was able to explore new features and concepts relating to Javascript and software development. The dedication allowed me to keep my momentum and build upon what I learned the previous day. Here is an overview of everything I learned: --------------------------------------------- * ES6 Javascript * Functional vs. OPP programming @@ -193,81 +173,51 @@ Here is an overview of everything I learned: * Separating the front-end / back-end * Deploying to Heroku -**Projects:** -------------- +### Projects Explore more [projects](https://spencerlepine.com) — or check out the ones mentioned in the article: +- QuickCart + - Make a shopping list with personal grocery data to help budget. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/quickcart) -### QuickCart - -Make a shopping list with personal grocery data to help budget. - -[GitHub Repo](https://github.com/spencerlepine/quickcart) - ------------------------ - - -### Portfolio Site - -Portfolio and blog website ( Visit Here) created by Spencer Lepine. Built using static pages created with GatsbyJS… - -[GitHub Repo](https://github.com/spencerlepine/spencerlepine.com) - ------------------------ - -### Cyber Dojo Exercises - -Personal solutions to various Cyber Dojo exercises. Code is written in Python and tests use 'asserts' with pytest. All… - -[GitHub Repo](https://github.com/spencerlepine/cyber-dojo-exercises) - ------------------------ - - -### Woofer - -Tinder for Pets Web App. Swipe and connect with other furry friends in the area. - -[GitHub Repo](https://github.com/spencerlepine/woofer) - ------------------------ - -### React Chess - -Play chess in the browser by with drag and drop moves. This was created using the Javascript React framework. component… - -[GitHub Repo](https://github.com/spencerlepine/react-chess) - ------------------------ - -### Study Garden - -Improve focus and discipline with this timer app. Study until the timer runs out and add plants to your personal… - -[GitHub Repo](https://github.com/spencerlepine/study-garden) - ------------------------ - - -### Spotify Top Songs - -Generate a Spotify playlist based on the top rated songs of your favorite artists. Connect user Spotify accounts to… +- Portfolio Site + - Portfolio and blog website ([Visit Here](https://www.spencerlepine.com)) created by Spencer Lepine. Built using static pages created with GatsbyJS… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/portfolio-site-v2) -[GitHub Repo](https://github.com/spencerlepine/spotify-top-songs) +- Cyber Dojo Exercises + - Personal solutions to various Cyber Dojo exercises. Code is written in Python and tests use 'asserts' with pytest. All… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/cyber-dojo-exercises) ------------------------ +- Woofer + - Tinder for Pets Web App. Swipe and connect with other furry friends in the area. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/woofer) -### GitHub User Overview +- React Chess + - Play chess in the browser by with drag and drop moves. This was created using the Javascript React framework. component… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/react-chess) -This React App allows the user to type a username get an overview of their GitHub repos using the GitHub REST API. +- Study Garden + - Improve focus and discipline with this timer app. Study until the timer runs out and add plants to your personal… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/study-garden) -[GitHub Repo](https://github.com/spencerlepine/github-api-react) +- Spotify Top Songs + - Generate a Spotify playlist based on the top rated songs of your favorite artists. Connect user Spotify accounts to… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/spotify-top-songs) ------------------------ +- GitHub User Overview + - This React App allows the user to type a username get an overview of their GitHub repos using the GitHub REST API. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/github-api-react) -### CS50 Problem Sets +- CS50 Problem Sets + - My solutions to the online CS50 course generously provided by Harvard University. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/cs50-problem-sets) -My solutions to the online CS50 course generously provided by Harvard University. +## Interested in working together? -[GitHub Repo](https://github.com/spencerlepine/cs50-problem-sets) +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) \ No newline at end of file diff --git a/content/what-i-learned-during-100-days-of-code/index.md b/content/what-i-learned-during-100-days-of-code/index.md new file mode 100644 index 0000000..cd7c74e --- /dev/null +++ b/content/what-i-learned-during-100-days-of-code/index.md @@ -0,0 +1,278 @@ +--- +title: What I Learned During 100DaysOfCode +slug: what-i-learned-during-100-days-of-code +tags: [Junior Engineer, Challenge, Learning] +authors: [spencerlepine] +date: 2021-06-26T12:00 +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +I recently completed a popular challenge on Twitter named #100DaysOfCode. There is no barrier to entry, and you just need to code for at least 1 hour a day. This is a great +challenge to motivate yourself and see your progress alongside others. + +In my case, it was not my first time coding when I started this. However, the challenge helped me stay dedicated and build upon each skill I learned. + +To see the original README journal, see [this repository](https://github.com/spencerlepine/100-days-of-code) + +## Day 1–10: The Challenge Begins! + +It all started with a ton of useful lessons on ES6 skills. There was a lot of new syntax and tricks that I never knew about. Since I started learning Javascript before ES6 was +released, there were quite a few features I needed to practice. + +[ ES6 Course - Scrimba](https://scrimba.com/learn/introtoes6) + +Having just completed a small course on the React framework, I worked on implementing ES6 skills I picked up to make small projects. Here is a simple React app connected to GitHubs +REST API. This helped me learn how to make fetch calls and save the data to state. + +[ spencerlepine/github-api-react - GitHub](https://github.com/spencerlepine/github-api-react) + +Each day I worked on different React concepts. Connecting/modifying a mock database locally. Working with state and props and pass data around. My most effective learning styles +was learning-by-doing. After reading the docs and seeing a new feature, I would realize how I could use it to improve my project. + +To wrap up this part of the challenge, there were some coding challenges from Cyber Dojo to help practice problem solving. I was able to solve “Align Columns”, “LCD Digits”, +“Wonderland Number”. Check out my repo with my solutions here: + +[spencerlepine/cyber-dojo-exercises - GitHub](https://github.com/spencerlepine/cyber-dojo-exercises) + +## Day 11–20: Just Getting Started + +At this point, there was some great momentum and I was always feeling more motivated to learn. The Scrimba React course had a lot of great lessons on all the basics of React. + +[The React Bootcamp - Scrimba](https://scrimba.com/learn/react) + +I built a controlled-form in React that would update state based on events and targets. Next up was the big concept of hooks and functional components. Little did I know this was +only the START of what is possible in React. + +The React course was complete, which led me to start a new project called Spotify Top Songs. This site would connect to the Spotify Web API with client-side authentication. When a +user connected their account, they could select various artists from a menu. The script would then generate a playlist by accessing the top 5 songs of each artist. + +This time, code was much more organized with the components and logic separated. With so many fetch calls and bits of logic to intertwine, it was important to build everything +slowly and cleanly. + +[spencerlepine/spotify-top-songs - GitHub](https://github.com/spencerlepine/spotify-top-songs) + +I learned about prop-types and default props, which can be pretty handy. Worked React higher order components and children components. Started learning about AWS S3 buckets. To +practice, I deployed my Spotify Top Songs to the S3 bucket. + +After discovering the behemoth of AWS products, I wasted no time working to set up an AWS EC2 instance to host a static site, which I would connect to my Route53 domain. + +Just before reaching day 20, a worked on an in-browser [Chess React](https://github.com/spencerlepine/react-chess) app. This was just another opportunity to practice Javascript and +apply knowledge. + +## Day 21–30: Gaining Momentum! + +With a solid understanding of React, it was time to double down on more computer science fundamentals. It was exciting to build toy projects, but that wouldn’t be enough. + +After finding the CS50 course online, I watched the lectures on C and Python. This was very useful to learn about memory pointers and how the interpreter reads code. Dave is a +GREAT teacher and I would highly recommend going through the course. + +Lots to learn about memory allocation, what libraries are doing under the hood, string manipulation, and regex. + +Alongside CS50 was more material about React memo and Context API — write a component to access a ‘global’ state in a separate file. Import that file and render through that in any +component of choice. Custom hooks that handle business logic. React router basics. Conditional rendering. All of these skills would allow me to start creating real multi-page +sites! + +Day 29 was the day I started working on Galvanize basic prep lessons. + +## Day 31–40: Diving Deeper + +CS50 included some lessons about data structures and SQL. I worked on some really good challenges for the CS50 Fiftyville assignment. + +It was time for me to learn how to connect a database. I began working with MongoDB and Node.js. I used Postman to practice making requests. + +With a lot of data to store in state, I needed a way to organize it all. Thats where React Redux came up — createStore, redux philosophies, subscribe, dispatch, combineReducer. +Abstracting reducers to handle each state in isolation. combineReducers to combine everything and handle state more cleanly in a rootReducer. + +With MongoDB connected to React, I was able to work on a MERN app that could read/write from the database. Connecting back-end/front-end routes and using controllers for the fetch +logic/requests. + +Day 36 was when I began the QuickCar react app. Connected it to a backend MongoDB Atlas server. Add reducer + actions for post/fetch from frontend. Save the data in redux state. I +created forms and routes with components connected to the Redux state using useSelectors. + +## Day 41–50: Working on QuickCart + +As I worked through some lessons for Galvanize basic prep, I also started lessons on [freeCodeCamp](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/). +Got a better understanding of Regex from that. + +Next came Javascript algorithm practice + Object Orientated Programming review. Inheriting methods from parent objects. Using Object.prototypes to reuse methods. + +I revisited my AWS account. Started basic portfolio site using React — Set up LAMP stack server to host website. Direct AWS Route53 domain to DigitalOcean droplet. Set up SSL, +MySQL, and WordPress. Working to set up a blog too. + +With a working site, it would be really nice to have a blog hosted on the domain. I attempted to set up a blog. Researched Gatsby, GraphCMS, ButterCMS, GraphQL. Queries were not +working. Unable to route to posts. This was a difficult concept to navigate, but along the way I learned a lot about apache and setting up ssl. + +## Day 51–60: A Working Blog! + +Gatsby.js was the answer. Instead of using a headless CMS, I settled with local md files to use for an article. During this challenge, I spent many hours working with the ‘mdx’ +plugin. I tried to connect a CMS through queries and GraphQL, but it was very difficult. + +Around this time I continued working through Learn.co lessons for Flatiron prep. There were two main sections on Javascript and Ruby. The Ruby material was interesting and they +even did a review on Object Oriented Programming. + +Flatiron wasn’t the only school that I was preparing for though. I completed my technical assessment by creating a basic HTML page with images and a clickable button. + +The last major assignment on hand was working through more of the freeCodeCamp Javascript fundamentals material. + +## Day 51–60: Coding Bootcamp! + +No, I didn’t start a coding bootcamp, but I was getting ready! I got accepted into Flatiron (they didn’t do a TAA anymore), accepted into General Assembly, and I was studying to +pass my Hack Reactor technical assessment. My target was in August, which was over 100 days from this point. + +Making sure I could get into these schools was my main priority, but I continued learning and working on projects on the side. + +I worked on building the QuickCart app and added tons of features. Import/Export a grocery database. Improve the UI and styles. Upload images for a product in the form. Convert +images to base64 strings. Work with file blobs and cropping images. Generate suggested products with a recommendation algorithm. Work on authentications between the front/back-end +for the MERN app. Add a “cart” to store items until purchase. + +At this point, the grocery app was still connected to MongoDB. I was able to use localStorage and save some user data, but I knew I needed EVERYTHING to be in the cloud. + +With all that work done, I began Hack Reactor premium prep. The technical admissions assessment was going to be difficult, so this would help me prepared my vocalization and +problem solving. + +This is where I began working testing. Test driven development is integral to Software Engineering. I was able to appreciate my code much more after practicing it. + +## Day 71–80: Hack Reactor and Firebase + +At this point, I was making really good progress in my Hack Reactor prep work. I was able to learn the basic methodology of testing my code. Whenever I worked on Javascript +challenges, it was important to practice writing tests and get used to the upfront setup. + +This week was my first attempt at the Hack Reactor TAA, and I passed! This was incredible, because I got to choose between GA, Flatiron, and Hack Reactor. + +I continued working on QuickCart on the side. There were some bug fixes and UI improvements that needed to be done. I migrated from MongoDB to Firebase for the backend. I had to +read through the docs and get familiar with Firestore. + +One of the most important themes of this week was practicing problem solving. Hack Reactor was really pushing best practices and effective communication. Each day I worked on a toy +problem/code challenge. With a timer running, I would work on my pseudo-code BEFORE starting and really explain/verbalize my thought process as much as I could. + +Now that I was able to write small tests for a challenge, I wanted to work on writing tests for a real project. I started learning how to use Enzyme and Jest for React +test-driven-development. The process is tedious at the start, but it will ensure the code is more robust. This was difficult for me at first, because I wasn’t sure if my React test +was written incorrectly, or I needed to pass the test now instead. There were lots of features to read Docs about, like redirecting, testing contexts/store, and tons more. + +## Day 81–90: Test Driven Development and APIs + +The TDD practice with React was the birth of Woofer. I wanted to work on a project and build it from the ground up writing tests. I did my best to write a test FIRST before writing +code. This project did not go very far during my challenge, since there were other priorities. It was going to take a long time to complete the idea, and it was just good practice +to implement testing. + +I documented/planned out the Woofer app before starting. I made wireframes and planned out the logic/routing ahead of time. It was taking WAY too much time to work with mock stores +and complex routing in testing. I even fell into certain anti-patterns with testing after researching about tests online. + +[spencerlepine/woofer - GitHub](https://github.com/spencerlepine/woofer) + +I stepped away from the deep rabbit hole of React TDD. I went back to QuickCart and migrated EVERYTHING to client-side. Now it was one complete React app with firebase +authentication built in. I was able to host this site on Heroku too, so anyone could use it. + +[spencerlepine/quickcart - GitHub](https://github.com/spencerlepine/quickcart) + +One feature I had been eager to add to the grocery app was “searching products”. With an empty form, users could manually input EVERY detail about a product, but nobody would want +to use that. By connecting to the OpenFoodFacts API, I could search a dump of thousands of grocery products. This was an open source dump that anybody can contribute to. They also +feature nutrition score data, so it can help users see healthier options. + +## Day 91–100: The Final Stretch + +After learning so much with Javascript and best-practices for writing code, it was time to USE these skills. I continued working through Hack Reactor prep material. I learned about +higher order functions, scopes, and hoisting. There were lessons about terminal commands and important dev tools like homebrew. It was time to upgrade my developer workflow, and +get familiar with industry standard software. + +Here I read about Node.js, npm, semvar, and modules. This was everything I need to know about how projects are set up and how developers are able to work together. There needs to +be structure and conventions throughout the code base so everyone is on the same page. + +I also added a some features to QuickCart on the side again. I connected a Google Custom Search Engine to allow image searches for a product. Instead of having the user upload or +snap a photo, they could simply link an existing photo. This allowed me to store the image sources with links, instead a long base64 string with image data. That would improve +scalability and prevent product images from being lost easily. + +The next Hack Reactor prep section was about Git and GitHub. This was a REALLY useful sections to go through because it will be the backbone of any project. Knowing how to properly +document and collaborate on a project makes everything so much more compatible. Your code needs to be readable and maintainable. People can review your code and merge branches to +improve the project. You could even checkout different commits and revert your code. Before I learned about these practices, I would always CTRL+Z my file and start over again, +wasting so much time. + +More work on Mocha and Chai testing was done. Getting familiar with different libraries and how they have similar functions. + +## Conclusion + +Challenge complete! After 100 days of coding, I was able to explore new features and concepts relating to Javascript and software development. The dedication allowed me to keep my +momentum and build upon what I learned the previous day. + +Here is an overview of everything I learned: + +- ES6 Javascript +- Functional vs. OPP programming +- Javascript algorithms and data structures +- Node.js +- Redux +- React +- SQL +- Python +- Comp Sci fundamentals +- MongoDB +- Firebase +- React Context, state, props, controlled forms +- CMS +- Hosting a static site +- Procedure for problem solving (pseudocode, breaking it down) +- Mocha/Chai testing +- React Jest/Enzyme testing +- Connecting to APIs (Spotify Web API, GitHub REST API, OpenFoodFacts API) +- Fetch calls + axios +- Separating the front-end / back-end +- Deploying to Heroku + +### Projects + +Explore more [projects](https://spencerlepine.com) — or check out the ones mentioned in the article: + +- QuickCart + + - Make a shopping list with personal grocery data to help budget. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/quickcart) + +- Portfolio Site + + - Portfolio and blog website ([Visit Here](https://www.spencerlepine.com)) created by Spencer Lepine. Built using static pages created with GatsbyJS… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/portfolio-site-v2) + +- Cyber Dojo Exercises + + - Personal solutions to various Cyber Dojo exercises. Code is written in Python and tests use 'asserts' with pytest. All… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/cyber-dojo-exercises) + +- Woofer + + - Tinder for Pets Web App. Swipe and connect with other furry friends in the area. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/woofer) + +- React Chess + + - Play chess in the browser by with drag and drop moves. This was created using the Javascript React framework. component… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/react-chess) + +- Study Garden + + - Improve focus and discipline with this timer app. Study until the timer runs out and add plants to your personal… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/study-garden) + +- Spotify Top Songs + + - Generate a Spotify playlist based on the top rated songs of your favorite artists. Connect user Spotify accounts to… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/spotify-top-songs) + +- GitHub User Overview + + - This React App allows the user to type a username get an overview of their GitHub repos using the GitHub REST API. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/github-api-react) + +- CS50 Problem Sets + - My solutions to the online CS50 course generously provided by Harvard University. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/cs50-problem-sets) + +## Interested in working together? + +Follow my journey or connect with me here: + +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) diff --git a/content/what-i-learned-during-100-days-of-code/index.medium b/content/what-i-learned-during-100-days-of-code/index.medium new file mode 100644 index 0000000..fa2a6c9 --- /dev/null +++ b/content/what-i-learned-during-100-days-of-code/index.medium @@ -0,0 +1,222 @@ +--- +title: What I Learned During 100DaysOfCode +description: Summary for a 100 day coding challenge. +publish_status: "draft" +--- + +![Blog Post Thumbnail](./thumbnail.jpg) + +I recently completed a popular challenge on Twitter named #100DaysOfCode. There is no barrier to entry, and you just need to code for at least 1 hour a day. This is a great challenge to motivate yourself and see your progress alongside others. + +In my case, it was not my first time coding when I started this. However, the challenge helped me stay dedicated and build upon each skill I learned. + +To see the original README journal, see [this repository](https://github.com/spencerlepine/100-days-of-code) + +## Day 1–10: The Challenge Begins! + +It all started with a ton of useful lessons on ES6 skills. There was a lot of new syntax and tricks that I never knew about. Since I started learning Javascript before ES6 was released, there were quite a few features I needed to practice. + +[ ES6 Course - Scrimba](https://scrimba.com/learn/introtoes6) + +Having just completed a small course on the React framework, I worked on implementing ES6 skills I picked up to make small projects. Here is a simple React app connected to GitHubs REST API. This helped me learn how to make fetch calls and save the data to state. + +[ spencerlepine/github-api-react - GitHub](https://github.com/spencerlepine/github-api-react) + +Each day I worked on different React concepts. Connecting/modifying a mock database locally. Working with state and props and pass data around. My most effective learning styles was learning-by-doing. After reading the docs and seeing a new feature, I would realize how I could use it to improve my project. + +To wrap up this part of the challenge, there were some coding challenges from Cyber Dojo to help practice problem solving. I was able to solve “Align Columns”, “LCD Digits”, “Wonderland Number”. Check out my repo with my solutions here: + +[spencerlepine/cyber-dojo-exercises - GitHub](https://github.com/spencerlepine/cyber-dojo-exercises) + +## Day 11–20: Just Getting Started + +At this point, there was some great momentum and I was always feeling more motivated to learn. The Scrimba React course had a lot of great lessons on all the basics of React. + +[The React Bootcamp - Scrimba](https://scrimba.com/learn/react) + +I built a controlled-form in React that would update state based on events and targets. Next up was the big concept of hooks and functional components. Little did I know this was only the START of what is possible in React. + +The React course was complete, which led me to start a new project called Spotify Top Songs. This site would connect to the Spotify Web API with client-side authentication. When a user connected their account, they could select various artists from a menu. The script would then generate a playlist by accessing the top 5 songs of each artist. + +This time, code was much more organized with the components and logic separated. With so many fetch calls and bits of logic to intertwine, it was important to build everything slowly and cleanly. + +[spencerlepine/spotify-top-songs - GitHub](https://github.com/spencerlepine/spotify-top-songs) + +I learned about prop-types and default props, which can be pretty handy. Worked React higher order components and children components. Started learning about AWS S3 buckets. To practice, I deployed my Spotify Top Songs to the S3 bucket. + +After discovering the behemoth of AWS products, I wasted no time working to set up an AWS EC2 instance to host a static site, which I would connect to my Route53 domain. + +Just before reaching day 20, a worked on an in-browser [Chess React](https://github.com/spencerlepine/react-chess) app. This was just another opportunity to practice Javascript and apply knowledge. + +## Day 21–30: Gaining Momentum! + +With a solid understanding of React, it was time to double down on more computer science fundamentals. It was exciting to build toy projects, but that wouldn’t be enough. + +After finding the CS50 course online, I watched the lectures on C and Python. This was very useful to learn about memory pointers and how the interpreter reads code. Dave is a GREAT teacher and I would highly recommend going through the course. + +Lots to learn about memory allocation, what libraries are doing under the hood, string manipulation, and regex. + +Alongside CS50 was more material about React memo and Context API — write a component to access a ‘global’ state in a separate file. Import that file and render through that in any component of choice. Custom hooks that handle business logic. React router basics. Conditional rendering. All of these skills would allow me to start creating real multi-page sites! + +Day 29 was the day I started working on Galvanize basic prep lessons. + +## Day 31–40: Diving Deeper + +CS50 included some lessons about data structures and SQL. I worked on some really good challenges for the CS50 Fiftyville assignment. + +It was time for me to learn how to connect a database. I began working with MongoDB and Node.js. I used Postman to practice making requests. + +With a lot of data to store in state, I needed a way to organize it all. Thats where React Redux came up — createStore, redux philosophies, subscribe, dispatch, combineReducer. Abstracting reducers to handle each state in isolation. combineReducers to combine everything and handle state more cleanly in a rootReducer. + +With MongoDB connected to React, I was able to work on a MERN app that could read/write from the database. Connecting back-end/front-end routes and using controllers for the fetch logic/requests. + +Day 36 was when I began the QuickCar react app. Connected it to a backend MongoDB Atlas server. Add reducer + actions for post/fetch from frontend. Save the data in redux state. I created forms and routes with components connected to the Redux state using useSelectors. + +## Day 41–50: Working on QuickCart + +As I worked through some lessons for Galvanize basic prep, I also started lessons on [freeCodeCamp](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/). Got a better understanding of Regex from that. + +Next came Javascript algorithm practice + Object Orientated Programming review. Inheriting methods from parent objects. Using Object.prototypes to reuse methods. + +I revisited my AWS account. Started basic portfolio site using React — Set up LAMP stack server to host website. Direct AWS Route53 domain to DigitalOcean droplet. Set up SSL, MySQL, and WordPress. Working to set up a blog too. + +With a working site, it would be really nice to have a blog hosted on the domain. I attempted to set up a blog. Researched Gatsby, GraphCMS, ButterCMS, GraphQL. Queries were not working. Unable to route to posts. This was a difficult concept to navigate, but along the way I learned a lot about apache and setting up ssl. + +## Day 51–60: A Working Blog! + +Gatsby.js was the answer. Instead of using a headless CMS, I settled with local md files to use for an article. During this challenge, I spent many hours working with the ‘mdx’ plugin. I tried to connect a CMS through queries and GraphQL, but it was very difficult. + +Around this time I continued working through Learn.co lessons for Flatiron prep. There were two main sections on Javascript and Ruby. The Ruby material was interesting and they even did a review on Object Oriented Programming. + +Flatiron wasn’t the only school that I was preparing for though. I completed my technical assessment by creating a basic HTML page with images and a clickable button. + +The last major assignment on hand was working through more of the freeCodeCamp Javascript fundamentals material. + +## Day 51–60: Coding Bootcamp! + +No, I didn’t start a coding bootcamp, but I was getting ready! I got accepted into Flatiron (they didn’t do a TAA anymore), accepted into General Assembly, and I was studying to pass my Hack Reactor technical assessment. My target was in August, which was over 100 days from this point. + +Making sure I could get into these schools was my main priority, but I continued learning and working on projects on the side. + +I worked on building the QuickCart app and added tons of features. Import/Export a grocery database. Improve the UI and styles. Upload images for a product in the form. Convert images to base64 strings. Work with file blobs and cropping images. Generate suggested products with a recommendation algorithm. Work on authentications between the front/back-end for the MERN app. Add a “cart” to store items until purchase. + +At this point, the grocery app was still connected to MongoDB. I was able to use localStorage and save some user data, but I knew I needed EVERYTHING to be in the cloud. + +With all that work done, I began Hack Reactor premium prep. The technical admissions assessment was going to be difficult, so this would help me prepared my vocalization and problem solving. + +This is where I began working testing. Test driven development is integral to Software Engineering. I was able to appreciate my code much more after practicing it. + +## Day 71–80: Hack Reactor and Firebase + +At this point, I was making really good progress in my Hack Reactor prep work. I was able to learn the basic methodology of testing my code. Whenever I worked on Javascript challenges, it was important to practice writing tests and get used to the upfront setup. + +This week was my first attempt at the Hack Reactor TAA, and I passed! This was incredible, because I got to choose between GA, Flatiron, and Hack Reactor. + +I continued working on QuickCart on the side. There were some bug fixes and UI improvements that needed to be done. I migrated from MongoDB to Firebase for the backend. I had to read through the docs and get familiar with Firestore. + +One of the most important themes of this week was practicing problem solving. Hack Reactor was really pushing best practices and effective communication. Each day I worked on a toy problem/code challenge. With a timer running, I would work on my pseudo-code BEFORE starting and really explain/verbalize my thought process as much as I could. + +Now that I was able to write small tests for a challenge, I wanted to work on writing tests for a real project. I started learning how to use Enzyme and Jest for React test-driven-development. The process is tedious at the start, but it will ensure the code is more robust. This was difficult for me at first, because I wasn’t sure if my React test was written incorrectly, or I needed to pass the test now instead. There were lots of features to read Docs about, like redirecting, testing contexts/store, and tons more. + +## Day 81–90: Test Driven Development and APIs + +The TDD practice with React was the birth of Woofer. I wanted to work on a project and build it from the ground up writing tests. I did my best to write a test FIRST before writing code. This project did not go very far during my challenge, since there were other priorities. It was going to take a long time to complete the idea, and it was just good practice to implement testing. + +I documented/planned out the Woofer app before starting. I made wireframes and planned out the logic/routing ahead of time. It was taking WAY too much time to work with mock stores and complex routing in testing. I even fell into certain anti-patterns with testing after researching about tests online. + +[spencerlepine/woofer - GitHub](https://github.com/spencerlepine/woofer) + +I stepped away from the deep rabbit hole of React TDD. I went back to QuickCart and migrated EVERYTHING to client-side. Now it was one complete React app with firebase authentication built in. I was able to host this site on Heroku too, so anyone could use it. + +[spencerlepine/quickcart - GitHub](https://github.com/spencerlepine/quickcart) + +One feature I had been eager to add to the grocery app was “searching products”. With an empty form, users could manually input EVERY detail about a product, but nobody would want to use that. By connecting to the OpenFoodFacts API, I could search a dump of thousands of grocery products. This was an open source dump that anybody can contribute to. They also feature nutrition score data, so it can help users see healthier options. + +## Day 91–100: The Final Stretch + +After learning so much with Javascript and best-practices for writing code, it was time to USE these skills. I continued working through Hack Reactor prep material. I learned about higher order functions, scopes, and hoisting. There were lessons about terminal commands and important dev tools like homebrew. It was time to upgrade my developer workflow, and get familiar with industry standard software. + +Here I read about Node.js, npm, semvar, and modules. This was everything I need to know about how projects are set up and how developers are able to work together. There needs to be structure and conventions throughout the code base so everyone is on the same page. + +I also added a some features to QuickCart on the side again. I connected a Google Custom Search Engine to allow image searches for a product. Instead of having the user upload or snap a photo, they could simply link an existing photo. This allowed me to store the image sources with links, instead a long base64 string with image data. That would improve scalability and prevent product images from being lost easily. + +The next Hack Reactor prep section was about Git and GitHub. This was a REALLY useful sections to go through because it will be the backbone of any project. Knowing how to properly document and collaborate on a project makes everything so much more compatible. Your code needs to be readable and maintainable. People can review your code and merge branches to improve the project. You could even checkout different commits and revert your code. Before I learned about these practices, I would always CTRL+Z my file and start over again, wasting so much time. + +More work on Mocha and Chai testing was done. Getting familiar with different libraries and how they have similar functions. + +## Conclusion + +Challenge complete! After 100 days of coding, I was able to explore new features and concepts relating to Javascript and software development. The dedication allowed me to keep my momentum and build upon what I learned the previous day. + +Here is an overview of everything I learned: + +* ES6 Javascript +* Functional vs. OPP programming +* Javascript algorithms and data structures +* Node.js +* Redux +* React +* SQL +* Python +* Comp Sci fundamentals +* MongoDB +* Firebase +* React Context, state, props, controlled forms +* CMS +* Hosting a static site +* Procedure for problem solving (pseudocode, breaking it down) +* Mocha/Chai testing +* React Jest/Enzyme testing +* Connecting to APIs (Spotify Web API, GitHub REST API, OpenFoodFacts API) +* Fetch calls + axios +* Separating the front-end / back-end +* Deploying to Heroku + +### Projects + +Explore more [projects](https://spencerlepine.com) — or check out the ones mentioned in the article: + +- QuickCart + - Make a shopping list with personal grocery data to help budget. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/quickcart) + +- Portfolio Site + - Portfolio and blog website ([Visit Here](https://www.spencerlepine.com)) created by Spencer Lepine. Built using static pages created with GatsbyJS… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/portfolio-site-v2) + +- Cyber Dojo Exercises + - Personal solutions to various Cyber Dojo exercises. Code is written in Python and tests use 'asserts' with pytest. All… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/cyber-dojo-exercises) + +- Woofer + - Tinder for Pets Web App. Swipe and connect with other furry friends in the area. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/woofer) + +- React Chess + - Play chess in the browser by with drag and drop moves. This was created using the Javascript React framework. component… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/react-chess) + +- Study Garden + - Improve focus and discipline with this timer app. Study until the timer runs out and add plants to your personal… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/study-garden) + +- Spotify Top Songs + - Generate a Spotify playlist based on the top rated songs of your favorite artists. Connect user Spotify accounts to… + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/spotify-top-songs) + +- GitHub User Overview + - This React App allows the user to type a username get an overview of their GitHub repos using the GitHub REST API. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/github-api-react) + +- CS50 Problem Sets + - My solutions to the online CS50 course generously provided by Harvard University. + - **Source Code:** [GitHub Repo](https://github.com/spencerlepine/cs50-problem-sets) + +## Interested in working together? + +Follow my journey or connect with me here: +- LinkedIn: [/in/spencerlepine](https://www.linkedin.com/in/spencerlepine/) +- Email: [spencer.sayhello@gmail.com](mailto:spencer.sayhello@gmail.com) +- Portfolio: [spencerlepine.com](https://spencerlepine.com) +- https://github.com/spencerlepine +- Twitter: [@spencerlepine](https://twitter.com/spencerlepine) \ No newline at end of file diff --git a/blog/what-i-learned-during-100-days-of-code/thumbnail.jpg b/content/what-i-learned-during-100-days-of-code/thumbnail.jpg similarity index 100% rename from blog/what-i-learned-during-100-days-of-code/thumbnail.jpg rename to content/what-i-learned-during-100-days-of-code/thumbnail.jpg diff --git a/docs/intro.md b/docs/intro.md deleted file mode 100644 index 45e8604..0000000 --- a/docs/intro.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Tutorial Intro - -Let's discover **Docusaurus in less than 5 minutes**. - -## Getting Started - -Get started by **creating a new site**. - -Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new)**. - -### What you'll need - -- [Node.js](https://nodejs.org/en/download/) version 18.0 or above: - - When installing Node.js, you are recommended to check all checkboxes related to dependencies. - -## Generate a new site - -Generate a new Docusaurus site using the **classic template**. - -The classic template will automatically be added to your project after you run the command: - -```bash -npm init docusaurus@latest my-website classic -``` - -You can type this command into Command Prompt, Powershell, Terminal, or any other integrated terminal of your code editor. - -The command also installs all necessary dependencies you need to run Docusaurus. - -## Start your site - -Run the development server: - -```bash -cd my-website -npm run start -``` - -The `cd` command changes the directory you're working with. In order to work with your newly created Docusaurus site, you'll need to navigate the terminal there. - -The `npm run start` command builds your website locally and serves it through a development server, ready for you to view at http://localhost:3000/. - -Open `docs/intro.md` (this page) and edit some lines: the site **reloads automatically** and displays your changes. diff --git a/docusaurus.config.js b/docusaurus.config.js index 033c70b..94b9658 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -41,6 +41,7 @@ const config = { ({ docs: false, // Optional: disable the docs plugin blog: { + path: 'content', routeBasePath: '/', showReadingTime: true, // Please change this to your repo. @@ -77,7 +78,7 @@ const config = { items: [ { label: 'GitHub', - to: 'https://github.com/spencerlepine/blog', + href: 'https://github.com/spencerlepine/blog', }, ], }, @@ -108,15 +109,15 @@ const config = { metadata: [ { property: 'og:title', - content: 'Spencer Lepine | Software Engineer', + content: 'Blog - Spencer Lepine', }, { property: 'og:image', - content: 'https://spencerlepine.github.io/images/thumbnail.jpg', + content: 'https://spencerlepine.github.io/blog/img/social-card-thumbnail.jpg', }, { property: 'og:description', - content: 'Website of Spencer Lepine, a Software Engineer.', + content: 'Developer blog of Spencer Lepine, a Software Engineer.', }, { name: 'twitter:card', @@ -124,15 +125,15 @@ const config = { }, { name: 'twitter:title', - content: 'Spencer Lepine | Software Engineer', + content: 'Blog | Spencer Lepine', }, { name: 'twitter:image', - content: 'https://spencerlepine.github.io/images/thumbnail.jpg', + content: 'https://spencerlepine.github.io/blog/img/social-card-thumbnail.jpg', }, { name: 'twitter:description', - content: 'Website of Spencer Lepine, a Software Engineer.', + content: 'Developer blog of Spencer Lepine, a Software Engineer.', }, ], }), diff --git a/package.json b/package.json index 98b755f..c777ab6 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ }, "husky": { "hooks": { - "pre-commit": "lint-staged" + "pre-commit": "yarn build && lint-staged" } }, "lint-staged": { diff --git a/sidebars.js b/sidebars.js deleted file mode 100644 index 3327580..0000000 --- a/sidebars.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ - -// @ts-check - -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { - // By default, Docusaurus generates a sidebar from the docs folder structure - tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], - - // But you can create a sidebar manually - /* - tutorialSidebar: [ - 'intro', - 'hello', - { - type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], - }, - ], - */ -}; - -export default sidebars; diff --git a/src/pages/markdown-page.md b/src/pages/markdown-page.md deleted file mode 100644 index 9756c5b..0000000 --- a/src/pages/markdown-page.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Markdown page example ---- - -# Markdown page example - -You don't need React to write simple standalone pages.