<?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 Jay Schwane on Medium]]></title>
        <description><![CDATA[Stories by Jay Schwane on Medium]]></description>
        <link>https://medium.com/@jrschwane?source=rss-c76756b9e066------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*F8xOxktpfzdnIjZnDATZtA.jpeg</url>
            <title>Stories by Jay Schwane on Medium</title>
            <link>https://medium.com/@jrschwane?source=rss-c76756b9e066------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 19:53:44 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@jrschwane/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[Indexing and MongoDB Query Performance]]></title>
            <link>https://itnext.io/indexing-and-mongodb-query-performance-a8a6a64c4308?source=rss-c76756b9e066------2</link>
            <guid isPermaLink="false">https://medium.com/p/a8a6a64c4308</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[mongodb]]></category>
            <category><![CDATA[database]]></category>
            <dc:creator><![CDATA[Jay Schwane]]></dc:creator>
            <pubDate>Tue, 27 Feb 2018 19:21:00 GMT</pubDate>
            <atom:updated>2018-02-28T14:46:24.699Z</atom:updated>
            <content:encoded><![CDATA[<p>This short post will look at the performance of MongoDB queries against indexed and non-indexed collections, for various (virtual) server hardware configurations. We’ll look at the performance gains possible through indexing and talk briefly about their implications. This is not meant to be a definitive treatment on the topic of indexing or MongoDB. Your mileage may vary.</p><p>We will spend nearly all our time in the <a href="https://docs.mongodb.com/getting-started/shell/client/">mongo shell</a>. This post assumes that the reader has MongoDB installed locally, and has basic familiarity with MongoDB and mongo shell commands. The mongo shell is a JavaScript environment; we’ll use basic JavaScript in the examples below.</p><p>For a nice introduction to MongoDB, refer to <a href="https://medium.com/chingu/an-overview-of-mongodb-mongoose-b980858a8994">An Overview of MongoDB &amp; Mongoose</a> by <a href="https://medium.com/u/ccde6aa9ae4f">Jim Medlock</a>.</p><h4>Indexes</h4><p><a href="https://docs.mongodb.com/manual/indexes/">MongoDB indexes</a> are defined at the collection level, and can be created on any field (or combination of fields) present in that collection’s documents. By default, MongoDB creates an index on the _id field. We can create additional indexes to support our application’s access patterns. This simply means that we should create indexes for fields that we commonly include in our queries. <a href="https://docs.mongodb.com/manual/applications/indexes/">See here</a> for more information on indexing strategies.</p><h4>Setup</h4><p>We need a database. In the mongo shell, the use command creates (or switches to) a specified database. We’ll call ours indexingdemo:</p><p>use indexingdemo</p><p>Now we need some documents. We’ll use JavaScript in the mongo shell to generate an array of 3 million documents. Then we can bulk-insert the array into the database. Our collection will consist of incrementing student IDs and random scores for quizzes, exams and homework.</p><p>I use a nested for loop to populate a docs array; 1 million outer iterations * 3 inner iterations = 3 million total documents:</p><pre>var docs = [];<br>for (var i = 0; i &lt; 1000000; i++) {<br>  var types = [&quot;quiz&quot;, &quot;exam&quot;, &quot;homework&quot;];<br>  for (var j = 0; j &lt; 3; j++) {<br>    docs.push({<br>      student : i,<br>      type    : types[j],<br>      score   : Math.round(Math.random()*100)<br>    });<br>  }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*WyARCvoTy0qvIfehLbzY5A.png" /><figcaption>Generating 3 million documents …</figcaption></figure><p>Then insert the array of documents into the scores collection (which will be created on the fly):</p><pre>db.scores.insert(docs)</pre><p>That could take a few minutes depending on the speed of your hardware. When finished, MongoDB will return a BulkWriteResult. The nInserted property should equal 3000000:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*343CFrUqD9TnH1OlBTt1LA.png" /><figcaption>… and the insertion results.</figcaption></figure><p>We can query our database now. For example, we may want to see all of one student’s scores:</p><pre>db.scores.find({ student: 585534 }).pretty()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*cwlwNE1dCLA5MLEX464fYQ.png" /><figcaption>Chain the .pretty() method for formatted results.</figcaption></figure><p>Our query returns 3 documents — one for each of the student’s quiz, exam, and homework scores.</p><p>Before creating our index, let’s get a performance baseline. We can chain the .explain() method to the end of our query, passing in &quot;executionStats&quot; to return detailed performance information:</p><pre>db.scores.find({ student: 585534 }).explain(&quot;executionStats&quot;)</pre><p>That produces a lot of output. Scroll up a bit to find the property executionTimeMillis. We’ll use this execution time when comparing test runs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*YlKV8uUIgOjuGO2ufdmw8Q.png" /><figcaption>Execution time: approx 1 second</figcaption></figure><p>Now let’s create our index. Assume that queries typically include both student and type fields. We will create a <a href="https://docs.mongodb.com/manual/core/index-compound/">compound index</a> on student and type. This will support efficient queries for just student or student and type.</p><pre>db.scores.createIndex({ student: 1, type: 1 })</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*eU_sdkACPj2iHHpHNx2xEw.png" /><figcaption>Create a compound index</figcaption></figure><p>Note the &quot;numIndexesBefore&quot; : 1 — that prior index is the one MongoDB automatically created for ObjectId.</p><p>Now let’s re-run the test query:</p><pre>db.scores.find({ student: 585534 }).explain(&quot;executionStats&quot;)</pre><p>You should notice that the query <em>feels</em> faster — it should complete almost instantaneously. Because — haha! — it does:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*2ZT0Dh3MqYb_LjnVDqL15g.png" /><figcaption>Yeah — zero milliseconds</figcaption></figure><p>Now, executionTimeMillis of 0ms doesn’t really mean it took <em>zero</em> time. If I re-run the query multiple times I occasionally see some non-zero results. Either way, the indexed query is <em>fast</em>.</p><p>The above results were obtained in a VirtualBox VM. Windows 7 Pro x64 host OS + Ubuntu 16.04 guest OS using 2 CPU cores (Intel Core i5–3470) and 4GB of RAM. Not elite hardware by today’s standards.</p><h4>Scaling</h4><p>Since this is a virtual machine and I have control over the system resources, I can examine how performance scales across various (virtual) hardware configurations by adjusting the VM’s settings. In VirtualBox this is as easy as moving some sliders around. Let’s play with CPU core count and RAM.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/831/1*T2qK3D1xpamx8LZ3YlLo7g.png" /><figcaption>What scaling?</figcaption></figure><p>The indexed results (in blue) for each configuration are to the left of each of the non-indexed results (in orange) — they’re not easy to see! Each bar in the chart represents the average of 5 runs for each of the following CPU/RAM combinations:</p><pre>                       Indexed avg     Non-Indexed avg<br>--------------------------------------------------------<br>2 cores, 4 GB RAM         0 ms             1100 ms<br>2 cores, 3 GB RAM         0 ms             1113 ms<br>2 cores, 2 GB RAM         0 ms             1062 ms<br>2 cores, 1 GB RAM         2 ms             1196 ms</pre><pre>1 cores, 4 GB RAM         1 ms             1102 ms<br>1 cores, 3 GB RAM         2 ms             1088 ms<br>1 cores, 2 GB RAM         1 ms             1061 ms<br>1 cores, 1 GB RAM         2 ms             1140 ms</pre><p>What’s going on here? First, we can generalize that our sample query’s performance is not bound by the number of CPU cores or system RAM ≥ 1GB. In all configurations, indexed queries execute within 1–2 ms of <em>zero</em> and non-indexed queries complete in a little over 1 second.</p><h4>Why?</h4><p>Without indexing MongoDB has to perform a full collection scan, which means hitting the disk(s). My host system has a single Crucial MX100 SATA3 SSD. I suspect the non-indexed results are limited by my disk I/O. To test this, I created a collection of 1.5 million documents (half the original size) and re-ran the queries. I did not test VM configurations other than the min/max configurations used above. The results below are averages of 5 runs:</p><pre>                      Indexed avg      Non-Indexed avg<br>--------------------------------------------------------<br>2 cores, 4 GB RAM         0 ms              <strong>497 ms</strong><br>1 cores, 1 GB RAM         1 ms              <strong>552 ms</strong></pre><p>Non-indexed queries against a collection of 1.5 million documents execute in about half a second. Compared to the 3 million document collection: half the documents = half the time. This supports my hypothesis re: full collection scans in a disk I/O limited environment.</p><p>But what about the lack of scaling for our indexed queries? Recall that our results are essentially 0ms regardless of hardware config. To answer this, let’s begin by looking at the size of our index:</p><pre>db.scores.totalIndexSize()</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*QC92ZivT7HbBSfjKfhC5zQ.png" /><figcaption>Index size (in bytes)</figcaption></figure><p>Our index is 85,639,168 bytes (81.67 MB). For best performance, <a href="https://docs.mongodb.com/manual/tutorial/ensure-indexes-fit-ram/">indexes should fit in available RAM</a>. And even with just 1 GB of system RAM there is plenty of available RAM to hold our index.</p><h4>Conclusions</h4><p>The main takeaway is obvious: <strong>create indexes to support your queries </strong>— the benefits are incredible! Otherwise queries require full collection scans, which are limited by your server’s disk subsystem I/O. Server CPU and RAM resources were less of a factor than expected. This is encouraging for those who use inexpensive products from VPS hosting providers like Digital Ocean and OVH.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a8a6a64c4308" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/indexing-and-mongodb-query-performance-a8a6a64c4308">Indexing and MongoDB Query Performance</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Writing Modular JavaScript — Pt 3]]></title>
            <link>https://medium.com/@jrschwane/writing-modular-javascript-pt-3-d6db23330641?source=rss-c76756b9e066------2</link>
            <guid isPermaLink="false">https://medium.com/p/d6db23330641</guid>
            <category><![CDATA[chingu]]></category>
            <category><![CDATA[gulp]]></category>
            <category><![CDATA[application-development]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Jay Schwane]]></dc:creator>
            <pubDate>Mon, 13 Mar 2017 21:20:36 GMT</pubDate>
            <atom:updated>2017-03-13T21:46:09.194Z</atom:updated>
            <content:encoded><![CDATA[<p>This is the third and final part in an introductory series on writing modular JavaScript applications. <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-1-b42a3bd23685">Part 1</a> explained why modularity is desirable and presented a modular application design structure. In <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-2-d7140d15c982">part 2</a>, we built a simple application based on that structure. We will conclude the series by preparing our project for deployment.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*qHpaZtyxjjJBTjJ4.jpg" /></figure><h3>Introduction</h3><p>We ended part 2 with a working modular web application. We wrote our modules and stylesheets as separate files, linked together through our index.html and bootstrapped by our app.js. This is an efficient and scalable development process for all the reasons discussed in part 1 of this series.</p><p>But it’s a process that produced eight separate files. Our browser has to open and maintain eight separate http requests to retrieve each of those files, and that’s before we include the hosted font or jQuery. Although our files are not large and modern browsers can make these requests in parallel, in a large application the cumulative latency of those requests would result in slower page loads. We can reduce the number of http requests through <a href="https://en.wikipedia.org/wiki/Concatenation">concatenatation</a>.</p><p>We can also increase performance through <a href="https://en.wikipedia.org/wiki/Minification_%28programming%29">minification</a>, a kind of compression where our function and variable names are replaced with smaller “tokens”, and all comments, white space and line breaks are removed. This results in smaller file sizes, which means less waiting for our users.</p><p>Our demo application includes a feature of es6/es2015: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals">template literals</a>. Template literals are amazingly useful, but their backtick delimiters cause problems for some code minifiers (including the one we will use). Additionally, browser support for es6/es2015 syntax is still evolving. We want to <a href="https://en.wikipedia.org/wiki/Source-to-source_compiler">transpile</a> our source code into traditional <em>every-browser-understands-it</em> es5 JavaScript.</p><p>Finally, imagine that we composed our stylesheets with SASS instead of CSS. Browsers do not natively understand SASS, so we want to convert that into regular CSS. We won’t actually rewrite our stylesheets — instead we’ll cheat a little for demonstration purposes. And while we’re at it, we should add all necessary vendor-prefixed selectors so different browsers render our application as expected.</p><p>That’s a lengthy wish list. In this article we will use <a href="http://gulpjs.com/">Gulp</a> to provide solutions to each of those “wishes”. Gulp will process our source files and create new production-ready files that we can use when deploying our application.</p><p>Although our demo is a <em>front-end</em> application, because Gulp depends on <a href="https://nodejs.org/en/">Node.js</a> — typically used in <em>back-end</em> applications — the reader should have basic familiarity with Node and <a href="https://www.npmjs.com/">NPM</a> and have them installed locally. If you do not, please refer to the <a href="https://nodejs.org/en/download/package-manager/">official docs</a> for installation instructions.</p><p>Aside from a few Node-specific functions (require and pipe), the rest of our code will be written in regular es5 JavaScript. We will spend a bit of time in the command line, but you needn&#39;t be a CLI ninja.</p><h3>Application Structure</h3><p>Part 2 left us with the following file/folder structure:</p><pre>|-- /src<br>|    |<br>|    |-- /css<br>|    |    |<br>|    |    |-- app.css<br>|    |    |-- background.css<br>|    |    |-- greeting.css<br>|    |    |-- quote.css<br>|    |<br>|    |-- /js<br>|         |<br>|         |-- app.js<br>|         |-- background.js<br>|         |-- greeting.js<br>|         |-- quote.js<br>|<br>| index.html</pre><p>We will work mainly in the root of our project folder; Gulp will be working on all those /src files.</p><h3>Initialization</h3><p>Begin by initializing a new project with NPM. While in our project’s root directory, issue the following terminal command:</p><p>npm init -y</p><blockquote>If you omit the -y flag, NPM will ask you a series of questions about your project. The -y just tells NPM to accept all the default answers. npm init creates a new package.json file in your project&#39;s root directory, populated with the answers to npm init&#39;s questions.</blockquote><h3>Gulp</h3><p>Gulp is a Node.js <em>task runner</em> — it runs the tasks that we will later write. But by itself, Gulp cannot fulfill our introduction’s wish list. To do that, we first need to install some plugins to equip Gulp with new abilities.</p><p>But before that, we need to install Gulp. Gulp installs using NPM. There are three parts to its installation: install Gulp globally, then install the local project package, and finally install any needed plugins.</p><blockquote>You may need elevated privileges to install Gulp globally. You’ll know if your installation attempt errors out! In a Debian/Ubuntu environment you need to preface the installation command with sudo. Elevated privileges are not required to install the <em>local </em>Gulp package or any of the plugins we need.</blockquote><p>Install the global Gulp package using the following command (sudo as needed):</p><p>npm install gulp-cli -g</p><p>Once that has finished, install Gulp locally. Make sure you are still in your demo project’s root folder and issue the following command:</p><p>npm install gulp --save-dev</p><p>The --save-dev command-line switch registers the package as a <em>developer dependency</em> in package.json. If you open package.json now, you&#39;ll see that it has a new &quot;devDependencies&quot; : {...} property listing &quot;gulp&quot; as its sole dependency. All our various plugins will be registered here after we install them. Let&#39;s do that now.</p><p>We need the following plugins:</p><ol><li><a href="https://www.npmjs.com/package/gulp-concat">gulp-concat</a> — to concatenate (merge together) our separate JavaScript and SASS files</li><li><a href="https://www.npmjs.com/package/gulp-sass">gulp-sass</a> — to convert SASS files into traditional .css files</li><li><a href="https://www.npmjs.com/package/gulp-autoprefixer">gulp-autoprefixer</a> — to automatically add vendor-prefixed selectors to our stylesheets based on <a href="http://caniuse.com/">CanIUse</a> rules</li><li><a href="https://www.npmjs.com/package/gulp-babel">gulp-babel</a> — to transpile any es6 syntax into traditional es5 JavaScript using Babel</li><li><a href="https://www.npmjs.com/package/babel-preset-es2015">babel-preset-es2015</a> — a preset Babel configuration</li><li><a href="https://www.npmjs.com/package/gulp-sourcemaps">gulp-sourcemaps</a> — to generate a JavaScript <a href="https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/">sourcemap</a> so that when we’re debugging we can make sense of our browser’s console output</li><li><a href="https://www.npmjs.com/package/gulp-uglify">gulp-uglify</a> — to minify our JavaScript</li></ol><p>We install these plugins using NPM, again using the --save-dev switch to add each module to package.json. You can install each individually or all at once:</p><p>npm install gulp-concat gulp-sass gulp-autoprefixer gulp-babel babel-preset-es2015 gulp-sourcemaps gulp-uglify --save-dev</p><p>You may have noticed that a node_modules folder was created in your project’s root directory. NPM stores everything required by our dependencies in there. We will not need to touch anything in node_modules.</p><blockquote>If you use Git for version control, now would be a good time to add node_modules/ to your .gitignore file. There&#39;s no reason for us to track or push those files to a remote repository. Should they be deleted, we can easily recreate them with a single npm install command.</blockquote><p>Our &quot;devDependencies&quot; object should now look like this (version numbers current as of publication date):</p><pre>&quot;devDependencies&quot;: {<br>  &quot;babel-preset-es2015&quot;: &quot;^6.22.0&quot;,<br>  &quot;gulp&quot;: &quot;^3.9.1&quot;,<br>  &quot;gulp-autoprefixer&quot;: &quot;^3.1.1&quot;,<br>  &quot;gulp-babel&quot;: &quot;^6.1.2&quot;,<br>  &quot;gulp-concat&quot;: &quot;^2.6.1&quot;,<br>  &quot;gulp-sass&quot;: &quot;^3.1.0&quot;,<br>  &quot;gulp-sourcemaps&quot;: &quot;^2.4.1&quot;,<br>  &quot;gulp-uglify&quot;: &quot;^2.1.0&quot;<br>}</pre><p>Gulp has everything it needs to process our JavaScript and SASS files. But before we can start writing tasks, we have to create a <strong>gulpfile</strong> to contain them. Create a new gulpfile.js in your project’s root directory and begin by importing our plugin modules:</p><pre>/* gulpfile.js */</pre><pre>var gulp         = require(&#39;gulp&#39;),<br>    concat       = require(&#39;gulp-concat&#39;),<br>    sass         = require(&#39;gulp-sass&#39;),<br>    autoprefixer = require(&#39;gulp-autoprefixer&#39;),<br>    sourcemaps   = require(&#39;gulp-sourcemaps&#39;),<br>    uglify       = require(&#39;gulp-uglify&#39;),<br>    babel        = require(&#39;gulp-babel&#39;);</pre><p>We’ll build our tasks below those module assignments.</p><h3>Processing CSS</h3><p>We want Gulp to concatenate our separate stylesheets, convert SASS to CSS, add any necessary vendor-prefixed selectors and output the result as a single file. But wait — we don’t actually have any SASS. Lucky for us, traditional CSS is also valid SASS, so we can fake it by just renaming our file extensions. In our project’s /src/css/ folder, rename all the .css files to .scss:</p><pre>|-- /src<br>|    |<br>|    |-- /css<br>|    |    |<br>|    |    |-- app.scss<br>|    |    |-- background.scss<br>|    |    |-- greeting.scss<br>|    |    |-- quote.scss</pre><p><em>Et voilà: SASS!</em></p><p>We’re <em>finally</em> ready to write our first Gulp task. Gulp tasks are methods that take two arguments: the task’s name (as a string) and an anonymous callback function:</p><pre>// example<br>gulp.task(&#39;taskName&#39;, function () {</pre><pre>    // do stuff</pre><pre>});</pre><p>Create a styles task in our gulpfile.js below the module assignments:</p><pre>/* gulpfile.js */</pre><pre>var gulp         = require(&#39;gulp&#39;),<br>    concat       = require(&#39;gulp-concat&#39;),<br>    sass         = require(&#39;gulp-sass&#39;),<br>    autoprefixer = require(&#39;gulp-autoprefixer&#39;),<br>    sourcemaps   = require(&#39;gulp-sourcemaps&#39;),<br>    uglify       = require(&#39;gulp-uglify&#39;),<br>    babel        = require(&#39;gulp-babel&#39;);<br></pre><pre>// process stylesheets<br>gulp.task(&#39;styles&#39;, function () {</pre><pre>  gulp.src(&#39;src/css/**/*.scss&#39;)<br>    .pipe(concat(&#39;quote-app.scss&#39;))<br>    .pipe(sass().on(&#39;error&#39;, sass.logError))<br>    .pipe(autoprefixer({<br>      browsers: [&#39;last 2 versions&#39;]  // config object<br>    }))<br>    .pipe(gulp.dest(&#39;dist/css&#39;));</pre><pre>});</pre><p>Inside the task’s callback, we first give gulp.src() the location of our .scss files. The strange-looking /**/ wildcard instructs Gulp to look for matching files in /src/css <em>and its subfolders</em>. This is especially handy if you organized your project folders <em>by feature</em>. Then we .pipe() those source files through each of our plugins, processing them along the way:</p><ol><li>The separate .scss source files are first concatenated into a single quote-app.scss file</li><li>that file is then converted to a standard .css file</li><li>then vendor-prefixed selectors are added based on the config object (ours targets the two most-recent browser versions)</li><li>finally, the processed CSS file is written to /dist/css/ (Gulp will create folders if they don&#39;t already exist)</li></ol><p>Task #1: <em>done</em>. Run it from your terminal: gulp styles</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/722/0*KYKqqYH6zgzX7KXh.png" /></figure><p>Gulp created new file /dist/css/quote-app.css - take a look at it in your editor. All of our separate .scss files were merged, converted to .css and vendor-prefixed (specifically the <em>flexbox</em> properties):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/603/0*-LQj83IGFW2V8m3b.png" /></figure><p>In index.html, we can now replace the four separate links to our original /src/css/ files with a single &lt;link&gt; to our new /dist/css/quote-app.css:</p><pre>&lt;!-- ===================== css ====================== --&gt;<br>&lt;link rel=&quot;stylesheet&quot; href=&quot;dist/css/quote-app.css&quot;&gt;</pre><p>If you make changes to your source /src/css files, those changes will not propagate to the production /dist/css/quote-app.css file until you re-run gulp styles. That&#39;s annoying; we&#39;ll learn how to automate this process after dealing with our JavaScript.</p><h3>Processing JavaScript</h3><p>Before we write the task to process our JavaScript files, we need to address a potential issue. In the preceding section we passed a string (&#39;src/css/**/*.scss&#39;) to gulp.src() which grabbed any SASS files found in src/css and its subfolders. Gulp grabs them irrespective of any order. That&#39;s not necessarily a problem with SASS/CSS, especially since we namespaced our selectors. But order is critical with our JavaScript - <strong>our modules need to be initialized first</strong> so that their public methods exist to be called by app.js.</p><p>We enforce a specific file order by passing an array to gulp.src() consisting of our source file names. Create the new array below our imported modules:</p><pre>/* gulpfile.js */</pre><pre>var gulp         = require(&#39;gulp&#39;),<br>    concat       = require(&#39;gulp-concat&#39;),<br>    sass         = require(&#39;gulp-sass&#39;),<br>    autoprefixer = require(&#39;gulp-autoprefixer&#39;),<br>    sourcemaps   = require(&#39;gulp-sourcemaps&#39;),<br>    uglify       = require(&#39;gulp-uglify&#39;),<br>    babel        = require(&#39;gulp-babel&#39;);<br></pre><pre>// ordered array of javascript source files<br>var sourceJS = [<br>    &#39;src/js/background.js&#39;,<br>    &#39;src/js/greeting.js&#39;,<br>    &#39;src/js/quote.js&#39;,<br>    &#39;src/js/app.js&#39;        // must come last!<br>];</pre><p>Now add a scripts task below the existing styles task:</p><pre>/* gulpfile.js */</pre><pre>/* ... snip ... */</pre><pre>// process scripts<br>gulp.task(&#39;scripts&#39;, function () {</pre><pre>  gulp.src(sourceJS)       // &lt;-- note new array<br>    .pipe(sourcemaps.init())<br>    .pipe(concat(&#39;quote-app.min.js&#39;))<br>    .pipe(babel({<br>      presets: [&#39;es2015&#39;]  // babel config object<br>    }))<br>    .pipe(uglify())<br>    .pipe(sourcemaps.write())<br>    .pipe(gulp.dest(&#39;dist/js&#39;));</pre><pre>});</pre><p>After passing our source file array to gulp.src we .pipe() them from one plugin to the next, just like we did in our styles task:</p><ol><li>We first initialize the sourcemaps plugin</li><li>then we concatenate our separate files into a single quote-app.min.js file</li><li>Babel then transpiles any es6/es2015 to es5 JavaScript using our Babel preset</li><li>then we minify the transpiled code</li><li>the generated sourcemap is appended to the the end of our code</li><li>and finally the processed file is written to /dist/js/</li></ol><p>Task #2: <em>done</em>. Now run it in your terminal: gulp scripts</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/719/0*sahFUe7tPEEEt0uf.png" /></figure><p>Open the newly-created /dist/js/quote-app.min.js in your editor to see the effects of uglify:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/752/0*1nbqzLYX2sYUPS8t.png" /></figure><p>That illegible mess is functionally equivalent to all of our original source code. And if you think that’s funky, <em>check out line 2</em> — that nonsense is the sourcemap.</p><p>We can now replace the separate links to each of our application and module files with a single &lt;script&gt; tag:</p><pre>&lt;!-- ================ our javascript ================== --&gt;<br>&lt;script src=&quot;dist/js/quote-app.min.js&quot;&gt;&lt;/script&gt;</pre><blockquote>You may have noticed that the total size of our four original files (5.3kB) is actually <em>less </em>than our minified quote-app.min.js (12.3kB). That doesn’t seem right — what&#39;s going on? Our minified file is larger because we appended the sourcemap to it. If we omit sourcemaps, our minified file weighs in at a lithe 1.6kB.</blockquote><h3>Watching Files for Changes</h3><p>Manually re-running Gulp tasks after each minor code change adds an annoying interruption to our work flow. Gulp is supposed to make life easier. And it does, with one of Gulp’s greatest features: <strong>watchers</strong>. A watcher automatically runs tasks in response to events. We will write one that watches our source .scss files for changes, and runs our styles task in response.</p><p>But first we’ll create a default task to contain our watcher. Add it after our scripts task:</p><pre>/* gulpfile.js */</pre><pre>/* ... snip ... */</pre><pre>// default task contains our watcher<br>gulp.task(&#39;default&#39;, [&#39;styles&#39;], function() {</pre><pre>  // watch sass source files and convert on changes<br>  gulp.watch(&#39;src/css/**/*.scss&#39;, [&#39;styles&#39;]);</pre><pre>});</pre><p>This task’s construction is slightly different than our previous tasks. Notice the additional array passed to .task() as its second parameter — think of that as a list of the tasks we&#39;ll be using inside our default task. Inside the task&#39;s callback, gulp.watch() takes two parameters: the path to the files we want to watch, and an array of tasks to run when those files change (we have only one, our styles task).</p><p>Gulp default tasks can be executed with just gulp - we do not need to provide the task&#39;s name. Running this task initiates a watcher — it will execute but not terminate. It continues to run, watching for additional changes to our files:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*mYG9XumwfHc4F4qK.png" /></figure><p>So let’s change something. Our quote text currently turns red (color: #F33) on hover - let&#39;s try a blueish lavender instead. Make the following change to /src/css/quote.scss:</p><pre>#quote &gt; a:hover {<br>    color: #AAF;<br>}</pre><p>Keep an eye on your terminal window and save the file — Gulp will automatically re-run our styles task in response to the save event. Since that task generates a new /dist/css/quote-app.css, you can reload your browser window to see the changes:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Xf18Wrble5JlMGN8.jpg" /></figure><p>Good looking, <em>indeed</em>. We can now generate production-ready CSS automatically and without workflow interruption.</p><h3>Summarizing</h3><p>At the end of <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-2-d7140d15c982">part 2</a>, we had a perfectly functional modular application. We could have left it at that; we had achieved our design goals after all. But in the process, we introduced the potential for degraded performance.</p><p>Foreseeing that and the other issues in our introduction, we used Gulp to generate production-ready files in preparation for deployment. We added vendor-prefixed selectors to our CSS, transpiled our SASS and es6 to CSS and es5 JavaScript, and minified our scripts for additional performance. Finally, we added a watcher to automate CSS processing in response to changes to our source stylesheets.</p><p>There are other build tools — <a href="https://webpack.github.io/">Webpack</a> and <a href="https://gruntjs.com/">Grunt</a> are very popular and do similar things. We picked Gulp because of how quickly we can get results, allowing us to spend more time developing applications.</p><p>Just like we can reuse our modules between projects, we can <strong>reuse our gulpfile</strong> in any other project that shares the same modular file/folder structure — another reason to adopt modular application design patterns.</p><h3>Conclusion</h3><p>This wraps up this series on writing modular JavaScript. It describes a method for planning and building modular applications that is easy to understand and implement, and does not require any exotic syntax, libraries or frameworks. This makes it well-suited for beginning JavaScript programmers.</p><p>You might ask, “why <em>not</em> use a framework?” It’s a fair question — Angular for example, is modular by design. I have nothing against frameworks (and I <strong>love</strong> Angular), but time is precious. The modular design structure described in this series can be used by anyone immediately — it does not require that you spend time first gaining proficiency in a framework’s syntax and methods.</p><p>And ultimately, <em>modular design</em> is more about the process. Framework or no framework, the applications you build will benefit from a sound foundation in modular thinking. I hope you can translate these ideas to your own projects.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d6db23330641" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Writing Modular JavaScript — Pt 2]]></title>
            <link>https://medium.com/@jrschwane/writing-modular-javascript-pt-2-d7140d15c982?source=rss-c76756b9e066------2</link>
            <guid isPermaLink="false">https://medium.com/p/d7140d15c982</guid>
            <category><![CDATA[application-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[jquery]]></category>
            <category><![CDATA[chingu]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Jay Schwane]]></dc:creator>
            <pubDate>Sat, 11 Mar 2017 15:54:17 GMT</pubDate>
            <atom:updated>2017-03-14T21:32:30.472Z</atom:updated>
            <content:encoded><![CDATA[<p>This is part 2 in a series on writing modular JavaScript applications. <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-1-b42a3bd23685">Part 1</a> explained why modularity is desirable and presented a simple modular application design structure. In this part we will actually build an application using those principles. In <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-3-d6db23330641">part 3</a> we will use Gulp, the Node task runner, to prepare our application for deployment.</p><blockquote>Update — our greeting module now makes its displayMessage() method public. This change allows our random quote module to call it, rendering both features simultaneously.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*Zqm-ndPV5kp2OZJAIkIwRQ.jpeg" /></figure><h3>Introduction</h3><p>In this installment we will write a simple application applying the modular design concepts discussed in part 1 of the series. Our application will have multiple features, each controlled by its own module and written as a separate file.</p><p>Remember that modular code helps satisfy the design goals we set in part 1: encourage code reuse (modules “plug-in” to projects), enhance code legibility (smaller, more-focused code is easier to make sense of), and facilitate collaboration (modules reveal a standard API for easy interconnection).</p><p>The demo application will be simple by design — our goal is to understand the modular design concepts by putting them into practice, not to explore in-depth any features of the JavaScript language. You should have some familiarity with client-side / front-end JavaScript and jQuery. We use jQuery because it simplifies AJAX and DOM manipulation. We will use a few <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">promises</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals">es6 template literals</a>, but nothing too abstract or complex.</p><h3>Application Features</h3><p>We are going to build a random quote application. If you’ve worked through <a href="http://freecodecamp.com/">Free Code Camp</a>’s front-end curriculum, you have probably already built one. We’ll add a few extra features to ours for additional practice writing and wiring up modules.</p><p>Our application will consist of:</p><ol><li>a <strong>greeting</strong> feature that displays a different message based on the time of day</li><li>a <strong>random background image </strong>feature that asynchronously gets an image from a remote service and displays it as our background</li><li>a <strong>random quote </strong>feature that makes an AJAX request to a remote API, processes the response and displays the quote in our view.</li></ol><h3>Application Structure</h3><p>We start with a simplified version of the <em>by type</em> structure described in part 1 of this series. We don’t need a /dist folder or anything related to Node just yet — we’ll add those in part 3. Begin by creating a project directory that contains the following files and sub-folders:</p><pre>|— /src<br>|    |<br>|    |— /css<br>|    |<br>|    |— /js<br>|<br>| index.html</pre><h3>Initial Boilerplate</h3><p>Our index.html will load our separate application and module files and define some &quot;containers&quot; for our feature modules to hook into. For now, we need a basic html5 document with links to a font, our main stylesheet and jQuery, and &lt;div&gt;s for our features.</p><pre>&lt;!DOCTYPE html&gt;<br>&lt;html lang=&quot;en&quot;&gt;<br>&lt;head&gt;<br>  &lt;meta charset=&quot;UTF-8&quot;&gt;</pre><pre>  &lt;title&gt;Modular Random Quote Machine&lt;/title&gt;</pre><pre>  &lt;!-- ==================== fonts ===================== --&gt;<br>  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://fonts.googleapis.com/css?family=Roboto+Condensed&quot;&gt;</pre><pre>  &lt;!-- ===================== css ====================== --&gt;<br>  &lt;link rel=&quot;stylesheet&quot; href=&quot;/src/css/app.css&quot;&gt;</pre><pre>&lt;/head&gt;<br>&lt;body&gt;</pre><pre>  &lt;div id=&quot;background&quot;&gt;&lt;/div&gt;</pre><pre>  &lt;div class=&quot;container&quot;&gt;<br>    &lt;div id=&quot;greeting&quot;&gt;&lt;/div&gt;<br>    &lt;div id=&quot;quote&quot;&gt;&lt;/div&gt;<br>  &lt;/div&gt;</pre><pre>  &lt;!-- =============== vendor javascript ================ --&gt;<br>  &lt;script src=&quot;https://code.jquery.com/jquery-3.1.1.js&quot;&gt;&lt;/script&gt;</pre><pre>  &lt;!-- ================ our javascript ================== --&gt;</pre><pre>&lt;/body&gt;<br>&lt;/html&gt;</pre><p>Let’s create our application’s main stylesheet now too. Create a new file app.css in your /src/css/ folder:</p><pre>/* /src/css/app.css */</pre><pre>html,<br>body {<br>  margin: 0;<br>  padding: 0;<br>}</pre><pre>body {<br>  background-color: #222;<br>  color: #fff;<br>  font-family: &#39;Roboto Condensed&#39;, sans-serif;<br>}</pre><pre>.container {<br>  display: flex;<br>  height: 100vh;<br>  flex-direction: column;<br>  align-items: center;<br>  justify-content: center;<br>}</pre><p>Now we can start writing our feature modules.</p><h3>Random Background Feature</h3><p>Our application consists of three features, but what about those features — what do they need? You can easily structure your modules by answering that question.</p><p>For example, our backgrounds module needs to:</p><ol><li>cache DOM elements</li><li>asynchronously get an image</li><li>assemble an element</li><li>render that to the DOM</li><li>provide us a way to initialize it</li></ol><p>You can convert and use that list of requirement as pseudo code in your module — instant function documentation! Let’s write the module — create a new file background.js in your /src/js/ folder:</p><pre>/* /src/js/background.js */</pre><pre>var Background = (function() {</pre><pre>  &#39;use strict&#39;;</pre><pre>  // placeholder for cached DOM elements<br>  var DOM = {};</pre><pre>  /* =================== private methods ================= */</pre><pre>  // cache DOM elements<br>  function cacheDom() {<br>    DOM.$background = $(&#39;#background&#39;);<br>  }<br></pre><pre>  // coordinate async assembly of image element and rendering<br>  function loadImage() {</pre><pre>    var baseUrl = &#39;https://source.unsplash.com/category&#39;,<br>        cat     = &#39;nature&#39;,<br>        size    = &#39;1920x1080&#39;;</pre><pre>    buildElement(`${baseUrl}/${cat}/${size}`)<br>      .then(render);<br>  }</pre><pre><br>  // assemble the image element<br>  function buildElement(source) {</pre><pre>    var deferred = $.Deferred(function (task) {</pre><pre>      var image = new Image();</pre><pre>      image.onload = function () {<br>        task.resolve(image);<br>      };</pre><pre>      image.onerror = function () {<br>        task.reject();<br>      };</pre><pre>      image.src = source;</pre><pre>    });</pre><pre>    return deferred.promise();<br>  }</pre><pre>  <br>  // render DOM<br>  function render(image) { </pre><pre>    DOM.$background<br>      .append(image)<br>      .css(&#39;opacity&#39;, 1);<br>  }<br></pre><pre>  /* =================== public methods ================== */</pre><pre>  // main init method<br>  function init() {<br>    cacheDom();<br>    loadImage();<br>  }<br></pre><pre>  /* =============== export public methods =============== */<br>  return {<br>    init: init<br>  };</pre><pre>}());</pre><p>This module appends an &lt;img&gt; to our target &lt;div&gt; once it receives an image from <a href="https://source.unsplash.com/">unsplash</a>. There&#39;s a bit of promise voodoo going on in there, because getting the image is <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests">asynchronous</a> — we can&#39;t set an image’s src attribute until we actually have a image! So we have to wait; promises happen to excel at waiting. We&#39;ll see them again in the random quote feature.</p><p>Now that we have a module, we should load it with a &lt;script&gt; tag in index.html. But our app still won&#39;t do anything because we haven&#39;t written our app.js. You can manually call Background.init() in your browser’s console, but that’s … um, not the best user experience. Remember: app.js bootstraps our modules. Let&#39;s instruct it to do so — create a new file app.js in your /src/js/ folder:</p><pre>/* /src/js/app.js */</pre><pre>$(document).ready(function () {</pre><pre>  Background.init();</pre><pre>});</pre><p>That’s it for now — we’ll add more as we complete additional modules. Recap: our app.js has only one job — to call our modules’ public methods once the document has finished loading. At this point, you can launch index.html in your browser and it will fetch and display a random image. Yay — it works! Also boo — it looks like crap! Let&#39;s fix that with a bit of CSS.</p><blockquote>Just like we are writing separate JavaScript files for each module, we will write separate stylesheets for each feature. This makes it even easier to reuse a whole module —JjavaScript and CSS — in another application. Just copy both files. Don’t forget to &lt;link&gt; to the separate stylesheet(s) in the &lt;head&gt; of your index.html.</blockquote><p>Create a new file background.css in your /src/css/ folder:</p><pre>/* /src/css/background.css */</pre><pre>#background {<br>  position: fixed;<br>  left: 0;<br>  top: 0;<br>  height: 100vh;<br>  width: 100%;</pre><pre>  background-attachment: fixed;<br>  background-position: bottom center;<br>  background-repeat: no-repeat;<br>  background-size: cover;</pre><pre>  opacity: 0;<br>  transition: opacity 0.75s linear;</pre><pre>  z-index: -1;<br>}</pre><pre>#background &gt; img {<br>  height: 100vh;<br>  width: 100vw;<br>  object-fit: cover;<br>}</pre><p>The above CSS positions, sizes and anchors the image on the page, and sets the opacity of the containing &lt;div&gt; to 0 — meaning it will be invisible. The &lt;div&gt; begins life invisible so that our module&#39;s render() function can <em>fade-in</em> the background feature using a CSS opacity transition.</p><blockquote>It’s a good idea to <em>namespace</em> each selector in your module stylesheets. Otherwise you may accidentally override some other stylesheet’s rules. For example, above we always include our feature’s selector when referring to any child elements: #backgrounds &gt; img. We might have other modules with images, and we wouldn&#39;t want our background feature’s rules to affect them.</blockquote><p>That wraps up the random background feature — not too bad, right? The other modules follow a similar pattern.</p><h3>Greeting Feature</h3><p>Define the module’s requirements — this module needs to:</p><ol><li>cache DOM elements</li><li>determine the time of day</li><li>craft a greeting based on the time of day</li><li>render the greeting to our view</li><li>provide us some way to initialize it</li></ol><p>We’ll add a random name picker for fun. Create new file greeting.js in your /src/js/ folder:</p><pre>/* /src/js/greeting.js */</pre><pre>var Greeting = (function() {</pre><pre>  var DOM = {},<br>      names = [<br>        &#39;handsome&#39;,<br>        &#39;smarty pants&#39;,<br>        &#39;good looking&#39;,<br>        &#39;classy&#39;,<br>        &#39;ace&#39;,<br>        &#39;Mr Roboto&#39;<br>      ],<br>      dummy = selectName();<br></pre><pre>  /* =================== private methods ================= */</pre><pre>  // cache DOM elements<br>  function cacheDom() {<br>    DOM.$greeting = $(&#39;#greeting&#39;);<br>  }<br></pre><pre>  // pick a name from names array<br>  function selectName() {<br>    var ind = Math.floor(Math.random() * names.length);</pre><pre>    return names[ind];<br>  }<br></pre><pre>  // assemble time-based greeting message<br>  function makeMessage() {<br>    var timeOfDay,<br>        theDate = new Date(),<br>        theHour = theDate.getHours();</pre><pre>    if (theHour &lt; 12) {<br>      timeOfDay = &quot;morning&quot;;<br>    } else if (theHour &gt;= 12 &amp;&amp; theHour &lt; 17) {<br>      timeOfDay = &quot;afternoon&quot;;<br>    } else {<br>      timeOfDay = &quot;evening&quot;;<br>    }</pre><pre>    return `Good ${timeOfDay}, ${dummy}.`;  // :D<br>  }<br></pre><pre>  // render DOM<br>  function displayMessage() {<br>    DOM.$greeting<br>      .text(makeMessage());<br>  }<br></pre><pre>  /* =================== public methods ================== */</pre><pre>  // main init method<br>  function init() {<br>    cacheDom();<br>  }<br></pre><pre>/* =============== export public methods =============== */<br>  return {<br>    init: init,<br>    displayMessage: displayMessage<br>  };</pre><pre>}());</pre><p>This module crafts a custom greeting using a name from the names array and a specific message that depends on the current time. Our init() method just caches our DOM element. And we export two public methods: init and displayMessage. In a previous version of this article, we called displayMessage within init(). We now publish displayMessage separately because our quotes module needs to call it. This is explained in the Random Quote Feature section below.</p><p>Add a &lt;script&gt; tag to index.html for our new module, and include a call to its public init() method in app.js:</p><pre>/* /src/js/app.js */</pre><pre>$(document).ready(function () {</pre><pre>  Background.init();<br>  Greeting.init();</pre><pre>});</pre><p>Let’s quickly style our greeting. Add a new file greeting.css to our /src/css/ folder:</p><pre>/* /src/css/greeting.css */</pre><pre>#greeting {<br>  font-size: 4em;<br>  font-weight: bold;<br>  text-align: center;<br>  text-shadow: 0 0 30px #000;<br>}</pre><p>Reload thy browser and be greeted! On to our final feature…</p><h3>Random Quote Feature</h3><p>Like we did with our previous modules, begin by defining what this module needs to do:</p><ol><li>cache DOM elements</li><li>fetch a random quote from a remote API</li><li>process the JSON response</li><li>call our greeting module’s public Greeting.displayMessage() method</li><li>render the quote to the DOM</li><li>provide us some way to initialize it</li></ol><blockquote>Note: you may have difficulty getting the API to respond if you are not serving your application from a proper server. Both Chrome and Firefox threw up CORS errors when I loaded the static files directly in those browsers. Brackets’ <em>Live Preview</em> works fine. Hosting anywhere (GitHub pages, for example) would also work.</blockquote><p>Create a new file quote.js in your /src/js/ folder:</p><pre>/* /src/js/quote.js */</pre><pre>var Quote = (function () {</pre><pre>  &#39;use strict&#39;;</pre><pre>  var DOM = {};<br></pre><pre>  /* =================== private methods ================= */</pre><pre>  // cache DOM elements<br>  function cacheDom() {<br>    DOM.$quoteFeature = $(&#39;#quote&#39;);<br>    DOM.$quoteLink    = $(document.createElement(&#39;a&#39;));<br>    DOM.$author       = $(document.createElement(&#39;p&#39;));<br>  }<br></pre><pre>  // get random quote<br>  function getQuote() {</pre><pre>    var api = {<br>      endpoint: &#39;https://quotesondesign.com/wp-json/posts&#39;,<br>      params: {<br>        &#39;filter[orderby]&#39;       : &#39;rand&#39;,<br>        &#39;filter[posts_per_page]&#39;: 1,<br>        &#39;cachingHack&#39;           : (new Date()).getTime()<br>      }<br>    };</pre><pre>    $.getJSON(api.endpoint, api.params)<br>      .then(renderQuote)<br>      .catch(handleError);<br>  }<br></pre><pre>  // handle errors<br>  function handleError(err) {<br>    console.log(err);<br>  }<br></pre><pre>  // render<br>  function renderQuote(response) {</pre><pre>    // call Greeting module&#39;s public displayMessage() method<br>    Greeting.displayMessage();</pre><pre>    DOM.$quoteLink<br>      .attr(&#39;target&#39;, &#39;_blank&#39;)<br>      .attr(&#39;href&#39;, response[0].link)<br>      .html(response[0].content);</pre><pre>    DOM.$author<br>      .html(response[0].title);</pre><pre>    DOM.$quoteFeature<br>      .css(&#39;background-color&#39;, &#39;rgba(0, 0, 0, .2)&#39;)<br>      .attr(&#39;href&#39;, response[0].link)<br>      .attr(&#39;target&#39;, &#39;_blank&#39;)<br>      .html(DOM.$quoteLink)<br>      .append(DOM.$author);<br>  }</pre><pre>  /* =================== public methods ================== */<br>  function init() {<br>    cacheDom();<br>    getQuote();<br>  }<br></pre><pre>  /* =============== export public methods =============== */<br>  return {<br>    init: init<br>  };</pre><pre>}());</pre><p>We use promise syntax again to coordinate the timing of the .getJSON() AJAX response with subsequent function calls. In this case, once the request has successfully resolved, we .render() the quote (wrapped in an anchor tag) and author&#39;s name.</p><p>In a previous version of this article, our greeting module’s init() method called its own renderer (displayMessage()). Although that works, it results in a diminished user experience: the greeting renders immediately, and then the quote renders after a short delay. This is because the quote module can&#39;t render until it receives a quote from the API. We can do better.</p><p>Our modular structure makes it easy to improve upon the previous version. We refactored the greeting module above to export its displayMessage() method instead of calling it internally. That allows our quote module (or any other module) to call it. We added that call to renderQuote() so that both features render at the same time.</p><blockquote>Special thanks to Chris Coyier for granting permission to use his <a href="https://quotesondesign.com/api-v4-0/">Quotes on Design</a> API. In addition to curating all those quotes, Chris founded <a href="https://css-tricks.com/">CSS-Tricks</a> and co-founded <a href="http://codepen.io/">Codepen</a>.</blockquote><p>Add a &lt;script&gt; link for our random quote module to index.html and call the module’s public method in app.js:</p><pre>$(document).ready(function () {</pre><pre>  Background.init();<br>  Greeting.init();<br>  Quote.init();</pre><pre>});</pre><p>Almost done — we have one last file to write: the quote module’s stylesheet. Create a new file quote.css in your /src/css/ folder:</p><pre>/* /src/css/quote.css */</pre><pre>#quote {<br>  font-size: 1.5em;<br>  padding: .5em 1em;<br>  width: 80%;<br>  max-width: 720px;<br>  border-radius: 8px;<br>  text-shadow: 0 0 40px #000;<br>}</pre><pre>#quote &gt; a {<br>  color: #fff;<br>  text-align: justify;<br>  text-decoration: none;<br>}</pre><pre>#quote &gt; a:hover {<br>  color: #f33;<br>}</pre><pre>#quote p {<br>  padding: .25em 0;<br>  margin: 0;<br>}</pre><pre>#quote &gt; p {<br>  font-style: italic;<br>  text-align: right<br>}</pre><p>Add a link to the stylesheet in index.html and <strong>we are done</strong>. Our final index.html is a well-organized, logical foundation for our application:</p><pre>&lt;!DOCTYPE html&gt;<br>&lt;html lang=&quot;en&quot;&gt;<br>&lt;head&gt;<br>  &lt;meta charset=&quot;UTF-8&quot;&gt;</pre><pre>  &lt;title&gt;Modular Random Quote Machine&lt;/title&gt;<br>  <br>  &lt;!-- ==================== fonts ===================== --&gt;<br>  &lt;link rel=&quot;stylesheet&quot; href=&quot;<a href="https://fonts.googleapis.com/css?family=Roboto+Condensed">https://fonts.googleapis.com/css?family=Roboto+Condensed</a>&quot;&gt;</pre><pre>  &lt;!-- ===================== css ====================== --&gt;<br>  &lt;link rel=&quot;stylesheet&quot; href=&quot;src/css/background.css&quot;&gt;<br>  &lt;link rel=&quot;stylesheet&quot; href=&quot;src/css/greeting.css&quot;&gt;<br>  &lt;link rel=&quot;stylesheet&quot; href=&quot;src/css/quote.css&quot;&gt;<br>  &lt;link rel=&quot;stylesheet&quot; href=&quot;src/css/app.css&quot;&gt;</pre><pre>&lt;/head&gt;<br>&lt;body&gt;</pre><pre>  &lt;div id=&quot;background&quot;&gt;&lt;/div&gt;<br>  <br>    &lt;div class=&quot;container&quot;&gt;<br>      &lt;div id=&quot;greeting&quot;&gt;&lt;/div&gt;<br>      &lt;div id=&quot;quote&quot;&gt;&lt;/div&gt;<br>    &lt;/div&gt;</pre><pre>  &lt;!-- =============== vendor javascript ================ --&gt;<br>  &lt;script src=&quot;<a href="https://code.jquery.com/jquery-3.1.1.js">https://code.jquery.com/jquery-3.1.1.js</a>&quot;&gt;&lt;/script&gt;</pre><pre>  &lt;!-- ================ our javascript ================== --&gt;<br>  &lt;script src=&quot;src/js/background.js&quot;&gt;&lt;/script&gt;<br>  &lt;script src=&quot;src/js/greeting.js&quot;&gt;&lt;/script&gt;<br>  &lt;script src=&quot;src/js/quote.js&quot;&gt;&lt;/script&gt;<br>  &lt;script src=&quot;src/js/app.js&quot;&gt;&lt;/script&gt;<br>  <br>&lt;/body&gt;<br>&lt;/html&gt;</pre><h3>Summarizing</h3><p>If all went well, your browser should show you something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*crvwFZ0ba3gLjsYjfVB48g.jpeg" /></figure><p>We wrote a simple web application based on the modular design principles <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-1-b42a3bd23685">outlined previously</a>. Each feature’s application logic and CSS is contained in separate files, loaded by index.html and bootstrapped by our app.js. We used a systematic requirements-based approach to build each module. Our modules’ public methods are namespaced to avoid collisions in the global scope. Their CSS selectors are similarly namespaced to avoid colliding with any generic selectors.</p><p>A live demo of <a href="https://belcurv.github.io/medium/">this application is hosted here</a>. The code and markdown versions of the article can be found at <a href="https://github.com/belcurv/medium">the GitHub repo</a>.</p><p>At this point our application structure looks like this:</p><pre>|-- /src<br>|    |<br>|    |-- /css<br>|    |    |<br>|    |    |-- app.css<br>|    |    |-- background.css<br>|    |    |-- greeting.css<br>|    |    |-- quote.css<br>|    |<br>|    |-- /js<br>|         |<br>|         |-- app.js<br>|         |-- background.js<br>|         |-- greeting.js<br>|         |-- quote.js<br>|<br>| index.html</pre><p>Looking good! Time to collect on all those promised mint juleps.</p><h3>Up Next: Preparing for Deployment</h3><p>Our application, modules and stylesheets are working together. But the browser has to make a separate request for each of those eight separate files. While the files themselves are not large, the cumulative latency of all those requests delays application load time. In <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-3-d6db23330641">Part 3</a> we will prepare our application for deployment using Gulp to concatenate, transpile, and minify our files.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d7140d15c982" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Writing Modular JavaScript — Pt 1]]></title>
            <link>https://medium.com/@jrschwane/writing-modular-javascript-pt-1-b42a3bd23685?source=rss-c76756b9e066------2</link>
            <guid isPermaLink="false">https://medium.com/p/b42a3bd23685</guid>
            <category><![CDATA[application-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[modular]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[jquery]]></category>
            <dc:creator><![CDATA[Jay Schwane]]></dc:creator>
            <pubDate>Thu, 09 Mar 2017 20:59:33 GMT</pubDate>
            <atom:updated>2017-03-13T21:21:21.833Z</atom:updated>
            <content:encoded><![CDATA[<p>This is part 1 of a series on writing modular JavaScript applications. In <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-2-d7140d15c982">part 2</a>, we will actually build a simple modular application together. Finally, in <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-3-d6db23330641">part 3</a> we will use Gulp, the Node task runner, to prepare our files for deployment.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-N6S20UVCAhe_BgWScFQnA.jpeg" /></figure><h3>Introduction</h3><p>If you have so much as glanced at a computer programming language, you have surely heard the mantra: <strong>Don’t Repeat Yourself</strong>. Basically, if you find yourself writing the same snippet of code more than once, you are better off sticking that code inside a function instead. In this post, I will show you how we can extend that mantra beyond its use within a single file. We’ll apply the concept at the application level — within a single project and even across projects — by breaking monolithic applications into smaller, self-contained, reusable <strong>modules</strong>.</p><p>Maybe you want to use some previously-written utility in your new application — instead of rewriting the whole thing, you can just copy your file into your new project and link to it with a &lt;script&gt; tag. The time savings alone makes this a worthwhile endeavor.</p><p>But there’s another, possibly greater benefit to modular design: it makes <strong>collaborating with other people</strong> a whole lot easier. When you are working with a team of developers, where each of you is creating a part of a larger application, you will eventually need to merge all of those separate parts together. If you’ve adopted a modular design structure in advance, joining everything up at the end is trivially easy. Develop modular habits today and you’ll be the hero of your team tomorrow.</p><p>Finally, modular design patterns make it much easier to read your code. You should personally care about this because you (or others — see previous paragraph) will eventually have to make sense of code you previously wrote. The fewer lines of code, the quicker you and others can make sense of it. A module is <em>by definition</em> a smaller, focused part of some larger whole.</p><p>This article is aimed at beginning JavaScript developers who already have some experience with the language, but who may not yet know how to structure code into modules, or why the modular design pattern is valuable.</p><p>I assume that you have basic familiarity with client-side / front-end JavaScript. My examples use a small amount of jQuery, but no other libraries or frameworks are required to get started. I will mention IIFEs and closures, but not go into too much detail about them here.</p><h3>Application Structure</h3><p>A modular application begins with a solid file/folder structure. There are many ways to organize a project’s files. I tend to use one of two ways: either by <strong>type of file</strong> (css, js, assets, etc.) or by <strong>application feature</strong> (header, landing, login, about, footer, etc). On large projects, organizing <em>by feature</em> is almost a requirement. But we’re going to use the simpler <em>by type</em> system for this post.</p><pre>|— /dist<br>|    |<br>|    |— /js<br>|    |— /css<br>|    |— /assets<br>|<br>|— /src<br>|    |<br>|    |— /js<br>|    |   |<br>|    |   | app.js<br>|    |   | module1.js<br>|    |   | module2.js<br>|    |   | module3.js<br>|    |<br>|    |— /css<br>|    |   |<br>|    |   | style.css<br>|    |<br>|    |— /assets<br>|         |<br>|         | image.jpg<br>|         | etc.jpg<br>|<br>|— /node_modules<br>|<br>| .gitignore<br>| gulpfile.js<br>| package.json<br>| index.html</pre><p>Briefly:</p><ul><li>/dist - ultimately our production-ready files will live here. Gulp will create them later - we don&#39;t need to do anything here.</li><li>/src - we&#39;ll write all our in-development code here (css, JavaScript, etc). Later, Gulp will process these files to produce the files in /dist. The module file names used above are just examples - you should definitely use more meaningful file names!</li><li>/node_modules - Node for front-end apps? Yes! We will use Node and NPM to install and run Gulp tasks.</li><li>.gitignore - files and folders specified in this file will be ignored (not tracked) by Git. They also won&#39;t be pushed to GitHub. We&#39;ll be ignoring the node_modules/ folder - no reason to track or push all those 3rd-party packages.</li><li>gulpfile.js - we&#39;ll write our Gulp concatenation, <a href="https://babeljs.io/">transpilation</a> and minification tasks in here.</li><li>index.html - during development, we&#39;ll itemize each script separately. Later, we will just link to a single production-ready JavaScript file.</li><li>package.json - Created by NPM. Among other things, this file catalogs all the packages our application depends on. Ours will include dependencies for Gulp and various Gulp plugins.</li></ul><h3>The Nitty and the Gritty</h3><p>Let’s begin by looking at the structure of our index.html. During development, we&#39;ll simply link to each of the JavaScript files in our /src/js folder. So our index.html might look like this:</p><pre>&lt;!DOCTYPE html&gt;<br>&lt;html lang=&quot;en&quot;&gt;<br>&lt;head&gt;<br>  &lt;meta charset=&quot;UTF-8&quot;&gt;<br>  &lt;title&gt;Nice Boilerplate&lt;/title&gt;<br>&lt;/head&gt;<br>&lt;body&gt;</pre><pre>  &lt;!-- =============== vendor javascript ================ --&gt;<br>  &lt;script src=&quot;https://example.com/jquery.min.js&quot;&gt;&lt;/script&gt;</pre><pre>  &lt;!-- ================ our javascript ================== --&gt;<br>  &lt;script src=&quot;src/js/module1.js&quot;&gt;&lt;/script&gt;<br>  &lt;script src=&quot;src/js/module2.js&quot;&gt;&lt;/script&gt;<br>  &lt;script src=&quot;src/js/module3.js&quot;&gt;&lt;/script&gt;<br>  &lt;script src=&quot;src/js/app.js&quot;    &gt;&lt;/script&gt;</pre><pre>&lt;/body&gt;<br>&lt;/html&gt;</pre><p>Order is important! <strong>Our modules must load first</strong> so that their public methods are available to be called. That statement will make more sense as we progress. For now, know that app.js must load last because we&#39;re going to use it to call all our other modules&#39; <em>public methods</em>. Other than that, it&#39;s just a normal index.html file. Scaffold your application as you would normally.</p><p>Things start to look a little different when we get to our app.js file:</p><pre>$(document).ready(function () {</pre><pre>  Module1.init();<br>  Module2.init();<br>  Module3.init();</pre><pre>);</pre><p>That’s it! If you’re used to seeing/writing volumes of code inside of $(document).ready(), the above may look a little strange. Our app.js has only one responsibility: call our separate modules&#39; .init() methods. All of the actual application logic resides in those other modules. Each time you add a new module to your application, you add a call to its .init() method here. Easy and organized.</p><p>Because we use app.js to <em>bootstrap</em> our other modules, it now makes sense that index.html has to load those modules first. If the modules were loaded after app.js, calling their .init() methods would fail.</p><p>We will write each module in a separate file to promote reuse. And we’ll adopt the style known as the <a href="https://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript">revealing module pattern</a>. The “revealing” qualifier hints at the module’s internal structure: some features are private, others are <em>revealed</em> publicly.</p><p>Here’s an example:</p><pre>var Module1 = (function() {</pre><pre>  &#39;use strict&#39;;</pre><pre>  // placeholder for cached DOM elements<br>  var DOM = {};<br></pre><pre>  /* =================== private methods ================= */</pre><pre>  // cache DOM elements<br>  function cacheDom() {<br>    DOM.$someElement = $(&#39;#some-element&#39;);<br>  }</pre><pre>  // bind events<br>  function bindEvents() {<br>    DOM.$someElement.click(handleClick);<br>  }</pre><pre>  // handle click events<br>  function handleClick(e) {<br>    render(); // etc<br>  }</pre><pre>  // render DOM<br>  function render() {<br>    DOM.$someElement<br>      .html(&#39;&lt;p&gt;Yeah!&lt;/p&gt;&#39;);<br>  }<br></pre><pre>  /* =================== public methods ================== */</pre><pre>  // main init method<br>  function init() {<br>    cacheDom();<br>    bindEvents();<br>  }<br></pre><pre>  /* =============== export public methods =============== */</pre><pre>  return {<br>    init: init<br>  };</pre><pre>}());</pre><p>We begin by declaring a variable (Module1) and assigning a function to it. <strong>All of the module’s code goes inside this function.</strong></p><p>Note that the function is both (wrapped in parentheses and ends with another set of parentheses)()) :</p><pre>var Module1 = (function () {</pre><pre>  // all module logic goes here</pre><pre>}());</pre><p>The parentheses () at the end causes the function to be interpreted <em>and evaluated</em> as an expression. This is known as an IIFE, or <a href="http://gregfranko.com/blog/i-love-my-iife/">Immediately Invoked Function Expression</a>. The IIFE means we don&#39;t call the function separately — the function is called when the JavaScript engine assigns it to our variable. And that happens as soon as the module loads. The wrapping () are not technically required, but are used by convention to let other programmers know that this function is an IIFE.</p><p>In addition to “auto-loading” our module, the function also creates its own <strong>local scope</strong> for all the variables and functions within it. Anything declared inside a function is scoped to the function — it can’t be called or referenced outside of the function (except when it can! We’ll get to this shortly). Isolating scope this way also prevents adding all kinds of variables and functions to the global scope.</p><p>Within the IIFE, our example module uses /* comments */ to organize its contents into four sections.</p><p>At the very beginning we declare all required module-scope variables. Standard stuff you already do — no big deal. This example only declares a single variable, an empty object that will cache a DOM element.</p><p>Next we define a few <em>private methods</em>. The example methods are commonly found in many front-end applications: cacheDom(), bindEvents(), and render(). They do exactly what you expect them to do. Additional private methods might handle form submission, AJAX requests, manipulating JSON responses, etc. What’s important to note is that these methods are <strong>private</strong> — we don&#39;t need or want them to be available outside of the module they&#39;re defined in. And they&#39;re not, because they&#39;re encapsulated within our IIFE. For example, there&#39;s no reason for any module&#39;s bindEvents() function to be available globally — it&#39;s irrelevant to any other module, so we keep it private.</p><blockquote>Also note that multiple modules can have the same private functions. They will never collide with each other because they are restricted to each module’s local function scope. Beyond that, each module can have the same public methods as well, since each of those is <em>namespaced </em>to its own module. For example, you might have the three modules, each with the same public method: modals.init(), greeting.init(), login.init(). Those identically-named methods will never collide with each other because they&#39;re all called on unique modules. Very courteous.</blockquote><p>In the next section we define our <em>public methods</em>. In this case we only have one: init(). But you could have any number of them. Notice that init() does only one thing: make calls to our <em>private methods</em>. When called, init() <em>closes over</em> the private module-scoped variables and functions, making them available outside the scope they were declared in (yay, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures">closure</a>).</p><p>You may ask, “what makes the init() function public? — it looks just like the other private functions above it.&quot; Good question — now go to the next paragraph!</p><p>The final section returns an object literal. This is what makes the revealing module pattern so cool. What we’re returning is essentially a set of “links” to any private methods that we want to make public outside our module. This allows us to separate the private and public parts of our modules, and — to answer the preceding paragraph’s question — is what makes init() a public method.</p><p>Remember that an object’s properties are { key : value } pairs:</p><pre>return {<br>  init : init<br>};</pre><p>In the above, the left-hand ‘key’ is the name of the method we’ll call <em>outside our module</em>. The right-hand ‘value’ refers to the name of the function defined <em>inside the module</em>. Although it looks strange to see init : init, it&#39;s common practice to use the same name externally that we use internally. It&#39;s also one less name you have to remember.</p><h3>Bringing Everything Together</h3><p>By returning public methods via the object literal, we “attach” them to the variable that we declared at the beginning: Module1 gets the init() method. And because Module1 was declared globally, <strong>it and its public methods are available in the global namespace</strong>. Once a module exposes its public methods globally, any other module can call those methods. So we can call Module1.init() anywhere we like — which is exactly what we did earlier in app.js. Module1 might have additional public methods — those can be called anywhere in the application as well.</p><p>See how it’s all starting to fit together? And how, in a team setting, each team member can work independently and then publish their module’s public methods, adding any necessary calls to their module’s public method(s) in app.js?</p><p>I typically limit each module to a single <strong>unique application feature</strong> or a single <strong>unique application utility</strong>. An application feature might have many private methods and not need anything other than a single init() method exposed publicly. In contrast, a utility module might have few (or zero) private methods and instead expose all its methods publicly. And utility modules may not need init() methods at all.</p><h3>Summarizing</h3><p>We break our application logic into chunks based on single feature or utility. Each team member composes their module(s) as an IIFE, consisting of all the business logic needed by the module. Each module reveals specific public methods, which can be called elsewhere in the application. Our main app.js bootstraps those modules by calling each of their public init() methods. Other project team members recognize your brilliance and buy you mint juleps.</p><h3>Up Next: Let’s Build a Modular App!</h3><p>Now that we understand the principles of basic modular application design, we’ll put them to use building a simple web application in <a href="https://medium.com/@jrschwane/writing-modular-javascript-pt-2-d7140d15c982">part 2</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b42a3bd23685" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>