<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by styfle on Medium]]></title>
        <description><![CDATA[Stories by styfle on Medium]]></description>
        <link>https://medium.com/@styfle?source=rss-3e147995dafb------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*gMe_yEEDPT0Iuzjg4i1zLA.jpeg</url>
            <title>Stories by styfle on Medium</title>
            <link>https://medium.com/@styfle?source=rss-3e147995dafb------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 18 Jun 2026 11:21:27 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@styfle/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Website Redesign 3.0]]></title>
            <link>https://medium.com/@styfle/website-redesign-3-0-cf3c9a737e0c?source=rss-3e147995dafb------2</link>
            <guid isPermaLink="false">https://medium.com/p/cf3c9a737e0c</guid>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[styfle]]></dc:creator>
            <pubDate>Sun, 10 May 2020 02:48:32 GMT</pubDate>
            <atom:updated>2020-05-10T04:19:53.908Z</atom:updated>
            <content:encoded><![CDATA[<p>It’s been a few years, well <a href="https://styfle.dev/blog/website-redesign-2-0">5 years</a>, since the last time I redesigned my website and roughly 2 years since my last blog post, excluding work related <a href="https://vercel.com/blog/social-og-image-cards-as-a-service">posts</a>.</p><h3>History</h3><p>A little history behind my personal website…</p><p>I purchased <a href="https://www.ceriously.com">ceriously.com</a> in 2010 because owning a dot com was <a href="https://answers.yahoo.com/question/index?qid=20080104203608AAhuSDZ">“da bomb”</a> as we used to say back then. I wanted a place to host personal projects and anyone who was cool owned their own domain. Maybe I would pick up blogging too. Who doesn’t like to talk about themselves?</p><p>I cobbled together some PHP pages and uploaded some .jar files via FTP because Java was a great way to distribute software back then (narrator: it is not). FTP was fine but then Git started becoming popular so I decided to setup SSH so I could git push to deploy my website.</p><p>For new projects, I found myself using GitHub instead of my personal website because it was much easier to manage source code as well as binary downloads (now called Releases). I started linking from my personal website to GitHub because all of the information was already there.</p><h3>Requirements</h3><p>Before I could rewrite my website from scratch, I made a few goals:</p><ol><li>Fast — perf matters, no one waits for a blog that takes several seconds to load</li><li>No PHP — embrace JavaScript TypeScript and React</li><li>GitHub — must fetch my projects from GitHub API as source of truth</li><li>Dark Mode — must support both Light Mode and Dark Mode based on system preference</li><li>Markdown — must be able to author blog posts with Markdown</li><li>Domain — must use a sweet gTLD like <a href="https://get.dev">.dev</a></li><li>Deploy — must use be hosted on GitHub and use git push to deploy</li></ol><h3>Solution</h3><p>I decided to use <a href="https://nextjs.org">Next.js</a> because of a recent <a href="https://nextjs.org/blog/next-9-3#next-gen-static-site-generation-ssg-support">SSG feature</a> that feels like SSR but it renders pages at build time. This allowed me to check off number 1 and 2 from the list because I could use TypeScript with React and ensure fast page loads because the generated pages would be static HTML. Next.js also hands <a href="https://nextjs.org/docs/api-reference/next/link">client-side transitions</a> which avoids a complete reload when navigating between pages.</p><p>For number 3, I utilized Next.js to fetch my projects at build time from the <a href="https://developer.github.com/v3/repos/#list-repositories-for-the-authenticated-user">GitHub REST API</a> using a personal access token. I didn’t want to show private or archived repositories so those are filtered out in the query.</p><p>I implemented support for Dark Mode and Light Mode by using the CSS media query prefers-color-scheme. It looks something like this:</p><p>The beauty here is that this media query respects the user’s system preference so enabling <a href="https://support.apple.com/en-us/HT208976">Appearance Auto</a> in macOS Catalina will use the light appearance during the day, and the dark appearance at night. No more burning your eyes out of their sockets.</p><p>In order to implement Markdown blog post authoring, I reached for <a href="https://github.com/markedjs/marked">Marked</a>, a project I help maintain that parses markdown and converts it to HTML. And, as you may have guessed, I used Next.js <a href="https://nextjs.org/docs/routing/introduction#dynamic-route-segments">dynamic route segments</a> to dynamically generate a page for each blog post. Is there anything Next.js can’t do?</p><p>The domain was easy. I actually purchased <a href="https://twitter.com/styfle/status/1101238620982308864">styfle.dev</a> a year ago because .dev is the new hotness. <a href="https://vercel.com/domains">Vercel</a> makes it really easy to purchase a domain and assign it to a project in seconds.</p><p>Which brings me to my last step, deployment. I set up <a href="https://vercel.com/github">Vercel GitHub Integration</a> with a few clicks so that each time I git push to my <a href="https://github.com/styfle/styfle.dev">repository</a>, a new deployment is created. The best part here is that Vercel will deploy Pull Requests to a Preview URL and even take screenshots of the modified pages using the <a href="https://vercel.com/integrations/deploy-summary">Deploy Summary Integration</a>. For example, see <a href="https://github.com/styfle/styfle.dev/pull/13">PR 13</a>.</p><h3>Conclusion</h3><p>Overall, I’m happy with the new design and productivity boost. Perhaps I’ll start blogging again. If you want to see the source code for my website, you can find it on <a href="https://github.com/styfle/styfle.dev">GitHub</a>.</p><p><em>Originally published at </em><a href="https://styfle.dev/blog/website-redesign-3"><em>https://styfle.dev</em></a><em> on May 9, 2020.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cf3c9a737e0c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ES6 Proxy and Localization]]></title>
            <link>https://medium.com/hackernoon/es6-proxy-and-localization-c1269bbc0a26?source=rss-3e147995dafb------2</link>
            <guid isPermaLink="false">https://medium.com/p/c1269bbc0a26</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[localization]]></category>
            <category><![CDATA[proxy]]></category>
            <category><![CDATA[internationalization]]></category>
            <category><![CDATA[es6]]></category>
            <dc:creator><![CDATA[styfle]]></dc:creator>
            <pubDate>Mon, 01 Jan 2018 00:00:00 GMT</pubDate>
            <atom:updated>2018-01-01T21:07:30.595Z</atom:updated>
            <content:encoded><![CDATA[<p>Maybe you’ve heard of JavaScript Proxy and think, “Hey that’s cool and such, but what should I use it for?” Don’t worry, I thought this too until recently when I needed a catch-all solution. And BEHOLD, the indirect intermediary known only as “Proxy” arose from the ashes and set ablaze all Text Editors throughout the known universe.</p><p>In my use case, I wanted to pass back an object (more like a dictionary) that would contain key/value pairs for each localized string in the application. But the magic sauce here is that any missing string should return a See-No-Evil monkey emoji (🙈) because that means the developer mistyped a letter or maybe the string wasn’t translated at all! The monkey will not judge you.</p><p>Let’s look at some example JSON that is emitted when a good ol’ chap from across the pond visits our application (someone using en-GB).</p><pre>{<br>  &quot;color&quot;: &quot;Colour&quot;,<br>  &quot;elevator&quot;: &quot;Lift&quot;,<br>  &quot;pants&quot;: &quot;Trousers&quot;<br>}</pre><p>At first, you might think that the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get">ES5 Getter</a> could solve our problem because you can override a property (such as elevator) and check if there is no value defined. But what about the keys you don&#39;t know about? You don&#39;t know what you don&#39;t know.</p><p>Enter the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy">Proxy</a>, where Bruce Lee plays a web developer determined to help capture the missing keys responsible for the death of his sister.</p><pre>let obj = JSON.parse(json);<br>let l10n = new Proxy(obj, {<br>  get(target, name) {<br>    if (typeof target[name] === &#39;undefined&#39;) {<br>      console.error(`Localized string is missing: ${name}`);<br>      return &#39;🙈&#39;;<br>    }<br>    return target[name];<br>  }<br>});</pre><p>We call the localization object l10n because we&#39;re lazy and this abbreviation is commonly used according to <a href="https://en.wikipedia.org/wiki/Internationalization_and_localization#Naming">Wikipedia</a> and other lazy devs. Ain&#39;t nobody got time for typing. Why am I writing this article anyway?</p><p>Now back to the topic of Proxy usage…let’s talk about React.</p><p>React is great and you should use it because the internet told you so and that one blogger blogged about it on their weblog so don’t challenge the blog. Embrace the blogosphere.</p><pre>const SelectAColor = (props) =&gt; (&lt;div&gt;<br>  &lt;label&gt;{props.l10n.color}:&lt;/label&gt;<br>  &lt;select&gt;{props.colors.map(c =&gt;<br>    &lt;option value={c}&gt;<br>      {c}<br>    &lt;/option&gt;)}<br>  &lt;/select&gt;<br>&lt;/div&gt;);</pre><p>Now that we have a React component, let’s see how it would render for users from different countries.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/460/0*B2GWWw47m8UwewT2.png" /></figure><p>USA looks A-OK! Great Britain looks great! Mexico is ¡Ay, caramba! We forgot to translate into Spanish! The monkey does not lie but the monkey is forgiving.</p><p>The same would happen if you misspelled props.l10n.color for example props.l10n.colr in which case, the monkey would visit you again, shielding its eyes from your incompetence.</p><p>If you would like to see a demo, visit <a href="https://codesandbox.io/s/48lknyyo47">CodeSandbox</a> to see the code in action and witness the magnificent monkey madness!</p><p><em>Originally published at </em><a href="https://www.ceriously.com/blog/post.php?id=2018-01-01-es6-proxy-localization.md"><em>www.ceriously.com</em></a><em> on January 1, 2018.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c1269bbc0a26" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/es6-proxy-and-localization-c1269bbc0a26">ES6 Proxy and Localization</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ES6 Modules Today With TypeScript]]></title>
            <link>https://medium.com/hackernoon/es6-modules-today-with-typescript-22969cd360f0?source=rss-3e147995dafb------2</link>
            <guid isPermaLink="false">https://medium.com/p/22969cd360f0</guid>
            <category><![CDATA[es2015]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[es6]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[es2017]]></category>
            <dc:creator><![CDATA[styfle]]></dc:creator>
            <pubDate>Mon, 16 Oct 2017 00:00:00 GMT</pubDate>
            <atom:updated>2017-10-20T16:17:16.602Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DM02gE7XW4dVDm2yBgl--w.jpeg" /><figcaption>Two work horses represent both ESM and CJS builds</figcaption></figure><p>Today, in 2017, many evergreen browsers support ES6 Modules out of the box. Some browsers have it hidden behind a flag, including Node.js. But is it possible to support old and new environments with the same npm package? Yes!</p><blockquote><em>Editor’s Note: ES6 Modules are sometimes referred to as ES2015 Modules, or ESM, or </em><em>module scripts, or sometimes even by the extension </em><em>.mjs pronounced &quot;Michael Jackson Scripts&quot;. We are all talking about the same thing so don&#39;t get confused if you hear different terms.</em></blockquote><p>I won’t go over the merits of using ES6 Modules or why TypeScript is awesome because there have been many blog posts describing these at length. Instead, I will focus on publishing a package to npm that is written in TypeScript but deployed as .mjs (ESM) and .js (CommonJS) so any consumer can use your package!</p><h3>Getting Started</h3><p>The first step is to setup your tsconfig.json file so that TypeScript will use the latest and greatest JavaScript features like so:</p><pre>{<br>  &quot;compilerOptions&quot;: {<br>    &quot;module&quot;: &quot;es2015&quot;,<br>    &quot;target&quot;: &quot;ES2017&quot;,<br>    &quot;rootDir&quot;: &quot;src&quot;,<br>    &quot;outDir&quot;: &quot;dist&quot;,<br>    &quot;sourceMap&quot;: false,<br>    &quot;strict&quot;: true<br>  }<br>}</pre><p>Obviously, we want modules to be es2015 because hey, its in the title of this article so we have to address it at some point! Let&#39;s target es2017 so we can use async and await keywords like a JS Ninja. You can name your rootDir and outDir to whatever you want, but its a bit of a convention to use dist for output in JS Land. Source Maps are optional but I like to turn them off until I need them. Strict Mode is also optional but it&#39;s easier to start strict and get a little loosey goosey if you need too later. I highly recommend enabling it since it is disabled by default.</p><h3>Wiring It Up</h3><p>Now we can discuss the package.json file. Here&#39;s an example for a package called <a href="https://github.com/styfle/copee">copee</a>:</p><pre>{ <br>  &quot;name&quot;: &quot;copee&quot;,<br>  &quot;version&quot;: &quot;1.0.0&quot;,<br>  &quot;description&quot;: &quot;Copy text from browser to clipboard...natively!&quot;,<br>  &quot;repository&quot;: &quot;styfle/copee&quot;,<br>  &quot;files&quot;: [ &quot;dist&quot; ],<br>  &quot;main&quot;: &quot;dist/copee&quot;,<br>  &quot;types&quot;: &quot;dist/copee.d.ts&quot;,<br>  &quot;scripts&quot;: {<br>    &quot;mjs&quot;: &quot;tsc -d &amp;&amp; mv dist/copee.js dist/copee.mjs&quot;,<br>    &quot;cjs&quot;: &quot;tsc -m commonjs&quot;,<br>    &quot;build&quot;: &quot;npm run mjs &amp;&amp; npm run cjs&quot;<br>  },<br>  &quot;devDependencies&quot;: {<br>    &quot;typescript&quot;: &quot;^2.5.3&quot;<br>  }<br>}</pre><p>The first four lines define the package name, version, description, and GitHub repository which are self explainatory.</p><p>Next, we define files which we simply define as a single folder, dist. These are the files that will be published to npm.</p><p>The entry point into your package is defined as main and this is where the magic happens. Notice there is no file extension (such as .js) as one might expect. This will allow Node to pick the file based on the way the consumer is importing your package--either legacy CJS or the new ESM.</p><p>Next is types which is necessary for consumers who want to import via TypeScript. If you&#39;re writing your package in TypeScript, you should most definitely include types for your fellow TS users to get type saftey! Seriously, it&#39;s just the right thing to do.</p><p>Now comes the fun part: scripts. These are your build steps which can be run via npm run thenameofthescriptgoeshere. The first build step mjs uses the TypeScript Compiler (tsc) to build our code using the tsconfig.json file we defined earlier, plus a -d flag which emits our .d.ts type definitions. Also note the mv command which moves (or rather renames) the output file from .js to .mjs. This is our ESM output.</p><p>Our next script, cjs uses the TypeScript Compiler (tsc) to build the same source code but emit the output as a CommonJS module. This is the module system for Node.js and is understood by browserify, webpack, etc.</p><p>Lastly, we have devDependencies which are your build tools. In this case, all we need is typescript which includes the tsc command used above.</p><h3>Node Usage</h3><p>I’m going to show you how to write a consumer that imports the package above. If you already use Node regularly, jump to the next section for ESM usage.</p><p>First, install the <a href="https://www.npmjs.com/package/copee">copee</a> package:</p><pre>npm install --save copee</pre><p>Then, create a index.js file with the following:</p><pre>const { toClipboard } = require(&#39;copee&#39;); console.log(&#39;CJS: We found a &#39;, typeof toClipboard);</pre><p>The new program can be executed like so:</p><pre>node index.js</pre><h3>Node ESM Usage</h3><p>I’m going to show you how to write a consumer that imports the <a href="https://www.npmjs.com/package/copee">copee</a> package above.</p><p>After installing <a href="https://www.npmjs.com/package/copee">copee</a>, create a index.mjs file. You must use the Michael Jackson Script extension (.mjs).</p><pre>import { toClipboard } from &#39;copee&#39;;<br>console.log(&#39;ESM: We found a &#39;, typeof toClipboard);</pre><p>The new program can be executed like so:</p><pre>node --experimental-modules index.mjs</pre><h3>Browser ESM Usage</h3><p>Node usage isn’t that spectacular because there have been modules since its inception, but the beauty of ESM is that the same code executing in a Node module will run unchanged in a browser! Yes, it’s true! Feast your eyes on this elegant code snippet below:</p><pre>&lt;script type=&quot;module&quot;&gt;<br>  import {<br>    toClipboard<br>  } from &#39;https://cdn.jsdelivr.net/npm/copee/dist/copee.mjs&#39;;</pre><pre>  $(&#39;#btn&#39;).on(&#39;click&#39;, () =&gt; {<br>    const win = toClipboard(&#39;Wow, &quot;copee&quot; works!&#39;);<br>      if (win) {<br>        // it worked, check your clipboard!<br>      }<br>  });<br>&lt;/script&gt;</pre><p>We have a new script type for module and we are using <a href="https://www.jsdelivr.com/">jsDelivr</a> to automatically host our code on a CDN. This makes it easy to write a single import line and use the <a href="https://www.npmjs.com/package/copee">copee</a> package in browsers all over the world!</p><h3>Legacy Browsers</h3><p>What about legacy browsers, you say? Not everyone supports ESM? Well this can be solved by bundling as UMD with rollup. After installing rollup, add this to the scripts section of your package.json file.</p><pre>{<br>  &quot;umd&quot;: &quot;rollup -i dist/copee.mjs -o dist/copee.umd.js -f umd -n copee&quot;<br>}</pre><p>You can include both ESM and UMD builds on the same page without conflicts. See the snippet below:</p><pre>&lt;script nomodule src=&quot;https://cdn.jsdelivr.net/npm/copee/dist/copee.umd.js&quot;&gt;&lt;/script&gt; &lt;script type=&quot;module&quot;&gt;<br>  import {<br>    toClipboard<br>  } from &#39;https://cdn.jsdelivr.net/npm/copee/dist/copee.mjs&#39;;<br>&lt;/script&gt;</pre><p>By using the nomodule attribute, you are telling new browsers to ignore the UMD script. By using type=module you are telling old browsers to ignore ESM. Now everyone wins!</p><p>You can see a working demo of this solution on the <a href="https://styfle.github.io/copee/">Demo page</a>.</p><p>Also, please checkout the <a href="https://github.com/styfle/copee">GitHub repo</a> for more details and of course, the working source code!</p><p><em>Originally published at </em><a href="https://www.ceriously.com/blog/post.php?id=2017-10-16-es6-modules-today-with-typescript.md"><em>www.ceriously.com</em></a><em> on October 16, 2017.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=22969cd360f0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/es6-modules-today-with-typescript-22969cd360f0">ES6 Modules Today With TypeScript</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Web Security: Best Practices in 2017]]></title>
            <link>https://medium.com/hackernoon/security-best-practices-in-2017-cfdf1784c0a2?source=rss-3e147995dafb------2</link>
            <guid isPermaLink="false">https://medium.com/p/cfdf1784c0a2</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[styfle]]></dc:creator>
            <pubDate>Mon, 10 Jul 2017 12:52:41 GMT</pubDate>
            <atom:updated>2017-07-17T01:35:18.704Z</atom:updated>
            <content:encoded><![CDATA[<p>I recently found out about <a href="https://observatory.mozilla.org">Mozilla Observatory</a> and ran <a href="https://www.ceriously.com">my website</a> through the tool. The results were depressing…a big, fat, ugly <strong>F</strong>. For those of you not familiar with <a href="https://en.wikipedia.org/wiki/Academic_grading_in_the_United_States">grading in the US</a>, an F is the lowest grade possible. It’s like a punch in the face to my pride.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NtpXVWlR1oMBd8rzDM9u6g.png" /><figcaption>Observatory results for ceriously.com</figcaption></figure><p>Okay, well every day is a learning experience so let’s dive a bit deeper and maybe you can learn something new too!</p><h3>Let’s Get Secure</h3><p>By now, you probably already have a free HTTPS certificate from the wonderful <a href="https://letsencrypt.org/">Let’s Encrypt</a> organization or another reputable Certificate Authority. But HTTPS is just one step in securing your website.</p><p>Mozilla Observatory provides a whole suite of tests to check your website for best practices such as HSTS, XSS preventative headers, and sub-resource integrity for any external assets. It will give you a score out of 100 and a letter grade to bolster your self confidence.</p><p>The reason for my F was simply ignorance. None of these features were implemented and I received a mere 5/100 score on Mozilla’s scale. My goal was to hit 90, which is considered an <strong>A</strong>.</p><p>Try it on your website now by visiting <a href="https://observatory.mozilla.org">https://observatory.mozilla.org</a></p><p>How did you do? If you’re like me, you might not be constantly updating your website, blog, or app so maybe your website failed too. No worries.</p><p>If you are using Apache as a web server, you can quickly learn from my mistakes and just grab the following .htaccess file and drop it in your web directory. Or view this <a href="https://gist.github.com/styfle/e5e54cb3156088b37729a626e1301b74">web.config</a> if your are more familiar with ASP.NET.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a756c5402a03fb9042d926f0e0e83d26/href">https://medium.com/media/a756c5402a03fb9042d926f0e0e83d26/href</a></iframe><p>The headers are taken straight from the Observatory results where you can read more about the intent and security implications (really, go read the docs). You might want to change the Content Security Policy to be a little more strict and protect against XSS if you website has any user input.</p><p>Below the headers, there is a redirect to make sure the browser is always redirected to <a href="https://www.*">https://www.*</a> This will make Google (and your visitors) hit the secure www sub-domain. This is good for security, and good for SEO.</p><p>I also changed &lt;script&gt; tag to include a sub-resource integrity which will avoid executing a malicious script if the CDN is compromised. This was easy because the jQuery CDN already supports this feature and provides the hash on their download page.</p><pre>&lt;script src=”https://code.jquery.com/jquery-2.2.4.min.js&quot; integrity=”sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=” crossorigin=”anonymous”&gt;&lt;/script&gt;</pre><p>If your CDN doesn’t provide this information, you can use a tool like <a href="https://www.srihash.org/">SRI Hash Generator</a>.</p><p>That wasn’t so bad. With the additional headers and one line of HTML, Observatory is reporting the coveted green <strong>A </strong>with a score of <em>90</em>!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*w1YyOfLKvOHOphI3M4z-KA.png" /></figure><h3>Compression and Caching</h3><p>Now that your website is secure, why not make it fast too?</p><p>Take a look at the &lt;ifmodule&gt; checks in the .htaccess file above.</p><p>The <em>deflate</em> header will compress assets such as html, css, and js before sending it over the network. This means first-time visitors will see your content faster.</p><p>The <em>expires</em> header will tell the browser to cache the assets for several days since they likely don’t change often enough to warrant a round trip to the server. This means that returning visitors will see your content really fast.</p><p>Adding these two settings gave me a 94/100 from <a href="https://developers.google.com/speed/pagespeed/insights/">Google PageSpeed Insights</a> on Desktop. Try it on your website and see how you do!</p><p><a href="https://www.ceriously.com/blog/post.php?id=2017-07-10-security-best-practices-2017.md">Let&#39;s Get Secure | ceriously.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cfdf1784c0a2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/security-best-practices-in-2017-cfdf1784c0a2">Web Security: Best Practices in 2017</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Promises in Node.js 8.x Core]]></title>
            <link>https://medium.com/front-end-weekly/promises-in-node-js-8-x-core-d6a8a93e85a2?source=rss-3e147995dafb------2</link>
            <guid isPermaLink="false">https://medium.com/p/d6a8a93e85a2</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[promises]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[styfle]]></dc:creator>
            <pubDate>Wed, 10 May 2017 01:59:16 GMT</pubDate>
            <atom:updated>2017-05-10T01:59:16.584Z</atom:updated>
            <content:encoded><![CDATA[<p>Promises are well-known in the JavaScript community since they landed in Chrome 32 (Jan 2014) and in Node.js 0.12 (Feb 2015). They were formally introduced as part of the ES6 (ES2015) spec and are even more important in 2017 due to the async/await primitives that landed in Chrome 55 (Dec 2016) and Node.js 7 (Feb 2017).</p><p>Ok so you already knew all that history because you’re a young, hip, state-of-the-art, JavaScript developer who writes hand-crafted, artisan-made code aged to perfection. <a href="https://www.youtube.com/watch?v=oJimiVFCjJ0">Big whoop</a>, wanna fight about it?</p><p>But did you know that Node.js 8 will have a Promise API shipped in core? No way? Too good to be true? Well yes, I may have fibbed a bit.</p><p>Node.js 8 will have a <em>utility</em> to “promisify” any core API. This is just as good and will <a href="https://medium.com/the-node-js-collection/keeping-the-node-js-core-small-137f83d18152">keep the Node.js core small</a>.</p><h3>How does it work?</h3><p>I’ll give you two easy steps: Require and Wrap.</p><ol><li>Require const promisify = require(&#39;util&#39;).promisify;</li><li>Wrap const stat = promisify(require(&#39;fs&#39;).stat);</li></ol><p>Ok so now you’re saying this is exactly what <em>bluebird</em> does because you’re a savvy, hipster code-monkey who started using Promises before they were cool.</p><p>You would be correct except that you’re missing how important this is! This means user-land dependencies are no longer needed to write async/await! Hurray! See the following code example.</p><h3>Get On With It!</h3><p>Here is is a simple example that updates an existing file or creates the file if it does not exist.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/118fef1c3cd700e289df9b2d80296dd1/href">https://medium.com/media/118fef1c3cd700e289df9b2d80296dd1/href</a></iframe><p>Some say this is callback hell, but we only went a couple layers deep so it’s really more like callback purgatory. Now let’s see how it looks with promisify!</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/85f00b6eb17f0752ac482e7d06931eab/href">https://medium.com/media/85f00b6eb17f0752ac482e7d06931eab/href</a></iframe><p>This code is asynchronous but there are no callbacks! The use if/else and try/catch is pretty intuitive and looks like synchronous code.</p><p>Now there is a little bit of boilerplate in order to promisify each function. So how about a helper function?</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2fae2e780e0a649bf6d36889e3e26665/href">https://medium.com/media/2fae2e780e0a649bf6d36889e3e26665/href</a></iframe><p>Not too shabby! Now it’s your turn to see what kind of async code you can cook up with Node.js 8!</p><p><a href="https://www.ceriously.com/blog/post.php?id=2017-05-09-nodejs-promisify.md">Promises in Node.js 8.x Core | ceriously.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d6a8a93e85a2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/front-end-weekly/promises-in-node-js-8-x-core-d6a8a93e85a2">Promises in Node.js 8.x Core</a> was originally published in <a href="https://medium.com/front-end-weekly">Frontend Weekly</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>