DEV Community: AndreasThe latest articles on DEV Community by Andreas (@devmount).
https://dev.to/devmount
https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F31184%2Fa0a1eef3-2293-4154-814c-995d552374d7.pngDEV Community: Andreas
https://dev.to/devmount
enBuilding a Static Site Generator in 3 stepsAndreasThu, 02 May 2024 12:04:08 +0000
https://dev.to/devmount/building-a-static-site-generator-in-3-steps-72e
https://dev.to/devmount/building-a-static-site-generator-in-3-steps-72e<p>Maybe you know this situation: You are not so happy anymore with your personal website, the look and feel no longer represents you well enough and the time has come for a relaunch. I've been at this point recently and asked myself:</p>
<h2>
What do I actually really need?
</h2>
<p>I've been through a bunch for CMSes, always using my own website as playground for new technologies. That isn't a bad or uncommon approach for a web dev, but I wanted to reduce complexity and maintenance effort this time. And then I had this most brilliant, completely new, unheard before, genius idea:</p>
<p><em>What if I'd just write vanilla HTML?!</em> (ba dum, tss!)</p>
<p>My head was spinning. That'd mean tiny loading times, no server side rendering or precompiling and best of all: No dependencies hence no build step! I was happy like a kid the day before Christmas. I felt like I had just made the invention of the century.</p>
<p>But then came the disillusionment: What about computed data? Or data retrieved per API? I usually showed some GitHub and DEV post stats on my website. Doing it with JavaScript would result in additional request on page load again. And I most certainly wouldn't want to change my age manually every year (okay, that one wouldn't be too bad if I forgot ๐ ). My brain was frantically searching for a way out of this to maintain its latest achievements. It finally had to realize, that at least one single layer of data retrieval and insertion was needed. But would that be possible without any dependencies?</p>
<p>It turned out, that I basically wanted a tiny <em>Static Site Generator</em> and I could have chosen one of the already existing great solutions out there. But sometimes, you just want to stay dependency free, keep things simple and and at the same time up-to-date and running long-term without having to worry about them.</p>
<p>I broke it down to 3 steps:</p>
<ol>
<li>
<strong>Create the markup</strong>: Do the actual webdesign work. Write HTML and CSS with all the content I want.</li>
<li>
<strong>Retrieve and process the data</strong>: Write a script that calls all APIs, does all data manipulation I need and inserts it into my content.</li>
<li>
<strong>Automate it</strong>: Call the script from 2. automatically to keep the content up-to-date</li>
</ol>
<p>Let's visualize that:</p>
<p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpggxwy8nafqw6nvq68q.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpggxwy8nafqw6nvq68q.png" alt="Schema of a static site generator"></a></p>
<p>Still interested? Then let's get our hands dirty.</p>
<h2>
1. Creating the markup
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>
<span class="c"># create the template file</span>
<span class="nb">touch </span>template.html
</code></pre>
</div>
<p>Ahh, feels good to write good ol' plain HTML again. I'm sure every IDE has a shortcut for a basic HTML structure. For VS Code, just create an empty HTML file, type <code>!</code> and hit TAB.</p>
<p>This one might be a bit more work than clicking "Install" on the next popular WordPress theme. But personally I enjoy writing HTML and CSS and building small websites from scratch like this, giving it a personal touch. I even decided not to use JavaScript but that was more of a personal challenge and totally not necessary.</p>
<p>If you don't want to start from scratch, there are a lot of good vanilla HTML templates out there, e.g. <a href="proxy.php?url=https://html5up.net/" rel="noopener noreferrer">HTML5up</a>. For now, let's use this example:</p>
<div class="highlight js-code-highlight">
<pre class="highlight html"><code>
<span class="c"><!-- template.html --></span>
<span class="cp"><!DOCTYPE html></span>
<span class="nt"><html</span> <span class="na">lang=</span><span class="s">"en"</span><span class="nt">></span>
<span class="nt"><head></span>
<span class="nt"><meta</span> <span class="na">charset=</span><span class="s">"UTF-8"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">name=</span><span class="s">"viewport"</span> <span class="na">content=</span><span class="s">"width=device-width, initial-scale=1.0"</span><span class="nt">></span>
<span class="nt"><title></span>My Website<span class="nt"></title></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="nt"><header></span>
I'm a 36 y/o software engineer.
<span class="nt"></header></span>
<span class="nt"><main></span>
<span class="nt"><p></span>I love Open Source.<span class="nt"></p></span>
<span class="nt"><p></span>I created 123 PRs on GitHub.<span class="nt"></p></span>
<span class="nt"></main></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</code></pre>
</div>
<h2>
2. Retrieving and Processing the data
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>
<span class="c"># create the script file</span>
<span class="nb">touch </span>build.sh
</code></pre>
</div>
<p>Now it gets interesting. To retrieve and manipulate data I decided to simply use the Bash. It is available on nearly every Linux distro and has a powerful language which should be sufficient to retrieve data and put it into our HTML file. So for our example, a possible build script could look like this:</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>
<span class="c"># build.sh</span>
<span class="nv">GH_API_URL</span><span class="o">=</span><span class="s1">'https://api.github.com/graphql'</span>
<span class="nv">GITHUB_TOKEN</span><span class="o">=</span><span class="s1">'abc_AB12CD34...'</span>
<span class="c"># call the GitHub API via curl</span>
<span class="nv">QUERY</span><span class="o">=</span><span class="s1">'{ viewer { pullRequests { totalCount } } }'</span>
<span class="nv">RESULT</span><span class="o">=</span><span class="si">$(</span>curl <span class="nt">-s</span> <span class="nt">-i</span> <span class="nt">-H</span> <span class="s1">'Content-Type: application/json'</span> <span class="nt">-H</span> <span class="s2">"Authorization: bearer </span><span class="nv">$GITHUB_TOKEN</span><span class="s2">"</span> <span class="nt">-X</span> POST <span class="nt">-d</span> <span class="s2">"{</span><span class="se">\"</span><span class="s2">query</span><span class="se">\"</span><span class="s2">: </span><span class="se">\"</span><span class="s2">query </span><span class="nv">$QUERY</span><span class="se">\"</span><span class="s2">}"</span> <span class="nv">$GH_API_URL</span> | <span class="nb">tail</span> <span class="nt">-n</span> 1<span class="si">)</span>
<span class="c"># get the data we want</span>
<span class="nb">let </span><span class="nv">AGE</span><span class="o">=(</span><span class="sb">`</span><span class="nb">date</span> +%s<span class="sb">`</span>-<span class="sb">`</span><span class="nb">date</span> +%s <span class="nt">-d</span> 1987-06-05<span class="sb">`</span><span class="o">)</span>/31536000
<span class="nv">PR_COUNT</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$RESULT</span> | <span class="nb">sed</span> <span class="nt">-r</span> <span class="s1">'s|.*"totalCount":([0-9]*).*|\1|g'</span><span class="si">)</span>
</code></pre>
</div>
<p>What's happening here? We're calling the <a href="proxy.php?url=https://docs.github.com/en/graphql" rel="noopener noreferrer">GitHub GraphQL API</a> by using curl and storing the json response in <code>$RESULT</code>. Note that you'll need an access token, which you can generate in <a href="proxy.php?url=https://github.com/settings/tokens" rel="noopener noreferrer">your GitHub settings</a>. Since we get JSON with only one <code>totalCount</code> key, we can extract the number that follows that key with <code>sed</code> and a little regex. Also you can use <code>let</code> to assign a calculation directly to a variable, here an age calculated from a given date.</p>
<p>The last thing that's missing now, is to insert the data into our template. I decided to just use common template variable notation <code>{{...}}</code> (of course you can choose whatever you like) and modified the template.html like this:</p>
<div class="highlight js-code-highlight">
<pre class="highlight html"><code>
<span class="c"><!-- template.html --></span>
...
<span class="nt"><header></span>
I'm a {{age}} y/o software engineer.
<span class="nt"></header></span>
<span class="nt"><main></span>
<span class="nt"><p></span>I love Open Source.<span class="nt"></p></span>
<span class="nt"><p></span>I created {{pr_count}} PRs on GitHub.<span class="nt"></p></span>
<span class="nt"></main></span>
...
</code></pre>
</div>
<p>To replace them, we let the script copy our template and just use <code>sed</code> with some replacement regex again:</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>
<span class="c"># build.sh</span>
...
<span class="nb">cp </span>template.html index.html
<span class="nb">sed</span> <span class="nt">-i</span> <span class="nt">-e</span> <span class="s2">"s|{{age}}|</span><span class="nv">$AGE</span><span class="s2">|g;s|{{pr_count}}|</span><span class="nv">$PR_COUNT</span><span class="s2">|g"</span> index.html
</code></pre>
</div>
<p>Et voilร ! We now have a ready-to-be-served index.html containg a computed age and API retrieved pull request count.</p>
<h2>
3. Configuration and automation
</h2>
<p>Let's now improve our bash script and make it actually configurable. You might have noticed that e.g. the GitHub token and the birth date both were just hard-coded into the script. A much better approach especially for sensitive data would be, to hold all config in a separate file. I decided to use a simple <code>.env</code> file, but you can use whatever suits your case:</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>
<span class="c"># create a config file</span>
<span class="nb">touch</span> .env
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>
<span class="c"># .env</span>
<span class="nv">BIRTH_DATE</span><span class="o">=</span>1987-06-05
<span class="nv">GITHUB_TOKEN</span><span class="o">=</span>ghp_ABCDEFGHIK123456789
</code></pre>
</div>
<p>To load this configuration into the bash script, you can simply <code>source</code> it. That way, all config variables automatically become bash variables:</p>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>
<span class="c"># build.sh</span>
<span class="nb">source</span> .env
...
<span class="nb">let </span><span class="nv">AGE</span><span class="o">=(</span><span class="sb">`</span><span class="nb">date</span> +%s<span class="sb">`</span>-<span class="sb">`</span><span class="nb">date</span> +%s <span class="nt">-d</span> <span class="nv">$BIRTH_DATE</span><span class="sb">`</span><span class="o">)</span>/31536000
...
</code></pre>
</div>
<p>Now that we have an HTML template and a configurable Bash script that generates a servable index.html, we can finally execute that scriptโhow and as often* as we like. You can run it manually, but you might as well automate the execution e.g. with a cron job or using GitHub actions. This flexibility is a huge advantage if you e.g. have to move your website to another server.</p>
<p>* Well, not limitless since there are limitations to the number of API calls per time. Just keep the repetition reasonably, e.g. I decided to call it once every 10 minutes.</p>
<h2>
Wrapping it up
</h2>
<p>So what we did here was creating a very basic and simple static site generator. Let's have a last look at the pros and cons of this approach in diff style:</p>
<div class="highlight js-code-highlight">
<pre class="highlight diff"><code><span class="err">
</span><span class="gi">+ Lightning fast, no blockers/requests on or after page load
+ Easy to maintain, no npm/composer update etc.
+ Flexible and (almost) tech and location independent
</span><span class="gd">- Might be hard for some people to create/find a HTML template
- Not exactly beginner-friendly, requires knowledge of command line and handling raw data
- Might become less maintainable with a lot of pages
</span><span class="err">
</span></code></pre>
</div>
<p>After diving into this, I can say it's still the best choice for my use case (single page website for a dev loving command line). If you want to have a look at my shiny new generated website, feel free:</p>
<p><a href="proxy.php?url=https://devmount.com" rel="noopener noreferrer">https://devmount.com</a></p>
<p>And of course it's open source! Would be an honor if you use it as a template for your next little project:</p>
<p><a href="proxy.php?url=https://github.com/devmount/devmount.com" rel="noopener noreferrer">https://github.com/devmount/devmount.com</a></p>
<p>You have something to add, need some explanation or found a critical aspect I didn't think of? Please let me know in the comments.</p>
<p>For convenience, here are the complete example files, if you'd like to fiddle around a bit with it:</p>
<div class="highlight js-code-highlight">
<pre class="highlight html"><code>
<span class="c"><!-- template.html --></span>
<span class="cp"><!DOCTYPE html></span>
<span class="nt"><html</span> <span class="na">lang=</span><span class="s">"en"</span><span class="nt">></span>
<span class="nt"><head></span>
<span class="nt"><meta</span> <span class="na">charset=</span><span class="s">"UTF-8"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">name=</span><span class="s">"viewport"</span> <span class="na">content=</span><span class="s">"width=device-width, initial-scale=1.0"</span><span class="nt">></span>
<span class="nt"><title></span>My Website<span class="nt"></title></span>
<span class="nt"></head></span>
<span class="nt"><body></span>
<span class="nt"><header></span>
I'm a {{age}} y/o software engineer.
<span class="nt"></header></span>
<span class="nt"><main></span>
<span class="nt"><p></span>I love Open Source.<span class="nt"></p></span>
<span class="nt"><p></span>I created {{pr_count}} PRs on GitHub.<span class="nt"></p></span>
<span class="nt"></main></span>
<span class="nt"></body></span>
<span class="nt"></html></span>
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>
<span class="c"># .env</span>
<span class="nv">BIRTH_DATE</span><span class="o">=</span>1987-06-05
<span class="nv">GITHUB_TOKEN</span><span class="o">=</span>ghp_ABCDEFGHIK123456789
</code></pre>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight shell"><code>
<span class="c"># build.sh</span>
<span class="nb">source</span> .env
<span class="nv">GH_API_URL</span><span class="o">=</span><span class="s1">'https://api.github.com/graphql'</span>
<span class="c"># call the GitHub API via curl</span>
<span class="nv">QUERY</span><span class="o">=</span><span class="s1">'{ viewer { pullRequests { totalCount } } }'</span>
<span class="nv">RESULT</span><span class="o">=</span><span class="si">$(</span>curl <span class="nt">-s</span> <span class="nt">-i</span> <span class="nt">-H</span> <span class="s1">'Content-Type: application/json'</span> <span class="nt">-H</span> <span class="s2">"Authorization: bearer </span><span class="nv">$GITHUB_TOKEN</span><span class="s2">"</span> <span class="nt">-X</span> POST <span class="nt">-d</span> <span class="s2">"{</span><span class="se">\"</span><span class="s2">query</span><span class="se">\"</span><span class="s2">: </span><span class="se">\"</span><span class="s2">query </span><span class="nv">$QUERY</span><span class="se">\"</span><span class="s2">}"</span> <span class="nv">$GH_API_URL</span> | <span class="nb">tail</span> <span class="nt">-n</span> 1<span class="si">)</span>
<span class="c"># get the data we want</span>
<span class="nb">let </span><span class="nv">AGE</span><span class="o">=(</span><span class="sb">`</span><span class="nb">date</span> +%s<span class="sb">`</span>-<span class="sb">`</span><span class="nb">date</span> +%s <span class="nt">-d</span> <span class="nv">$BIRTH_DATE</span><span class="sb">`</span><span class="o">)</span>/31536000
<span class="nv">PR_COUNT</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$RESULT</span> | <span class="nb">sed</span> <span class="nt">-r</span> <span class="s1">'s|.*"totalCount":([0-9]*).*|\1|g'</span><span class="si">)</span>
<span class="c"># generate website and replace template variables</span>
<span class="nb">cp </span>template.html index.html
<span class="nb">sed</span> <span class="nt">-i</span> <span class="nt">-e</span> <span class="s2">"s|{{age}}|</span><span class="nv">$AGE</span><span class="s2">|g;s|{{pr_count}}|</span><span class="nv">$PR_COUNT</span><span class="s2">|g"</span> index.html
</code></pre>
</div>
<p><em>Published: 2nd May 2024</em></p>
cssbashshowdevhtmlJavaScript Array Methods Explained with EmojisAndreasThu, 25 Feb 2021 12:47:19 +0000
https://dev.to/devmount/javascript-array-methods-explained-with-emojis-2amn
https://dev.to/devmount/javascript-array-methods-explained-with-emojis-2amn<p>JavaScript has a lot of useful Array operations. If you are just as confused as me about which one to take and what they all do, let's visualize these operations using emojis to better remember and apply them where they fit best โ And who knows, maybe they are capable of doing even more than we expect...</p>
<p><em>All examples in this article actually work, so feel free to try them in your browsers console</em> ๐ค</p>
<h2>
1. <code>Array.push()</code>
</h2>
<p>Adds one or more elements to the end of an array. Or grows a farm.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">let</span> <span class="nx">livestock</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ท</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฎ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">];</span>
<span class="nx">livestock</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="dl">"</span><span class="s2">๐ด</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฎ</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// console.log(livestock);</span>
<span class="c1">// ["๐ท", "๐ฎ", "๐", "๐ด", "๐ฎ"]</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/push">MDN</a></em></small></p>
<h2>
2. <code>Array.from()</code>
</h2>
<p>Creates a new array from an array-like or iterable object. Or separates some wild animals.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">wild</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">๐ป๐ฏ๐ฆ</span><span class="dl">"</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">tamed</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="k">from</span><span class="p">(</span><span class="nx">wild</span><span class="p">);</span>
<span class="c1">// console.log(tamed);</span>
<span class="c1">// ["๐ป", "๐ฏ", "๐ฆ"]</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/from">MDN</a></em></small></p>
<h2>
3. <code>Array.concat()</code>
</h2>
<p>Merges two or more arrays into a single new one. Or brings different worlds together.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">dogs</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ถ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ถ</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">cats</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ฑ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฑ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฑ</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">pets</span> <span class="o">=</span> <span class="nx">dogs</span><span class="p">.</span><span class="nf">concat</span><span class="p">(</span><span class="nx">cats</span><span class="p">);</span>
<span class="c1">// console.log(pets);</span>
<span class="c1">// ["๐ถ", "๐ถ", "๐ฑ", "๐ฑ", "๐ฑ"]</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">MDN</a></em></small></p>
<h2>
4. <code>Array.every()</code>
</h2>
<p>Checks if all elements of an array pass the test. Or detects intruders.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">visitors</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ง</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฝ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ง</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ง</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ค</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">isHuman</span> <span class="o">=</span> <span class="nx">e</span> <span class="o">=></span> <span class="nx">e</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">๐ง</span><span class="dl">"</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">onlyHumans</span> <span class="o">=</span> <span class="nx">visitors</span><span class="p">.</span><span class="nf">every</span><span class="p">(</span><span class="nx">isHuman</span><span class="p">);</span>
<span class="c1">// console.log(onlyHumans);</span>
<span class="c1">// false</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/every">MDN</a></em></small></p>
<h2>
5. <code>Array.fill()</code>
</h2>
<p>Replaces the elements of an array from start to end index with a given value. Or grows some trees.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">let</span> <span class="nx">seeds</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ฑ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฑ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฑ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฑ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฑ</span><span class="dl">"</span><span class="p">];</span>
<span class="nx">seeds</span><span class="p">.</span><span class="nf">fill</span><span class="p">(</span><span class="dl">"</span><span class="s2">๐ณ</span><span class="dl">"</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
<span class="c1">// console.log(seeds);</span>
<span class="c1">// ["๐ฑ", "๐ณ", "๐ณ", "๐ณ", "๐ฑ"]</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/fill">MDN</a></em></small></p>
<h2>
6. <code>Array.filter()</code>
</h2>
<p>Creates a new array containing all elements passing the test. Or predicts your relationship status.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">guests</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ฉ๐จ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฉ๐ฉ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐จ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฉ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐จ๐จ</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">singles</span> <span class="o">=</span> <span class="nx">guests</span><span class="p">.</span><span class="nf">filter</span><span class="p">(</span><span class="nx">g</span> <span class="o">=></span> <span class="nx">g</span><span class="p">.</span><span class="nx">length</span><span class="o">/</span><span class="mi">2</span> <span class="o">===</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// *</span>
<span class="c1">// console.log(singles);</span>
<span class="c1">// ["๐จ", "๐ฉ"]</span>
</code></pre>
</div>
<p><small><em>* You might wonder, why the string length is divided by two here. The reason is that emojis actually are represented by a pair of code points, also known as a surrogate pair.<br>Try <code>"๐ฉ".length</code> in your console and see for yourself. More information in <a href="proxy.php?url=https://thekevinscott.com/emojis-in-javascript/">this article</a>.</em></small></p>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">MDN</a></em></small></p>
<h2>
7. <code>Array.flat()</code>
</h2>
<p>Creates a new array containing all elements from all sub-arrays up to a given depth. Or cracks any safe.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">savings</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ต</span><span class="dl">"</span><span class="p">,</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ต</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ต</span><span class="dl">"</span><span class="p">],</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ต</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ต</span><span class="dl">"</span><span class="p">],</span> <span class="p">[[[</span><span class="dl">"</span><span class="s2">๐ฐ</span><span class="dl">"</span><span class="p">]]]];</span>
<span class="kd">const</span> <span class="nx">loot</span> <span class="o">=</span> <span class="nx">savings</span><span class="p">.</span><span class="nf">flat</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="c1">// console.log(loot);</span>
<span class="c1">// ["๐ต", "๐ต", "๐ต", "๐ต", "๐ต", "๐ฐ"];</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/flat">MDN</a></em></small></p>
<h2>
8. <code>Array.includes()</code>
</h2>
<p>Checks if an array contains a specific element. Or finds the secret sweet tooth.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">food</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ฅฆ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฅฌ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ </span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฅ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฉ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฅ</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">caught</span> <span class="o">=</span> <span class="nx">food</span><span class="p">.</span><span class="nf">includes</span><span class="p">(</span><span class="dl">"</span><span class="s2">๐ฉ</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// console.log(caught);</span>
<span class="c1">// true</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/includes">MDN</a></em></small></p>
<h2>
9. <code>Array.join()</code>
</h2>
<p>Concatenates all array elements to one single string, using an optional separator. Or builds local area networks.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">devices</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐ป</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฅ๏ธ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฅ๏ธ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ป</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐จ๏ธ</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">network</span> <span class="o">=</span> <span class="nx">devices</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="dl">"</span><span class="s2">ใฐ๏ธ</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// console.log(network);</span>
<span class="c1">// "๐ปใฐ๏ธ๐ฅ๏ธใฐ๏ธ๐ฅ๏ธใฐ๏ธ๐ปใฐ๏ธ๐จ๏ธ"</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/join">MDN</a></em></small></p>
<h2>
10. <code>Array.map()</code>
</h2>
<p>Calls a function on each array element and returns the result as new array. Or feeds all hungry monkeys.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">hungryMonkeys</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฆ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฆง</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">feededMonkeys</span> <span class="o">=</span> <span class="nx">hungryMonkeys</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="nx">m</span> <span class="o">=></span> <span class="nx">m</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// console.log(feededMonkeys);</span>
<span class="c1">// ["๐๐", "๐ฆ๐", "๐ฆง๐"]</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map">MDN</a></em></small></p>
<h2>
11. <code>Array.reverse()</code>
</h2>
<p>Reverses the order of elements in an array. Or decides the outcome of a race.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">let</span> <span class="nx">rabbitWins</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ฆ</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">hedgehogWins</span> <span class="o">=</span> <span class="nx">rabbitWins</span><span class="p">.</span><span class="nf">reverse</span><span class="p">();</span>
<span class="c1">// console.log(hedgehogWins);</span>
<span class="c1">// ["๐ฆ", "๐"]</span>
</code></pre>
</div>
<p><small><em>Note that this method is destructive, it modifies the original array. So after line 2 of this example <code>rabbitWins</code> and <code>hedgehogWins</code> both have the value</em> <code>["๐ฆ", "๐"]</code></small></p>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse">MDN</a></em></small></p>
<h2>
12. <code>Array.slice()</code>
</h2>
<p>Creates a new array from copying a portion of an array defined by start and end index. Or cheats in an exam.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">solutionsOfClassmates</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">myOwnSolutionReally</span> <span class="o">=</span> <span class="nx">solutionsOfClassmates</span><span class="p">.</span><span class="nf">slice</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>
<span class="c1">// console.log(myOwnSolutionReally);</span>
<span class="c1">// ["๐"]</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">MDN</a></em></small></p>
<h2>
13. <code>Array.some()</code>
</h2>
<p>Tests if at least one element of an array passes the test. Or finds if some participants of your meeting forgot to mute their mic.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">participants</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">];</span>
<span class="kd">const</span> <span class="nx">isLoud</span> <span class="o">=</span> <span class="nx">p</span> <span class="o">=></span> <span class="nx">p</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">troubles</span> <span class="o">=</span> <span class="nx">participants</span><span class="p">.</span><span class="nf">some</span><span class="p">(</span><span class="nx">isLoud</span><span class="p">);</span>
<span class="c1">// console.log(troubles);</span>
<span class="c1">// true</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/some">MDN</a></em></small></p>
<h2>
14. <code>Array.sort()</code>
</h2>
<p>Sorts all elements of an array. Or organizes your bookshelf again.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">let</span> <span class="nx">books</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">];</span>
<span class="nx">books</span><span class="p">.</span><span class="nf">sort</span><span class="p">();</span>
<span class="c1">// console.log(books);</span>
<span class="c1">// ["๐", "๐", "๐", "๐", "๐", "๐"]</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">MDN</a></em></small></p>
<h2>
15. <code>Array.splice()</code>
</h2>
<p>Removes, replaces or adds elements to an array. Or changes the weather.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">let</span> <span class="nx">weather</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">โ๏ธ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐ง๏ธ</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">โ๏ธ</span><span class="dl">"</span><span class="p">];</span>
<span class="nx">weather</span><span class="p">.</span><span class="nf">splice</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="dl">"</span><span class="s2">โ๏ธ</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// console.log(weather);</span>
<span class="c1">// ["โ๏ธ", "โ๏ธ"]</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">MDN</a></em></small></p>
<h2>
16. <code>Array.unshift()</code>
</h2>
<p>Adds one or more elements to the beginning of an array. Or couples a loco.<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">let</span> <span class="nx">train</span> <span class="o">=</span> <span class="p">[</span><span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">];</span>
<span class="nx">train</span><span class="p">.</span><span class="nf">unshift</span><span class="p">(</span><span class="dl">"</span><span class="s2">๐</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// console.log(train);</span>
<span class="c1">// ["๐", "๐", "๐", "๐", "๐"]</span>
</code></pre>
</div>
<p><small><em>Documentation on <a href="proxy.php?url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift">MDN</a></em></small></p>
<h2>
Wrap it up
</h2>
<p>We saw that we have quite a lot of possibilities for array processing and manipulation in JavaScript. See MDN for an overview of all <a href="proxy.php?url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#instance_methods">Array instance methods</a>. You want to add another nice example how to explain a JavaScript method or just want to show us your favorite emoji? Please comment below ๐ฌโฌ</p>
<p><em>Published: 25th February 2021</em><br>
<em>Title image: <a href="proxy.php?url=https://codepen.io/devmount/pen/oNxGpgQ">https://codepen.io/devmount/pen/oNxGpgQ</a></em></p>
javascriptwebdevbeginnersemojisPHP 8 features I wish also existed in JavaScriptAndreasMon, 08 Feb 2021 12:34:25 +0000
https://dev.to/devmount/php-8-features-i-wish-also-existed-in-javascript-1a5
https://dev.to/devmount/php-8-features-i-wish-also-existed-in-javascript-1a5<p>I know there is still a lot of hatred for PHP out there, but in my opinion with version 7 at the latest (which is already over 5 years old!), PHP evolved to a great language that is fun and even type-safe to use. Next to <a href="proxy.php?url=https://php.watch/articles/jit-in-depth">Just-In-Time compilation</a>, which may give a big performance boost to PHP applications, version 8 brings <a href="proxy.php?url=https://www.php.net/releases/8.0/en.php">a lot of useful features</a>.</p>
<p>I want to present three of them I really wish I could use in JavaScript as well. I hope that comes in handy especially for those, who didn't take a look at PHP 8 yet. Let's go!</p>
<h2>
#1 Named arguments
</h2>
<p>Let's assume, you have a function <code>foo</code> with 6 parameters <code>a</code> to <code>f</code> having different default values and now you want to call that function passing the argument <code>false</code> for the last parameter only.</p>
<p>PHP 8:<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="nf">foo</span><span class="p">(</span><span class="n">f</span><span class="o">:</span> <span class="kc">false</span><span class="p">);</span>
<span class="c1">//-----^</span>
</code></pre>
</div>
<p>JavaScript:<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="nf">foo</span><span class="p">(</span><span class="dl">'</span><span class="s1">test</span><span class="dl">'</span><span class="p">,</span> <span class="mi">42</span><span class="p">,</span> <span class="kc">true</span><span class="p">,</span> <span class="dl">'</span><span class="s1">bar</span><span class="dl">'</span><span class="p">,</span> <span class="mf">5.5</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="c1">//--------------------------------^</span>
</code></pre>
</div>
<p>In JavaScript passing arguments to a function is solely based on the parameter position, unfortunately. I know that named arguments can be simulated by using objects and destructuring, but a native feature would be much more convenient here.</p>
<p>See <a href="proxy.php?url=https://wiki.php.net/rfc/named_params">RFC: Named Arguments</a></p>
<h2>
#2 Match expression
</h2>
<p>The new <code>match</code> expression of PHP is very similar to the <code>switch</code> statement, except it is an expression and can be used to directly assign values to a variable or return values. This comes in very handy, if you have more than two possible values for assignment.</p>
<p>PHP 8:<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="nv">$fontWeight</span> <span class="o">=</span> <span class="k">match</span> <span class="p">(</span><span class="nv">$weight</span><span class="p">)</span> <span class="p">{</span>
<span class="mi">100</span><span class="p">,</span> <span class="mi">200</span> <span class="o">=></span> <span class="s2">"Super Thin"</span><span class="p">,</span>
<span class="mi">300</span> <span class="o">=></span> <span class="s2">"Thin"</span><span class="p">,</span>
<span class="mi">400</span><span class="p">,</span> <span class="mi">500</span> <span class="o">=></span> <span class="s2">"Normal"</span><span class="p">,</span>
<span class="mi">600</span><span class="p">,</span> <span class="mi">700</span><span class="p">,</span> <span class="mi">800</span> <span class="o">=></span> <span class="s2">"Bold"</span><span class="p">,</span>
<span class="mi">900</span> <span class="o">=></span> <span class="s2">"Heavy"</span><span class="p">,</span>
<span class="k">default</span> <span class="o">=></span> <span class="s2">"Not valid"</span>
<span class="p">};</span>
</code></pre>
</div>
<p>JavaScript:<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">let</span> <span class="nx">fontWeight</span> <span class="o">=</span> <span class="dl">''</span><span class="p">;</span>
<span class="k">switch </span><span class="p">(</span><span class="nx">weight</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="mi">100</span><span class="p">:</span>
<span class="k">case</span> <span class="mi">200</span><span class="p">:</span>
<span class="nx">fontWeight</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Super Thin</span><span class="dl">"</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">300</span><span class="p">:</span>
<span class="nx">fontWeight</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Thin</span><span class="dl">"</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">400</span><span class="p">:</span>
<span class="k">case</span> <span class="mi">500</span><span class="p">:</span>
<span class="nx">fontWeight</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Normal</span><span class="dl">"</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">600</span><span class="p">:</span>
<span class="k">case</span> <span class="mi">700</span><span class="p">:</span>
<span class="k">case</span> <span class="mi">800</span><span class="p">:</span>
<span class="nx">fontWeight</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Bold</span><span class="dl">"</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="mi">900</span><span class="p">:</span>
<span class="nx">fontWeight</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Heavy</span><span class="dl">"</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="nl">default</span><span class="p">:</span>
<span class="nx">fontWeight</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Not valid</span><span class="dl">"</span><span class="p">;</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The <code>match</code> expression may be simulated by a JavaScript object, but that would require an additional variable (thus more reserved memory) and will fail for cases, where the checked values aren't allowed to be used as object keys.</p>
<p>See <a href="proxy.php?url=https://www.php.net/manual/en/control-structures.match.php">Docs: <code>match</code></a></p>
<h2>
#3 Optional Chaining
</h2>
<p>Chaining only if the needed property exists is a very elegant way to query objects. In PHP you can do this now with the nullsafe operator.</p>
<p>PHP 8:<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code><span class="nv">$country</span> <span class="o">=</span> <span class="nv">$session</span><span class="o">?-></span><span class="n">user</span><span class="o">?-></span><span class="nf">getAddress</span><span class="p">()</span><span class="o">?-></span><span class="n">country</span><span class="p">;</span>
</code></pre>
</div>
<p>JavaScript:<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">const</span> <span class="nx">country</span> <span class="o">=</span>
<span class="nx">session</span> <span class="o">&&</span> <span class="nx">session</span><span class="p">.</span><span class="nx">user</span> <span class="o">&&</span> <span class="nx">session</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nf">getAddress</span><span class="p">()</span> <span class="o">&&</span> <span class="nx">session</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nf">getAddress</span><span class="p">()[</span><span class="dl">'</span><span class="s1">country</span><span class="dl">'</span><span class="p">]</span>
<span class="p">?</span> <span class="nx">session</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nf">getAddress</span><span class="p">()[</span><span class="dl">'</span><span class="s1">country</span><span class="dl">'</span><span class="p">]</span>
<span class="p">:</span> <span class="kc">null</span><span class="p">;</span>
</code></pre>
</div>
<p>In JavaScript you still have to check step by step, if the corresponding property exists. There is a corresponding <a href="proxy.php?url=https://github.com/tc39/proposal-optional-chaining">TC39 proposal</a> which is in stage 4 by now and I'm really looking forward to this being part of the ECMAScript Specs.</p>
<p>See <a href="proxy.php?url=https://wiki.php.net/rfc/nullsafe_operator">RFC: Nullsafe Operator</a></p>
<h2>
Wrap it up
</h2>
<p>So we saw a small selection of the new PHP 8 features that would also be a great addition to JavaScript. Maybe you have other PHP features in mind that are missing in JavaScript or you know a better JavaScript counterpart to the above problems than me? Great! Let's discuss it in the comments.</p>
<p><em>Edited: 10th of February 2021 (extended <code>match</code> example)<br>
Published: 8th of February 2021</em></p>
phpjavascriptwebdevprogrammingThirdStats โ Beautifully Visualized Email Account StatsAndreasTue, 29 Sep 2020 14:22:50 +0000
https://dev.to/devmount/thirdstats-beautifully-visualized-email-account-stats-eaf
https://dev.to/devmount/thirdstats-beautifully-visualized-email-account-stats-eaf<p>In the first post of this series I told you the background story why I built a tool that's able to show some email analytics in the Mozilla Thunderbird email client. After using this tool for a year now, I've determined three major issues:</p>
<p>โ It depends on the mail storage engine<br>
โ The stats creation process is a little too complex<br>
โ The stats page cannot be accessed directly from Thunderbird</p>
<h2>
What I did
</h2>
<p>To address all of these issues, I decided to create <a href="proxy.php?url=https://addons.thunderbird.net/en-US/thunderbird/addon/thirdstats/" rel="noopener noreferrer">a native Thunderbird add-on</a> with the same functionality. Well, I never built a Thunderbird add-on before, so I took a look into the Thunderbird documentation. It turned out, that thanks to <a href="proxy.php?url=https://thunderbird-webextensions.readthedocs.io/en/latest/index.html" rel="noopener noreferrer">Thunderbirds WebExtension APIs</a>, I was able to reuse nearly all of my Vue.js code - nice! I spent a weekend of porting my code and creating <strong>ThirdStats</strong>:</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/devmount" rel="noopener noreferrer">
devmount
</a> / <a href="proxy.php?url=https://github.com/devmount/third-stats" rel="noopener noreferrer">
third-stats
</a>
</h2>
<h3>
Thunderbird add-on turning your emails into beautifully visualized email account stats. Built with Vue.js and Chart.js
</h3>
</div>
<div class="ltag-github-body">
<div id="readme" class="md">
<p>
<a href="proxy.php?url=https://addons.thunderbird.net/en-US/thunderbird/addon/thirdstats" rel="nofollow noopener noreferrer">
<img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5441654%2F127195945-f0de0059-72bf-45e9-a4d6-00ca68e84c9d.png" width="500px">
</a>
</p>
<p>
ThirdStats is a Thunderbird add-on for beautifully visualized email account stats.<br>Download from <a href="proxy.php?url=https://addons.thunderbird.net/en-US/thunderbird/addon/thirdstats" rel="nofollow noopener noreferrer">Thunderbird Add-ons</a> repository. Contributions, corrections & requests can be made <a href="proxy.php?url=https://github.com/devmount/third-stats" rel="noopener noreferrer">on GitHub</a>.<br>Created by <a href="proxy.php?url=https://github.com/devmount" rel="noopener noreferrer">Andreas Mรผller</a>.</p>
<p>
<a href="proxy.php?url=https://github.com/devmount/third-stats/releases" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/a3eca96534bba32b26c2b0d4155e50607c048311ad24d9f834efda957bfb4782/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f7461672f6465766d6f756e742f74686972642d73746174732e7376673f6c6162656c3d5468697264537461747326636f6c6f72423d306138346666267374796c653d666c61742d737175617265266c6f676f3d646174613a696d6167652f706e673b6261736536342c6956424f5277304b47676f414141414e53556845556741414144414141414177434159414141425841766d48414141414358424957584d414142596c414141574a51464a556954774141414444556c455156526f6765315a4d57376251424163422b6c5979433272364164785868433659636e514c306a3841366d2b496e4c424f763642346838344c4e6c456559476c4831675657376d3457734552792b4230756a33654351677041527a414d455175795a323732646d6c644c58663733484a65486652325938457a67416a6761487866716a6e31316d564133674573414f77694d76302b5a543744474b6a6456596c41483462682b2f6a4d76305a65712f654a56526e3151304132326f7636367a36466e712f58676e555758554e514b337968416b4a4a744833447169562f396752453053694e774a3156716d562f3277632f714f3062776e334a74454c4155726d713346344179436e776a325a7848393349635a783367416b635a6d7574546956374e4a794336633742524d674631456572684a624b532b507933546e6946315a697659324c6c4e3133497a6e534e787866534a495170545143344476704766312f37584f716755356a42374c4f6336394c586b4668357875754a793843564243746c57594d4552736a765055316177634a4b7a776c6c4364565371684c783668537439726d2b50455a5a72344a6b616a527276794b32375876416a5557545544384d4d347246786b366d684b5a6d796931307055344741576b734b367535336f4a4b4470587364575735305a2f5846456a68776e4b6d43646861524138437a6b4a45423656672f2b594a7a365a466a677459504967654e4552624e7261345a774d496b75416a62647a2b4d79665754695779494a4a666c734a48394e74756f614a344a4973415159542f34566c326e7565334d545564456b5a6e5a6b4737784a75477830616e7857756738656431744552624d7a746e466962676c66526f5866733178765a475a337a5130584f657249556878643038596d46686454785a314c6764656f614b347a64317552514e644f75435130705258666b512f724c6d4a7a706a64365254776734696a6157796d673177633743376c496e44544d52555754454665492f346a515a3176527a7158416b524534534e787866534b595146526751614e444637694f2f43514672322b477846614b6f3570734544544d6b58544d354c655572496d4a4a666b4e3253774c6b6f733543356c39364451434e463261794d6d78486867694c647169745261366a70412b3445324170474e712b55454b72465653556a546e58555161782f46396e692b38616f42786e593055396a6d644f75354d73396956376a672b69416f634a435946726d79582b58347a5a3974537468424a4a6f7551684539467034526330756b6a7753343443544375737947396e775736646942494f6b4f41725146474f676f76616b6135684231774e70787a77615838774c486c546e5474674b757a3967586e65386a344f2f485147416b4d6a5a48413042674a44416f416677476f694662756f377363325141414141424a52553545726b4a6767673d3d" alt="release"></a>
<a href="proxy.php?url=https://github.com/devmount/third-stats/commits/main" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/ad2e4c308ae46454bfd52ccd4fa38b3eb44f134f2a6093a63885d1064a1c728c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6465766d6f756e742f74686972642d73746174733f6c6162656c3d7570646174656426636f6c6f723d306138346666267374796c653d666c61742d737175617265" alt="last commit"></a>
<a href="proxy.php?url=https://github.com/devmount/third-stats/actions?query=workflow%3ACodeQL" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/f07f594628eb0bda84ef81f7daec8a81af605f96bc8ae2caa2a953d54deca1ae/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6465766d6f756e742f74686972642d73746174732f636f6465716c2d616e616c797369732e796d6c3f6c6162656c3d436f6465514c266c6f676f3d67697468756226636f6c6f723d306138346666267374796c653d666c61742d737175617265" alt="CodeQL analysis"></a>
<a href="proxy.php?url=https://github.com/devmount/third-stats./LICENSE" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/719eb70ae25d1dfb792d4f8ea06da2887b0b38a548e90281cd3ebcc95883a881/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6465766d6f756e742f74686972642d73746174732e7376673f636f6c6f72423d653634646239267374796c653d666c61742d737175617265" alt="license"></a>
<a href="proxy.php?url=https://github.com/devmount/third-stats./.github/CONTRIBUTING.md" rel="noopener noreferrer"><img src="proxy.php?url=https://camo.githubusercontent.com/62b94070139dfe71ecca50a4ff3cb3d9bb2faebf2160f941949f968b7560b5f3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6e747269627574696f6e732d77656c636f6d652d6536346462392e7376673f7374796c653d666c61742d737175617265" alt="contributions welcome"></a>
</p>
<div class="markdown-heading">
<h2 class="heading-element">Get started</h2>
</div>
<p>Install ThirdStats from the Thunderbird Add-ons repository:</p>
<ol>
<li>Start Thunderbird, open the main menu and click on Add-ons</li>
<li>Search for <em>ThirdStats</em>
</li>
<li>Click <em>Add to Thunderbird</em> and give necessary permissions</li>
<li>Open the ThirdStats Popup in the upper right corner of the main toolbar and enjoy your email account stats</li>
</ol>
<p>To properly recognize emails as <em>sent</em>, make sure to configure all email adresses you write from as Thunderbird identities for your email account. You can do so under <em>account settings</em> > select your account > click button <em>more identities</em> at the bottom and add or modify identities as you need.</p>
<p>Also keep in mind, that the processing of large mailboxes can take a lot of time.</p>
<div class="markdown-heading">
<h2 class="heading-element">Features</h2>
</div>
<ul>
<li>Check keyโฆ</li>
</ul>
</div>
</div>
<div class="gh-btn-container"><a class="gh-btn" href="proxy.php?url=https://github.com/devmount/third-stats" rel="noopener noreferrer">View on GitHub</a></div>
</div>
<p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5441654%2F93931445-14066b80-fd1f-11ea-8fe7-bde8674b26f4.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F5441654%2F93931445-14066b80-fd1f-11ea-8fe7-bde8674b26f4.png" alt="thirdstats screenshot"></a></p>
A screenshot showing ThirdStats on the Thunderbird default dark theme on Windows
<h2>
What you can do
</h2>
<p>This is actually the first Thunderbird 78+ add-on providing visual statistics of email accounts (at least I wasn't able to find something similar in the repository)! So if you are interested in contributing to the large community of Thunderbird users - you are very welcome to do so! I've prepared the GitHub repository so it's ripe and ready for harvest in this year's Hacktoberfest.</p>
<h3>
Add translations
</h3>
<p>If you're new to contributing to OSS and you want to get to know the process of creating Pull Requests first, you can just add a translation of the add-on in your native language. <strong>This is as simple as adding a single JSON file.</strong> I explained everything in the <a href="proxy.php?url=https://github.com/devmount/third-stats/blob/master/.github/CONTRIBUTING.md" rel="noopener noreferrer">Contribution Guidelines</a> and prepared <a href="proxy.php?url=https://github.com/devmount/third-stats/issues?q=is%3Aopen+is%3Aissue+no%3Aassignee+translation" rel="noopener noreferrer">some example issues</a>.</p>
<h3>
Improve the UI
</h3>
<p>If you're already familiar with Vue.js app development and you have some experience in building user interfaces, you can help improving ThirdStats UI. I've prepared some example issues for this topic too (e.g. <a href="proxy.php?url=https://github.com/devmount/third-stats/issues/8" rel="noopener noreferrer">#8</a>, <a href="proxy.php?url=https://github.com/devmount/third-stats/issues/9" rel="noopener noreferrer">#9</a>, <a href="proxy.php?url=https://github.com/devmount/third-stats/issues/10" rel="noopener noreferrer">#10</a>). Please discuss your ideas or possible changes in the corresponding issue first before investing a lot of time for a pull request that won't get merged for some reason.</p>
<h3>
Add charts
</h3>
<p>And for those of you who are looking for the real challenge, I prepared some feature requests (<a href="proxy.php?url=https://github.com/devmount/third-stats/issues/11" rel="noopener noreferrer">#11</a>, <a href="proxy.php?url=https://github.com/devmount/third-stats/issues/12" rel="noopener noreferrer">#12</a>) to implement additional charts and analytics to make this add-on even more complete. What numbers are you interested in about your mail account?</p>
<p>Again: Please discuss your ideas in a corresponding issue <strong>first</strong> before investing a lot of time for a pull request that won't get merged for some reason.</p>
<h2>
Wrap it up
</h2>
<p>So I made my first steps contributing to the (in my opinion) best open source email client out there by creating an add-on to expand its functionality. Do you use Thunderbird? Would you use this add-on? What is missing in your opinion? Let's discuss here in the comments or <a href="proxy.php?url=https://github.com/devmount/third-stats/issues/new/choose" rel="noopener noreferrer">directly on GitHub</a>!</p>
<h2>
Links
</h2>
<ul>
<li>Download and Install: <a href="proxy.php?url=https://addons.thunderbird.net/en-US/thunderbird/addon/thirdstats/" rel="noopener noreferrer">https://addons.thunderbird.net/en-US/thunderbird/addon/thirdstats/</a>
</li>
<li>Discuss and Contribute: <a href="proxy.php?url=https://github.com/devmount/third-stats" rel="noopener noreferrer">https://github.com/devmount/third-stats</a>
</li>
</ul>
<p><em>Edited: 30th of September 2020 (added repository links)</em><br>
<em>Published: 29th of September 2020</em></p>
showdevhacktoberfestvuejavascriptAutomatic Deployment via good ol' FTPAndreasThu, 03 Sep 2020 08:55:33 +0000
https://dev.to/devmount/automatic-deployment-via-good-ol-ftp-3044
https://dev.to/devmount/automatic-deployment-via-good-ol-ftp-3044<p>Since their release, GitHub actions are on my long-term todo list for increasing automation of my workflows. Thanks to <a href="proxy.php?url=https://dev.to/devteam/announcing-the-github-actions-hackathon-on-dev-3ljn">DEVs GitHub Actions Hackathon</a>, I'm finally tackling this topic.</p>
<p>I'm not really sure if it's a thing to be ashamed of today, but I'm still pushing build files of most of my personal open source projects manually via good ol' FTP to my server. Maybe I just don't wanted to give up too much control over the files that I push to production. Or after doing web development for more than 15 years now, I was just too lazy to change something ๐ </p>
<p>However, I found an awesome GitHub action to publish files automatically via FTP to my server on build.</p>
<h2>
My Workflow
</h2>
<p>It's the <a href="proxy.php?url=https://github.com/SamKirkland/FTP-Deploy-Action" rel="noopener noreferrer">FTP-Deploy-Action</a> by Sam Kirkland which utilizes <a href="proxy.php?url=https://github.com/git-ftp/git-ftp" rel="noopener noreferrer">Git-ftp</a>. I'm mostly creating Vue.js applications with the Vue CLI - so my normal workflow always looked like this:</p>
<ol>
<li>โ Make code changes (e.g. fixing an important security issue)</li>
<li>๐จ Test code changes</li>
<li>โ Commit these changes to the repository</li>
<li>๐ Create new build files optimized for production using <code>vue-cli-service build</code>
</li>
<li>โ Delete old build files from production server</li>
<li>โซ Upload new build files to production server</li>
</ol>
<p>Especially the last two points always bothered me, because most of the time I was pushing some smaller changes that only affected a few files and I still deleted and reuploaded the whole application. And this is, where Git-ftp really pays off: It can upload only those files, that changed since the last upload! This is extremely useful, especially for projects with a lot of files. A few of my PHP projects e.g. use Git Submodules and uploading the whole project on each build would take an incredible amount of time. So my new workflow now looks like this:</p>
<ol>
<li>โ Make code changes (e.g. fixing an important security issue)</li>
<li>๐จ Test code changes</li>
<li>โ Commit these changes to the repository</li>
<li>๐ Create new build files optimized for production using <code>vue-cli-service build</code>
</li>
<li>Lean back and let the GitHub FTP-Deploy-Action do the rest</li>
</ol>
<h2>
Submission Category
</h2>
<p>โ DIY Deployments</p>
<h2>
Configuration
</h2>
<p>So, how can you set up this FTP-Deploy-Action? You simply have to create a configuration file called <code>ftp-deploy.yaml</code> under <code>your-repo/.github/workflows/</code>. This is what my configuration looks like:<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight yaml"><code><span class="na">on</span><span class="pi">:</span>
<span class="na">push</span><span class="pi">:</span>
<span class="na">paths</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s1">'</span><span class="s">dist/*'</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">FTP Deploy</span>
<span class="na">jobs</span><span class="pi">:</span>
<span class="na">FTP-Deploy-Action</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">FTP-Deploy-Action</span>
<span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
<span class="na">steps</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/[email protected]</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">fetch-depth</span><span class="pi">:</span> <span class="m">2</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">FTP-Deploy-Action</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">SamKirkland/FTP-Deploy-Action@master</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">ftp-server</span><span class="pi">:</span> <span class="s">${{ secrets.ftp_server }}</span>
<span class="na">ftp-username</span><span class="pi">:</span> <span class="s">${{ secrets.ftp_username }}</span>
<span class="na">ftp-password</span><span class="pi">:</span> <span class="s">${{ secrets.ftp_password }}</span>
<span class="na">local-dir</span><span class="pi">:</span> <span class="s">dist/</span>
</code></pre>
</div>
<p>I'm going to explain every part in the following for you to understand, how this works ๐ก</p>
<div class="table-wrapper-paragraph"><table>
<tr>
<th>Lines</th>
<th>Explanation</th>
</tr>
<tr>
<td>1โ4</td>
<td>
<code>on: push: paths:</code><br>Only start this action, when changes where pushed to the `dist/` directory (this is the default build folder for Vue CLI)</td>
</tr>
<tr>
<td>5</td>
<td>
<code>name:</code><br>The name of your GitHub action which is shown in the repositories action tab on GitHub.</td>
</tr>
<tr>
<td>6โ15</td>
<td>
<code>jobs: FTP-Deploy-Action: ...</code><br>This is the default configuration for this action, accourding to <a href="proxy.php?url=https://github.com/SamKirkland/FTP-Deploy-Action/blob/master/README.md" rel="noopener noreferrer">its documentation</a>.</td>
</tr>
<tr>
<td>16</td>
<td>
<code>with:</code><br>This section allows for further required or optional configuration of the action.</td>
</tr>
<tr>
<td>17โ19</td>
<td>
<code>ftp-server: | ftp-username: | ftp-password:</code><br>Obviously GitHub needs to know your FTP access data like server url, username and password. Even more obviously, you don't want to store these data in this configuration file rather than as <a href="proxy.php?url=https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets" rel="noopener noreferrer">encrypted secrets</a>. The port number is appended to the url, if you need it. Also you can specify the security protocol (see security hint below), e.g.:<br><code>ftps://your.ftp-server.com:21</code>
</td>
</tr>
<tr>
<td>20</td>
<td>
<code>local-dir:</code><br>This makes sure, that not the whole repository, but only (in my case) the `dist/` directory gets uploaded, where my build files live.</td>
</tr>
</table></div>
<p><strong>Bonus</strong>: If you want to explicitly exclude some files from being uploaded, you can create a <code>.git-ftp-ignore</code> file in the root of your repository, which works the same way as a <code>.gitignore</code> file.</p>
<h2>
Additional Resources / Info
</h2>
<p>Here are the repositories of the GitHub action and <code>git-ftp</code>:</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/SamKirkland" rel="noopener noreferrer">
SamKirkland
</a> / <a href="proxy.php?url=https://github.com/SamKirkland/FTP-Deploy-Action" rel="noopener noreferrer">
FTP-Deploy-Action
</a>
</h2>
<h3>
Deploys a GitHub project to a FTP server using GitHub actions
</h3>
</div>
</div>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/git-ftp" rel="noopener noreferrer">
git-ftp
</a> / <a href="proxy.php?url=https://github.com/git-ftp/git-ftp" rel="noopener noreferrer">
git-ftp
</a>
</h2>
<h3>
Uses Git to upload only changed files to FTP servers.
</h3>
</div>
</div>
<h2>
Security hint
</h2>
<p>FTP itself transfers files unencrypted. Therefore it's highly recommended to use FTPS (FTP with TLS) or SFTP (SSH file transfer), which are both supported by <code>git-ftp</code>. Thanks to <a class="mentioned-user" href="proxy.php?url=https://dev.to/lampewebdev">@lampewebdev</a> for his comment on this topic.</p>
<h2>
Wrap it up
</h2>
<p>So we saw that it's fairly simple to let GitHub deploy you build files automatically via FTP. You just need to create one configuration file and set a few repository secrets.</p>
<p>Let me know, if you also deploy via FTP and this is useful for your own workflows.</p>
<p><em>Edited: 4th September 2020 (add server url example and security hint)</em><br>
<em>Published: 3rd September 2020</em><br>
<em>Title image: <a href="proxy.php?url=https://codepen.io/devmount/full/qBZPpEM" rel="noopener noreferrer">https://codepen.io/devmount/full/qBZPpEM</a></em></p>
actionshackathonjavascriptvuegit10 Awesome Pythonic One-Liners ExplainedAndreasWed, 29 Jul 2020 11:18:30 +0000
https://dev.to/devmount/10-awesome-pythonic-one-liners-explained-3doc
https://dev.to/devmount/10-awesome-pythonic-one-liners-explained-3doc<p>Since I wrote my first lines of code in Python, I was fascinated by its simplicity, excellent readability and its popular one-liners in particular. In the following, I want to present and explain some of these one-liners - maybe there are a few you didn't already know and are useful for your next Python project.</p>
<h2>
1. Swap two variables
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="c1"># a = 1; b = 2
</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">b</span><span class="p">,</span> <span class="n">a</span>
<span class="c1"># print(a,b) >> 2 1
</span></code></pre>
</div>
<p>Let's start with a classic: swapping the values of variables by simply swapping positions on assignment - the most intuitive way in my opinion. No need to use a temporary variable. It even works with more than two variables.</p>
<h2>
2. Multiple variable assignment
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="o">*</span><span class="n">c</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">]</span>
<span class="c1"># print(a,b,c) >> 1 2 [3, 4, 5]
</span></code></pre>
</div>
<p>Swapping variables is actually a special case of Pythons ability to assign multiple variables at once. Here you can use it to assign <a href="proxy.php?url=https://docs.python.org/3/tutorial/datastructures.html">list</a> elements to the given variables, which is also called <em>unpacking</em>. The <code>*</code> will do packing the remaining values again, which results in a sublist for <code>c</code>. It even works for every other position of <code>*</code> (e.g. the beginning or middle part of the list).</p>
<h2>
3. Sum over every second element of a list
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="c1"># a = [1,2,3,4,5,6]
</span><span class="n">s</span> <span class="o">=</span> <span class="nf">sum</span><span class="p">(</span><span class="n">a</span><span class="p">[</span><span class="mi">1</span><span class="p">::</span><span class="mi">2</span><span class="p">])</span>
<span class="c1"># print(s) >> 12
</span></code></pre>
</div>
<p>No need for a special reduce function here, <a href="proxy.php?url=https://docs.python.org/3/library/functions.html#sum"><code>sum</code></a> just adds the items of every given iterable. The <a href="proxy.php?url=https://docs.python.org/3/whatsnew/2.3.html#extended-slices">extended slicing syntax</a> <code>[::]</code> is used here to return every second element. You can read it as <em>[start : stop : step]</em>, so <code>[1::2]</code> translates to <em>start with the element of index 1 (second element), don't stop until the list ends (no argument given for second parameter) and always take 2 steps</em>.</p>
<h2>
4. Delete multiple elements
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="c1"># a = [1,2,3,4,5]
</span><span class="k">del</span> <span class="n">a</span><span class="p">[::</span><span class="mi">2</span><span class="p">]</span>
<span class="c1"># print(a) >> [2, 4]
</span></code></pre>
</div>
<p>The extended slicing syntax can also be used to delete multiple list elements at once.</p>
<h2>
5. Read file into array of lines
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="n">c</span> <span class="o">=</span> <span class="p">[</span><span class="n">line</span><span class="p">.</span><span class="nf">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="nf">open</span><span class="p">(</span><span class="sh">'</span><span class="s">file.txt</span><span class="sh">'</span><span class="p">)]</span>
<span class="c1"># print(c) >> ['test1', 'test2', 'test3', 'test4']
</span></code></pre>
</div>
<p>With Pythons inline <a href="proxy.php?url=https://docs.python.org/3/tutorial/controlflow.html#for-statements">for loop</a> you can easily read a file into an array of lines. The <a href="proxy.php?url=https://docs.python.org/3/library/stdtypes.html#str.strip"><code>strip()</code></a> is needed to remove the trailing line breaks. If you want to keep them or they don't matter to you, you can use an even shorter one-liner:<br>
</p>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="n">c</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="nf">open</span><span class="p">(</span><span class="sh">'</span><span class="s">file.txt</span><span class="sh">'</span><span class="p">))</span>
<span class="c1"># print(c) >> ['test1\n', 'test2\n', 'test3\n', 'test4\n']
</span></code></pre>
</div>
<p>It's really that simple to read a file in Python. Side note: you can also use the <a href="proxy.php?url=https://docs.python.org/3/library/io.html#io.IOBase.readlines"><code>readlines()</code></a> method if you like.</p>
<h2>
6. Write string to file
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="k">with</span> <span class="nf">open</span><span class="p">(</span><span class="sh">'</span><span class="s">file.txt</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">a</span><span class="sh">'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span> <span class="n">f</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="sh">'</span><span class="s">hello world</span><span class="sh">'</span><span class="p">)</span>
<span class="c1"># print(list(open('file.txt'))) >> ['test1\n', 'test2\n', 'test3\n', 'test4\n', 'hello world']
</span></code></pre>
</div>
<p>With the help of the <code>with</code> statement, you can directly write content to a file. Make sure to use the correct <a href="proxy.php?url=https://docs.python.org/3/library/io.html#raw-file-i-o">mode</a> to open the file (here <code>'a'</code> for <strong>a</strong>ppending content).</p>
<h2>
7. List creation
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="n">l</span> <span class="o">=</span> <span class="p">[(</span><span class="sh">'</span><span class="s">Hi </span><span class="sh">'</span><span class="err">โ</span> <span class="o">+</span> <span class="n">x</span><span class="p">)</span> <span class="err">โ</span><span class="k">for</span><span class="err">โ</span> <span class="n">x</span> <span class="err">โ</span><span class="ow">in</span><span class="err">โ</span> <span class="p">[</span><span class="err">โ</span><span class="sh">'</span><span class="s">Alice</span><span class="sh">'</span><span class="err">โ</span><span class="p">,</span> <span class="err">โ</span><span class="sh">'</span><span class="s">Bob</span><span class="sh">'</span><span class="err">โ</span><span class="p">,</span> <span class="err">โ</span><span class="sh">'</span><span class="s">Pete</span><span class="sh">'</span><span class="err">โ</span><span class="p">]]</span>
<span class="c1"># print(l) >> ['Hi Alice', 'Hi Bob', 'Hi Pete']
</span></code></pre>
</div>
<p>Lists can be dynamically created from other lists with the inline for loop. You can directly modify the values, like string concatenation in this example.</p>
<h2>
8. List mapping
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="n">l</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="nf">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="p">[</span><span class="sh">'</span><span class="s">1</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">2</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">3</span><span class="sh">'</span><span class="p">]))</span>
<span class="c1"># print(l) >> [1, 2, 3]
</span></code></pre>
</div>
<p>You can also use Pythons <code>map()</code> function to cast every list element to another type.</p>
<h2>
9. Set creation
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="n">squares</span> <span class="o">=</span> <span class="p">{</span> <span class="n">x</span><span class="o">**</span><span class="mi">2</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span> <span class="k">if</span> <span class="n">x</span> <span class="o"><</span> <span class="mi">4</span> <span class="p">}</span>
<span class="c1"># print(squares) >> {0, 1, 4, 9}
</span></code></pre>
</div>
<p>It's similar with <a href="proxy.php?url=https://docs.python.org/3/tutorial/datastructures.html#sets">sets</a>. In addition to the inline for loop, you can even directly append a condition!</p>
<h2>
10. Palindrome check
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="c1"># phrase = 'deleveled'
</span><span class="n">isPalindrome</span> <span class="o">=</span> <span class="n">phrase</span> <span class="o">==</span> <span class="n">phrase</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="c1"># print(isPalindrome) >> true
</span></code></pre>
</div>
<p>A palindrome is a series of characters that read the same both forwards and backwards. Normally you would need some looping and conditions to check, if a given string is a palindrome. In Python, you just compare the string with its reverse string. Instead of using the slicing operator <code>[::-1]</code>, you can also use the <code>reverse()</code> function to reverse the string.</p>
<h2>
Bonus: The Zen of Python
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight python"><code><span class="kn">import</span> <span class="n">this</span>
</code></pre>
</div>
<p>Well, this one needs no explanation. Just try it yourself by simply entering it in your Python shell ๐๐</p>
<h2>
Wrap it up
</h2>
<p>We've seen some (admittedly simple) examples of Python one-liners, that are powerful and well readable at the same time. Maybe you know another helpful one-liner? Share it with us in the comments!</p>
<p><em>Published: 29th July 2020</em></p>
pythonbeginnersprogrammingSome Emmet Magic Frontend Devs should knowAndreasMon, 20 Jul 2020 13:13:00 +0000
https://dev.to/devmount/some-emmet-magic-frontend-devs-should-know-2p2o
https://dev.to/devmount/some-emmet-magic-frontend-devs-should-know-2p2o<p>I would like to share some examples of useful Emmet commands that heavily speed up my markup creation - and maybe yours too.</p>
<p>If you haven't heard of Emmet before, see this <a href="proxy.php?url=https://dev.to/lalawuhan/emmet-love-4be5">awesome introduction to Emmet</a> by <a href="proxy.php?url=https://dev.to/thabisegoe">Thabi</a>. Emmet is integrated in most code editors by default, so maybe you're using it right now without knowing it's Emmet under the hood ๐ . In VS Code e.g. you just have to type the Emmet abbreviation and hit TAB to create the markup.</p>
<h2>
Document creation
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>doc
</code></pre>
</div>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr4pziy8yn8epkfmktyu3.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr4pziy8yn8epkfmktyu3.gif" alt="Screencast Emmet command doctype" width="720" height="300"></a></p>
<p>No need to write the whole doctype yourself. Each HTML file can be kickstarted by simply typing <code>doc</code> and hit TAB.</p>
<h2>
Table creation
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>table>#row$*3>[colspan=2]
</code></pre>
</div>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fft9xsgitq10w6nn03zq9.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fft9xsgitq10w6nn03zq9.gif" alt="Screencast Emmet command table" width="720" height="300"></a></p>
<p>Emmet inserts implicit tag names here (such as <code>tr</code> and <code>td</code>) and you can simply multiply elements and apply the current iteration number to e.g. the elements id with the <code>$</code> sign.</p>
<h2>
Form creation
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>form:post>(select>opt[value=$]{#$$}*4)+btn:s
</code></pre>
</div>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq674167o7mc9tmepodfg.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq674167o7mc9tmepodfg.gif" alt="Screencast Emmet command form" width="720" height="300"></a></p>
<p>There are also a lot of aliases, that massively reduces the number of characters you have to type, e.g. <code>btn:s</code> instead of <code>button[type=submit]</code>. Also you can force leading Zeros with multiple <code>$</code> signs.</p>
<h2>
Generic content
</h2>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>ul.generic>lorem6.item*5
</code></pre>
</div>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv2ozlo92sqfjivi0ytrl.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv2ozlo92sqfjivi0ytrl.gif" alt="Screencast Emmet command generic content" width="720" height="300"></a></p>
<p>In case you just create HTML layout demos, the <code>lorem</code> abbreviation comes in very handy, followed by the number of words the sentence should consist of.</p>
<h2>
Bonus: Abbreviation Wrap in VS Code
</h2>
<p>If you're changing existing markup rather than creating it from scratch (which is probably almost always the case), you can make use of VS Code's command <em>Emmet: Wrap with Abbreviation</em>. Here you can select some content and wrap it with the desired tags by using Emmet Syntax:</p>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F66l307elpgr2swrbehd7.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F66l307elpgr2swrbehd7.gif" alt="Screencast Abbreviation Wrap in VS Code" width="870" height="311"></a></p>
<p>Plus: Setting a keyboard shortcut for this feature saves a lot of time! On my Windows machine, I configured CTRL+ALT+E</p>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvggdjizoybkjaiwe3hjx.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvggdjizoybkjaiwe3hjx.png" alt="Screenshot of VS Code Shortcuts Setting for Emmets Abbreviation Wrap" width="720" height="320"></a></p>
<h2>
Wrap it up
</h2>
<p>We've seen, that there are a lot of abbreviations that speed up the process of creating markup. This is especially useful, when you're creating a lot of markup by hand.</p>
<p>Check the <a href="proxy.php?url=https://docs.emmet.io/cheat-sheet/">Emmet Cheat Sheet</a> if you want to learn more. Happy coding!</p>
<p><em>Published: 20th July 2020</em></p>
htmlproductivityemmetmarkupWhat was the funniest typo in your client conversations?AndreasFri, 17 Jul 2020 10:38:33 +0000
https://dev.to/devmount/what-was-the-funniest-typo-in-your-client-conversations-4mce
https://dev.to/devmount/what-was-the-funniest-typo-in-your-client-conversations-4mce<p>Have you ever experienced a funny or embarrassing situation because of a typo you or your client made?</p>
<p>(title photo by <a href="proxy.php?url=https://unsplash.com/@amadorloureiroblanco?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Amador Loureiro</a> on <a href="proxy.php?url=https://unsplash.com/s/photos/letter?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>)</p>
watercoolerdiscussdevlifefunnyYou Can Quit! ...with the help of Vue and DexieAndreasMon, 27 Apr 2020 13:12:56 +0000
https://dev.to/devmount/you-can-quit-with-the-help-of-vue-and-dexie-221i
https://dev.to/devmount/you-can-quit-with-the-help-of-vue-and-dexie-221i<p>I humbly assume that every single one of us has a bad habit we want to get rid of. At least I have those habits ๐ . Be it committing untested code, coding without proper documentation, just copying-and-pasting code or not even programming or computer related things like spending too less time with family or friends, blaming others for any faults instead of taking responsibility or eating too many candies ๐ญ๐คท๐ปโโ๏ธ.</p>
<p>Back in July 2018 I came to a point where I really got frustrated about my inability to listen to my wife. I mean <strong>real listening</strong>. Listening without instantly forgetting what she said in the next minutes. Listening while giving her full attention. Though it's difficult being interrupted when you're really into something like programming, I could at least properly communicate that now is not a good time to talk instead of pretending to listen and not knowing what she said as soon as she was leaving the room. This often resulted in discussions like "I thought we talked about that" or "I asked you to do that and you didn't". I didn't liked that and knew, I had to do something about it.</p>
<p>Like a good programmer I first analyzed the problem. The problem was, that it just happened - <strong>it became one of my habits</strong> and habits are typically difficult to break, because it's too easy to do things as always and I'm not aware of it being a bad thing in that situation. So my problem was summarized by this one question: <strong>How to get that awareness to actually improve myself?</strong> My programmer mind instantly knew the answer: Build a tool!</p>
<p>That is how <a href="proxy.php?url=https://github.com/devmount/you-can-quit">you-can-quit</a> was born. A tool that aims to help the user not doing something anymore on a daily basis, by tracking the progress, provide encouraging notifications, funny achievements and the possibility for the user to recognize patterns.</p>
<h2>
How it looks
</h2>
<p>I host this app at <a href="proxy.php?url=https://youcanqu.it">youcanqu.it</a>. Just drop by and play around, test or use it as you like. I decided to do the layout and styling myself and not use a CSS Framework. The following are the main sections of the app.</p>
<h3>
Month view and actual input area
</h3>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqzbq55pfzd2bix89qgti.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqzbq55pfzd2bix89qgti.png" alt="month section" width="773" height="816"></a></p>
<p>The month view shows the current or selected month. When hovering over a day in the past, some buttons to set the state of that day appear. You can use arrow keys to navigate between different months.</p>
<h3>
Stats
</h3>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwhypa8lfi8mqqjkomax2.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwhypa8lfi8mqqjkomax2.png" alt="stats section" width="800" height="217"></a></p>
<p>Currently the stats are just showing the current streak (number of successful days in a row until today), the longest streak and the total number of successful days.</p>
<h3>
Achievements
</h3>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2wmjhjus1ab60ejdcce7.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2wmjhjus1ab60ejdcce7.png" alt="achievement section" width="800" height="464"></a></p>
<p>I thought it would be much more fun and a lot more effective to reach various small goals on the way. So I created 18 achievements where most of them can be rewarded multiple times. The white bar at the bottom of each achievement indicates its progress. More achievements are planned, as well as a <em>score-of-success</em>, that's calculated based on streaks and weighted achievements score.</p>
<h3>
Year view
</h3>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzs7el518a8sfzpy2vklk.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzs7el518a8sfzpy2vklk.png" alt="year section" width="800" height="183"></a></p>
<p>Here you have the possibility to find possible patterns over a longer time interval. Maybe you are more prone to failure on Mondays or a certain season in the year. You can navigate between years with <code>STRG</code> + arrow keys.</p>
<h3>
Administration
</h3>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1v8bdtn3vsou9g6aacwn.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1v8bdtn3vsou9g6aacwn.png" alt="administration section" width="800" height="213"></a></p>
<p>You can export, import or delete your data here.</p>
<h2>
How it works
</h2>
<p>It's as simple as setting the past day(s) successful or failed, depending on whether you have reached your goal on that day or not. To do that, just move the cursor over one of the past days in the monthly overview and click the left or right button that appear (You can also set that day back to undecided, if you want). You can do that e.g. everyday in the morning for the past day. With every successful day, you will see your stats and achievements increase.</p>
<p>Under the hood, it's a <a href="proxy.php?url=https://vuejs.org">Vue.js</a> <a href="proxy.php?url=https://en.wikipedia.org/wiki/Single-page_application">SPA</a> using <a href="proxy.php?url=https://dexie.org">Dexie.js</a> to store the data via your browsers <a href="proxy.php?url=https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API">Indexed Database API</a>. That means no data is leaving your machine or synchronized with a server. Privacy โ !</p>
<p>If you want to know more details, here is the project repository:</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/devmount">
devmount
</a> / <a href="proxy.php?url=https://github.com/devmount/you-can-quit">
you-can-quit
</a>
</h2>
<h3>
A tool to support your progress in quitting whatever your bad habit is.
</h3>
</div>
</div>
<p>You are very welcome to support this Github project by staring it โญ, creating issues ๐ or pull request ๐. Maybe you have ideas for additional achievements or you want to translate this tool into your own language? See <a href="proxy.php?url=https://github.com/devmount/you-can-quit/blob/master/.github/CONTRIBUTING.md">these guidelines</a> if you'd like to contribute ๐</p>
<h2>
Final words
</h2>
<p>I really hope this project is as useful for some of you as it is for myself. I'm still in the process of improving my communication skills, but it helped me to literally see my progress and success. I always love to build something while knowing, that people are actually using it and it really helps them! That's what Open Source is about, isn't it?</p>
<p>Don't hesitate to share your story of a bad habit in the comments. I'm sure we can all help each other to become a little bit better every day!</p>
<p>DEV-community-๐ค! Keep it up, you are awesome.</p>
<p><em>Published: 27th April 2020</em></p>
vuejavascriptdexieshowdev4 PHP Tricks to Boost Script PerformanceAndreasTue, 14 Apr 2020 12:07:57 +0000
https://dev.to/devmount/4-php-tricks-to-boost-script-performance-ol1
https://dev.to/devmount/4-php-tricks-to-boost-script-performance-ol1<p>Normally I write code by using the conventional, obvious PHP functions to solve corresponding problems. But for some of these problems I came across alternative solutions that especially increase performance.</p>
<p>In this article I want to present some of these alternatives. This is useful, if you're searching for possibilities to decrease execution time even more in production. Let's see, which PHP methods might be replaced by a more performant approach and if there is any cost or trade-off.</p>
<p>โน <em>All these methods were tested with PHP 7.4 on a local web server</em></p>
<h2>
1. Removing duplicates
</h2>
<p>You have a large array with duplicates and want to remove them to only have an array with unique values only.</p>
<h3>
๐ Conventional
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code>
<span class="nb">array_unique</span><span class="p">(</span><span class="nv">$array</span><span class="p">);</span>
</code></pre>
</div>
<h3>
โก Alternative
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code>
<span class="nb">array_keys</span><span class="p">(</span><span class="nb">array_flip</span><span class="p">(</span><span class="nv">$array</span><span class="p">));</span>
</code></pre>
</div>
<h3>
โฒ Performance
</h3>
<p>I created an array with more than 4 million elements having more than 3 million duplicates. Here is the top result:</p>
<div class="table-wrapper-paragraph"><table>
<thead>
<tr>
<th>method</th>
<th>execution time</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>array_unique</code></td>
<td>787.31 ms</td>
</tr>
<tr>
<td>
<code>array_keys</code> <code>array_flip</code>
</td>
<td>434.03 ms</td>
</tr>
</tbody>
</table></div>
<p>The alternative approach is <strong>1.8x</strong> (44.87%) faster in this measurement. On average, it was ~1.5x (30%) faster. Trade-off: This is only applicable for simple, one-dimensional arrays since <code>array_flip</code> replaces keys by values.</p>
<h2>
2. Get random array element
</h2>
<p>You have a large array and want to pick a random value from it.</p>
<h3>
๐ Conventional
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code>
<span class="nb">array_rand</span><span class="p">(</span><span class="nv">$array</span><span class="p">);</span>
</code></pre>
</div>
<h3>
โก Alternative
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code>
<span class="nv">$array</span><span class="p">[</span><span class="nb">mt_rand</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">count</span><span class="p">(</span><span class="nv">$array</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)];</span>
</code></pre>
</div>
<h3>
โฒ Performance
</h3>
<p>I created an array with 5 million elements. Here is the top result:</p>
<div class="table-wrapper-paragraph"><table>
<thead>
<tr>
<th>method</th>
<th>execution time</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>array_rand</code></td>
<td>25.99 ฮผs</td>
</tr>
<tr>
<td><code>mt_rand</code></td>
<td>0.95 ฮผs</td>
</tr>
</tbody>
</table></div>
<p>The alternative approach is <strong>27.3x</strong> (96.33%) faster in this measurement. On average, it was ~8x (87%) faster. This result is particularly surprising, as <code>mt_rand</code> is the implementation of the Mersenne Twister Random Number Generator and since PHP 7.1, the internal randomization algorithm <a href="proxy.php?url=https://www.php.net/manual/en/migration71.incompatible.php#migration71.incompatible.rand-srand-aliases" rel="noopener noreferrer">has been changed</a> to use exactly that same algorithm.</p>
<h2>
3. Test for alphanumeric characters
</h2>
<p>You have a string and want to test, if it only contains alphanumeric characters.</p>
<h3>
๐ Conventional
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code>
<span class="nb">preg_match</span><span class="p">(</span><span class="s1">'/[a-zA-Z0-9]+/'</span><span class="p">,</span> <span class="nv">$string</span><span class="p">);</span>
</code></pre>
</div>
<h3>
โก Alternative
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code>
<span class="nb">ctype_alnum</span><span class="p">(</span><span class="nv">$string</span><span class="p">);</span>
</code></pre>
</div>
<h3>
โฒ Performance
</h3>
<p>I created an array with more than 100k alphanumeric and non-alphanumeric strings. Here is the top result:</p>
<div class="table-wrapper-paragraph"><table>
<thead>
<tr>
<th>method</th>
<th>execution time</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>preg_match</code></td>
<td>15.39 ms</td>
</tr>
<tr>
<td><code>ctype_alnum</code></td>
<td>2.06 ms</td>
</tr>
</tbody>
</table></div>
<p>The alternative approach is <strong>7.5x</strong> (86.59%) faster in this measurement. On average, it was ~4x (76%) faster.</p>
<p>The same can be applied to <code>ctype_alpha()</code> (check for alphabetic characters) and <code>ctype_digit()</code> (check for numeric characters).</p>
<h2>
4. Replace substrings
</h2>
<p>You have a string and want to replace a part of it by another substring.</p>
<h3>
๐ Conventional
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code>
<span class="nb">str_replace</span><span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="nv">$string</span><span class="p">);</span>
</code></pre>
</div>
<h3>
โก Alternative
</h3>
<div class="highlight js-code-highlight">
<pre class="highlight php"><code>
<span class="nb">strtr</span><span class="p">(</span><span class="nv">$string</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">);</span>
</code></pre>
</div>
<h3>
โฒ Performance
</h3>
<p>I created an array with 5 million random strings. Here is the top result:</p>
<div class="table-wrapper-paragraph"><table>
<thead>
<tr>
<th>method</th>
<th>execution time</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>str_replace</code></td>
<td>676.59 ms</td>
</tr>
<tr>
<td><code>strtr</code></td>
<td>305.59 ms</td>
</tr>
</tbody>
</table></div>
<p>The alternative approach is <strong>2.2x</strong> (54.83%) faster in this measurement. On average, it was ~2x (51%) faster.</p>
<h2>
Additional performance improvements
</h2>
<p>Here are some additional points I integrated into my coding convention that I found to improve perfomance slightly (if applicable):</p>
<ul>
<li>Prefer JSON over XML</li>
<li>Declare variables before, not in every iteration of the loop</li>
<li>Avoid function calls in the loop header (in <code>for ($i=0; $i<count($array); $i)</code> the <code>count()</code> gets called in every iteration)</li>
<li>Unset memory consuming variables</li>
<li>Prefer select statement over multiple if statements</li>
<li>Prefer require/include over require_once/include_once (ensure proper opcode caching)</li>
</ul>
<p>Some final words: I know the discussion about premature optimization. And I agree that performance in production is depending on bottlenecks like database queries which should be focused on when dealing with performance. But I think, if there are alternatives that are faster and e.g. in case of regex easier to handle and maintain, why not using them?</p>
<h2>
Wrap it up
</h2>
<p>We've seen, that even with the current PHP 7.4 (which is already a lot faster than previous PHP versions) there are possibilities to boost script performance with alternative approaches even more. If you want to verify the figures presented in this article yourself, I created a repository with all tests:</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/devmount" rel="noopener noreferrer">
devmount
</a> / <a href="proxy.php?url=https://github.com/devmount/faster-php" rel="noopener noreferrer">
faster-php
</a>
</h2>
<h3>
Testing different approaches to improve PHP script performance
</h3>
</div>
</div>
<p>I used <a href="proxy.php?url=https://github.com/bvanhoekelen/performance" rel="noopener noreferrer">this great tool</a> by Bart van Hoekelen to measure execution time.</p>
<p>Please don't hesitate to comment here or <a href="proxy.php?url=https://github.com/devmount/faster-php/issues/new" rel="noopener noreferrer">create an issue</a>/PR at the repo above if you know additional ways to improve performance of certain PHP functions.</p>
<p><em>Published: 14th April 2020</em></p>
phpwebdevprogrammingperformanceA CheatSheet of 128 CheatSheets for DevelopersAndreasTue, 25 Feb 2020 12:36:45 +0000
https://dev.to/devmount/a-cheatsheet-of-128-cheatsheets-for-developers-f4m
https://dev.to/devmount/a-cheatsheet-of-128-cheatsheets-for-developers-f4m<p>I compiled a list of the (in my opinion) best Cheatsheets and tutorials for some of the top languages, frameworks and tools out there. I considered clarity, interactivity and simplicity for beginners. Lets go!</p>
<h3>
General
</h3>
<h4>
Awesome
</h4>
<p><code>001</code> <a href="proxy.php?url=https://github.com/topics/awesome" rel="noopener noreferrer">https://github.com/topics/awesome</a><br>
<code>002</code> <a href="proxy.php?url=https://github.com/detailyang/awesome-cheatsheet" rel="noopener noreferrer">https://github.com/detailyang/awesome-cheatsheet</a></p>
<h4>
Tech interview
</h4>
<p><code>003</code> <a href="proxy.php?url=https://www.frontendinterviewhandbook.com" rel="noopener noreferrer">https://www.frontendinterviewhandbook.com</a><br>
<code>004</code> <a href="proxy.php?url=https://github.com/TSiege/Tech-Interview-Cheat-Sheet" rel="noopener noreferrer">https://github.com/TSiege/Tech-Interview-Cheat-Sheet</a><br>
<code>005</code> <a href="proxy.php?url=https://dev.to/elliot/my-google-technical-interview-cheat-sheet-1lbd">https://dev.to/elliot/my-google-technical-interview-cheat-sheet-1lbd</a></p>
<h4>
Complexity
</h4>
<p><code>006</code> <a href="proxy.php?url=https://www.bigocheatsheet.com/" rel="noopener noreferrer">https://www.bigocheatsheet.com/</a><br>
<code>007</code> <a href="proxy.php?url=http://cooervo.github.io/Algorithms-DataStructures-BigONotation/" rel="noopener noreferrer">http://cooervo.github.io/Algorithms-DataStructures-BigONotation/</a></p>
<h4>
SEO
</h4>
<p><code>008</code> <a href="proxy.php?url=https://dev.to/pagely/seo-cheat-sheet-for-devs-5h1g">https://dev.to/pagely/seo-cheat-sheet-for-devs-5h1g</a></p>
<h3>
Programming, Scripting and Query Languages
</h3>
<h4>
C
</h4>
<p><code>009</code> <a href="proxy.php?url=https://developerinsider.co/c-programming-language-cheat-sheet/" rel="noopener noreferrer">https://developerinsider.co/c-programming-language-cheat-sheet/</a></p>
<h4>
C++
</h4>
<p><code>010</code> <a href="proxy.php?url=https://www.educba.com/c-programming-language-basics/" rel="noopener noreferrer">https://www.educba.com/c-programming-language-basics/</a></p>
<h4>
Go
</h4>
<p><code>011</code> <a href="proxy.php?url=https://github.com/a8m/golang-cheat-sheet" rel="noopener noreferrer">https://github.com/a8m/golang-cheat-sheet</a><br>
<code>012</code> <a href="proxy.php?url=https://devhints.io/go" rel="noopener noreferrer">https://devhints.io/go</a><br>
<code>013</code> <a href="proxy.php?url=https://dev.to/codehakase/how-i-learned-go-programming">https://dev.to/codehakase/how-i-learned-go-programming</a></p>
<h4>
GraphQL
</h4>
<p><code>014</code> <a href="proxy.php?url=https://devhints.io/graphql" rel="noopener noreferrer">https://devhints.io/graphql</a><br>
<code>015</code> <a href="proxy.php?url=https://raw.githubusercontent.com/sogko/graphql-shorthand-notation-cheat-sheet/master/graphql-shorthand-notation-cheat-sheet.png" rel="noopener noreferrer">https://raw.githubusercontent.com/sogko/graphql-shorthand-notation-cheat-sheet/master/graphql-shorthand-notation-cheat-sheet.png</a><br>
<code>016</code> <a href="proxy.php?url=https://dev.to/methodcoder/graphql-crash-course-in-10-pics-3b04">https://dev.to/methodcoder/graphql-crash-course-in-10-pics-3b04</a></p>
<h4>
Java
</h4>
<p><code>017</code> <a href="proxy.php?url=https://overapi.com/java" rel="noopener noreferrer">https://overapi.com/java</a><br>
<code>018</code> <a href="proxy.php?url=https://cheatography.com/son9912/cheat-sheets/java-oop-concept/" rel="noopener noreferrer">https://cheatography.com/son9912/cheat-sheets/java-oop-concept/</a><br>
<code>019</code> <a href="proxy.php?url=https://www.educba.com/category/software-development/software-development-tutorials/java-tutorial/" rel="noopener noreferrer">https://www.educba.com/category/software-development/software-development-tutorials/java-tutorial/</a><br>
<code>020</code> <a href="proxy.php?url=https://dev.to/monknomo/java-8-stream-cheatsheet--oad">https://dev.to/monknomo/java-8-stream-cheatsheet--oad</a></p>
<h4>
JavaScript, ES2015+
</h4>
<p><code>021</code> <a href="proxy.php?url=https://quickref.me/es6.html" rel="noopener noreferrer">https://quickref.me/es6.html</a><br>
<code>022</code> <a href="proxy.php?url=https://htmlcheatsheet.com/js/" rel="noopener noreferrer">https://htmlcheatsheet.com/js/</a><br>
<code>023</code> <a href="proxy.php?url=https://devhints.io/es6" rel="noopener noreferrer">https://devhints.io/es6</a><br>
<code>024</code> <a href="proxy.php?url=https://overapi.com/javascript" rel="noopener noreferrer">https://overapi.com/javascript</a><br>
<code>025</code> <a href="proxy.php?url=https://dev.to/samanthaming/javascript-module-cheatsheet-5b4o">https://dev.to/samanthaming/javascript-module-cheatsheet-5b4o</a><br>
<code>026</code> <a href="proxy.php?url=https://dev.to/samanthaming/es6-arrow-functions-cheatsheet-1cn">https://dev.to/samanthaming/es6-arrow-functions-cheatsheet-1cn</a></p>
<h4>
PHP
</h4>
<p><code>027</code> <a href="proxy.php?url=https://overapi.com/php" rel="noopener noreferrer">https://overapi.com/php</a><br>
<code>028</code> <a href="proxy.php?url=https://phpcheatsheets.com/" rel="noopener noreferrer">https://phpcheatsheets.com/</a><br>
<code>029</code> <a href="proxy.php?url=https://dev.to/biros/awesome-php-resources-on-dev----3a18">https://dev.to/biros/awesome-php-resources-on-dev----3a18</a></p>
<h4>
Python
</h4>
<p><code>030</code> <a href="proxy.php?url=https://devhints.io/python" rel="noopener noreferrer">https://devhints.io/python</a><br>
<code>031</code> <a href="proxy.php?url=https://overapi.com/python" rel="noopener noreferrer">https://overapi.com/python</a><br>
<code>032</code> <a href="proxy.php?url=https://www.pythoncheatsheet.org" rel="noopener noreferrer">https://www.pythoncheatsheet.org</a><br>
<code>033</code> <a href="proxy.php?url=https://dev.to/abhirajb/the-ultimate-python-cheatsheet-56g7">https://dev.to/abhirajb/the-ultimate-python-cheatsheet-56g7</a></p>
<h4>
Regex
</h4>
<p><code>034</code> <a href="proxy.php?url=https://www.debuggex.com/cheatsheet/regex/javascript" rel="noopener noreferrer">https://www.debuggex.com/cheatsheet/regex/javascript</a><br>
<code>035</code> <a href="proxy.php?url=https://devhints.io/regexp" rel="noopener noreferrer">https://devhints.io/regexp</a><br>
<code>036</code> <a href="proxy.php?url=https://overapi.com/regex" rel="noopener noreferrer">https://overapi.com/regex</a><br>
<code>037</code> <a href="proxy.php?url=https://dev.to/emmabostian/regex-cheat-sheet-2j2a">https://dev.to/emmabostian/regex-cheat-sheet-2j2a</a><br>
<code>038</code> <a href="proxy.php?url=https://dev.to/catherinecodes/a-regex-cheatsheet-for-all-those-regex-haters-and-lovers--2cj1">https://dev.to/catherinecodes/a-regex-cheatsheet-for-all-those-regex-haters-and-lovers--2cj1</a></p>
<h4>
Ruby
</h4>
<p><code>039</code> <a href="proxy.php?url=https://overapi.com/ruby" rel="noopener noreferrer">https://overapi.com/ruby</a><br>
<code>040</code> <a href="proxy.php?url=https://dev.to/teekay/idiomatic-ruby-writing-beautiful-code-56ef">https://dev.to/teekay/idiomatic-ruby-writing-beautiful-code-56ef</a><br>
<code>041</code> <a href="proxy.php?url=https://dev.to/philnash/top-10-errors-from-1000-ruby-on-rails-projects-and-how-to-avoid-them-24m">https://dev.to/philnash/top-10-errors-from-1000-ruby-on-rails-projects-and-how-to-avoid-them-24m</a></p>
<h4>
SQL, MySQL
</h4>
<p><code>042</code> <a href="proxy.php?url=https://devhints.io/mysql" rel="noopener noreferrer">https://devhints.io/mysql</a><br>
<code>043</code> <a href="proxy.php?url=https://overapi.com/mysql" rel="noopener noreferrer">https://overapi.com/mysql</a></p>
<h4>
TypeScript
</h4>
<p><code>044</code> <a href="proxy.php?url=https://learnxinyminutes.com/docs/typescript/" rel="noopener noreferrer">https://learnxinyminutes.com/docs/typescript/</a><br>
<code>045</code> <a href="proxy.php?url=https://devhints.io/typescript" rel="noopener noreferrer">https://devhints.io/typescript</a></p>
<h3>
Frameworks, libraries and their extensions
</h3>
<h4>
Angular
</h4>
<p><code>046</code> <a href="proxy.php?url=https://docs.w3cub.com/angular/guide/cheatsheet.html" rel="noopener noreferrer">https://docs.w3cub.com/angular/guide/cheatsheet.html</a><br>
<code>047</code> <a href="proxy.php?url=https://dev.to/lysofdev/an-angular-testing-cheatsheet-5hj2">https://dev.to/lysofdev/an-angular-testing-cheatsheet-5hj2</a></p>
<h4>
jQuery
</h4>
<p><code>048</code> <a href="proxy.php?url=https://oscarotero.com/jquery/" rel="noopener noreferrer">https://oscarotero.com/jquery/</a><br>
<code>049</code> <a href="proxy.php?url=https://overapi.com/jquery" rel="noopener noreferrer">https://overapi.com/jquery</a></p>
<h4>
React
</h4>
<p><code>050</code> <a href="proxy.php?url=https://cheatsheets.shecodes.io/react" rel="noopener noreferrer">https://cheatsheets.shecodes.io/react</a><br>
<code>051</code> <a href="proxy.php?url=https://devhints.io/react" rel="noopener noreferrer">https://devhints.io/react</a><br>
<code>052</code> <a href="proxy.php?url=https://reactcheatsheet.com/" rel="noopener noreferrer">https://reactcheatsheet.com/</a></p>
<h4>
Redux
</h4>
<p><code>053</code> <a href="proxy.php?url=https://medium.com/@javascript_7596/react-redux-concept-workflow-cheatsheet-be00e3ffa853" rel="noopener noreferrer">https://medium.com/@javascript_7596/react-redux-concept-workflow-cheatsheet-be00e3ffa853</a><br>
<code>054</code> <a href="proxy.php?url=https://devhints.io/redux" rel="noopener noreferrer">https://devhints.io/redux</a><br>
<code>055</code> <a href="proxy.php?url=https://github.com/linkmesrl/react-journey-2016/blob/master/resources/egghead-redux-cheat-sheet-3-2-1.pdf" rel="noopener noreferrer">https://github.com/linkmesrl/react-journey-2016/blob/master/resources/egghead-redux-cheat-sheet-3-2-1.pdf</a></p>
<h4>
Vue.js
</h4>
<p><code>056</code> <a href="proxy.php?url=https://learnvue.co/LearnVue-Vue-3-Cheatsheet.pdf" rel="noopener noreferrer">https://learnvue.co/LearnVue-Vue-3-Cheatsheet.pdf</a><br>
<code>057</code> <a href="proxy.php?url=https://devhints.io/vue" rel="noopener noreferrer">https://devhints.io/vue</a><br>
<code>058</code> <a href="proxy.php?url=https://dev.to/adnanbabakan/vue-cheat-sheet-1-194a">https://dev.to/adnanbabakan/vue-cheat-sheet-1-194a</a><br>
<code>059</code> <a href="proxy.php?url=https://dev.to/adnanbabakan/vue-cheat-sheet-2-5aj8">https://dev.to/adnanbabakan/vue-cheat-sheet-2-5aj8</a><br>
<code>060</code> <a href="proxy.php?url=https://dev.to/adnanbabakan/vue-cheat-sheet-3-advanced-4khj">https://dev.to/adnanbabakan/vue-cheat-sheet-3-advanced-4khj</a><br>
<code>061</code> <a href="proxy.php?url=https://dev.to/devmount/how-to-kickstart-a-vuejs-project-2mj5">https://dev.to/devmount/how-to-kickstart-a-vuejs-project-2mj5</a></p>
<h4>
Vuex
</h4>
<p><code>062</code> <a href="proxy.php?url=https://vuejs-tips.github.io/vuex-cheatsheet/" rel="noopener noreferrer">https://vuejs-tips.github.io/vuex-cheatsheet/</a><br>
<code>063</code> <a href="proxy.php?url=https://dev.to/napoleon039/when-why-and-how-to-use-vuex-9fl">https://dev.to/napoleon039/when-why-and-how-to-use-vuex-9fl</a></p>
<h3>
Editors, IDEs and other tools
</h3>
<h4>
Atom
</h4>
<p><code>064</code> <a href="proxy.php?url=https://devhints.io/atom" rel="noopener noreferrer">https://devhints.io/atom</a></p>
<h4>
Bash
</h4>
<p><code>065</code> <a href="proxy.php?url=https://devhints.io/bash" rel="noopener noreferrer">https://devhints.io/bash</a><br>
<code>066</code> <a href="proxy.php?url=http://johnstowers.co.nz/pages/bash-cheat-sheet.html" rel="noopener noreferrer">http://johnstowers.co.nz/pages/bash-cheat-sheet.html</a><br>
<code>067</code> <a href="proxy.php?url=https://dev.to/devmount/9-evil-bash-commands-explained-4k5e">https://dev.to/devmount/9-evil-bash-commands-explained-4k5e</a></p>
<h4>
Docker
</h4>
<p><code>068</code> <a href="proxy.php?url=https://devhints.io/docker" rel="noopener noreferrer">https://devhints.io/docker</a><br>
<code>069</code> <a href="proxy.php?url=https://dev.to/emarsys/the-missing-docker-cheatsheet-4dbg">https://dev.to/emarsys/the-missing-docker-cheatsheet-4dbg</a></p>
<h4>
Git
</h4>
<p><code>070</code> <a href="proxy.php?url=http://www.ndpsoftware.com/git-cheatsheet.html" rel="noopener noreferrer">http://www.ndpsoftware.com/git-cheatsheet.html</a><br>
<code>071</code> <a href="proxy.php?url=https://overapi.com/git" rel="noopener noreferrer">https://overapi.com/git</a><br>
<code>072</code> <a href="proxy.php?url=https://dev.to/maxpou/git-cheat-sheet-advanced-3a17">https://dev.to/maxpou/git-cheat-sheet-advanced-3a17</a><br>
<code>073</code> <a href="proxy.php?url=https://dev.to/duomly/git-cheatsheet-for-beginners-5apl">https://dev.to/duomly/git-cheatsheet-for-beginners-5apl</a><br>
<code>074</code> <a href="proxy.php?url=https://dev.to/antjanus/my-personal-git-tricks-cheatsheet-23j1">https://dev.to/antjanus/my-personal-git-tricks-cheatsheet-23j1</a><br>
<code>075</code> <a href="proxy.php?url=https://dev.to/hengnee/yet-another-git-cheatsheet-4gjk">https://dev.to/hengnee/yet-another-git-cheatsheet-4gjk</a><br>
<code>076</code> <a href="proxy.php?url=https://dev.to/devmount/how-to-correct-git-commit-messages-402d">https://dev.to/devmount/how-to-correct-git-commit-messages-402d</a><br>
<code>077</code> <a href="proxy.php?url=https://dev.to/devmount/signed-git-commits-in-vs-code-36do">https://dev.to/devmount/signed-git-commits-in-vs-code-36do</a></p>
<h4>
Node.js
</h4>
<p><code>078</code> <a href="proxy.php?url=https://devhints.io/nodejs" rel="noopener noreferrer">https://devhints.io/nodejs</a><br>
<code>079</code> <a href="proxy.php?url=https://overapi.com/nodejs" rel="noopener noreferrer">https://overapi.com/nodejs</a><br>
<code>080</code> <a href="proxy.php?url=https://dev.to/santypk4/bulletproof-node-js-project-architecture-4epf">https://dev.to/santypk4/bulletproof-node-js-project-architecture-4epf</a><br>
<code>081</code> <a href="proxy.php?url=https://dev.to/jorge_rockr/everything-you-need-to-know-about-node-js-lnc">https://dev.to/jorge_rockr/everything-you-need-to-know-about-node-js-lnc</a></p>
<h4>
Sublime Text
</h4>
<p><code>082</code> <a href="proxy.php?url=https://devhints.io/sublime-text" rel="noopener noreferrer">https://devhints.io/sublime-text</a><br>
<code>083</code> <a href="proxy.php?url=https://shortcuts.design/toolspage-sublimetext.html" rel="noopener noreferrer">https://shortcuts.design/toolspage-sublimetext.html</a></p>
<h4>
Vim
</h4>
<p><code>084</code> <a href="proxy.php?url=https://vim.rtorr.com/" rel="noopener noreferrer">https://vim.rtorr.com/</a><br>
<code>085</code> <a href="proxy.php?url=https://devhints.io/vim" rel="noopener noreferrer">https://devhints.io/vim</a><br>
<code>086</code> <a href="proxy.php?url=https://sheet.shiar.nl/vi" rel="noopener noreferrer">https://sheet.shiar.nl/vi</a></p>
<h4>
Visual Studio Code
</h4>
<p><code>087</code> <a href="proxy.php?url=https://devhints.io/vscode" rel="noopener noreferrer">https://devhints.io/vscode</a><br>
<code>088</code> <a href="proxy.php?url=https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf" rel="noopener noreferrer">https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf</a><br>
<code>089</code> <a href="proxy.php?url=https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf" rel="noopener noreferrer">https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf</a><br>
<code>090</code> <a href="proxy.php?url=https://code.visualstudio.com/shortcuts/keyboard-shortcuts-linux.pdf" rel="noopener noreferrer">https://code.visualstudio.com/shortcuts/keyboard-shortcuts-linux.pdf</a><br>
<code>091</code> <a href="proxy.php?url=https://dev.to/devmount/23-lesser-known-vs-code-shortcuts-as-gif-80">https://dev.to/devmount/23-lesser-known-vs-code-shortcuts-as-gif-80</a></p>
<h3>
Markup and Styling
</h3>
<h4>
CSS, CSS3, Flexbox
</h4>
<p><code>092</code> <a href="proxy.php?url=https://htmlcheatsheet.com/css/" rel="noopener noreferrer">https://htmlcheatsheet.com/css/</a><br>
<code>093</code> <a href="proxy.php?url=https://devhints.io/css" rel="noopener noreferrer">https://devhints.io/css</a><br>
<code>094</code> <a href="proxy.php?url=http://overapi.com/css" rel="noopener noreferrer">http://overapi.com/css</a><br>
<code>095</code> <a href="proxy.php?url=https://yoksel.github.io/flex-cheatsheet/" rel="noopener noreferrer">https://yoksel.github.io/flex-cheatsheet/</a><br>
<code>096</code> <a href="proxy.php?url=https://dev.to/proticm/css-variables-cheat-sheet-32id">https://dev.to/proticm/css-variables-cheat-sheet-32id</a><br>
<code>097</code> <a href="proxy.php?url=https://dev.to/iggredible/css-selectors-cheatsheet-24bh">https://dev.to/iggredible/css-selectors-cheatsheet-24bh</a><br>
<code>098</code> <a href="proxy.php?url=https://dev.to/devmount/learn-css-animation-by-creating-pure-css-loaders-3lm6">https://dev.to/devmount/learn-css-animation-by-creating-pure-css-loaders-3lm6</a><br>
<code>099</code> <a href="proxy.php?url=https://dev.to/devmount/8-games-to-learn-css-the-fun-way-4e0f">https://dev.to/devmount/8-games-to-learn-css-the-fun-way-4e0f</a></p>
<h4>
Emmet
</h4>
<p><code>100</code> <a href="proxy.php?url=https://docs.emmet.io/cheat-sheet/" rel="noopener noreferrer">https://docs.emmet.io/cheat-sheet/</a><br>
<code>101</code> <a href="proxy.php?url=https://devhints.io/emmet" rel="noopener noreferrer">https://devhints.io/emmet</a><br>
<code>102</code> <a href="proxy.php?url=https://dev.to/lalawuhan/emmet-love-4be5">https://dev.to/lalawuhan/emmet-love-4be5</a></p>
<h4>
HTML, HTML5
</h4>
<p><code>103</code> <a href="proxy.php?url=https://htmlcheatsheet.com/" rel="noopener noreferrer">https://htmlcheatsheet.com/</a><br>
<code>104</code> <a href="proxy.php?url=https://devhints.io/html" rel="noopener noreferrer">https://devhints.io/html</a><br>
<code>105</code> <a href="proxy.php?url=http://overapi.com/html" rel="noopener noreferrer">http://overapi.com/html</a></p>
<h4>
JSON
</h4>
<p><code>106</code> <a href="proxy.php?url=https://cheatography.com/mackan90096/cheat-sheets/json/" rel="noopener noreferrer">https://cheatography.com/mackan90096/cheat-sheets/json/</a></p>
<h4>
LaTeX
</h4>
<p><code>107</code> <a href="proxy.php?url=https://wch.github.io/latexsheet/" rel="noopener noreferrer">https://wch.github.io/latexsheet/</a><br>
<code>108</code> <a href="proxy.php?url=https://dev.to/nickymarino/lets-use-latex">https://dev.to/nickymarino/lets-use-latex</a></p>
<h4>
Markdown
</h4>
<p><code>109</code> <a href="proxy.php?url=https://www.markdownguide.org/cheat-sheet" rel="noopener noreferrer">https://www.markdownguide.org/cheat-sheet</a><br>
<code>110</code> <a href="proxy.php?url=https://devhints.io/markdown" rel="noopener noreferrer">https://devhints.io/markdown</a><br>
<code>111</code> <a href="proxy.php?url=https://dev.to/rattanakchea/markdown-cheatsheet-for-developers-2bjj">https://dev.to/rattanakchea/markdown-cheatsheet-for-developers-2bjj</a></p>
<h4>
Pug
</h4>
<p><code>112</code> <a href="proxy.php?url=https://devhints.io/pug" rel="noopener noreferrer">https://devhints.io/pug</a></p>
<h4>
SASS, SCSS
</h4>
<p><code>113</code> <a href="proxy.php?url=https://quickref.me/sass.html" rel="noopener noreferrer">https://quickref.me/sass.html</a><br>
<code>114</code> <a href="proxy.php?url=https://devhints.io/sass" rel="noopener noreferrer">https://devhints.io/sass</a><br>
<code>115</code> <a href="proxy.php?url=https://dev.to/finallynero/scss-cheatsheet-7g6">https://dev.to/finallynero/scss-cheatsheet-7g6</a></p>
<h4>
Stylus
</h4>
<p><code>116</code> <a href="proxy.php?url=https://devhints.io/stylus" rel="noopener noreferrer">https://devhints.io/stylus</a></p>
<h4>
Xpath
</h4>
<p><code>117</code> <a href="proxy.php?url=https://devhints.io/xpath" rel="noopener noreferrer">https://devhints.io/xpath</a></p>
<h4>
Yaml
</h4>
<p><code>118</code> <a href="proxy.php?url=https://lzone.de/#/LZone%20Cheat%20Sheets/Languages/YAML" rel="noopener noreferrer">https://lzone.de/#/LZone%20Cheat%20Sheets/Languages/YAML</a><br>
<code>119</code> <a href="proxy.php?url=https://devhints.io/yaml" rel="noopener noreferrer">https://devhints.io/yaml</a></p>
<h3>
Platforms, web apps and code management
</h3>
<h4>
Github
</h4>
<p><code>120</code> <a href="proxy.php?url=https://github.com/tiimgreen/github-cheat-sheet" rel="noopener noreferrer">https://github.com/tiimgreen/github-cheat-sheet</a><br>
<code>121</code> <a href="proxy.php?url=https://github.github.com/training-kit/downloads/github-git-cheat-sheet/" rel="noopener noreferrer">https://github.github.com/training-kit/downloads/github-git-cheat-sheet/</a></p>
<h4>
Gitlab
</h4>
<p><code>122</code> <a href="proxy.php?url=https://docs.gitlab.com/ee/user/markdown.html" rel="noopener noreferrer">https://docs.gitlab.com/ee/user/markdown.html</a></p>
<h4>
Jupyter Notebook
</h4>
<p><code>123</code> <a href="proxy.php?url=https://s3.amazonaws.com/assets.datacamp.com/blog_assets/Jupyter_Notebook_Cheat_Sheet.pdf" rel="noopener noreferrer">https://s3.amazonaws.com/assets.datacamp.com/blog_assets/Jupyter_Notebook_Cheat_Sheet.pdf</a></p>
<h4>
NPM
</h4>
<p><code>124</code> <a href="proxy.php?url=https://devhints.io/npm" rel="noopener noreferrer">https://devhints.io/npm</a><br>
<code>125</code> <a href="proxy.php?url=https://guide.freecodecamp.org/developer-tools/npm-cheatsheet/" rel="noopener noreferrer">https://guide.freecodecamp.org/developer-tools/npm-cheatsheet/</a><br>
<code>126</code> <a href="proxy.php?url=https://dev.to/therealdanvega/creating-your-first-npm-package-2ehf">https://dev.to/therealdanvega/creating-your-first-npm-package-2ehf</a></p>
<h4>
Yarn
</h4>
<p><code>127</code> <a href="proxy.php?url=https://devhints.io/yarn" rel="noopener noreferrer">https://devhints.io/yarn</a><br>
<code>128</code> <a href="proxy.php?url=https://github.com/areai51/yarn-cheatsheet" rel="noopener noreferrer">https://github.com/areai51/yarn-cheatsheet</a></p>
<h2>
Wrap it up
</h2>
<p>Having a lot of basic information at one glance is often very useful for me, because I tend to forget the most basic things regularly ๐ . As I already wrote in <a href="proxy.php?url=https://dev.to/devmount/23-lesser-known-vs-code-shortcuts-as-gif-80">one of my earlier posts</a>, I created a repository on GitHub, where I maintain this list above and collect commands I tend to forget - check it out if you want:</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/devmount" rel="noopener noreferrer">
devmount
</a> / <a href="proxy.php?url=https://github.com/devmount/CheatSheets" rel="noopener noreferrer">
CheatSheets
</a>
</h2>
<h3>
A curated list of everything I look up more than twice
</h3>
</div>
</div>
<p>I hope there are one or two useful links for you regarding the technologies you use. If you know other awesome cheat sheets, please comment them below and don't hesitate to <a href="proxy.php?url=https://github.com/devmount/CheatSheets/pulls" rel="noopener noreferrer">make a PR</a> to make this list more complete.</p>
<p><em>Published: 25th February 2020<br>
Edited: 28th October 2024 (fixed broken links)<br>
Cover Image: <a href="proxy.php?url=https://codepen.io/devmount/full/ZEGLaKR" rel="noopener noreferrer">https://codepen.io/devmount/full/ZEGLaKR</a></em></p>
webdevproductivitybeginnersjavascript22 Shout-Outs to Open Source and Infinite CreativityAndreasWed, 19 Feb 2020 14:52:04 +0000
https://dev.to/devmount/22-shout-outs-to-open-source-and-infinite-creativity-4dk8
https://dev.to/devmount/22-shout-outs-to-open-source-and-infinite-creativity-4dk8<p>Sorry if this is a bit emotional, but I just have to say this now. Even at the risk of boring some of you. This isn't another Vue vs React vs Angular postโit's more like the opposite.</p>
<p>I love the open source community. I really do. It's simply amazing what people are capable of to make things easier to use, make things more performant, build things to connect and find solutions for complex problems โ in short: make the life of other developers and users easier and help each other out โ even without being paid (in many cases)! I don't know another professional area where this is the case to this extent.</p>
<p>Sometimes when <a href="proxy.php?url=https://github.com/explore">exploring Github repositories</a>, I'm especially impressed by how creative people are when it comes to create a logo for their extension of an existing framework. So I thought it would be nice to just showcase some totally random projects to see how colorful and creative Open Source is! And maybe there are some you haven't heard about yet and are useful for your current project.</p>
<p>But even if not, let's take this as inspiration and motivation for our own Open Source contributions and projects in 2020!</p>
<h2>
Vue.js
</h2>
<p>Let's start with some Vue.js projects I found on Github. Here is the original logo: </p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--tw1vSYeT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://vuejs.org/images/logo.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--tw1vSYeT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://vuejs.org/images/logo.png" alt="Vue.js logo" width="400" height="400"></a></p>
<h3>
1. vee-validate
</h3>
<p>This framework allows you to validate inputs and display errors. How efficiently simple the Vue.js logo was changed here to represent validation โ !</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ojWspHhT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://logaretm.github.io/vee-validate/logo.svg" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ojWspHhT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://logaretm.github.io/vee-validate/logo.svg" alt="vee validate logo" width="640" height="640"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/logaretm">
logaretm
</a> / <a href="proxy.php?url=https://github.com/logaretm/vee-validate">
vee-validate
</a>
</h2>
<h3>
โ Painless Vue forms
</h3>
</div>
</div>
<h3>
2. Awesome Vue.js
</h3>
<p>A very very long list of projects related to Vue.js. And of course, what doesn't look awesome with sunglasses ๐!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--GeUx5ste--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/vuejs/awesome-vue/master/logo.svg" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--GeUx5ste--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/vuejs/awesome-vue/master/logo.svg" alt="awesome vue logo" width="800" height="560"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/vuejs">
vuejs
</a> / <a href="proxy.php?url=https://github.com/vuejs/awesome-vue">
awesome-vue
</a>
</h2>
<h3>
๐ A curated list of awesome things related to Vue.js
</h3>
</div>
</div>
<h3>
3. BootstrapVue
</h3>
<p>An implementation of the Bootstrap v4 component and grid system for Vue.js.</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--Bh_KH5sB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/bootstrap-vue/bootstrap-vue/dev/static/logo.svg" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--Bh_KH5sB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/bootstrap-vue/bootstrap-vue/dev/static/logo.svg" alt="BootstrapVue logo" width="800" height="847"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/bootstrap-vue">
bootstrap-vue
</a> / <a href="proxy.php?url=https://github.com/bootstrap-vue/bootstrap-vue">
bootstrap-vue
</a>
</h2>
<h3>
BootstrapVue provides one of the most comprehensive implementations of Bootstrap v4 for Vue.js. With extensive and automated WAI-ARIA accessibility markup.
</h3>
</div>
</div>
<h3>
4. Vuefire & Vuexfire
</h3>
<p>A really handy package for those using Firebase/Firestore with Vue.js. I like how the Vue.js logo becomes a stylised torch ๐ฅ!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--5yut-lTZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://vuefire.vuejs.org/vuefire-logo.svg" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--5yut-lTZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://vuefire.vuejs.org/vuefire-logo.svg" alt="Vuefire logo" width="60" height="80"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/vuejs">
vuejs
</a> / <a href="proxy.php?url=https://github.com/vuejs/vuefire">
vuefire
</a>
</h2>
<h3>
๐ฅ Firebase bindings for Vue.js
</h3>
</div>
</div>
<h3>
5. Vue Styleguidist
</h3>
<p>A Vue.js development environment with a living style guide. Nice tie ๐!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--gmNKv6oc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/vue-styleguidist/vue-styleguidist/dev/assets/logo.svg" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--gmNKv6oc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/vue-styleguidist/vue-styleguidist/dev/assets/logo.svg" alt="Vue Styleguidist logo" width="215" height="176"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/vue-styleguidist">
vue-styleguidist
</a> / <a href="proxy.php?url=https://github.com/vue-styleguidist/vue-styleguidist">
vue-styleguidist
</a>
</h2>
<h3>
Created from react styleguidist for Vue Components with a living style guide
</h3>
</div>
</div>
<h3>
6. vuesion
</h3>
<p>Build production-ready PWAs with this Vue.js boilerplate. Not much left of the Vue.js logo ๐ถ!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--b3xWr7yy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/vuesion/vuesion/raw/master/src/static/logo.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--b3xWr7yy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/vuesion/vuesion/raw/master/src/static/logo.png" alt="vuesion logo" width="800" height="800"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/vuesion">
vuesion
</a> / <a href="proxy.php?url=https://github.com/vuesion/vuesion">
vuesion
</a>
</h2>
<h3>
Vuesion is a boilerplate that helps product teams build faster than ever with fewer headaches and modern best practices across engineering & design.
</h3>
</div>
</div>
<h3>
7. electron-vue
</h3>
<p>Build electron applications with this Vue.js boilderplate. You don't always have to modify the Vue.js logo, sometimes using the Vue.js colors is enough โ!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--1TAO7uPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/SimulatedGREG/electron-vue/raw/master/docs/images/logo.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--1TAO7uPj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/SimulatedGREG/electron-vue/raw/master/docs/images/logo.png" alt="electron-vue logo" width="800" height="178"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/SimulatedGREG">
SimulatedGREG
</a> / <a href="proxy.php?url=https://github.com/SimulatedGREG/electron-vue">
electron-vue
</a>
</h2>
<h3>
An Electron & Vue.js quick start boilerplate with vue-cli scaffolding, common Vue plugins, electron-packager/electron-builder, unit/e2e testing, vue-devtools, and webpack.
</h3>
</div>
</div>
<h3>
8. Vuesax
</h3>
<p>A component framework based on Vue.js. Color gradients ftw ๐จ!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--NaUUAwYN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/lusaxweb/vuesax/master/public/vuesax-logo.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--NaUUAwYN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/lusaxweb/vuesax/master/public/vuesax-logo.png" alt="Vuesax logo" width="474" height="431"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/lusaxweb">
lusaxweb
</a> / <a href="proxy.php?url=https://github.com/lusaxweb/vuesax">
vuesax
</a>
</h2>
<h3>
New Framework Components for Vue.js 2
</h3>
</div>
</div>
<h3>
9. VueUse
</h3>
<p>And some utilities of the Vue Composition API. Need a logo for your Vue.js project? Just change the letter ๐ !</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ExmaI5_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/antfu/vueuse/master/resources/logo-vertical.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ExmaI5_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/antfu/vueuse/master/resources/logo-vertical.png" alt="VueUse logo" width="800" height="801"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/antfu">
antfu
</a> / <a href="proxy.php?url=https://github.com/antfu/vueuse">
vueuse
</a>
</h2>
<h3>
Collection of essential Vue Composition Utilities for Vue 2 and 3
</h3>
</div>
</div>
<h2>
React.js
</h2>
<p>Now let's see some examples from the React.js community. Here is the original logo:</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--3PA5RDzO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://chloerei.com/rails-frontend/images/reactjs-logo.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--3PA5RDzO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://chloerei.com/rails-frontend/images/reactjs-logo.png" alt="React.js logo" width="800" height="800"></a></p>
<h3>
10. Redux
</h3>
<p>A popular predictable state container for JavaScript apps that can be used together with React (but also with any other view library).</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ahM3e6S9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/reduxjs/redux/master/logo/logo.svg" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ahM3e6S9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/reduxjs/redux/master/logo/logo.svg" alt="Redux logo" width="100" height="100"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/reduxjs">
reduxjs
</a> / <a href="proxy.php?url=https://github.com/reduxjs/redux">
redux
</a>
</h2>
<h3>
A JS library for predictable global state management
</h3>
</div>
</div>
<h3>
11. React-Leaflet
</h3>
<p>Some React components for Leaflet maps. A logo showing React on a leaf ๐ ... or is it a map marker?</p>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fifclz6r8ag8s20gxeqmi.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fifclz6r8ag8s20gxeqmi.png" alt="React-Leaflet logo" width="500" height="500"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/PaulLeCam">
PaulLeCam
</a> / <a href="proxy.php?url=https://github.com/PaulLeCam/react-leaflet">
react-leaflet
</a>
</h2>
<h3>
React components for Leaflet maps
</h3>
</div>
</div>
<h3>
12. React SVG morph
</h3>
<p>A library to morph SVG components one into another. Here an example showing the authors love for React โฅ!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--tcbwXbCy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://raw.githubusercontent.com/gorangajic/react-svg-morph/master/example.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--tcbwXbCy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://raw.githubusercontent.com/gorangajic/react-svg-morph/master/example.gif" alt="React SVG morph logo" width="250" height="222"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/gorangajic">
gorangajic
</a> / <a href="proxy.php?url=https://github.com/gorangajic/react-svg-morph">
react-svg-morph
</a>
</h2>
<h3>
๐ฎ morph your svg component one into another other
</h3>
</div>
</div>
<h3>
13. React Cosmos
</h3>
<p>A development environment for building scalable, high-quality user interfaces. Not exactly the React logo, but both logos show some kind of cosm ๐! Don't they?</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s---eYPtvd---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/react-cosmos/react-cosmos/master/website/static/cosmonaut128.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s---eYPtvd---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/react-cosmos/react-cosmos/master/website/static/cosmonaut128.png" alt="React Cosmos logo" width="128" height="128"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/react-cosmos">
react-cosmos
</a> / <a href="proxy.php?url=https://github.com/react-cosmos/react-cosmos">
react-cosmos
</a>
</h2>
<h3>
Sandbox for developing and testing UI components in isolation
</h3>
</div>
</div>
<h3>
14. Reactotron
</h3>
<p>An app for inspecting React JS and React Native apps. Hello again color gradients ๐ !</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--juX0Lm3m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/infinitered/reactotron/master/docs/images/readme/Reactotron-128.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--juX0Lm3m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/infinitered/reactotron/master/docs/images/readme/Reactotron-128.png" alt="Reactotron logo" width="126" height="127"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/infinitered">
infinitered
</a> / <a href="proxy.php?url=https://github.com/infinitered/reactotron">
reactotron
</a>
</h2>
<h3>
A desktop app for inspecting your React JS and React Native projects. macOS, Linux, and Windows.
</h3>
</div>
</div>
<h3>
15. React Styleguidist
</h3>
<p>As we've already seen for Vue.js, here is the React version of the Styleguidist with a completely different logo... ๐!</p>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc88x79o3o80ptiwlxy5z.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc88x79o3o80ptiwlxy5z.png" alt="React Styleguidist logo" width="543" height="370"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/styleguidist">
styleguidist
</a> / <a href="proxy.php?url=https://github.com/styleguidist/react-styleguidist">
react-styleguidist
</a>
</h2>
<h3>
Isolated React component development environment with a living style guide
</h3>
</div>
</div>
<h2>
Angular
</h2>
<p>At last let's see what's out there for Angular. Here is the original logo:</p>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzst75eviwu3pcvmibjaq.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzst75eviwu3pcvmibjaq.png" alt="Angular logo" width="300" height="300"></a></p>
<h3>
16. NG Bootstrap
</h3>
<p>Bootstrap 4 Angular widgets. The original logo in layers and with another letter ๐ก!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--uOjNx500--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ng-bootstrap.github.io/img/logo-stack.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--uOjNx500--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://ng-bootstrap.github.io/img/logo-stack.png" alt="NG Bootstrap logo" width="512" height="512"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/ng-bootstrap">
ng-bootstrap
</a> / <a href="proxy.php?url=https://github.com/ng-bootstrap/ng-bootstrap">
ng-bootstrap
</a>
</h2>
<h3>
Angular powered Bootstrap
</h3>
</div>
</div>
<h3>
17. Awesome Angular
</h3>
<p>As we've already seen for Vue.js: Here is an awesome version of Angular. Why not simply reusing the original logo ๐ก!?</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--W1098DWi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/PatrickJS/awesome-angular/gh-pages/media/awesome-angular.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--W1098DWi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/PatrickJS/awesome-angular/gh-pages/media/awesome-angular.png" alt="Awesome Angular logo" width="691" height="190"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/PatrickJS">
PatrickJS
</a> / <a href="proxy.php?url=https://github.com/PatrickJS/awesome-angular">
awesome-angular
</a>
</h2>
<h3>
๐ A curated list of awesome Angular resources
</h3>
</div>
</div>
<h3>
18. ngx-materialize
</h3>
<p>Another Angular wrap around the Materialize library. The Angular logo materialized!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--MjUDpvhD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/sherweb/ngx-materialize/master/demo/src/assets/ngx-materialize-circle.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--MjUDpvhD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/sherweb/ngx-materialize/master/demo/src/assets/ngx-materialize-circle.png" alt="ngx-materialize logo" width="217" height="223"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/sherweb">
sherweb
</a> / <a href="proxy.php?url=https://github.com/sherweb/ngx-materialize">
ngx-materialize
</a>
</h2>
<h3>
Angular wrap around Materialize library
</h3>
</div>
</div>
<h3>
19. NG-ZORRO
</h3>
<p>A combination of Ant Design and Angular which is also visible in a unified logo ๐ค๐ป!</p>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhssomy65nu0apnq1rtxl.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhssomy65nu0apnq1rtxl.png" alt="NG-ZORRO logo" width="300" height="340"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/NG-ZORRO">
NG-ZORRO
</a> / <a href="proxy.php?url=https://github.com/NG-ZORRO/ng-zorro-antd">
ng-zorro-antd
</a>
</h2>
<h3>
Angular UI Component Library based on Ant Design
</h3>
</div>
</div>
<h3>
20. Angular-Cesium
</h3>
<p>A project using Cesium and Angular components to create mapping applications. A world map, a name, the Angular logo - that's all it takes ๐บ!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--m5-bvHTp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://angular-cesium.com/assets/angular_cesium3.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--m5-bvHTp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://angular-cesium.com/assets/angular_cesium3.png" alt="Angular-Cesium logo" width="320" height="340"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/articodeltd">
articodeltd
</a> / <a href="proxy.php?url=https://github.com/articodeltd/angular-cesium">
angular-cesium
</a>
</h2>
<h3>
JavaScript library for creating map based web apps using Cesium and Angular
</h3>
</div>
</div>
<h3>
21. Angular Progressbar
</h3>
<p>A nanoscopic progress bar that tries to convince users that something is happening. Angular logo loading in progress โณ!</p>
<p><a href="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F84kem3xnzzv1r91u0e9f.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F84kem3xnzzv1r91u0e9f.png" alt="Angular Progressbar logo" width="300" height="300"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/MurhafSousli">
MurhafSousli
</a> / <a href="proxy.php?url=https://github.com/MurhafSousli/ngx-progressbar">
ngx-progressbar
</a>
</h2>
<h3>
Angular progress bar โ
</h3>
</div>
</div>
<h3>
22. ngx-auth-firebaseui
</h3>
<p>Angular UI component for firebase authentication. Put something inside the famous Angular outline and it will be recognized as Angular project ๐ฅ!</p>
<p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ihVmEI3M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/AnthonyNahas/ngx-auth-firebaseui/master/assets/angular-material-extensions-logo.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ihVmEI3M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/AnthonyNahas/ngx-auth-firebaseui/master/assets/angular-material-extensions-logo.png" alt="ngx-auth-firebaseui logo" width="796" height="796"></a><br>
</p>
<div class="ltag-github-readme-tag">
<div class="readme-overview">
<h2>
<img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo">
<a href="proxy.php?url=https://github.com/AnthonyNahas">
AnthonyNahas
</a> / <a href="proxy.php?url=https://github.com/AnthonyNahas/ngx-auth-firebaseui">
ngx-auth-firebaseui
</a>
</h2>
<h3>
Angular Material UI component for firebase authentication
</h3>
</div>
</div>
<h2>
Wrap it up
</h2>
<p>I hope I was able to show some of the creativity in Open Source and you are now motivated to fork something or create your own. This list could be continued forever. There are countless great OS projects out there.</p>
<p>A big big thanks again for everyone who contributes to OS - doesn't matter how much or how little! It's so good to have you.</p>
<p>If you want to feature a great OS project or one of your own, feel free to do so in the comments.</p>
<p><em>Published: 19th February 2020</em></p>
opensourcevuereactangular