<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ webpack - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ webpack - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 29 May 2026 16:31:53 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/webpack/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ The JavaScript Modules Handbook – Complete Guide to ES Modules and Module Bundlers ]]>
                </title>
                <description>
                    <![CDATA[ Modules and Module Bundlers are essential components of modern web development. But understanding how they work can quickly become overwhelming. This article will show you all you need to know about ES Modules and Module Bundlers in plain English. Ta... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-es-modules-and-module-bundlers/</link>
                <guid isPermaLink="false">66ba0df4052fa53219e0a365</guid>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ json ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwatobi Sofela ]]>
                </dc:creator>
                <pubDate>Wed, 11 May 2022 23:06:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/JavaScript-Module-Book-Cover--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>Modules</strong> and <strong>Module Bundlers</strong> are essential components of modern web development. But understanding how they work can quickly become overwhelming.</p>
<p>This article will show you all you need to know about ES Modules and Module Bundlers in plain English.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><a class="post-section-overview" href="#heading-what-exactly-is-a-javascript-module-2">What Exactly Is a JavaScript Module?</a></li>
<li><a class="post-section-overview" href="#heading-why-use-modules">Why Use Modules?</a></li>
<li><a class="post-section-overview" href="#heading-common-types-of-module-systems-in-javascript">Common Types of Module Systems in JavaScript</a></li>
<li><a class="post-section-overview" href="#heading-how-to-convert-a-javascript-file-into-a-module">How to Convert a JavaScript File into a Module</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-an-es-module">How to Use an ES Module</a></li>
<li><a class="post-section-overview" href="#heading-how-to-export-a-modules-code">How to Export a Module's Code</a></li>
<li><a class="post-section-overview" href="#heading-how-to-import-exported-code">How to Import Exported Code</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-a-modules-imported-code">How to Use a Module's Imported Code</a></li>
<li><a class="post-section-overview" href="#heading-how-to-rename-exports-and-imports-in-es-modules">How to Rename Exports and Imports in ES Modules</a></li>
<li><a class="post-section-overview" href="#heading-why-rename-a-modules-code">Why Rename a Module's Code?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-rename-multiple-exports-in-an-es-module">How to Rename Multiple Exports in an ES Module</a></li>
<li><a class="post-section-overview" href="#heading-how-to-rename-multiple-imports-in-an-es-module">How to Rename Multiple Imports in an ES Module</a></li>
<li><a class="post-section-overview" href="#heading-how-to-import-all-exportable-items-from-an-es-module-in-one-go">How to Import All Exportable Items from an ES Module in One Go</a></li>
<li><a class="post-section-overview" href="#heading-how-to-export-anonymously-to-an-es-module">How to Export Anonymously to an ES Module</a></li>
<li><a class="post-section-overview" href="#heading-what-exactly-is-an-aggregator-file">What Exactly Is an Aggregator File?</a></li>
<li><a class="post-section-overview" href="#heading-project-how-to-use-an-aggregator-file">Project: How to Use an Aggregator File</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-the-import-syntax-to-load-a-module-dynamically">How to Use the <code>import()</code> Syntax to Load a Module Dynamically</a></li>
<li><a class="post-section-overview" href="#heading-what-exactly-is-importmeta-in-es-modules">What Exactly Is <code>import.meta</code> in ES Modules?</a></li>
<li><a class="post-section-overview" href="#heading-quick-review-of-modules-so-far">Quick Review of Modules So Far</a></li>
<li><a class="post-section-overview" href="#heading-what-is-a-module-bundler">What Is a Module Bundler?</a></li>
<li><a class="post-section-overview" href="#heading-why-do-you-need-a-module-bundler">Why Do You Need a Module Bundler?</a></li>
<li><a class="post-section-overview" href="#heading-how-does-a-module-bundler-work">How Does a Module Bundler Work?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-use-webpack">How to Use Webpack</a></li>
<li><a class="post-section-overview" href="#heading-how-to-make-webpack-auto-generate-your-apps-html-file">How to Make Webpack Auto-Generate Your App's HTML File</a></li>
<li><a class="post-section-overview" href="#heading-how-to-make-htmlwebpackplugin-use-your-source-file-as-a-template-to-auto-generate-a-new-html-page">How to Make <code>HtmlWebpackPlugin</code> Use Your Source File as a Template to Auto-Generate a New HTML Page</a></li>
<li><a class="post-section-overview" href="#heading-important-stuff-to-know-about-updating-your-app">Important Stuff to Know about Updating Your App</a></li>
<li><a class="post-section-overview" href="#heading-how-to-rerun-webpack-automatically-1">How to Rerun Webpack Automatically</a></li>
<li><a class="post-section-overview" href="#heading-how-to-reload-the-browser-automatically">How to Reload the Browser Automatically</a></li>
<li><a class="post-section-overview" href="#heading-what-exactly-is-webpacks-configuration-file-3">What Exactly Is Webpack's Configuration File?</a></li>
<li><a class="post-section-overview" href="#heading-common-webpack-configuration-options">Common Webpack Configuration Options</a></li>
<li><a class="post-section-overview" href="#heading-overview">Overview</a></li>
</ol>
<p>So, without any further ado, let's get started with modules.</p>
<h2 id="heading-what-exactly-is-a-javascript-module">What Exactly Is a JavaScript Module?</h2>
<p>A JavaScript <strong>module</strong> is a file that allows you to export its code. This allows other JavaScript files to import and use the exported code as their dependencies.</p>
<p>Specifically, a module is simply a JavaScript file that allows you to share its code with other files within your project (or with the world through <a target="_blank" href="https://www.codesweetly.com/package-manager-explained">package managers</a> like Yarn and NPM).</p>
<h2 id="heading-why-use-modules">Why Use Modules?</h2>
<p>In its early days, people used JavaScript mainly for trivial scripting tasks like providing bits and pieces of interactivity to web pages where needed. In other words, developers predominately used JavaScript to write small scripts—not large ones.</p>
<p>Today, however, JavaScript has grown into a vast scripting tool capable of doing a lot more than just making web pages interactive.</p>
<p>It is now the norm to have large JavaScript code used for diverse functions like server-side website development, game development, and mobile app development.</p>
<p>Since JavaScript can be used for virtually any programming task, a need arose to share scripts between a project's files and the world.</p>
<p>So the JavaScript community developed the module system to allow developers to share their scripts on demand.</p>
<h2 id="heading-common-types-of-module-systems-in-javascript">Common Types of Module Systems in JavaScript</h2>
<p>Below are some of the popular module systems in JavaScript:</p>
<ul>
<li><a target="_blank" href="https://github.com/amdjs/amdjs-api/blob/master/AMD.md">Asynchronous Module Definition (AMD)</a></li>
<li><a target="_blank" href="https://en.wikipedia.org/wiki/CommonJS">CommonJS Modules</a></li>
<li><a target="_blank" href="https://github.com/umdjs/umd">Universal Module Definition (UMD)</a></li>
<li><a target="_blank" href="https://tc39.es/ecma262/#sec-modules">ES Modules</a></li>
</ul>
<p><strong>Note:</strong> ES modules are sometimes called "JS modules" or "ECMAScript modules".</p>
<p>Amongst the module systems listed above, the ES module system is the official standard for JavaScript.</p>
<p>The remaining three (AMD, CommonJS, and UMD) were created by various developers when JavaScript did not have a standardized module system.</p>
<p>However, since ES module's appearance in the 2015 ECMAScript standard, the previous module systems have gradually become part of JavaScript's history.</p>
<p>Therefore, this article will focus on showing you how ES modules work.</p>
<p>First, though, it is essential to know how to convert a JavaScript file into a module. So, let's discuss that below.</p>
<h2 id="heading-how-to-convert-a-javascript-file-into-a-module">How to Convert a JavaScript File into a Module</h2>
<p>To convert a JavaScript file to an ES module, do the following:</p>
<h3 id="heading-step-1-create-a-project-directory">Step 1: Create a project directory</h3>
<p>Create a project folder—where this project's HTML and JavaScript files will reside.</p>
<h3 id="heading-step-2-create-your-code-files">Step 2: Create your code files</h3>
<p>Create the following files inside your project folder:</p>
<ol>
<li><code>index.html</code></li>
<li><code>index.js</code></li>
</ol>
<h3 id="heading-step-3-add-your-javascript-file-to-your-html-document">Step 3: Add your JavaScript file to your HTML document</h3>
<p>Open your <code>index.html</code> file and replicate the code below:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>ES Module Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

    <span class="hljs-comment">&lt;!-- Add the "index.js" JavaScript file to this HTML document --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>In the HTML snippet above, we used the <code>&lt;script&gt;</code>'s <code>type="module"</code> attribute to convert the <code>index.js</code> JavaScript file to an ES module.</p>
<p>So, now that we know how to convert a JavaScript file into a module, let's see how to use one.</p>
<h2 id="heading-how-to-use-an-es-module">How to Use an ES Module</h2>
<p>Follow the steps below to learn how to use an ES module.</p>
<h3 id="heading-step-1-create-a-project-directory-1">Step 1: Create a project directory</h3>
<p>Create a project folder—where this project's HTML and module files will reside.</p>
<h3 id="heading-step-2-create-your-code-files-1">Step 2: Create your code files</h3>
<p>Create the following files inside your project folder:</p>
<ol>
<li><code>index.html</code></li>
<li><code>module-1.js</code></li>
<li><code>module-2.js</code></li>
</ol>
<h3 id="heading-step-3-add-the-modules-to-your-html-document">Step 3: Add the modules to your HTML document</h3>
<p>Open your <code>index.html</code> file and replicate the code below:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>ES Module Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Check the console<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"module-1.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"module-2.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Here are the main things we did in the HTML snippet above:</p>
<ol>
<li>We added the two JavaScript files to our HTML document.</li>
<li>We used the <code>type="module"</code> attribute to convert the regular JavaScript files to ES module files.</li>
</ol>
<p><strong>Note</strong> that JavaScript defers ES modules automatically. So, you do not need to use a <code>defer</code> attribute in your module's <code>&lt;script&gt;</code> element.</p>
<p>Also, the computer will execute a module only once—regardless of the number of <code>&lt;script&gt;</code> tags you use to reference it.</p>
<h3 id="heading-step-4-view-your-app">Step 4: View your app</h3>
<p>Open your <code>index.html</code> file in any browser to see the current state of your app.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/module-tutorial-open-html-file-in-chrome-browser-codesweetly.png" alt="Open your HTML file in your browser - Modules Tutorial" width="600" height="400" loading="lazy">
<em>Opening an index.html file in a Chrome browser</em></p>
<p>Once opened, if you inspect your browser's console, you will see some error messages.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/module-tutorial-cors-policy-error-codesweetly.png" alt="CORS policy error in the browser's console - Modules Tutorial" width="600" height="400" loading="lazy">
<em>Inspecting a Chrome browser's console</em></p>
<p>The browser threw a CORS policy error because ES modules only work through <code>http://</code> and <code>https://</code> URLs—not locally via a <code>file://</code> URL.</p>
<p>In other words, since our HTML file contains two ES modules, we need to load the document via an <code>http://</code> scheme.</p>
<p>The two typical ways to load an HTML document via an <code>http://</code> scheme are:</p>
<ul>
<li>By using a Local Server, or</li>
<li>Through the use of a Module Bundler</li>
</ul>
<p>We will discuss Module Bundlers in detail later on in this article. For now, though, let's see how to use a local server to load the <code>index.html</code> file via an <code>http://</code> scheme.</p>
<h4 id="heading-how-to-run-an-html-file-through-a-local-server">How to run an HTML file through a local server</h4>
<p>The steps below will show you how to use a <a target="_blank" href="https://code.visualstudio.com/">VS Code</a> local server extension to run your HTML file.</p>
<p><strong>Note:</strong> Suppose your code editor is Atom or Sublime Text. In that case, follow the links below to learn how to install a local server plugin.</p>
<ul>
<li><a target="_blank" href="https://atom.io/packages/atom-live-server">Atom Live Server</a></li>
<li><a target="_blank" href="https://youtu.be/5CinAgQylao">Sublime Text Live Server</a></li>
</ul>
<h5 id="heading-1-add-your-project-folder-to-vscodes-workspace">1. Add your project folder to VSCode's workspace</h5>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/module-tutorial-add-proj-folder-to-vscode-workspace-codesweetly.gif" alt="Add your project's folder to VSCode's workspace" width="600" height="400" loading="lazy">
<em>Adding a project folder to VSCode's workspace</em></p>
<h5 id="heading-2-install-a-local-server-live-server-by-ritwick-dey">2. Install a local server (Live Server by Ritwick Dey)</h5>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/module-tutorial-install-live-server-codesweetly.png" alt="Install the Live Server by Ritwick Dey" width="600" height="400" loading="lazy">
<em>Installing the VSCode Live Server by Ritwick Dey</em></p>
<h5 id="heading-3-open-your-html-file-in-the-code-editor">3. Open your HTML file in the code editor</h5>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/module-tutorial-open-html-file-in-code-editor-codesweetly.png" alt="Open your HTML file in your code editor" width="600" height="400" loading="lazy">
<em>Opening HTML file in VSCode editor</em></p>
<h5 id="heading-4-use-live-server-to-run-the-html-file-in-your-default-browser">4. Use Live Server to run the HTML file in your default browser</h5>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/module-tutorial-run-html-file-with-live-server-codesweetly.png" alt="Run your HTML File with Live Server - Modules Tutorial" width="600" height="400" loading="lazy">
<em>Opening the project's HTML file with Live Server</em></p>
<p>Your app should now load with the <code>http://</code> scheme—without any CORS error in your browser's console.</p>
<p><strong>Some things to note:</strong></p>
<ul>
<li>Suppose you did not add your project folder to VSCode's workspace (step 1). In that case, the Live Server might not load your file correctly.</li>
<li>Live Server will auto-reload your browser whenever you save any changes to your HTML file.</li>
<li>Suppose you wish to stop the Live Server. In that case, right-click on the HTML editor page and click on "Stop Live Server".</li>
<li>JavaScript modules operate in strict mode by default. As such, you must abide by JavaScript's strict syntax rules. Otherwise, your program might malfunction.</li>
</ul>
<p>So, now that you've converted your JavaScript file to an ES module, you can begin to use the <code>export</code> and <code>import</code> keywords to share your modules' code. Let's discuss how below.</p>
<h2 id="heading-how-to-export-a-modules-code">How to Export a Module's Code</h2>
<p>There are two equivalent ways to export a module's item.</p>
<ol>
<li>Place an <code>export</code> keyword before your code</li>
<li>Create an export statement</li>
</ol>
<p>Let's discuss both ways below.</p>
<h3 id="heading-how-to-share-a-modules-code-by-placing-an-export-keyword-before-the-code">How to share a module's code by placing an <code>export</code> keyword before the code</h3>
<p>One way to export an item is to place an <code>export</code> keyword before the code you wish to share with other modules.</p>
<p>For instance, open your <code>module-1.js</code> file and replicate the code below:</p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-comment">// Export the "bestClub" variable:</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;
</code></pre>
<p>You can see how we place the <code>export</code> keyword before the <code>const</code> variable statement in the snippet above.</p>
<p>We prepended the <code>const</code> variable with the <code>export</code> keyword to tell the computer to share the <code>bestClub</code> variable with other modules that request it.</p>
<p><strong>Note:</strong> The <code>export</code> keyword highlights the code you wish to share with other modules.</p>
<p><strong>Here's another example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// Export the "multiply" function:</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params">x, y</span>) </span>{
  <span class="hljs-keyword">return</span> x * y;
}
</code></pre>
<p>The statement above instructs the computer to export <code>multiply()</code> to the modules that request it.</p>
<p>Let's now see the second way to export a module's code.</p>
<h3 id="heading-how-to-share-a-modules-code-by-creating-an-export-statement">How to share a module's code by creating an export statement</h3>
<p>An alternate way to share a module's code is to use the <code>export</code> keyword as a standalone statement. You can do so by prepending a single <code>export</code> keyword to a block (<code>{...}</code>) of comma-separated names of code you wish to share.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// Create a variable named "bestClub":</span>
<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;

<span class="hljs-comment">// Create a function named "multiply":</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params">x, y</span>) </span>{
  <span class="hljs-keyword">return</span> x * y;
}

<span class="hljs-comment">// Create an array named "fruits":</span>
<span class="hljs-keyword">const</span> fruits = [<span class="hljs-string">"Mango"</span>, <span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Orange"</span>, <span class="hljs-string">"Lemon"</span>];

<span class="hljs-comment">// Export the three statements above:</span>
<span class="hljs-keyword">export</span> { bestClub, multiply, fruits };
</code></pre>
<p>The snippet above used an <code>export</code> statement to indicate that the computer can share <code>bestClub</code>, <code>multiply</code>, and <code>fruits</code> with other modules that request any of them.</p>
<p>Keep in mind that <code>export</code> works only as a top-level item. So, it would not work in a function, for example.</p>
<p>Therefore, the snippet below will throw an error because we used the <code>export</code> keyword inside the function.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">wrong</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> bestClub = <span class="hljs-string">"Your Club"</span>;
  <span class="hljs-keyword">return</span> bestClub;
}
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>The <code>export</code> keyword works only inside modules—not inside regular JavaScript programs.</li>
<li>JavaScript <a target="_blank" href="https://www.codesweetly.com/javascript-hoisting">hoists</a> <code>export</code> statements. So, you can define them anywhere in your module.</li>
<li>Exported modules operate in strict mode by default—regardless of whether you specified the <code>strict</code> statement.</li>
</ul>
<p>Let's now see how to import the exported code.</p>
<h2 id="heading-how-to-import-exported-code">How to Import Exported Code</h2>
<p>To import exported code, use ES module's <code>import</code> statement.</p>
<p>For instance, open your <code>module-2.js</code> file and replicate the code below:</p>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> { bestClub } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;
</code></pre>
<p>In the snippet above, we used an <code>import</code> statement to bring in the <code>bestClub</code> variable from the <code>module-1.js</code> file.</p>
<p>So, <code>module-2.js</code> is a top-level module because it contains another script.</p>
<p>On the other hand, <code>module-1.js</code> is a submodule because it is a script used inside another file.</p>
<p><strong>Note:</strong></p>
<ul>
<li>We use the <code>import</code> statement to import items from other modules.</li>
<li>It is mandatory to wrap your named exports in curly braces while importing them.</li>
</ul>
<p>Keep in mind that an <code>import</code> statement can only get another module's code if exported with the <code>export</code> keyword.</p>
<p>For instance, the <code>import</code> statement below will import the <code>bestClub</code>, <code>multiply</code>, and <code>fruits</code> items if they got marked for exportation in the <code>module-1.js</code> file.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Import three items from the module-1.js file:</span>
<span class="hljs-keyword">import</span> { bestClub, multiply, fruits } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;
</code></pre>
<p>Suppose you did not use the <code>export</code> keyword to mark the three items as exportable features. In that case, the <code>import</code> statement will throw an <code>Uncaught SyntaxError</code>.</p>
<p><strong>Note:</strong></p>
<ul>
<li>"Module specifier" and the "import specifier" are other names people call the <code>"./module-1.js"</code> file path string in the snippet above.</li>
<li>The dot (<code>.</code>) mark in the <code>"./module-1.js"</code> module specifier means <em>"same directory"</em>. In other words, the dot mark tells the computer to find the <code>module-1.js</code> file in the same folder where the current module is.</li>
<li>The current module referred to in the snippet above is the file where the <code>import</code> statement got defined.</li>
</ul>
<p>An alternative to the import specifier's dot (<code>.</code>) syntax is to write out the entire <a target="_blank" href="https://docs.oracle.com/javase/tutorial/essential/io/path.html">relative path</a> to a module's location.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// Import three items from the module-1.js file:</span>
<span class="hljs-keyword">import</span> { bestClub, multiply, fruits } <span class="hljs-keyword">from</span> <span class="hljs-string">"/codesweetly/blog/notes/modular-javascript/es-modules/module-1.js"</span>;
</code></pre>
<p>You can see how long the <code>import</code> statement above is. We often use the dot syntax because of its short and portable length.</p>
<p>Suppose you choose to use the dot syntax. In that case, keep in mind that some module systems (such as Node.js and module bundlers) permit you to omit the dot mark and the file extension like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Import three items from the module-1.js file:</span>
<span class="hljs-keyword">import</span> { bestClub, multiply, fruits } <span class="hljs-keyword">from</span> <span class="hljs-string">"module-1"</span>;
</code></pre>
<p>However, other module systems, such as ES modules, do not permit such omissions.</p>
<p><strong>Note:</strong></p>
<ul>
<li>A module specifier with <em>no</em> dot mark and file extension is called a "bare" module specifier.</li>
<li>A module's imported item is a read-only view of the exported feature. So, you can modify the code only inside the module that exported it—not in the module that imported it.</li>
<li>JavaScript imports a module's code as live binding. So, suppose you update the imported code's value in the exportation module. In that case, your changes will also reflect in the importation module.</li>
</ul>
<p>Let's now discuss how to use the imported code.</p>
<h2 id="heading-how-to-use-a-modules-imported-code">How to Use a Module's Imported Code</h2>
<p>Once you've imported your code, you can use it as if it was defined in the module into which you've imported it.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> { bestClub } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> myBestClub = bestClub + <span class="hljs-string">" "</span> + <span class="hljs-string">"is my best club."</span>;

<span class="hljs-built_in">console</span>.log(myBestClub);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-ka4gdj?devtoolsheight=33&amp;file=module-2.js"><strong>Try it on StackBlitz</strong></a></p>
<p><strong>Note:</strong></p>
<ul>
<li>The <code>import</code> keyword works only inside modules—not inside regular JavaScript programs.</li>
<li>An imported module's features are not available in the global <a target="_blank" href="https://www.codesweetly.com/javascript-scope">scope</a>. Therefore, you can access imported items only in the script you have imported them into—not in other places like the JavaScript console.</li>
<li>JavaScript <a target="_blank" href="https://www.codesweetly.com/javascript-hoisting">hoists</a> <code>import</code> statements. So, you can define them anywhere in your module.</li>
<li>Imported modules operate in strict mode by default—regardless of whether you specified the <code>strict</code> statement.</li>
</ul>
<p>So, now that we know how to use an ES module, let's discuss how to rename the code you wish to export (or import).</p>
<h2 id="heading-how-to-rename-exports-and-imports-in-es-modules">How to Rename Exports and Imports in ES Modules</h2>
<p>Suppose you wish to rename the code you are exporting (or importing). In such a case, use the <code>as</code> keyword.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-comment">// Create a variable named "bestClub":</span>
<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;

<span class="hljs-comment">// Export the bestClub variable as "favoriteTeam":</span>
<span class="hljs-keyword">export</span> { bestClub <span class="hljs-keyword">as</span> favoriteTeam };
</code></pre>
<p>In the snippet above, we told the computer to export the <code>bestClub</code> variable <em>as</em> <code>favoriteTeam</code>.</p>
<p>Therefore, when importing the variable, you will use the name <code>favoriteTeam</code>—not <code>bestClub</code>.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> { favoriteTeam } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> myBestClub = favoriteTeam + <span class="hljs-string">" "</span> + <span class="hljs-string">"is my best club."</span>;

<span class="hljs-built_in">console</span>.log(myBestClub);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-dltrvv?devtoolsheight=33&amp;file=module-2.js"><strong>Try it on StackBlitz</strong></a></p>
<p>We renamed the <code>bestClub</code> variable in the example above while exporting it. However, you can also rename it during its importation.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-comment">// Create a variable named "bestClub":</span>
<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;

<span class="hljs-comment">// Export the bestClub variable:</span>
<span class="hljs-keyword">export</span> { bestClub };
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> { bestClub <span class="hljs-keyword">as</span> favoriteTeam } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> myBestClub = favoriteTeam + <span class="hljs-string">" "</span> + <span class="hljs-string">"is my best club."</span>;

<span class="hljs-built_in">console</span>.log(myBestClub);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-qrnt6y?devtoolsheight=33&amp;file=module-2.js"><strong>Try it on StackBlitz</strong></a></p>
<p>The choice of whether to rename your code during exportation or importation is totally up to you.</p>
<p>However, many developers prefer to rename during importation because you don't always have control over a code's source file, especially when importing from a third party's module.</p>
<h2 id="heading-why-rename-a-modules-code">Why Rename a Module's Code?</h2>
<p>Renaming can help prevent browsers from throwing errors due to name conflicts. For instance, consider these snippets:</p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-comment">// Create a variable named "bestClub":</span>
<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;

<span class="hljs-comment">// Export the bestClub variable:</span>
<span class="hljs-keyword">export</span> { bestClub };
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> { bestClub } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> bestClub = bestClub + <span class="hljs-string">" "</span> + <span class="hljs-string">"is my best club."</span>;

<span class="hljs-built_in">console</span>.log(bestClub);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-vvcy2d?devtoolsheight=33&amp;file=module-2.js"><strong>Try it on StackBlitz</strong></a></p>
<p>When you run the snippets above, the browser will throw an error similar to:</p>
<pre><code class="lang-js"><span class="hljs-string">"SyntaxError: Identifier 'bestClub' has already been declared"</span>
</code></pre>
<p>The browser threw the error because the imported code's name conflicts with <code>module-2.js</code>' <code>bestClub</code> variable.</p>
<p>However, you can rectify the error by simply renaming the imported code like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> { bestClub <span class="hljs-keyword">as</span> favoriteTeam } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> bestClub = favoriteTeam + <span class="hljs-string">" "</span> + <span class="hljs-string">"is my best club."</span>;

<span class="hljs-built_in">console</span>.log(bestClub);
</code></pre>
<p>Keep in mind that you can also rename multiple exports. Let's see how below.</p>
<h2 id="heading-how-to-rename-multiple-exports-in-an-es-module">How to Rename Multiple Exports in an ES Module</h2>
<p>You can rename multiple exports by separating each <code>as</code> statement with a comma.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;
<span class="hljs-keyword">const</span> fruits = [<span class="hljs-string">"Grape"</span>, <span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Pineapple"</span>, <span class="hljs-string">"Lemon"</span>];

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params">x, y</span>) </span>{
  <span class="hljs-keyword">return</span> x * y;
}

<span class="hljs-comment">// Export the three statements above:</span>
<span class="hljs-keyword">export</span> { 
  bestClub <span class="hljs-keyword">as</span> favoriteTeam, 
  fruits <span class="hljs-keyword">as</span> crops, 
  multiply <span class="hljs-keyword">as</span> product 
};
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> { favoriteTeam, crops, product } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">`I bought <span class="hljs-subst">${product(<span class="hljs-number">2</span>, <span class="hljs-number">11</span>)}</span> <span class="hljs-subst">${crops[<span class="hljs-number">2</span>]}</span>s at <span class="hljs-subst">${favoriteTeam}</span>.`</span>;

<span class="hljs-built_in">console</span>.log(bestClub);
</code></pre>
<p><strong><a target="_blank" href="https://stackblitz.com/edit/web-platform-ir5f1h?devtoolsheight=33&amp;file=module-1.js">Try it on StackBlitz</a></strong></p>
<p>You can also rename multiple imports. Let's see how.</p>
<h2 id="heading-how-to-rename-multiple-imports-in-an-es-module">How to Rename Multiple Imports in an ES Module</h2>
<p>You can rename multiple imports by separating each <code>as</code> statement with a comma.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;
<span class="hljs-keyword">const</span> fruits = [<span class="hljs-string">"Grape"</span>, <span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Pineapple"</span>, <span class="hljs-string">"Lemon"</span>];
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params">x, y</span>) </span>{
  <span class="hljs-keyword">return</span> x * y;
}

<span class="hljs-comment">// Export the three statements above:</span>
<span class="hljs-keyword">export</span> { bestClub, fruits, multiply };
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> { 
  bestClub <span class="hljs-keyword">as</span> favoriteTeam, 
  fruits <span class="hljs-keyword">as</span> crops, 
  multiply <span class="hljs-keyword">as</span> product 
} <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">`I bought <span class="hljs-subst">${product(<span class="hljs-number">2</span>, <span class="hljs-number">11</span>)}</span> <span class="hljs-subst">${crops[<span class="hljs-number">2</span>]}</span>s at <span class="hljs-subst">${favoriteTeam}</span>.`</span>;

<span class="hljs-built_in">console</span>.log(bestClub);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-yinyru?devtoolsheight=33&amp;file=module-2.js"><strong>Try it on StackBlitz</strong></a></p>
<p>Suppose you wish to import all exportable content from <code>module-1.js</code> without specifying each import's name. How can you do this? Let's find out.</p>
<h2 id="heading-how-to-import-all-exportable-items-from-an-es-module-in-one-go">How to Import All Exportable Items from an ES Module in One Go</h2>
<p>Suppose you wish to import all exportable items from a specific module without specifying each import's name. In such a case, use the <code>import * as</code> syntax to bring in the items through a module object.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// Import all exportable features from the "countries.js" module:</span>
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> allCountries <span class="hljs-keyword">from</span> <span class="hljs-string">"./countries.js"</span>;
</code></pre>
<p>The statement above instructs the computer to import all exportable content of the <code>./countries.js</code> module and encase the imports in a module object named <code>allCountries</code>.</p>
<p>After the importation, you can use the imported items just as before. However, you now need to access them through the module object's name.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;
<span class="hljs-keyword">const</span> fruits = [<span class="hljs-string">"Grape"</span>, <span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Pineapple"</span>, <span class="hljs-string">"Lemon"</span>];
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params">x, y</span>) </span>{
  <span class="hljs-keyword">return</span> x * y;
}

<span class="hljs-comment">// Export the three statements above:</span>
<span class="hljs-keyword">export</span> { bestClub, fruits, multiply };
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> firstModule <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">`I bought <span class="hljs-subst">${firstModule.multiply(<span class="hljs-number">2</span>, <span class="hljs-number">11</span>)}</span> <span class="hljs-subst">${firstModule.fruits[<span class="hljs-number">2</span>]}</span>s at <span class="hljs-subst">${firstModule.bestClub}</span>.`</span>;

<span class="hljs-built_in">console</span>.log(bestClub);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-s5bug2?devtoolsheight=33&amp;file=module-2.js"><strong>Try it on StackBlitz</strong></a></p>
<p>So, what if you prefer to export a module's content anonymously? Let's discuss the technique you can use.</p>
<h2 id="heading-how-to-export-anonymously-to-an-es-module">How to Export Anonymously to an ES Module</h2>
<p>So far, we have exported items by explicitly stating the name of the specific code we wish to share—for instance, <code>export { bestClub }</code>.</p>
<p>Such exportation technique is called the <strong>named export</strong>.</p>
<p>You can also export anonymously by using the <strong>default export</strong> technique. But what exactly is a default export? Let's find out.</p>
<h3 id="heading-what-exactly-is-a-default-export-in-es-modules">What Exactly Is a Default Export in ES Modules?</h3>
<p><strong>Default export</strong> is a technique developers use to export code anonymously (namelessly).</p>
<p>You can implement a default export by prepending the keyword <code>default</code> to the code you wish to export. By so doing, the computer will share the code as a default export.</p>
<p>In other words, the code will get exported with the special name, <code>default</code>—instead of its original name (if it had one).</p>
<p>So, during the code's importation, you will have the options to import it with the name <code>default</code>, a custom name of choice, or without any name.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;

<span class="hljs-comment">// Export the bestClub variable as a default export:</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> bestClub;
</code></pre>
<p>We did not use curly braces in the default export statement above because you can have only one default export in a module.</p>
<p>Alternatively, you can also rewrite the code above like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-comment">// Export the string value as a default export:</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-string">"Your Club"</span>;
</code></pre>
<p>Keep in mind that you can use the default export technique to share a function, variable, string, class, or object literal.</p>
<p>However, you cannot prepend the <code>export default</code> keyword to a <code>var</code>, <code>let</code>, or <code>const</code> keyword.</p>
<p>In other words, the snippet below will throw a <code>SyntaxError</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;
</code></pre>
<p>Let's now discuss how to import a default export.</p>
<h3 id="heading-how-to-import-a-default-export-into-an-es-module">How to Import a Default Export into an ES Module</h3>
<p>There are two equivalent ways to import a default export:</p>
<ul>
<li>Use the <code>default as</code> syntax</li>
<li>Specify the imported code's name only</li>
</ul>
<p>Let's discuss the two importation techniques.</p>
<h4 id="heading-how-to-use-the-default-as-syntax-to-import-a-default-export">How to use the <code>default as</code> syntax to import a default export</h4>
<p>One way to import a default export is to use the <code>default as</code> syntax like so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { <span class="hljs-keyword">default</span> <span class="hljs-keyword">as</span> newName } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-relative-path.js"</span>;
</code></pre>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-comment">// Export the string value as a default export:</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-string">"Your Club"</span>;
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> { <span class="hljs-keyword">default</span> <span class="hljs-keyword">as</span> favoriteTeam } <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> bestClub = favoriteTeam + <span class="hljs-string">" "</span> + <span class="hljs-string">"is my best club."</span>;

<span class="hljs-built_in">console</span>.log(bestClub);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-zcyvst?devtoolsheight=33&amp;file=module-2.js"><strong>Try it on StackBlitz</strong></a></p>
<p>Notice that we didn't need to specify the name of the code we imported from the <code>module-1.js</code> file. Instead, we used the <code>default</code> keyword to import the code anonymously.</p>
<p>Afterward, we renamed the imported code <em>as</em> <code>favoriteTeam</code>.</p>
<p>Let's now see the second way to import a default export.</p>
<h4 id="heading-how-to-import-a-default-export-by-specifying-the-imported-codes-name-only">How to import a default export by specifying the imported code's name only</h4>
<p>An alternate way to import a default export is to ignore the curly braces (<code>{...}</code>), the <code>default</code> keyword, and the <code>as</code> keyword.</p>
<p>Instead, simply specify the name you wish to use to reference the imported code like so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> newName <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-relative-path.js"</span>;
</code></pre>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// module-1.js</span>

<span class="hljs-comment">// Export the string value as a default export:</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-string">"Your Club"</span>;
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// module-2.js</span>

<span class="hljs-keyword">import</span> favoriteTeam <span class="hljs-keyword">from</span> <span class="hljs-string">"./module-1.js"</span>;

<span class="hljs-keyword">const</span> bestClub = favoriteTeam + <span class="hljs-string">" "</span> + <span class="hljs-string">"is my best club."</span>;

<span class="hljs-built_in">console</span>.log(bestClub);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-rgrlh7?devtoolsheight=33&amp;file=module-2.js"><strong>Try it on StackBlitz</strong></a></p>
<p>You can see that the shortened importation technique above is neater than the previous option.</p>
<p><strong>Note:</strong></p>
<ul>
<li>The <code>export default</code> statement makes it possible for a JavaScript module to interpolate (work reliable) with existing CommonJS and AMD module systems.</li>
<li>See the "<a target="_blank" href="https://hacks.mozilla.org/2015/08/es6-in-depth-modules/">Default exports</a>" section of <em>ES6 In Depth: Modules</em> to learn more about interpolation.</li>
</ul>
<p>Before we wrap up our discussion on ES modules, you should be aware that you can use an aggregator file to collate your project's <code>import</code> statements.</p>
<p>But what exactly is an aggregator file, I hear you ask? Let's find out below.</p>
<h2 id="heading-what-exactly-is-an-aggregator-file">What Exactly Is an Aggregator File?</h2>
<p>An <strong>aggregator file</strong> is a script used solely to import and re-export the items you've exported from other modules.</p>
<p>In other words, instead of congesting your <a target="_blank" href="https://www.codesweetly.com/web-tech-glossary#top-level-module-javascript">top-level module</a> with multiple import statements from various files, you can create a single parent script (the aggregator file).</p>
<p>The parent script's sole purpose will be to import and re-export items from other modules.</p>
<p>Then, in your top-level module, you can simply import any required code from the aggregator file alone—not from numerous other scripts.</p>
<p>By so doing, you will make your top-level module neater.</p>
<p>So, what exactly does all this mean? Let's see with a mini-project.</p>
<h2 id="heading-project-how-to-use-an-aggregator-file">Project: How to Use an Aggregator File</h2>
<p>Follow the steps below to learn how to use an aggregator file.</p>
<h3 id="heading-step-1-create-a-project-directory-2">Step 1: Create a project directory</h3>
<p>Create a project folder—where this project's HTML and module files will reside.</p>
<h3 id="heading-step-2-create-your-code-files-2">Step 2: Create your code files</h3>
<p>Create the following files inside your project folder:</p>
<ol>
<li><code>index.html</code></li>
<li><code>index.js</code></li>
<li><code>preferences.js</code></li>
<li><code>calculation.js</code></li>
<li><code>bio.js</code></li>
</ol>
<h3 id="heading-step-3-add-the-modules-to-your-html-document-1">Step 3: Add the modules to your HTML document</h3>
<p>Open your <code>index.html</code> file and replicate the code below:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>How to use an aggregator file - ES Module Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Check the console<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"preferences.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"calculation.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"bio.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Here are the main things we did in the HTML snippet above:</p>
<ol>
<li>We added the four JavaScript files to our HTML document.</li>
<li>We used the <code>type="module"</code> attribute to convert the regular JavaScript files to ES module files.</li>
</ol>
<h3 id="heading-step-4-export-items-from-your-preference-module">Step 4: Export items from your <code>preference</code> module</h3>
<p>Open your <code>preferences.js</code> module and export some items from it like so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bestFruits = [<span class="hljs-string">"Grape"</span>, <span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Pineapple"</span>, <span class="hljs-string">"Lemon"</span>];
<span class="hljs-keyword">const</span> bestColor = <span class="hljs-string">"White"</span>;
<span class="hljs-keyword">const</span> bestNumber = <span class="hljs-number">111</span>;
<span class="hljs-keyword">const</span> bestClub = <span class="hljs-string">"Your Club"</span>;
<span class="hljs-keyword">const</span> bestTime = <span class="hljs-string">"Now"</span>;

<span class="hljs-keyword">export</span> { bestClub, bestFruits };
</code></pre>
<h3 id="heading-step-5-export-items-from-your-calculation-module">Step 5: Export items from your <code>calculation</code> module</h3>
<p>Open your <code>calculation.js</code> module and export some items from it like so:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">x, y</span>) </span>{
  <span class="hljs-keyword">return</span> x + y;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subtract</span>(<span class="hljs-params">x, y</span>) </span>{
  <span class="hljs-keyword">return</span> x - y;
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">multiply</span>(<span class="hljs-params">x, y</span>) </span>{
  <span class="hljs-keyword">return</span> x * y;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">divide</span>(<span class="hljs-params">x, y</span>) </span>{
  <span class="hljs-keyword">return</span> x / y;
}
</code></pre>
<h3 id="heading-step-6-export-items-from-your-bio-module">Step 6: Export items from your <code>bio</code> module</h3>
<p>Open your <code>bio.js</code> module and export some items from it like so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> aboutMe = {
  <span class="hljs-attr">firstName</span>: <span class="hljs-string">"Oluwatobi"</span>,
  <span class="hljs-attr">lastName</span>: <span class="hljs-string">"Sofela"</span>, 
  <span class="hljs-attr">companyName</span>: <span class="hljs-string">"CodeSweetly"</span>,
  <span class="hljs-attr">profession</span>: <span class="hljs-string">"Web Developer"</span>,
  <span class="hljs-attr">gender</span>: <span class="hljs-string">"Male"</span>,
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> aboutMe;
</code></pre>
<h3 id="heading-step-7-import-the-exported-features">Step 7: Import the exported features</h3>
<p>To import the exported items into your top-level module, you have two options:</p>
<ol>
<li>Import directly from the exporting modules to your top-level script.</li>
<li>Import from an aggregator file to your top-level module.</li>
</ol>
<p>Let's see the difference between the two options.</p>
<h4 id="heading-import-directly-from-the-exporting-modules-to-your-top-level-script">Import directly from the exporting modules to your top-level script</h4>
<p>One way to import your code is to import it directly from the exporting scripts to your top-level module.</p>
<p>For instance, open your <code>index.js</code> file and import the exported content of the <code>preferences.js</code>, <code>calculation.js</code>, and <code>bio.js</code> modules like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// index.js</span>

<span class="hljs-keyword">import</span> { bestFruits } <span class="hljs-keyword">from</span> <span class="hljs-string">"./preferences.js"</span>;
<span class="hljs-keyword">import</span> { multiply } <span class="hljs-keyword">from</span> <span class="hljs-string">"./calculation.js"</span>;
<span class="hljs-keyword">import</span> aboutMe <span class="hljs-keyword">from</span> <span class="hljs-string">"./bio.js"</span>;

<span class="hljs-keyword">const</span> news = <span class="hljs-string">`All <span class="hljs-subst">${aboutMe.companyName}</span>'s staff gave Tom <span class="hljs-subst">${multiply(<span class="hljs-number">7</span>, <span class="hljs-number">129</span>)}</span> <span class="hljs-subst">${bestFruits[<span class="hljs-number">2</span>]}</span>s.`</span>;

<span class="hljs-built_in">console</span>.log(news);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-dqmd1u?devtoolsheight=33&amp;file=index.js"><strong>Try it on StackBlitz</strong></a></p>
<p>You can see that we imported items directly from three exporting scripts into the <code>index.js</code> module.</p>
<p>The above importation technique works OK. However, a cleaner alternative is to use an aggregator file. Let's see how.</p>
<h4 id="heading-import-from-an-aggregator-file-to-your-top-level-module">Import from an aggregator file to your top-level module</h4>
<p>An alternate way to bring in your code is to import it from an aggregator file to your top-level module.</p>
<p>Follow the steps below to see how you can create and use an aggregator file.</p>
<h5 id="heading-1-create-the-aggregator-file">1. Create the aggregator file</h5>
<p>You can name the file <code>aggregator.js</code> or any other name you prefer.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/module-tutorial-aggregator-file-highlight-codesweetly.png" alt="Create an aggregator file - Modules Tutorial" width="600" height="400" loading="lazy">
<em>A highlight of the project's aggregator file</em></p>
<h5 id="heading-2-add-the-aggregator-script-to-your-html-file">2. Add the aggregator script to your HTML file</h5>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>How to use an aggregator file - ES Module Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Check the console<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"preferences.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"calculation.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"bio.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"aggregator.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Note the following:</p>
<ol>
<li><code>index.js</code> is the <a target="_blank" href="https://www.codesweetly.com/web-tech-glossary#top-level-module-javascript">top-level module</a> because it is the file where we imported and used <code>preferences.js</code>, <code>calculation.js</code>, and <code>bio.js</code>.</li>
<li><code>preferences.js</code>, <code>calculation.js</code>, and <code>bio.js</code> are the <a target="_blank" href="https://www.codesweetly.com/web-tech-glossary#submodule-javascript">submodules</a> because they are the files we imported into the top-level module.</li>
<li><code>aggregator.js</code> is the <a target="_blank" href="https://www.codesweetly.com/web-tech-glossary#parent-module-es-module">parent module</a> because it is the script for aggregating and re-exporting the three submodules.</li>
</ol>
<p>Technically, you can indicate just the top-level module in your project's HTML file like so:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>How to use an aggregator file - ES Module Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Check the console<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>By so doing, you avoid cluttering your HTML page with the submodules and parent module.</p>
<p>Let's now see how to use the aggregator module.</p>
<h5 id="heading-3-use-the-aggregator-module-to-aggregate-the-submodules">3. Use the aggregator module to aggregate the submodules</h5>
<p>Here's how to use the aggregator module to import and re-export all your project's exported items:</p>
<pre><code class="lang-js"><span class="hljs-comment">// aggregator.js</span>

<span class="hljs-keyword">import</span> { bestFruits } <span class="hljs-keyword">from</span> <span class="hljs-string">"./preferences.js"</span>;
<span class="hljs-keyword">import</span> { multiply } <span class="hljs-keyword">from</span> <span class="hljs-string">"./calculation.js"</span>;
<span class="hljs-keyword">import</span> aboutMe <span class="hljs-keyword">from</span> <span class="hljs-string">"./bio.js"</span>;

<span class="hljs-keyword">export</span> { bestFruits, multiply, aboutMe };
</code></pre>
<p>You can see that we used the aggregator file only to import and re-export our project's exported features.</p>
<p>The shorthand way to write the <code>import</code>/<code>export</code> statements above is like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// aggregator.js</span>

<span class="hljs-keyword">export</span> { bestFruits } <span class="hljs-keyword">from</span> <span class="hljs-string">"./preferences.js"</span>;
<span class="hljs-keyword">export</span> { multiply } <span class="hljs-keyword">from</span> <span class="hljs-string">"./calculation.js"</span>;
<span class="hljs-keyword">export</span> { <span class="hljs-keyword">default</span> <span class="hljs-keyword">as</span> aboutMe } <span class="hljs-keyword">from</span> <span class="hljs-string">"./bio.js"</span>;
</code></pre>
<p>Keep in mind that the following syntax is invalid:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> aboutMe <span class="hljs-keyword">from</span> <span class="hljs-string">"./bio.js"</span>;
</code></pre>
<p>In other words, whenever you use the <code>export...from</code> syntax to re-export a default export, make sure that you rename the re-exportation like so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> { <span class="hljs-keyword">default</span> <span class="hljs-keyword">as</span> aboutMe } <span class="hljs-keyword">from</span> <span class="hljs-string">"./bio.js"</span>;
</code></pre>
<p>Let's now see how to import the re-exported features from an aggregator file.</p>
<h5 id="heading-4-import-your-exports-from-the-aggregator-file">4. Import your exports from the aggregator file</h5>
<p>Once you've aggregated all your submodules into the aggregator module, go to your top-level script (<code>index.js</code> in this case) and import the exported items.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// index.js</span>

<span class="hljs-keyword">import</span> { bestFruits, multiply, aboutMe } <span class="hljs-keyword">from</span> <span class="hljs-string">"./aggregator.js"</span>;

<span class="hljs-keyword">const</span> news = <span class="hljs-string">`All <span class="hljs-subst">${aboutMe.companyName}</span>'s staff gave Tom <span class="hljs-subst">${multiply(<span class="hljs-number">7</span>, <span class="hljs-number">129</span>)}</span> <span class="hljs-subst">${bestFruits[<span class="hljs-number">2</span>]}</span>s.`</span>;

<span class="hljs-built_in">console</span>.log(news);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-fttqqb?devtoolsheight=33&amp;file=index.js"><strong>Try it on StackBlitz</strong></a></p>
<p>You see, like magic, we've cleaned up our code by replacing three <code>import</code> statements with a single line!</p>
<p>Using an aggregator file to collate your project's exports helps separate concerns and makes your top-level module neater.</p>
<p>Up till now, we've used the static <code>import</code> syntax to instruct the computer to evaluate our imported modules' code at load time.</p>
<p>But suppose you prefer to load your modules conditionally or on-demand. In that case, you can use the dynamic <code>import()</code> syntax. Let's see exactly how it works below.</p>
<h2 id="heading-how-to-use-the-import-syntax-to-load-a-module-dynamically">How to Use the <code>import()</code> Syntax to Load a Module Dynamically</h2>
<p>To load your module conditionally or on-demand, use the <code>import()</code> syntax like so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span>(<span class="hljs-string">"./module/relative-path.js"</span>).then(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">module</span>) </span>{ });
</code></pre>
<p>The <code>import()</code> syntax does two main things:</p>
<ol>
<li>It loads its module specifier argument (<code>"./module/relative-path.js"</code> in this case).</li>
<li>It returns a promise object that resolves to a module object containing the import specifier's exports.</li>
</ol>
<p>So, since the <code>import()</code> syntax returns a promise, you can also use the <code>await</code> keyword with it.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> <span class="hljs-built_in">module</span> = <span class="hljs-keyword">await</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">"./module/relative-path.js"</span>);
</code></pre>
<p><strong>Note:</strong> Although <code>import()</code> resembles a function call, it is not. Instead, the <code>import()</code> code is a special ES modules syntax that uses parentheses (similar to the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super"><code>super()</code></a> syntax).</p>
<p>Therefore, you cannot <a target="_blank" href="https://www.codesweetly.com/call-apply-bind-javascript/#what-is-the-call-method">call</a>, <a target="_blank" href="https://www.codesweetly.com/call-apply-bind-javascript/#what-is-the-apply-method">apply</a>, or <a target="_blank" href="https://www.codesweetly.com/call-apply-bind-javascript/#what-is-the-bind-method">bind</a> the <code>import()</code> syntax because it does not inherit <code>Function.prototype</code>'s properties.</p>
<p>To see precisely how <code>import()</code> works in practice, let's update our previous project by following the steps below.</p>
<h3 id="heading-1-update-your-html-file">1. Update your HTML file</h3>
<p>Open your <code>index.html</code> file and do the following:</p>
<ol>
<li>Update your <code>&lt;h1&gt;</code>'s content to "The Latest News".</li>
<li>Substitute the <code>&lt;h2&gt;</code> element with an empty <code>&lt;p&gt;</code> element.</li>
<li>Create a <code>&lt;button&gt;</code> element.</li>
</ol>
<p>In other words, your <code>index.html</code> file should look like this:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>The Latest News<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"news-paragraph"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"news-button"</span>&gt;</span>Get the News<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h3 id="heading-2-update-your-indexjs-module">2. Update your <code>index.js</code> module</h3>
<p>Open your <code>index.js</code> file and replicate the code below:</p>
<pre><code class="lang-js"><span class="hljs-comment">// index.js</span>

<span class="hljs-keyword">const</span> paragraphElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"news-paragraph"</span>);
<span class="hljs-keyword">const</span> buttonElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"news-button"</span>);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">displayNews</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> news = <span class="hljs-literal">null</span>;
  <span class="hljs-comment">// highlight-next-line</span>
  <span class="hljs-keyword">const</span> aggregatorModule = <span class="hljs-keyword">await</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">"./aggregator.js"</span>);

  news = <span class="hljs-string">`All <span class="hljs-subst">${aggregatorModule.aboutMe.companyName}</span>'s staff gave Tom <span class="hljs-subst">${aggregatorModule.multiply(<span class="hljs-number">7</span>, <span class="hljs-number">129</span>)}</span> <span class="hljs-subst">${aggregatorModule.bestFruits[<span class="hljs-number">2</span>]}</span>s.`</span>;

  paragraphElement.innerText = news;
}

buttonElement.addEventListener(<span class="hljs-string">"click"</span>, displayNews);
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-pw3xpq?file=index.js"><strong>Try it on StackBlitz</strong></a></p>
<p>You can see how we used the <code>import()</code> method to load the aggregator module on demand (when a user clicks the button)—rather than upfront.</p>
<p>Although dynamic importation can improve your program's initial load-time performance, it's best to use it only when needed.</p>
<p><strong>Note:</strong> The <code>import()</code> method does not require its <a target="_blank" href="https://www.codesweetly.com/javascript-arguments">argument</a> to have a <code>&lt;script&gt;</code> of <code>type="module"</code>. Therefore, you can use it in a regular JavaScript file.</p>
<p>Now, suppose you wish to get <a target="_blank" href="https://en.wikipedia.org/wiki/Metadata">metadata</a> about your current module. In that case, you can use the <code>import.meta</code> syntax.</p>
<h2 id="heading-what-exactly-is-importmeta-in-es-modules">What Exactly Is <code>import.meta</code> in ES Modules?</h2>
<p>The <code>import.meta</code> code is an object containing information about your current module.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>About import.meta<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Check the console ⬇⬇⬇<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript">
      <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">import</span>.meta);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">import</span>.meta.url);
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p><a target="_blank" href="https://stackblitz.com/edit/web-platform-8ky5vd?devtoolsheight=33&amp;file=index.html"><strong>Try it on StackBlitz</strong></a></p>
<p>The <code>import.meta</code> code in the snippet above will return some information about the module in which it got used.</p>
<h2 id="heading-quick-review-of-modules-so-far">Quick Review of Modules So Far</h2>
<p>We've learned that a JavaScript module is simply a file with an add-on capability to share its code with other modules within a project—or <a target="_blank" href="https://www.codesweetly.com/package-manager-explained/#how-to-publish-your-project-to-the-npm-registry">with the world</a> through package managers like Yarn and NPM.</p>
<p>We also used a local server to load our HTML documents via an <code>http://</code> scheme—which made browsers load our apps without throwing any CORS error.</p>
<p>However, live servers are limited to local developments and testing purposes.</p>
<p>In other words, you cannot use a live server in production to serve your HTML document via an <code>http://</code> scheme. Instead, it would be best if you used a <em>module bundler</em>.</p>
<p>But what exactly is a module bundler, I hear you ask? Let's find out below.</p>
<h2 id="heading-what-is-a-module-bundler">What Is a Module Bundler?</h2>
<p>A <strong>module bundler</strong> is a tool developers use to bundle an app's <a class="post-section-overview" href="#heading-what-exactly-is-a-javascript-module-2">modules</a> and dependencies into a single browser-compatible JavaScript file.</p>
<h2 id="heading-why-do-you-need-a-module-bundler">Why Do You Need a Module Bundler?</h2>
<p>Module bundlers allow browsers to access the file you specified in a <code>require()</code> or <code>import</code> statement.</p>
<p>In other words, suppose a browser runs a JavaScript file with a <code>require("./node_module/test/sample/app.js")</code> statement. In such a case, the browser will throw an error that says <code>Uncaught ReferenceError: require is not defined</code>.</p>
<p>The computer will throw such an error because browsers cannot access files specified in a JavaScript program.</p>
<p>However, you can use a module bundler to create a new JavaScript file containing code browsers can read.</p>
<h2 id="heading-how-does-a-module-bundler-work">How Does a Module Bundler Work?</h2>
<p>A module bundler does its bundling work as follows:</p>
<h3 id="heading-first-it-creates-an-output-script-file">First, it creates an output script file</h3>
<p>The module bundler will first create an "output script file" in your project's <code>dist</code> folder.</p>
<p><strong>Note:</strong></p>
<ul>
<li>The bundler uses the <em>output script file</em> to save the bundled code.</li>
<li>An <strong>output file</strong> is the compiled version of an entry file. In other words, an output script file refers to the JavaScript file a bundler generates automatically for your project.</li>
<li>An <strong>entry point</strong> is a file that a bundler uses to start building a <a target="_blank" href="https://webpack.js.org/concepts/dependency-graph/">dependency graph</a> of all the project's modules it needs to combine into a single browser-compatible module.</li>
<li>An entry point is the most critical file of a build step that links (directly or indirectly) to every other module in a project.</li>
</ul>
<h3 id="heading-next-the-module-bundler-compiles-your-code">Next, the module bundler compiles your code</h3>
<p>Secondly, the bundler will check the build step's entry point for any occurrence of some <code>require()</code> or <code>import</code> statements.</p>
<p>Suppose the module bundler finds a <code>require()</code> or <code>import</code> statement. In such a case, the bundler will compile (combine) the content of each dependency specified in the statements with the entry point's content.</p>
<p><strong>Note:</strong></p>
<ul>
<li>A <strong>build step</strong> is a process through which a module bundler builds a new browser compatible JavaScript file.</li>
<li>A build step's output file is sometimes called a <strong>distribution code</strong>. In other words, distribution code is the minified and optimized source code version.</li>
<li>A <strong>dependency</strong> is a file your script requires to work as intended. So, in <code>import { variable } from "./path/to/module.js"</code>, <code>module.js</code> is the dependency file because it is a script our app depends on to function as designed.</li>
</ul>
<p>Let's now discuss the last thing a module bundler does.</p>
<h3 id="heading-finally-it-saves-the-compiled-code">Finally, it saves the compiled code</h3>
<p>A module bundler's last step is to save the compiled code into <a class="post-section-overview" href="#heading-first-it-creates-an-output-script-file">step 1</a>'s output script file.</p>
<p>As a result, step 1's script file (the build step's output) will contain the content of the entry point and its dependencies—but no <code>require()</code> or <code>import</code> statements.</p>
<p><strong>Note:</strong> Typical examples of module bundlers are <a target="_blank" href="https://webpack.js.org">webpack</a>, <a target="_blank" href="http://browserify.org/">browserify</a>, <a target="_blank" href="https://rollupjs.org/guide/en/">rollup</a>, and <a target="_blank" href="https://parceljs.org/">parcel</a>.</p>
<p>So, now that we know how a module bundler works, let's discuss how to use a popular one—<em>Webpack</em>.</p>
<h2 id="heading-how-to-use-webpack">How to Use Webpack</h2>
<p>Follow the steps below to learn how to use Webpack to bundle your project's JavaScript file and its dependencies into a single output script file.</p>
<h3 id="heading-step-1-create-a-project-directory-3">Step 1: Create a project directory</h3>
<p>Create a project folder—where this project's files will reside.</p>
<h3 id="heading-step-2-go-to-the-projects-root-folder">Step 2: Go to the project's root folder</h3>
<p>Using the command line, navigate to the root directory of your project like so:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> path/to/project/root-directory
</code></pre>
<p><strong>Note:</strong> A <strong>root directory</strong> is a folder containing all other files and sub-folders of a specific project.</p>
<p>In other words, the folder you created in step 1 is your root folder because it will house everything concerning this particular project.</p>
<h3 id="heading-step-3-create-a-packagejson-file">Step 3: Create a <code>package.json</code> file</h3>
<p>Create a <a target="_blank" href="https://www.codesweetly.com/package-json-file-explained">package.json</a> file in your project's root directory like so:</p>
<pre><code class="lang-bash">npm init -y
</code></pre>
<p>Alternatively, you can use Yarn like this:</p>
<pre><code class="lang-bash">yarn init -y
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>The <code>-y</code> flag instructs NPM (or Yarn) to <a target="_blank" href="https://www.codesweetly.com/package-json-file-explained/#how-to-create-a-default-packagejson-file">create a default <code>package.json</code> file</a>.</li>
<li>You must have Node and NPM installed on your system for the initialization code above to work. You can get both by installing the latest LTS version from the <a target="_blank" href="https://nodejs.org/en/">Node.js</a> website.</li>
</ul>
<h3 id="heading-step-4-install-the-webpack-module-bundler">Step 4: Install the Webpack module bundler</h3>
<p>Install <code>webpack</code> and <code>webpack-cli</code> locally into your project as <a target="_blank" href="https://www.codesweetly.com/package-manager-explained/#npm-installation-command">development dependency</a> libraries:</p>
<pre><code class="lang-bash">npm install webpack webpack-cli --save-dev
</code></pre>
<p>Or, if your package manager is Yarn, run:</p>
<pre><code class="lang-bash">yarn add webpack webpack-cli --dev
</code></pre>
<p><strong>Note:</strong> The <code>webpack-cli</code> package makes running webpack on the command line possible.</p>
<h3 id="heading-step-5-create-your-projects-directories">Step 5: Create your project's directories</h3>
<p>Create a "source" code folder (<code>./src</code>) and a "distribution" code folder (<code>./dist</code>).</p>
<pre><code class="lang-bash">mkdir src dist
</code></pre>
<p><strong>Note:</strong> Although <code>src</code> and <code>dist</code> are the names typically given to the source and distribution code's folders, you are free to choose any other name you prefer.</p>
<h3 id="heading-step-6-create-your-source-code-files">Step 6: Create your source code files</h3>
<p>Create the following files inside the newly created source code directory:</p>
<ol>
<li><code>index.html</code></li>
<li><code>index.js</code></li>
</ol>
<p><strong>Note:</strong></p>
<ul>
<li>Webpack recommends saving <a target="_blank" href="https://www.codesweetly.com/web-tech-glossary#source-code">source code</a> in a <code>./src</code> directory and <a target="_blank" href="https://www.codesweetly.com/web-tech-glossary#distribution-code">distribution code</a> in a <code>./dist</code> directory.</li>
<li>Webpack does not alter any other code apart from the <code>require()</code>, <code>import</code>, and <code>export</code> statements.</li>
</ul>
<h3 id="heading-step-7-add-the-javascript-file-to-your-html-document">Step 7: Add the JavaScript file to your HTML document</h3>
<p>Open your <code>index.html</code> file and replicate the code below:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"body"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Module Bundler Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"button"</span>&gt;</span>Click Me to Change Color!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Here are the main things we did in the HTML snippet above:</p>
<ol>
<li>We created a <code>&lt;h1&gt;</code> and <code>&lt;button&gt;</code> element.</li>
<li>We added step 6's JavaScript file to our HTML document.</li>
</ol>
<p><strong>Note:</strong> When using a bundler, you do not need to add the <code>type="module"</code> attribute to your project's <code>&lt;script&gt;</code> element. Instead, the bundler will automatically treat all scripts containing <code>import</code> and <code>export</code> statements as modules.</p>
<h3 id="heading-step-8-install-some-dependencies">Step 8: Install some dependencies</h3>
<p>Using your text editor, <a target="_blank" href="https://www.codesweetly.com/package-manager-explained/#local-package-installation">install your project's dependencies locally</a>.</p>
<p>For instance, here's how you can install the <a target="_blank" href="https://www.npmjs.com/package/randomcolor">randomColor</a> package as a local dependency:</p>
<pre><code class="lang-bash">npm install randomcolor --save
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>Use the <code>npm install package-name --save</code> command for dependencies your app needs in production.</li>
<li>Use the <code>npm install package-name --save-dev</code> command for dependencies your app only needs for its local development and testing purposes.</li>
</ul>
<p>Alternatively, you can use Yarn like so:</p>
<pre><code class="lang-bash">yarn add randomcolor
</code></pre>
<p><strong>Note:</strong> Use the <code>yarn add package-name --dev</code> command for dependencies your app only needs for its local development and testing purposes.</p>
<h3 id="heading-step-9-import-your-dependencies">Step 9: Import your dependencies</h3>
<p>Import your dependencies into your JavaScript source code with the <code>require()</code> method or the <code>import</code> statement.</p>
<p>For instance, here's how to use the <code>import</code> statement to bring in step 8's <code>randomColor</code> dependency into your <code>index.js</code> script file:</p>
<pre><code class="lang-js"><span class="hljs-comment">// index.js</span>

<span class="hljs-keyword">import</span> randomColor <span class="hljs-keyword">from</span> <span class="hljs-string">"randomcolor"</span>;
</code></pre>
<p>The <code>require()</code> method equivalence of the snippet above is like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// index.js</span>

<span class="hljs-keyword">const</span> randomColor = <span class="hljs-built_in">require</span>(<span class="hljs-string">"randomcolor"</span>);
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li>The <code>import</code> statement is JavaScript's native way of importing modules.</li>
<li>The <code>require()</code> function is the CommonJS syntax for importing modules into a script.</li>
<li>An alternative way to import your project's dependencies is to implicitly load them with your HTML document's <code>&lt;script&gt;</code> tag. However, such a technique pollutes the global scope. So, using the <code>import</code> or <code>require()</code> syntax is better.</li>
</ul>
<h3 id="heading-step-10-use-the-dependencies">Step 10: Use the dependencies</h3>
<p>Use the dependencies you imported in step 9 to do as you desire.</p>
<p>For instance, here's how you may use the <code>randomColor</code> dependency:</p>
<pre><code class="lang-js"><span class="hljs-comment">// index.js</span>

<span class="hljs-keyword">import</span> randomColor <span class="hljs-keyword">from</span> <span class="hljs-string">"randomcolor"</span>;

<span class="hljs-keyword">const</span> bodyElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"body"</span>);
<span class="hljs-keyword">const</span> buttonElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"button"</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeBodyColor</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> color = randomColor();
  bodyElement.style.backgroundColor = color;
}

buttonElement.addEventListener(<span class="hljs-string">"click"</span>, changeBodyColor);
</code></pre>
<p>In the snippet above, we told the computer that whenever a user clicks the <code>buttonElement</code>, it should:</p>
<ol>
<li>Invoke the <code>changeBodyColor</code> function.</li>
<li>Initialize the function's <code>color</code> variable with <code>randomColor</code>'s <a target="_blank" href="https://www.codesweetly.com/declaration-initialization-invocation-in-programming/#what-does-invocation-mean-in-programming">invocation</a> output.</li>
<li>Use the <code>color</code> variable's value to style the <code>bodyElement</code>'s background color.</li>
</ol>
<p>Let's now bundle up our entry point (the <code>index.js</code> file) and the <code>randomColor</code> dependency into a single JavaScript file.</p>
<h3 id="heading-step-11-start-the-build-step">Step 11: Start the build step</h3>
<p>Using your terminal, create your bundle by running webpack like so:</p>
<pre><code class="lang-bash">npx webpack
</code></pre>
<p>After running the command above, webpack will do the following:</p>
<ol>
<li>It will use your <code>index.js</code> as its entry point.</li>
<li>It will create a bundle (the output file) in your project's <code>dist</code> folder containing the content of the entry point and its dependencies.</li>
</ol>
<p><strong>Note:</strong></p>
<ul>
<li>By default, Webpack generates its bundle as a <code>main.js</code> file—which it will save in the distribution folder you created in step 5. However, you can change the default setting by creating a configuration file—which Webpack will use automatically. We will discuss creating and using a configuration file <a class="post-section-overview" href="#heading-what-exactly-is-webpacks-configuration-file-3">later</a> in this guide.</li>
<li><a target="_blank" href="https://nodejs.dev/learn/the-npx-nodejs-package-runner">NPX</a> is Node's package runner that will automatically find and execute Webpack.</li>
</ul>
<p>Our next step is to tell browsers to use the newly created bundle. Let's do that below.</p>
<h3 id="heading-step-12-refer-browsers-to-the-newly-created-bundle">Step 12: Refer browsers to the newly created bundle</h3>
<p>So, now that you have created a browser-compatible bundle file, you need to tell browsers to use it instead of the <code>index.js</code> source code file.</p>
<p>Therefore, go to your HTML file and substitute the reference to your JavaScript source code with Webpack's distribution bundle.</p>
<p>For instance, instead of using <code>"./index.js"</code> in the <code>&lt;script&gt;</code> tag of your HTML file, you would use <code>"../dist/main.js"</code> like so:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"body"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Module Bundler Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"button"</span>&gt;</span>Click Me to Change Color!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"../dist/main.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Let's now see our app!</p>
<h3 id="heading-step-13-check-your-app-in-the-browser">Step 13: Check your app in the browser</h3>
<p>Open your HTML file in the browser to confirm that the browser can successfully read your app and its dependencies.</p>
<p>Remember that you created your HTML file manually in <a class="post-section-overview" href="#heading-step-6-create-your-source-code-files">step 6</a>. However, Webpack can also auto-generate one for you. Let's find out how.</p>
<h2 id="heading-how-to-make-webpack-auto-generate-your-apps-html-file">How to Make Webpack Auto-Generate Your App's HTML File</h2>
<p>Suppose your app is now outputting multiple bundles, or you've started <a target="_blank" href="https://www.codesweetly.com/javascript-module-bundler#substitutions-technique-3-content-hash">using hashes</a> to create unique filenames. In that case, you may find it increasingly difficult to manage your HTML file manually.</p>
<p>Therefore, Webpack allows you to use the <a target="_blank" href="https://webpack.js.org/plugins/html-webpack-plugin/">HtmlWebpackPlugin</a> to auto-generate and manage your project's <code>index.html</code> file.</p>
<p>Follow the steps below to learn how to use <code>HtmlWebpackPlugin</code> to auto-generate and manage your project's HTML file.</p>
<h3 id="heading-step-1-install-htmlwebpackplugin">Step 1: Install <code>HtmlWebpackPlugin</code></h3>
<p>Install the <code>HtmlWebpackPlugin</code> like so:</p>
<pre><code class="lang-bash">npm install html-webpack-plugin --save-dev
</code></pre>
<p>Or, if your package manager is Yarn, use:</p>
<pre><code class="lang-bash">yarn add html-webpack-plugin --dev
</code></pre>
<h3 id="heading-step-2-create-a-configuration-file">Step 2: Create a configuration file</h3>
<p>Create a Webpack configuration file in your project's <a target="_blank" href="https://www.codesweetly.com/web-tech-glossary#root-directory">root folder</a> like so:</p>
<pre><code class="lang-bash">touch webpack.config.js
</code></pre>
<h3 id="heading-step-3-add-the-plugin-to-webpacks-configuration">Step 3: Add the plugin to webpack's configuration</h3>
<p>Open your <code>webpack.config.js</code> file and add the <code>HtmlWebpackPlugin</code> plugin to it like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"html-webpack-plugin"</span>);

<span class="hljs-built_in">module</span>.exports = { 
  <span class="hljs-attr">plugins</span>: [<span class="hljs-keyword">new</span> HtmlWebpackPlugin()] 
}
</code></pre>
<p><strong>Note:</strong> We will discuss how to use a configuration file <a class="post-section-overview" href="#heading-what-exactly-is-webpacks-configuration-file-3">later</a> in this guide.</p>
<h3 id="heading-step-4-run-the-build-step">Step 4: Run the build step</h3>
<p>Once you've installed and added <code>HtmlWebpackPlug</code> into your project, recompile your modules like so:</p>
<pre><code class="lang-bash">npx webpack
</code></pre>
<p>After running the build step, <code>HtmlWebpackPlugin</code> will do the following:</p>
<ol>
<li>It will auto-generate a new <code>index.html</code> file.</li>
<li>The plugin will automatically insert the bundles that Webpack generated into the newly created HTML document.</li>
<li>It will auto-save the new HTML file inside your project's distribution folder.</li>
</ol>
<p>In other words, after running a build, the <code>new HtmlWebpackPlugin()</code>'s invocation (in the configuration file) will auto-generate a <code>dist/index.html</code> file with the following content:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!doctype <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Webpack App<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width,initial-scale=1"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">defer</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"main.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Notice that the HTML document generated by <code>HtmlWebpackPlugin</code> does not contain <a class="post-section-overview" href="#heading-step-7-add-the-javascript-file-to-your-html-document">your source file</a>'s <code>&lt;h1&gt;</code> and <code>&lt;button&gt;</code> elements.</p>
<p>In other words, suppose you open the <code>dist/index.html</code> file in the browser. In that case, the browser will open an empty HTML page.</p>
<p>The <code>HtmlWebpackPlugin</code> omitted the content of the source code's <code>&lt;body&gt;</code> element because it did not create the new file from the original document. Instead, it automatically created a brand-new HTML page that includes only the bundles Webpack generated.</p>
<p>However, you can also tell <code>HtmlWebpackPlugin</code> to use your source file as a template. Let's see how below.</p>
<h2 id="heading-how-to-make-htmlwebpackplugin-use-your-source-file-as-a-template-to-auto-generate-a-new-html-page">How to Make <code>HtmlWebpackPlugin</code> Use Your Source File as a Template to Auto-Generate a New HTML Page</h2>
<p>To make <code>HtmlWebpackPlugin</code> use your HTML source file as a template, do the following:</p>
<h3 id="heading-1-update-your-html-file-1">1. Update your HTML file</h3>
<p>Open your <code>index.html</code> <em>source code</em> file and delete the <code>&lt;script&gt;</code> tag you <a class="post-section-overview" href="#heading-step-12-refer-browsers-to-the-newly-created-bundle">previously used</a> to reference Webpack's distribution bundle.</p>
<p>So, your HTML source code should look like this:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"body"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Module Bundler Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"button"</span>&gt;</span>Click Me to Change Color!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>We deleted the distribution bundle's script because <code>HtmlWebpackPlugin</code> will automatically insert one while it auto-generates the new HTML file.</p>
<p><strong>Remember:</strong> The plugin will use your source code as a template to create the new file. Therefore, deleting the hand-coded bundle's reference helps avoid conflicting scripts.</p>
<p>Now, let's configure the plugin to use your source code as a template.</p>
<h3 id="heading-2-update-your-configuration-file">2.  Update your configuration file</h3>
<p>Open your project's <code>webpack.config.js</code> file and update <code>HtmlWebpackPlugin</code>'s settings like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"html-webpack-plugin"</span>);

<span class="hljs-built_in">module</span>.exports = { 
  <span class="hljs-attr">plugins</span>: [<span class="hljs-keyword">new</span> HtmlWebpackPlugin({
    <span class="hljs-attr">template</span>: <span class="hljs-string">"./src/index.html"</span>
  })] 
}
</code></pre>
<p>In the configuration snippet above, we did the following:</p>
<ol>
<li>We passed an object argument containing a <code>template</code> property to the <code>HtmlWebpackPlugin</code> function.</li>
<li>We initialized the <code>template</code> property with the path to our HTML source code.</li>
</ol>
<p>So, if you now run the <code>npx webpack</code> command, <code>HtmlWebpackPlugin</code> will use <code>./src/index.html</code> as a template to generate the new <code>dist/index.html</code> file.</p>
<p>Therefore, the newly created HTML distribution file will look like so:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!doctype <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>ES Module - CodeSweetly<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">defer</span>=<span class="hljs-string">"defer"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"main.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"body"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Module Bundler Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"button"</span>&gt;</span>Click Me to Change Color!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Suppose an <code>index.html</code> file already exists in your output (<code>dist</code>) directory. In that case, the new one generated by <code>HtmlWebpackPlugin</code> will replace the existing HTML file.</p>
<h3 id="heading-3-check-your-app-in-the-browser">3. Check your app in the browser</h3>
<p>Open the newly generated <code>dist/index.html</code> file in the browser to confirm that the browser can successfully read your app and its dependencies.</p>
<p><strong>Note:</strong></p>
<ul>
<li><code>HtmlWebpackPlugin</code> allows you to specify how and where you want it to generate your HTML file by providing specific <a target="_blank" href="https://github.com/jantimon/html-webpack-plugin#options">configuration options</a>. For instance, <code>new HtmlWebpackPlugin({ title: "A CodeSweetly Project" })</code> tells the plugin to use <code>"A CodeSweetly Project"</code> as the title of the generated HTML file.</li>
<li>Suppose you get an error message (for instance, <code>ReferenceError: __webpack_base_uri__ is not defined</code>). In that case, you likely need to update your Webpack dependency. You can do so by running <code>npm update webpack webpack-cli</code> on your terminal.</li>
</ul>
<h2 id="heading-important-stuff-to-know-about-updating-your-app">Important Stuff to Know about Updating Your App</h2>
<p>Whenever you make changes to your source code, make sure you do the following for your updates to reflect in the browser:</p>
<ol>
<li>Rerun the build step.</li>
<li>Refresh your browser.</li>
</ol>
<p>Repeating the manual process of running the build step and refreshing your browser can be burdensome. Luckily, Webpack provides a way to automate the two tasks. Let's find out how.</p>
<h2 id="heading-how-to-rerun-webpack-automatically">How to Rerun Webpack Automatically</h2>
<p>Suppose you wish to automate the process of rerunning the build step. In that case, you can add a <code>watch</code> property to your <a target="_blank" href="https://www.codesweetly.com/package-json-file-explained/">package.json</a>'s <code>scripts</code> field.</p>
<p>For instance, do the following:</p>
<h3 id="heading-1-add-watch-to-the-scripts-fields">1. Add <code>watch</code> to the <code>scripts</code> fields</h3>
<p>Open your project's <code>package.json</code> file and add a <code>watch</code> property to its <code>scripts</code> field like so:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"your_package"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,
    <span class="hljs-attr">"watch"</span>: <span class="hljs-string">"webpack --progress --watch"</span>
  }
}
</code></pre>
<p>The snippet above added a <code>"watch"</code> property—with the value <code>"webpack --progress --watch"</code>—to the <code>"scripts"</code> field of our <code>package.json</code> file.</p>
<h3 id="heading-2-run-the-watch-script">2. Run the <code>watch</code> script</h3>
<p>Using your terminal, invoke your <code>package.json</code>'s <code>watch</code> script like so:</p>
<pre><code class="lang-bash">npm run watch
</code></pre>
<p>Alternatively, you can use Yarn like this:</p>
<pre><code class="lang-bash">yarn run watch
</code></pre>
<p>Once you've invoked the <code>watch</code> script, NPM will execute <code>"webpack --progress --watch"</code>.</p>
<h3 id="heading-what-is-webpack-progress-watch">What is <code>"webpack --progress --watch"</code>?</h3>
<p>The <code>"webpack --progress --watch"</code> command instructs NPM to:</p>
<ol>
<li>Run Webpack.</li>
<li>Pass the <code>--progress</code> and <code>--watch</code> options to Webpack's configuration.</li>
</ol>
<p>The <code>--progress</code> option will make NPM show the percentage progress of Webpack's compilation.</p>
<p>The <code>--watch</code> option activates Webpack's watch mode.</p>
<p>In other words, <code>--watch</code> instructs Webpack to watch and automatically recompile your modules each time you save changes to files within your dependency graph.</p>
<p>As an example, go to your <code>index.js</code> file and add a <code>console.log</code> statement to the <code>changeBodyColor()</code> function like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// index.js</span>

<span class="hljs-keyword">import</span> randomColor <span class="hljs-keyword">from</span> <span class="hljs-string">"randomcolor"</span>;

<span class="hljs-keyword">const</span> bodyElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"body"</span>);
<span class="hljs-keyword">const</span> buttonElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"button"</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeBodyColor</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> color = randomColor();
  bodyElement.style.backgroundColor = color;
  <span class="hljs-built_in">console</span>.log(color);
}

buttonElement.addEventListener(<span class="hljs-string">"click"</span>, changeBodyColor);
</code></pre>
<p>Afterward, save your changes. Then refresh your browser.</p>
<p>After the refresh, do the following:</p>
<ol>
<li>Open your browser's console.</li>
<li>Click your app's <code>"Click Me to Change Color!"</code> button.</li>
</ol>
<p>You can see that the <code>--watch</code> flag automatically recompiled your modules when you saved your source code's changes.</p>
<p>Therefore, you no longer need to run the <code>npx webpack</code> command manually again. Instead, the <code>--watch</code> flag will watch and automatically recompile your modules whenever you save changes.</p>
<p><strong>Note:</strong></p>
<ul>
<li>After running <code>npm run watch</code>, your currently opened terminal will continue to process the <code>watch</code> command's activities. So, you won't be able to input any command on that terminal until you stop <code>watch</code>'s execution. However, you can open a new terminal window to use simultaneously with the one processing <code>watch</code>. In other words, use one terminal to run <code>watch</code> and another to input commands.</li>
<li>To stop <code>watch</code>'s execution, use <code>ctrl + c</code> on windows or <code>cmd + c</code> on mac.</li>
<li>You can rename the <code>"watch"</code> key (or any other <a target="_blank" href="https://www.codesweetly.com/package-json-file-explained/#scripts">scripts' key</a>) to any other name you prefer.</li>
<li>You can ignore watching huge folders like <code>node_modules</code> by adding them to the <a target="_blank" href="https://webpack.js.org/configuration/watch/#watchoptionsignored">watchOptions.ignored</a> field of your project's <a target="_blank" href="https://www.codesweetly.com/javascript-module-bundler#what-exactly-is-webpacks-configuration-file">configuration file</a>.</li>
</ul>
<p>So, now that we know how to automate Webpack's execution, let's discuss how to reload the browser automatically.</p>
<h2 id="heading-how-to-reload-the-browser-automatically">How to Reload the Browser Automatically</h2>
<p>Suppose you wish to automate the process of reloading your browser. In that case, you can use Webpack's <a target="_blank" href="https://github.com/webpack/webpack-dev-server">dev server</a> package.</p>
<p>The following steps will show you how to configure and use the package.</p>
<h3 id="heading-step-1-install-webpacks-web-server">Step 1: Install webpack's web server</h3>
<p>Using your terminal, install the <code>webpack-dev-server</code> package like so:</p>
<pre><code class="lang-bash">npm install webpack-dev-server --save-dev
</code></pre>
<p>Or, if your package manager is Yarn, run:</p>
<pre><code class="lang-bash">yarn add webpack-dev-server --dev
</code></pre>
<p><strong>Note:</strong> The <code>webpack-dev-server</code> package enables watch mode by default. Therefore, you do not need to enable a <code>watch</code> script manually whenever you use the dev server.</p>
<p>In other words, once you've decided to use Webpack's dev server, do the following:</p>
<ol>
<li>Use <code>ctrl + c</code> on windows or <code>cmd + c</code> on mac to stop <code>watch</code>'s execution (if the script is still running).</li>
<li>Delete the <code>watch</code> property you <a class="post-section-overview" href="#heading-how-to-rerun-webpack-automatically-1">previously added</a> to your <code>package.json</code> file.</li>
</ol>
<h3 id="heading-step-2-specify-your-files-location">Step 2: Specify your files' location</h3>
<p>Tell the web server where it should get the files that Webpack did not generate by adding a <code>devServer</code> option to the configuration file you <a class="post-section-overview" href="#heading-step-2-create-a-configuration-file">created previously</a>:</p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"html-webpack-plugin"</span>);

<span class="hljs-built_in">module</span>.exports = { 
  <span class="hljs-attr">plugins</span>: [<span class="hljs-keyword">new</span> HtmlWebpackPlugin({
    <span class="hljs-attr">template</span>: <span class="hljs-string">"./src/index.html"</span>
  })],
  <span class="hljs-attr">devServer</span>: {
    <span class="hljs-attr">static</span>: <span class="hljs-string">"./dist"</span>
  }
}
</code></pre>
<p>The configuration snippet above tells the dev server to serve contents Webpack did not build from the project's <code>dist</code> folder.</p>
<p>Note that the dev server serves files on <code>localhost:8080</code> by default. However, you can specify the port you wish to use by adding a <code>port</code> property to the <code>devServer</code> option like so:</p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"html-webpack-plugin"</span>);

<span class="hljs-built_in">module</span>.exports = { 
  <span class="hljs-attr">plugins</span>: [<span class="hljs-keyword">new</span> HtmlWebpackPlugin({
    <span class="hljs-attr">template</span>: <span class="hljs-string">"./src/index.html"</span>
  })],
  <span class="hljs-attr">devServer</span>: {
    <span class="hljs-attr">static</span>: <span class="hljs-string">"./dist"</span>,
    <span class="hljs-attr">port</span>: <span class="hljs-number">5001</span>
  }
}
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li><code>webpack-dev-server</code> uses <a target="_blank" href="https://www.codesweetly.com/javascript-module-bundler#outputpath">output.path</a>'s directory to serve bundled files.<br>In other words, the dev server will use <code>http://[devServer.host]:[devServer.port]/[output.publicPath]/[output.filename]</code> to generate the bundled file's URL.</li>
<li>We will discuss how to use a configuration file <a class="post-section-overview" href="#heading-what-exactly-is-webpacks-configuration-file-3">later</a> in this guide.</li>
</ul>
<p>Let's now see how to run the dev server.</p>
<h3 id="heading-step-3-run-the-dev-server">Step 3: Run the dev server</h3>
<p>There are two ways to run the dev server.</p>
<ul>
<li>Use NPX on your CLI</li>
<li>Use <code>package.json</code>'s scripts field</li>
</ul>
<p>Let's discuss both ways below.</p>
<h4 id="heading-how-to-run-webpacks-dev-server-by-using-npx-on-your-cli">How to run Webpack's dev server by using NPX on your CLI</h4>
<p>Using the terminal, navigate to your project's root directory—where the <code>webpack.config.js</code> file is—then use NPX to run the dev server like this:</p>
<pre><code class="lang-bash">npx webpack serve --mode development --open
</code></pre>
<p>The snippet above uses NPX to do the following:</p>
<ol>
<li>Run the build step by executing Webpack.</li>
<li>Serve the build step's output file from memory, not your hard disk.</li>
</ol>
<p><strong>Note:</strong></p>
<ul>
<li>The dev server requires an HTML document (usually an <code>index.html</code> file) to serve the build step's output.</li>
<li>The <code>--mode development</code> flag tells Webpack to run the build step in development mode.</li>
<li>The <code>--open</code> flag tells the dev server to open your default browser.</li>
</ul>
<p>Keep in mind that the dev server does not save the build step's output file to any of your project's directories. Instead, it does the following:</p>
<ol>
<li>It keeps the build step's output files <a target="_blank" href="https://en.wikipedia.org/wiki/In-memory_processing">in memory</a> (your system's RAM).</li>
<li>It serves the output files from memory, not your system's <a target="_blank" href="https://www.computerhope.com/jargon/m/memory.htm#storage">hard drive</a>.</li>
</ol>
<p>Using your system's memory to build and serve the output file makes the dev server fast at serving your bundle.</p>
<p>However, when your app is ready for production, remember to run the <code>npx webpack</code> compilation command to save your bundle in your project's distribution folder—rather than in memory.</p>
<p>Let's now discuss the second way to run the dev server.</p>
<h4 id="heading-how-to-run-webpacks-dev-server-by-using-packagejsons-scripts-field">How to run Webpack's dev server by using <code>package.json</code>'s scripts field</h4>
<p>An alternate way to run the dev server is to add the <code>"webpack serve --mode development --open"</code> command to your <code>package.json</code>'s <code>scripts</code> field like so:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"your_package"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"webpack serve --mode development --open"</span>
  }
}
</code></pre>
<p>Afterward, you can use <code>npm run start</code> on your terminal to execute the <code>webpack serve --mode development --open</code> command.</p>
<p>Once you've started the dev server—via either option 1 or 2, your default browser will automatically open with your project's HTML page.</p>
<p>Then, anytime you save changes to your source code, the dev server will automatically reload your browser to reflect the recent updates.</p>
<p><strong>Note:</strong></p>
<ul>
<li>After running <code>npm run start</code>, your currently opened terminal will continue to process the dev server's activities. So, you won't be able to input any command on that terminal until you stop the server. However, you can open a new terminal window while using the current one to process the server. In other words, use one terminal to run the dev server and another to input commands.</li>
<li>To stop the dev server's execution, use <code>ctrl + c</code> on windows or <code>cmd + c</code> on mac.</li>
<li>You can rename the <code>"start"</code> key (or any other <a target="_blank" href="https://www.codesweetly.com/package-json-file-explained/#scripts">scripts' key</a>) to any other name you prefer.</li>
<li>Check out <a target="_blank" href="https://webpack.js.org/configuration/dev-server">Webpack's documentation</a> for more ways to configure the dev server.</li>
</ul>
<p>Remember that we used a configuration file in <a class="post-section-overview" href="#heading-step-2-specify-your-files-location">step 2</a>. Let's talk more about what the file does.</p>
<h2 id="heading-what-exactly-is-webpacks-configuration-file">What Exactly Is Webpack's Configuration File?</h2>
<p>Webpack's <strong>configuration file</strong> is a JavaScript file that allows you to modify or extend Webpack's default settings.</p>
<p>For instance, Webpack's default setting assumes your project's entry point is <code>src/index.js</code>.</p>
<p>Also, by default, Webpack will minimize, optimize, and output the result of its build step into a <code>dist/main.js</code> file.</p>
<p>However, suppose you wish to change those default settings (or add more configurations). In such a case, you would need to create a configuration file—which Webpack will use automatically.</p>
<p>The following steps will show you how to create and use a Webpack configuration file.</p>
<p><strong>Note:</strong> You can skip steps 1 and 2 if your project already has a configuration file.</p>
<h3 id="heading-step-1-go-to-the-projects-root-folder">Step 1: Go to the project's root folder</h3>
<p>Navigate to your project's root directory like so:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> path/to/project/root-directory
</code></pre>
<h3 id="heading-step-2-create-your-projects-configuration-file">Step 2: Create your project's configuration file</h3>
<p>Create a configuration file in your project's root folder like so:</p>
<pre><code class="lang-bash">touch webpack.config.js
</code></pre>
<h3 id="heading-step-3-specify-your-configurations">Step 3: Specify your configurations</h3>
<p>Open your project's <code>webpack.config.js</code> file and specify the <a target="_blank" href="https://webpack.js.org/configuration/#options">configuration options</a> you wish to change (or add).</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"html-webpack-plugin"</span>);

<span class="hljs-built_in">module</span>.exports = { 
  <span class="hljs-attr">plugins</span>: [<span class="hljs-keyword">new</span> HtmlWebpackPlugin()] 
};
</code></pre>
<p>Here's what we did in the configuration file above:</p>
<ol>
<li>We initialized the <code>HtmlWebpackPlugin</code> variable with the <code>"html-webpack-plugin"</code> package.</li>
<li>We exported an object containing the <code>plugins</code> configuration we want Webpack to use.</li>
</ol>
<p>So, whenever you run the build step, Webpack will automatically use the settings you've specified in the configuration file—rather than its default settings.</p>
<p>Let's now run the build step.</p>
<h3 id="heading-step-4-run-the-module-bundler">Step 4: Run the module bundler</h3>
<p>Using your terminal, create your bundle by running Webpack like so:</p>
<pre><code class="lang-bash">npx webpack --config webpack.config.js
</code></pre>
<p>The <code>--config webpack.config.js</code> code used in the snippet above is optional. We used it above to illustrate that it is possible to pass a configuration of <a target="_blank" href="https://webpack.js.org/configuration/#use-a-different-configuration-file">any name</a>—which you may need for complex configurations that requires a split into multiple files.</p>
<p>However, Webpack will use the <code>webpack.config.js</code> file by default if it is present in your project's root directory.</p>
<p>Keep in mind that <a target="_blank" href="https://webpack.js.org/concepts/plugins/">plugins</a> is only one of the numerous options you can use in a configuration file.</p>
<p>Let's discuss other configuration options developers use.</p>
<h2 id="heading-common-webpack-configuration-options">Common Webpack Configuration Options</h2>
<p>Below are popular configuration options you can use to alter (or extend) Webpack's default settings.</p>
<h3 id="heading-entry">entry</h3>
<p>The <code>entry</code> field specifies the file or files you want Webpack to use to begin the application's bundling process.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
};
</code></pre>
<p>The snippet above instructs Webpack to start its bundling process from <code>"./src/index.js"</code>.</p>
<p>Suppose you used an array (or an object) as the <code>entry</code> field's value. In that case, Webpack will process all the array's (or object's) items as the application's entry points.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: [
    <span class="hljs-string">"./src/index.js"</span>,
    <span class="hljs-string">"./src/index-two.js"</span>,
    <span class="hljs-string">"./src/index-three.js"</span>
  ]
}
</code></pre>
<p>The code above instructs Webpack to start its bundling process from the three files specified in the <code>entry</code> array (that is, <code>"./src/index.js"</code>, <code>"./src/index-two.js"</code>, and <code>"./src/index-three.js"</code>).</p>
<p><strong>Here's another example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: {
    <span class="hljs-attr">index</span>: <span class="hljs-string">"./src/index.js"</span>,
    <span class="hljs-attr">indexTwo</span>: <span class="hljs-string">"./src/index-two.js"</span>,
    <span class="hljs-attr">indexThree</span>: <span class="hljs-string">"./src/index-three.js"</span>
  }
}
</code></pre>
<p>The code above instructs Webpack to start its bundling process from the three files specified in the <code>entry</code> object (that is, <code>"./src/index.js"</code>, <code>"./src/index-two.js"</code>, and <code>"./src/index-three.js"</code>).</p>
<p><strong>Note:</strong></p>
<ul>
<li>If <code>entry</code>'s value is a string or an array, Webpack will create a chunk (bundle)—which it will name <code>main</code> by default.</li>
<li>If <code>entry</code>'s value is an object, Webpack will create one or more chunks. The specific number of chucks created will depend on the total properties of the object.</li>
<li>Supposing <code>entry</code>'s value is an object. In that case, Webpack will use each key to name each chunk. For instance, in <code>entry: { home: './home-module.js' }</code>, Webpack will create a chunk (bundle) named <code>home</code>.</li>
</ul>
<h3 id="heading-context">context</h3>
<p>The <code>context</code> field points Webpack to the directory containing your entry files.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-attr">context</span>: path.resolve(__dirname, <span class="hljs-string">"src"</span>)
}
</code></pre>
<p>The snippet above tells Webpack to locate the <code>index.js</code> entry file in the project's <code>src</code> directory.</p>
<h3 id="heading-output">output</h3>
<p>The <code>output</code> field specifies how and where Webpack should output the bundles and assets it processed.</p>
<p>The three options commonly used with the <code>output</code> field are <code>path</code>, <code>filename</code>, and <code>clean</code>.</p>
<h4 id="heading-outputpath">output.path</h4>
<p>The <code>output.path</code> option specifies the output directory you want Webpack to place the bundled file.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  }
}
</code></pre>
<p>The snippet above used the <code>output.path</code> option to tell Webpack to use the project's <code>"./dist"</code> folder as the output directory.</p>
<h4 id="heading-outputfilename">output.filename</h4>
<p>The <code>output.filename</code> option specifies how Webpack should name each bundle it creates.</p>
<p>Suppose you are creating only a single bundle via one entry point. In that case, you can specify a static name as the bundle's filename.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"codesweetly.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  }
}
</code></pre>
<p>The <code>output.filename</code> option tells Webpack to use <code>"codesweetly.js"</code> as the filename of the bundle created after processing <code>"./src/index.js"</code>.</p>
<p>Suppose you wish to create multiple bundles through two or more entry points, code splitting, or various plugins. In such a case, it is better to dynamically generate each bundle's filename via any of Webpack's substitutions techniques.</p>
<p><strong>Note:</strong> Substitutions—in Webpack—refer to using bracketed strings to create <a target="_blank" href="https://webpack.js.org/configuration/output/#template-strings">templates</a> for filenames.</p>
<p>Let's now discuss the three commonly used substitution techniques.</p>
<h5 id="heading-substitutions-technique-1-entry-name">Substitutions technique 1: Entry name</h5>
<p>The <strong>"entry name"</strong> substitutions naming technique makes Webpack create each bundle's name by <a target="_blank" href="https://www.codesweetly.com/web-tech-glossary#concatenation">concatenating</a> a bundle's entry point's name with a given string.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: {
    <span class="hljs-attr">home</span>: <span class="hljs-string">"./src/home-module.js"</span>,
    <span class="hljs-attr">promo</span>: <span class="hljs-string">"./src/promo-module.js"</span>,
    <span class="hljs-attr">music</span>: <span class="hljs-string">"./src/music-module.js"</span>
  },
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"[name].bundle.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  }
}
</code></pre>
<p>The <code>output.filename</code> option tells Webpack to create each bundle's filename by concatenating each entry point's name with the <code>".bundle.js"</code> string value.</p>
<p>So, for instance, suppose Webpack has finished processing the <code>promo</code> entry point (that is, <code>"./src/promo-module.js"</code>). In that case, the final bundle's name will be <code>"promo.bundle.js"</code>.</p>
<p>Let's now discuss the second substitutions technique.</p>
<h5 id="heading-substitutions-technique-2-internal-chunk-id">Substitutions technique 2: Internal chunk id</h5>
<p>The <strong>"internal chunk id"</strong> substitutions naming technique makes Webpack create each bundle's name by concatenating a bundle's entry point's id with a given string.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: {
    <span class="hljs-attr">home</span>: <span class="hljs-string">"./src/home-module.js"</span>,
    <span class="hljs-attr">promo</span>: <span class="hljs-string">"./src/promo-module.js"</span>,
    <span class="hljs-attr">music</span>: <span class="hljs-string">"./src/music-module.js"</span>
  },
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"[id].bundle.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  }
}
</code></pre>
<p>The <code>output.filename</code> option tells Webpack to create each bundle's filename by concatenating each entry point's internal chuck id with the <code>".bundle.js"</code> string value.</p>
<p>Let's now discuss the third substitutions technique.</p>
<h5 id="heading-substitutions-technique-3-content-hash">Substitutions technique 3: Content hash</h5>
<p>The <strong>"content hash"</strong> substitutions naming technique makes Webpack create each bundle's name by concatenating the generated content's hashes with a given string.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: {
    <span class="hljs-attr">home</span>: <span class="hljs-string">"./src/home-module.js"</span>,
    <span class="hljs-attr">promo</span>: <span class="hljs-string">"./src/promo-module.js"</span>,
    <span class="hljs-attr">music</span>: <span class="hljs-string">"./src/music-module.js"</span>
  },
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"[contenthash].bundle.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  }
}
</code></pre>
<p>The <code>output.filename</code> option tells Webpack to create each bundle's filename by concatenating each chunk's content hash with the <code>".bundle.js"</code> string value.</p>
<p>Keep in mind that Webpack allows you to combine different substitutions—for instance, <code>filename: "[name].[contenthash].bundle.js"</code>.</p>
<p>You can also use a function to return a filename like so:</p>
<pre><code class="lang-js">filename: <span class="hljs-function">(<span class="hljs-params">pathData</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> pathData.chunk.name === <span class="hljs-string">"main"</span> ? <span class="hljs-string">"[name].js"</span> : <span class="hljs-string">"[name].bundle.js"</span>;
}
</code></pre>
<p>Webpack also permits you to initialize the filename property with a folder structure like so:</p>
<pre><code class="lang-js">filename: <span class="hljs-string">"codesweetly/[name]/bundle.js"</span>
</code></pre>
<p>Now, let's discuss the third property developers commonly use within the <code>output</code> field.</p>
<h4 id="heading-outputclean">output.clean</h4>
<p>As Webpack increasingly generates and saves files into your output directory, it is common to clutter a project's <code>/dist</code> folder with unused files.</p>
<p>So, a good practice is to clean your output directory before each build step. By so doing, your <code>/dist</code> folder will contain used files only.</p>
<p>Let's see how to do the cleanup below:</p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"codesweetly.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>),
    <span class="hljs-attr">clean</span>: <span class="hljs-literal">true</span>
  }
}
</code></pre>
<p>The <code>clean</code> option in the snippet above tells Webpack to clean the project's output directory before each build step.</p>
<p>In other words, Webpack will empty the output directory before it begins each build step.</p>
<p>Therefore, the output directory will contain only the files generated from the compilation process—not any of the old files that Webpack previously saved there.</p>
<p>Let's now discuss another popular configuration option that you can use to alter (or extend) Webpack's default settings.</p>
<h3 id="heading-module">module</h3>
<p>The <code>module</code> field makes Webpack process assets—like CSS files and fonts—as <a class="post-section-overview" href="#heading-what-exactly-is-a-javascript-module-2">modules</a> in the dependency graph.</p>
<p>So, suppose you want Webpack to bundle non-JavaScript assets such as images, CSS files, fonts, and so on. In such a case, you can use the <code>module</code> option to specify how Webpack should manage those assets before adding them to the dependency graph.</p>
<p>Below are some common ways to use the <code>module</code> option.</p>
<h4 id="heading-how-to-use-webpacks-module-option-to-load-css-stylesheets">How to use Webpack's <code>module</code> option to load CSS stylesheets</h4>
<p>Here's how you can use Webpack's module option to load CSS stylesheets:</p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"main.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  },
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rule</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/i</span>,
        use: [<span class="hljs-string">"style-loader"</span>, <span class="hljs-string">"css-loader"</span>]
      }
    ]
  }
}
</code></pre>
<p>The configuration snippet above used the <code>module</code> property to tell Webpack to use <code>"style-loader"</code> and <code>"css-loader"</code> to load CSS files.</p>
<p>Keep in mind that the loaders' order matters.</p>
<p>In other words, Webpack reads the loaders from right to left. Therefore, it will first execute the <code>"css-loader"</code> before the <code>"style-loader"</code>.</p>
<p>So, <a target="_blank" href="https://github.com/webpack-contrib/css-loader">"css-loader"</a> will pass its result (that is, the processed resource) to the <code>"style-loader"</code>. Then, <a target="_blank" href="https://github.com/webpack-contrib/style-loader">"style-loader"</a> will insert the final CSS resource into the <code>&lt;head&gt;</code> element of your HTML page.</p>
<p>It is necessary to install the loaders you want Webpack to use in loading your CSS assets.</p>
<p>So, for instance, before Webpack can use the previous configuration file to load ".css" assets, you need to install <code>"style-loader"</code> and the <code>"css-loader"</code>.</p>
<p>Here's how to install the two loaders:</p>
<pre><code class="lang-bash">npm install style-loader css-loader --save-dev
</code></pre>
<p>Alternatively, if your package manager is Yarn, run:</p>
<pre><code class="lang-bash">yarn add style-loader css-loader --dev
</code></pre>
<p><strong>Note:</strong></p>
<ul>
<li><code>"css-loader"</code> helps to interpret and resolve <code>@import</code> and <code>url()</code> items such as <code>import</code>, <code>require()</code>, and <code>url('./my-image.png')</code>.</li>
<li><code>"style-loader"</code> helps to inject a <code>&lt;style&gt;</code> tag and the styles derived from <code>"css-loader"</code> to your project's HTML file.</li>
</ul>
<p>Let's now see how to use the <code>module</code> option to load images.</p>
<h4 id="heading-how-to-use-webpacks-module-option-to-load-images">How to use Webpack's <code>module</code> option to load images</h4>
<p>Here's how you can use Webpack's <code>module</code> option to load images:</p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"main.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  },
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rule</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(png|svg|jpg|jpeg|gif)$/i</span>,
        type: <span class="hljs-string">"asset/resource"</span>
      }
    ]
  }
}
</code></pre>
<p>The configuration snippet above used the module property to tell webpack to load <code>".png"</code>, <code>".svg"</code>, <code>".jpg"</code>, <code>".jpeg"</code>, and <code>".gif"</code> files as <a target="_blank" href="https://webpack.js.org/guides/asset-modules/#resource-assets">resource asset modules</a>.</p>
<p>So, suppose the following <code>import</code> statement is in your script file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> anyImage <span class="hljs-keyword">from</span> <span class="hljs-string">"./your-image.png"</span>;
</code></pre>
<p>In such a case, here's how Webpack will load the image:</p>
<ol>
<li>Webpack will process <code>your-image.png</code>.</li>
<li>It will add the processed image to your <em>output</em> directory.</li>
<li>Webpack will initialize the <code>anyImage</code> variable with the processed image's URL.</li>
</ol>
<p><strong>Note:</strong> While processing and adding <code>your-image.png</code> to the output folder, Webpack will change the image's filename to something like <code>150b55a1bf7461efb720.png</code>.</p>
<p>Let's now see how to use the <code>module</code> option to load fonts.</p>
<h4 id="heading-how-to-use-webpacks-module-option-to-load-fonts">How to use Webpack's <code>module</code> option to load fonts</h4>
<p>Here's how you can use Webpack's <code>module</code> option to load fonts:</p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"main.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  },
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rule</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(woff|woff2|eot|ttf|otf)$/i</span>,
        type: <span class="hljs-string">"asset/resource"</span>
      }
    ]
  }
}
</code></pre>
<p>The configuration snippet above used the <code>module</code> property to tell Webpack to load <code>".woff"</code>, <code>".woff2"</code>, <code>".eot"</code>, <code>".ttf"</code>, and <code>".otf"</code> files as <a target="_blank" href="https://webpack.js.org/guides/asset-modules/#resource-assets">resource asset modules</a>.</p>
<p>Once you've configured the loader, you can incorporate your fonts via the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face">@font-face</a> CSS declaration.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-css"><span class="hljs-comment">/* styles.css */</span>

<span class="hljs-keyword">@font-face</span> {
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">"Digital7"</span>;
  <span class="hljs-attribute">src</span>: <span class="hljs-built_in">url</span>(<span class="hljs-string">"./digital-7.regular.woff"</span>) <span class="hljs-built_in">format</span>(<span class="hljs-string">"woff"</span>),
       <span class="hljs-built_in">url</span>(<span class="hljs-string">"./digital-7.regular.ttf"</span>) <span class="hljs-built_in">format</span>(<span class="hljs-string">"truetype"</span>);
  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">600</span>;
  <span class="hljs-attribute">font-style</span>: italic;
}

<span class="hljs-selector-tag">div</span> {
  <span class="hljs-attribute">color</span>: red;
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">"Digital7"</span>;
}
</code></pre>
<p>Whenever <code>css-loader</code> loads the stylesheet above, it will process the specified fonts and add the processed copies to your project's output directory.</p>
<p><strong>Note:</strong></p>
<ul>
<li>Webpack will change the processed fonts' filename to something similar to <code>93911ab167c943140756.ttf</code>.</li>
<li>See <a target="_blank" href="https://webpack.js.org/guides/asset-management/#loading-data">Webpack's documentation</a> to learn how to load JSON, CSV, TSV, and XML files.</li>
</ul>
<p>Let's now discuss another popular configuration option that you can use to alter (or extend) Webpack's default settings.</p>
<h3 id="heading-devtool">devtool</h3>
<p>The <code>devtool</code> field tells Webpack to convert a compiled file to the source code format. Therefore, making it easier for you to debug the exact file (and line) where an error occurred in your source code.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"main.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  },
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">"source-map"</span>
}
</code></pre>
<p>At compilation time, if Webpack sees a <code>devtool</code> property in your configuration script, it will generate a <code>.js.map</code> file that the browser will use instead of the <code>.js</code> file.</p>
<p><strong>Note:</strong> There are different <a target="_blank" href="https://webpack.js.org/configuration/devtool/">devtool options</a> for specifying if and how Webpack should generate the source maps.</p>
<p>Let's now discuss another popular configuration option that you can use to alter (or extend) Webpack's default settings.</p>
<h3 id="heading-mode">mode</h3>
<p>The <code>mode</code> field tells Webpack the specific built-in optimization configuration you want it to use to build your output file.</p>
<p>You can specify whether Webpack should use <code>production</code>, <code>development</code>, or no (<code>none</code>) configuration to optimize your bundle. Let's discuss each of the three optimization settings below.</p>
<h4 id="heading-development-mode">Development mode</h4>
<p>A <code>mode: "development"</code> setting tells Webpack to build an output file for use in the development environment.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"main.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  },
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">"source-map"</span>,
  <span class="hljs-attr">mode</span>: <span class="hljs-string">"development"</span>
}
</code></pre>
<p>Setting a <code>mode: "development"</code> configuration will make Webpack create a bundle that:</p>
<ul>
<li>is fast to build</li>
<li>is less optimized</li>
<li>includes comments</li>
<li>is not minified</li>
<li>produces helpful error messages</li>
<li>is easy to debug</li>
</ul>
<p>Here's an example of a <code>mode: "development"</code> bundle:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bundle-development-mode-webpack-codesweetly.png" alt="A development mode bundle" width="600" height="400" loading="lazy">
<em>Image of a development mode bundle compiled with webpack</em></p>
<p>To make a non-minified output file readable, ensure Webpack's <a class="post-section-overview" href="#heading-devtool">devtool</a> field is not <code>eval</code>.</p>
<p>Whenever you set the <code>mode</code> to <code>development</code>, Webpack may default <code>devtool</code>'s value to <code>eval</code>. So, ensure to select a different <code>devtool</code>—like <a target="_blank" href="https://webpack.js.org/configuration/devtool/#devtool">source-map</a> or disable it by setting its value to <code>"false"</code>—whenever you wish to make your output file readable.</p>
<p>Suppose you choose to run Webpack in development mode. In that case, remember to change your configuration to production mode when you are ready to deploy your app.</p>
<p>Now, let's discuss configuring Webpack to build your output file in production mode.</p>
<h4 id="heading-production-mode">Production mode</h4>
<p>A <code>mode: "production"</code> setting tells Webpack to build an output file for use in the production environment.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"main.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  },
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">"source-map"</span>,
  <span class="hljs-attr">mode</span>: <span class="hljs-string">"production"</span>
}
</code></pre>
<p>Setting a <code>mode: "production"</code> configuration will make Webpack create a bundle that:</p>
<ul>
<li>is slow to build</li>
<li>is more optimized</li>
<li>excludes comments</li>
<li>is minified</li>
<li>does not produce detailed error messages</li>
<li>is difficult to debug</li>
</ul>
<p>Here's an example of a <code>mode: "production"</code> bundle:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bundle-production-mode-webpack-codesweetly.png" alt="A production mode bundle" width="600" height="400" loading="lazy">
<em>Image of a production mode bundle compiled with webpack</em></p>
<p><strong>Note:</strong> Webpack <a target="_blank" href="https://webpack.js.org/guides/production/#source-mapping">recommends</a> having source maps—like <code>source-map</code>—enabled in production.</p>
<p>Now, let's discuss configuring Webpack to build your output file without any optimization settings.</p>
<h4 id="heading-none-mode">None mode</h4>
<p>A <code>mode: "none"</code> setting tells Webpack to build an output file without optimizing it for development or production.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-js"><span class="hljs-comment">// webpack.config.js</span>

<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">"./src/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"main.js"</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"dist"</span>)
  },
  <span class="hljs-attr">mode</span>: <span class="hljs-string">"none"</span>
}
</code></pre>
<p>Here's an example of a <code>mode: "none"</code> bundle:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/05/bundle-none-mode-webpack-codesweetly.png" alt="A none mode bundle" width="600" height="400" loading="lazy">
<em>Image of a none mode bundle compiled with webpack</em></p>
<h4 id="heading-important-stuff-to-know-about-the-mode-option">Important stuff to know about the <code>mode</code> option</h4>
<p>To make switching between development and production mode easy, you can store the <code>mode</code> configurations in the <code>"scripts"</code> field of your <code>package.json</code> file.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"your-app-name"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,
    <span class="hljs-attr">"dev"</span>: <span class="hljs-string">"webpack --mode development"</span>,
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"webpack --mode production"</span>
  }
}
</code></pre>
<p>The snippet above initialized the scripts' <code>"dev"</code> property with Webpack's <code>development</code> mode command.</p>
<p>Likewise, we initialized the scripts' <code>"build"</code> property with Webpack's <code>production</code> mode command.</p>
<p>Therefore, suppose you execute <code>npm run dev</code> on your terminal. In that case, Webpack will execute the build step in development mode.</p>
<h2 id="heading-overview">Overview</h2>
<p>This article discussed what a JavaScript module is and how it works. We also discussed how to use a popular module bundler (Webpack) to bundle a project's JavaScript file and its dependencies into a single output file.</p>
<p>And there we have it. I hope you have found this article helpful.</p>
<p>Thanks for reading!</p>
<h3 id="heading-and-heres-a-useful-reactjs-resource"><strong>And here's a useful ReactJS resource:</strong></h3>
<p>I wrote a book about React!</p>
<ul>
<li>It's beginners friendly ✔</li>
<li>It has live code snippets ✔</li>
<li>It contains scalable projects ✔</li>
<li>It has plenty of easy-to-grasp examples ✔</li>
</ul>
<p>The <a target="_blank" href="https://www.amazon.com/dp/B09KYGDQYW">React Explained Clearly</a> book is all you need to understand ReactJS.</p>
<p><a target="_blank" href="https://www.amazon.com/dp/B09KYGDQYW"><img src="https://www.freecodecamp.org/news/content/images/2022/01/Twitter-React_Explained_Clearly-CodeSweetly-Oluwatobi_Sofela.jpg" alt="React Explained Clearly Book Now Available at Amazon" width="600" height="400" loading="lazy"></a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Popular Front End Development Tools You Should Know ]]>
                </title>
                <description>
                    <![CDATA[ By Yiğit Kemal Erinç If you are just getting started with JavaScript, the number of tools and technologies you'll hear about may be overwhelming. And you might have a hard time deciding which tools you actually need. Or maybe you're familiar with the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/front-end-development-tools-you-should-know/</link>
                <guid isPermaLink="false">66d45e4273634435aafcef82</guid>
                
                    <category>
                        <![CDATA[ Babel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CircleCI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ eslint ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ npm ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 03 Nov 2020 02:35:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/11/frontend-dev-tools.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Yiğit Kemal Erinç</p>
<p>If you are just getting started with JavaScript, the number of tools and technologies you'll hear about may be overwhelming. And you might have a hard time deciding which tools you actually need.</p>
<p>Or maybe you're familiar with the tools, but you haven't given much thought to what problems they solve and how miserable your life would be without their help.</p>
<p>I believe it is important for Software Engineers and Developers to understand the purpose of the tools we use every day. </p>
<p>That's why, in this article, I look at NPM, Babel, Webpack, ESLint, and CircleCI and I try to clarify the problems they solve and how they solve them. </p>
<h2 id="heading-npm">NPM</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>NPM is the default package manager for JavaScript development. It helps you find and install packages (programs) that you can use in your programs.</p>
<p>You can add npm to a project simply by using the "<strong>npm init</strong>" command. When you run this command it creates a "<strong>package.json</strong>" file in the current directory. This is the file where your dependencies are listed, and npm views it as the ID card of the project. </p>
<p>You can add a dependency with the "<strong>npm install (package_name)</strong>" command. </p>
<p>When you run this command, npm goes to the remote registry and checks if there is a package identified by this package name. If it finds it, a new dependency entry is added to your <strong>package.json</strong> and the package, with it's internal dependencies, is downloaded from the registry.</p>
<p>You can find downloaded packages or dependencies under the <strong>"node_modules"</strong> folder. Just keep in mind that it usually gets pretty big – so make sure to add it to <strong>.gitignore</strong>.</p>
<p><img src="https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/06/node-modules-meme.jpeg?resize=730%2C525&amp;ssl=1" alt="How to keep your JavaScript libraries up to date - LogRocket Blog" width="730" height="525" loading="lazy"></p>
<p>NPM does not only ease the process of finding and downloading packages but also makes it easier to work collaboratively on a project. </p>
<p>Without NPM, it would be hard to manage external dependencies. You would need to download the correct versions of every dependency by hand when you join an existing project. And that would be a real hassle. </p>
<p>With the help of npm, you can just run <strong>"npm install"</strong> and it will install all external dependencies for you. Then you can just run it again anytime someone on your team adds a new one.</p>
<h2 id="heading-babel">Babel</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Babel is a JavaScript compiler or transpiler which translates the ECMAScript 2015+ code into code that can be understood by older JavaScript engines.</p>
<p>Babel is the most popular Javascript compiler, and frameworks like Vue and React use it by default. That said, concepts we will talk about here are not only related to Babel and will apply to any JavaScript compiler.</p>
<h3 id="heading-why-do-you-need-a-compiler">Why do you need a compiler?</h3>
<p>"Why do we need a compiler, isn't JavaScript an interpreted language?" you may ask if you are familiar with the concepts of compiled and interpreted languages. </p>
<p>It's true that we usually call something a "compiler" if it translates our human-readable code to an executable binary that can be understood by the CPU. But that is not the case here. </p>
<p>The term transpiler may be more appropriate since it is a subset of a compiler: Transpilers are compilers that translate the code from a programming language to another language (in this example, from modern JS to an older version).</p>
<p>JavaScript is the language of browsers. But there is a problem with browsers: Cross compatibility. JavaScript tools and the language itself are evolving rapidly and many browsers fail to match that pace. This results in compatibility issues.</p>
<p>You probably want to write code in the most recent versions of JavaScript so you can use its new features. But if the browser that your code is running has not implemented some of the new features in its JavaScript engine, the code will not execute properly on that browser.</p>
<p>This is a complex problem because every browser implements the features at a different speed. And even if they do implement those new features, there will always be people who use an older version of their browser. </p>
<p>So what if you want to be able to use the recent features but also want your users to view those pages without any problems?</p>
<p>Before Babel, we used polyfills to run older versions of certain code if the browser did not support the modern features. And when you use Babel, it uses polyfills behind the scenes and does not require you to do anything.</p>
<h3 id="heading-how-do-transpilerscompilers-work">How do transpilers/compilers work?</h3>
<p>Babel works similar to other compilers. It has parsing, transformation, and code generation stages. </p>
<p>We won't go in-depth here into how it works, since compilers are complicated things. But to understand the basics of how compilers work, you can check out the <a target="_blank" href="https://github.com/jamiebuilds/the-super-tiny-compiler">the-super-tiny-compiler project</a>. It is also mentioned in Babel's official documentation as being helpful in understanding how Babel works.</p>
<p>We can usually get away with knowing about Babel plugins and presets. Plugins are the snippets that Babel uses behind the scenes to compile your code to older versions of JavaScript. You can think of each modern feature as a plugin. You can go to <a target="_blank" href="https://babeljs.io/docs/en/plugins/">this</a> link to check out the full list of plugins.</p>
<p><img src="https://erinc.io/wp-content/uploads/2020/10/image.png" alt="Image" width="600" height="400" loading="lazy">
<em>List of plugins for ES5</em></p>
<p>Presets are collections of plugins. If you want to use Babel for a React project you can use the pre-made <strong>@babel/preset-react</strong> which contains the necessary plugins.</p>
<p><img src="https://erinc.io/wp-content/uploads/2020/10/image-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>React Preset Plugins</em></p>
<p>You can add plugins by editing the Babel config file.</p>
<h3 id="heading-do-you-need-babel-for-your-react-app">Do you need Babel for your React App?</h3>
<p>For React, you need a compiler because React code generally uses JSX and JSX needs to be compiled. Also the library is built on the concept of using ES6 syntax. </p>
<p>Luckily, when you create a project with <strong>create-react-app</strong>, it comes with Babel already configured and you usually do not need to modify the config.</p>
<h3 id="heading-examples-of-a-compiler-in-action">Examples of a compiler in action</h3>
<p>Babel's website has an online compiler and it is really helpful to understand how it works. Just plug in some code and analyze the output.</p>
<p><img src="https://erinc.io/wp-content/uploads/2020/10/image-4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://erinc.io/wp-content/uploads/2020/10/image-5.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-webpack">Webpack</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/image.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Webpack is a static module bundler. When you create a new project, most JavaScript frameworks/libraries use it out of the box nowadays. </p>
<p>If the phrase "static module bundler" sounds confusing, keep reading because I have some great examples to help you understand.</p>
<h3 id="heading-why-do-you-need-a-bundler">Why do you need a bundler?</h3>
<p>In web apps you're going to have a lot of files. This is especially the case for Single Page Applications (React, Vue, Angular), with each having their own dependencies. </p>
<p>What I mean by a dependency is an import statement – if file A needs to import file B to run properly, then we say A depends on B. </p>
<p>In small projects, you can handle the module dependencies with <code>&lt;script&gt;</code> tags. But when the project gets larger, the dependencies rapidly become hard to manage. </p>
<p>Maybe, more importantly, dividing the code into multiple files makes your website load more slowly. This is because the browser needs to send more requests compared to one large file, and your website starts to consume a ton of bandwidth, because of HTTP headers.</p>
<p>We, as developers want our code to be modular. We divide it into multiple files because we do not want to work with one file with thousands of lines. Still, we also want our websites to be performant, to use less bandwidth, and to load fast. </p>
<p>So now, we'll see how Webpack solves this issue.</p>
<h3 id="heading-how-webpack-works">How Webpack works</h3>
<p>When we were talking about Babel, we mentioned that JavaScript code needs to be transpiled before the deployment. </p>
<p>But compiling with Babel is not the only operation you need before deploying your project. </p>
<p>You usually need to uglify it, transpile it, compile the SASS or SCSS to CSS if you are using any preprocessors, compile the TypeScript if you are using it...and as you can see, this list can get long easily. </p>
<p>You do not want to deal with all those commands and operations before every deployment. It would be great if there was a tool that did all that for you in the correct order and correct way. </p>
<p>The good news – there is: Webpack.</p>
<p>Webpack also provides features like a local server with hot reload (they call it hot module replacement) to make your development experience better. </p>
<p>So what's hot reloading? It means that whenever you save your code, it gets compiled and deployed to the local HTTP server running on your machine. And whenever a file changes, it sends a message to your browser so you do not even need to refresh the page. </p>
<p>If you have ever used "npm run serve", "npm start" or "npm run dev", those commands also start Webpack's dev server behind the scenes.</p>
<p>Webpack starts from the entry point of your project (index) and generates the Abstract Syntax Tree of the file. You can think of it as parsing the code. This operation is also done in compilers, which then look for import statements recursively to generate a graph of dependencies.</p>
<p>It then converts the files into [IIFEs](https://developer.mozilla.org/en-US/docs/Glossary/IIFE#:~:text=An%20IIFE%20(Immediately%20Invoked%20Function,soon%20as%20it%20is%20defined.) to modularize them (remember, putting code inside a function restricts its scope). By doing this, they modularize the files and make sure the variables and functions are not accessible to other files. </p>
<p>Without this operation, it would be like copying and pasting the code of the imported file and that file would have the same scope.</p>
<p>Webpack does many other advanced things behind the scenes, but this is enough to understand the basics.</p>
<h2 id="heading-bonus-eslint">Bonus – ESLint</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Code quality is important and helps keep your projects maintainable and easily extendable. While most of us developers recognize the significance of clean coding, we sometimes tend to ignore the long term consequences under the pressure of deadlines.</p>
<p>Many companies decide on coding standards and encourage developers to obey those standards. But how can you make sure that your code meets the standards? </p>
<p>Well, you can use a tool like ESLint to enforce rules in the code. For example, you can create a rule to enforce or disallow the usage of semicolons in your JavaScript code. If you break a rule, ESLint shows an error and the code does not even get compiled – so it is not possible to ignore that unless you disable the rule.</p>
<p>Linters can be used to enforce standards by writing custom rules. But you can also use the pre-made ESLint configs established by big tech companies to help devs get into the habit of writing clean code. </p>
<p>You can take a look at Google's ESLint config <a target="_blank" href="https://github.com/google/eslint-config-google">here</a> – it is the one I prefer.</p>
<p>ESLint helps you get used to best practices, but that's not its only benefit. ESLint also warns you about possible bugs/errors in your code so you can avoid common mistakes.</p>
<p><img src="https://erinc.io/wp-content/uploads/2020/11/image-1024x717.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-bonus-cicd-circleci">Bonus – CI/CD (CircleCI)</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/image-4.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Continuous Integration/Development has gained a lot of popularity in recent years as many companies have adopted Agile principles. </p>
<p>Tools like Jenkins and CircleCI allow you to automate the deployment and testing of your software so you can deploy more often and reliably without going through difficult and error-prone build processes by yourselves. </p>
<p>I mention CircleCI as the product here because it is free and used frequently in JavaScript projects. It's also quite easy to use.</p>
<p>Let's go over an example: Say you have a deployment/QA server and your Git repository. You want to deploy your changes to your deployment/QA server, so here is an example process:</p>
<ol>
<li>Push the changes to Git</li>
<li>Connect to the server</li>
<li>Create a Docker container and run it</li>
<li>Pull the changes to the server, download all the dependencies (npm install)</li>
<li>Run the tests to make sure nothing is broken</li>
<li>Use a tool like ESLint/Sonar to ensure code quality</li>
<li>Merge the code if everything is fine</li>
</ol>
<p>With the help of CircleCI, you can automatically do all these operations. You can set it up and configure to do all of the above operations whenever you push a change to Git. It will reject the push if anything goes wrong, for example a failing test.</p>
<p>I will not get into the details of how to configure CircleCI because this article is more about the "Why?" of each tool. But if you are interested in learning more and seeing it in action, you can check out <a target="_blank" href="https://www.youtube.com/watch?v=CB7vnoXI0pE&amp;ab_channel=TheCodingTrain">this tutorial series</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The world of JavaScript is evolving rapidly and new tools are gaining popularity every year. </p>
<p>It's easy to react to this change by just learning how to use the tool – we are often too busy to take our time and think about the reason why that tool became popular or what problem it solves.</p>
<p>In this article, I picked the tools I think are most popular and shared my thoughts on their significance. I also wanted to make you think about the problems they solve rather than just the details of how to use them.</p>
<p>If you liked the article you can check out and subscribe to my <a target="_blank" href="https://erinc.io/">blog</a> where I try to write frequently. Also, let me know what you think by commenting so we can brainstorm or you can tell me what other tools you love to use :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Production-Ready Webpack 4 Config From Scratch ]]>
                </title>
                <description>
                    <![CDATA[ By Tyler Hawkins Webpack is a powerful bundler and dependency manager used by many enterprise-level companies as tooling for their front-end code. Typically, webpack is configured when a project is first set up, and small tweaks are then made to the ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/creating-a-production-ready-webpack-4-config-from-scratch/</link>
                <guid isPermaLink="false">66d461714bc8f441cb6df82f</guid>
                
                    <category>
                        <![CDATA[ Bundler ]]>
                    </category>
                
                    <category>
                        <![CDATA[ dependency management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer Tools ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 29 Mar 2020 02:40:01 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9beb740569d1a4ca2ec5.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Tyler Hawkins</p>
<p><a target="_blank" href="https://webpack.js.org/">Webpack</a> is a powerful bundler and dependency manager used by many enterprise-level companies as tooling for their front-end code.</p>
<p>Typically, webpack is configured when a project is first set up, and small tweaks are then made to the config files as needed from time to time. Because of this, many developers don’t have a lot of experience working with webpack.</p>
<p>In this hands-on tutorial, we’ll go through the basics of setting up your very own production-ready webpack config using webpack 4. We’ll discuss output management, asset management, dev and prod configs, Babel, minification, cache busting, and more.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/webpack-js-opt.png" alt="Webpack bundles your code" width="600" height="400" loading="lazy">
<em>Webpack bundles your code</em></p>
<p>Let's get started!</p>
<h2 id="heading-demo-app">Demo App</h2>
<p>For the purposes of this demo, we'll be setting up a webpack config from scratch using webpack 4. Our app will just use vanilla JavaScript so that we don't get bogged down with any framework-specific details. The actual app code will be pretty small so that we can focus more on webpack.</p>
<p>If you'd like to follow along, all of the code in this article can be found in GitHub. The <a target="_blank" href="https://github.com/thawkin3/webpack-training-1/tree/demo/start">starting point is found here</a>, and the <a target="_blank" href="https://github.com/thawkin3/webpack-training-1">finished result is found here</a>.</p>
<h2 id="heading-starting-point">Starting Point</h2>
<p>To begin, we'll start out with just a few files in our project directory. The directory structure looks like this:</p>
<pre><code>webpack-demo
 |_ src
    |_ index.js
 |_ .gitignore
 |_ index.html
 |_ package.json
 |_ README.md
 |_ yarn.lock
</code></pre><p>The <code>index.html</code> file is nice and simple, just a page header and a <code>script</code> tag:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!doctype <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Webpack Training 1<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Webpack Training 1<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./src/index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The <code>script</code> tag references our <code>./src/index.js</code> file, which has just a few lines of JavaScript in it that outputs the text, "Hello from webpack!":</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> p = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'p'</span>)
p.textContent = <span class="hljs-string">'Hello from webpack!'</span>
<span class="hljs-built_in">document</span>.body.append(p)
</code></pre>
<p>If you drag the <code>index.html</code> file into your browser, you should be able to view our simple web page:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-27-at-3.10.23-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Demo app output 1 - hello from webpack</em></p>
<hr>
<h2 id="heading-install-dependencies">Install Dependencies</h2>
<p>I've included <code>webpack</code> and <code>webpack-cli</code> as <code>devDependencies</code> in the <code>package.json</code> file.</p>
<p>To install those, run:</p>
<pre><code class="lang-bash">yarn install
</code></pre>
<h2 id="heading-webpack-test-run">Webpack Test Run</h2>
<p>Webpack 4 is set up as a "zero config" tool, meaning that you can run it out of the box without doing any initial configuration. Now, for any real project you <em>will</em> need to do some configuration, but it's nice that you can at least do a quick sanity check to ensure that webpack is able to run without having to go through a bunch of initial configuration steps.</p>
<p>So, let's check it out. Run:</p>
<pre><code class="lang-bash">yarn webpack
</code></pre>
<p>You should now see a <code>dist</code> directory created in your project directory. And inside it you should see a <code>main.js</code> file, which is our minified code.</p>
<p>Great! Webpack appears to be working.</p>
<h2 id="heading-reference-the-output-code">Reference the Output Code</h2>
<p>OK, now that we have JavaScript code in our <code>dist</code> directory, let's have our <code>index.html</code> file reference that. Instead of the <code>script</code> tag looking like this:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./src/index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Let's change it to this:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./dist/main.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>Now, refresh the page in your browser, and you should still see the exact same output, only this time the "Hello from webpack!" text is being generated by the <code>./dist/main.js</code> file now.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-27-at-3.10.23-PM-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Demo app output 2 - no changes</em></p>
<h2 id="heading-create-a-webpack-config-file">Create a Webpack Config File</h2>
<p>Now that we have webpack installed and have gone through a quick sanity check exercise, let's create an actual webpack config file. Create a file called <code>webpack.config.js</code> and place the following code inside it:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  }
}
</code></pre>
<p>The <code>entry</code> property tells webpack where our source code is located. It is the "entry point" for our app.</p>
<p>The <code>output</code> property tells webpack what to call the output file and which directory to place it in.</p>
<p>Simple enough, right?</p>
<p>Now let's create an npm script in our <code>package.json</code> file:</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {
  <span class="hljs-attr">"build"</span>: <span class="hljs-string">"webpack --config=webpack.config.js"</span>
}
</code></pre>
<p>Now we can run our build process with the command <code>yarn build</code>. Go ahead and run that command to verify you have things set up properly. You could even delete your <code>dist</code> directory prior to running the <code>yarn build</code> command to verify that the directory is being generated.</p>
<h2 id="heading-change-the-output-file-name">Change the Output File Name</h2>
<p>Now, just for fun, let's change the output file name. To do this, we'll open up our <code>webpack.config.js</code> file and change the <code>output</code> property from this:</p>
<pre><code class="lang-javascript">output: {
  <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
  <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
}
</code></pre>
<p>To this:</p>
<pre><code class="lang-javascript">output: {
  <span class="hljs-attr">filename</span>: <span class="hljs-string">'tacos.js'</span>,
  <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
}
</code></pre>
<p>Now run <code>yarn build</code> again to generate the output. You should see a <code>tacos.js</code> file in your <code>dist</code> directory now.</p>
<p>But wait! We also see the old <code>main.js</code> file in our <code>dist</code> directory too! Wouldn't it be nice if webpack could delete the old unneeded output each time we do a new build?</p>
<p>There's got to be a plugin for that.</p>
<h2 id="heading-webpack-plugins">Webpack Plugins</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-178.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@feelfarbig?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Feelfarbig Magazine / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>Webpack has a rich ecosystem of modules called "<a target="_blank" href="https://webpack.js.org/concepts/#plugins">plugins</a>", which are libraries that can modify and enhance the webpack build process. We'll explore a handful of helpful plugins as we continue to improve our webpack config throughout the rest of this article.</p>
<h2 id="heading-cleanwebpackplugin">CleanWebpackPlugin</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-179.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@honest?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;The Honest Company / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>OK, back to our problem. It'd be nice if we could clean up the <code>dist</code> directory before each new build. There's a plugin for that!</p>
<p>We can use the <a target="_blank" href="https://github.com/johnagan/clean-webpack-plugin">CleanWebpackPlugin</a> to help us here. First, we need to install it in our project:</p>
<pre><code class="lang-bash">yarn add --dev clean-webpack-plugin
</code></pre>
<p>To use it, we'll simply <code>require</code> the plugin in our <code>webpack.config.js</code> file and then include it in the <code>plugins</code> array in our config setup:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)
<span class="hljs-keyword">const</span> { CleanWebpackPlugin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'clean-webpack-plugin'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> CleanWebpackPlugin()
  ]
}
</code></pre>
<p>Now run <code>yarn build</code> again, and you should see only a single output file in your <code>dist</code> directory. Problem solved!</p>
<h2 id="heading-htmlwebpackplugin">HTMLWebpackPlugin</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-180.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@rxspawn?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Florian Olivo / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>One other thing that's a little annoying with our setup is that any time we change the <code>output</code> file name in our <code>webpack.config.js</code> file, we also have to change that file name we reference in our <code>script</code> tag in our <code>index.html</code> file. Wouldn't it be nice if webpack could manage that for us?</p>
<p>There's a plugin for that! We can use the <a target="_blank" href="https://webpack.js.org/plugins/html-webpack-plugin/">HTMLWebpackPlugin</a> to help us manage our HTML file. Let's install it in our project now:</p>
<pre><code class="lang-bash">yarn add --dev html-webpack-plugin
</code></pre>
<p>Now let's move our <code>index.html</code> file inside our <code>src</code> directory so that it's a sibling to the <code>index.js</code> file.</p>
<pre><code>webpack-demo
 |_ src
    |_ index.html
    |_ index.js
 |_ .gitignore
 |_ package.json
 |_ README.md
 |_ yarn.lock
</code></pre><p>We can also delete the <code>script</code> tag in our <code>index.html</code> file since we'll have webpack handle inserting the appropriate <code>script</code> tag for us. Delete that line so that your <code>index.html</code> file looks like this:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!doctype <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Webpack Training 1<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Webpack Training 1<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Now let's <code>require</code> this plugin in our <code>webpack.config.js</code> file and then include it in the <code>plugins</code> array in our config setup, just like we did for the first plugin:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)
<span class="hljs-keyword">const</span> { CleanWebpackPlugin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'clean-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> CleanWebpackPlugin(),
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'index.html'</span>,
      <span class="hljs-attr">inject</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">template</span>: path.resolve(__dirname, <span class="hljs-string">'src'</span>, <span class="hljs-string">'index.html'</span>),
    }),
  ]
}
</code></pre>
<p>In those options for the <code>HtmlWebpackPlugin</code>, we specify the <code>filename</code> for what we'd like the output file to be called.</p>
<p>We specify for <code>inject</code> that we would like our JavaScript file to be injected into the <code>body</code> tag by setting the value to <code>true</code>.</p>
<p>And finally, for the <code>template</code> we supply the location of our <code>index.html</code> file in the <code>src</code> directory.</p>
<h2 id="heading-sanity-check">Sanity Check</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-181.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@glenncarstenspeters?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Glenn Carstens-Peters / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>OK, let's make sure everything is still working properly. Run <code>yarn build</code>, and verify that you see two files in your <code>dist</code> directory: <code>index.html</code> and <code>main.js</code>.</p>
<p>If you look closely in your <code>index.html</code> file, you'll see the <code>main.js</code> file referenced.</p>
<p>Now, open the <code>./dist/index.html</code> file in your browser to verify that your page loads correctly. If you followed these steps correctly, your page should still be working:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-27-at-3.10.23-PM-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Demo app output 3 - no changes</em></p>
<h2 id="heading-create-a-development-server">Create a Development Server</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-182.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@tvick?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Taylor Vick / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>We've made some good improvements so far using the <code>CleanWebpackPlugin</code> and the <code>HtmlWebpackPlugin</code>. As we've made these changes, we've had to manually run the <code>yarn build</code> command each time to see new changes in our app. We've also just been viewing the file in our browser rather than viewing the content served from a server running locally. Let's improve our process by creating a development server.</p>
<p>To do this, we'll use <code>webpack-dev-server</code>. First, we'll need to install it:</p>
<pre><code class="lang-bash">yarn add --dev webpack-dev-server
</code></pre>
<p>Now, let's split up our single <code>webpack.config.js</code> file into two separate config files, one for production and one for development. We'll call the file for production <code>webpack.config.prod.js</code> and the file for development <code>webpack.config.dev.js</code>.</p>
<h2 id="heading-development-webpack-config">Development Webpack Config</h2>
<p>Here's our development config file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)
<span class="hljs-keyword">const</span> { CleanWebpackPlugin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'clean-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'development'</span>,
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">'inline-source-map'</span>,
  <span class="hljs-attr">devServer</span>: {
    <span class="hljs-attr">contentBase</span>: <span class="hljs-string">'./dist'</span>,
  },
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> CleanWebpackPlugin(),
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'index.html'</span>,
      <span class="hljs-attr">inject</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">template</span>: path.resolve(__dirname, <span class="hljs-string">'src'</span>, <span class="hljs-string">'index.html'</span>),
    }),
  ]
}
</code></pre>
<p>Note that we've specified the <code>mode</code> as <code>development</code> now, and we've specified that we would like an <code>inline-source-map</code> for our JavaScript files, meaning that a source map is included at the end of each JavaScript file. For our dev server, we've specified that our content will be found in the <code>dist</code> directory.</p>
<p>All the rest of the development config has stayed the same.</p>
<h2 id="heading-production-webpack-config">Production Webpack Config</h2>
<p>Now, here's our production config file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)
<span class="hljs-keyword">const</span> { CleanWebpackPlugin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'clean-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'production'</span>,
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">'source-map'</span>,
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> CleanWebpackPlugin(),
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'index.html'</span>,
      <span class="hljs-attr">inject</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">template</span>: path.resolve(__dirname, <span class="hljs-string">'src'</span>, <span class="hljs-string">'index.html'</span>),
    }),
  ]
}
</code></pre>
<p>This file also looks very similar to our original config file. Here we've specified that the <code>mode</code> is <code>production</code> and that we would like the <code>source-map</code> option for source maps, which provides separate source map files for minified code.</p>
<h2 id="heading-production-and-development-npm-scripts">Production and Development NPM Scripts</h2>
<p>Finally, let's add a few more npm scripts in our <code>package.json</code> file so that we can work with our development and production webpack configs:</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {
  <span class="hljs-attr">"build"</span>: <span class="hljs-string">"webpack --config=webpack.config.prod.js"</span>,
  <span class="hljs-attr">"build-dev"</span>: <span class="hljs-string">"webpack --config=webpack.config.dev.js"</span>,
  <span class="hljs-attr">"start"</span>: <span class="hljs-string">"webpack-dev-server --config=webpack.config.dev.js --open"</span>
}
</code></pre>
<p>Now, let's try out each of these scripts.</p>
<p>Run <code>yarn build</code> to see the production build output. You should see that the <code>main.js</code> file in your <code>dist</code> directory is minified and that it has an accompanying <code>main.js.map</code> source map file.</p>
<p>Now run <code>yarn build-dev</code> to see the development build output. You should see the <code>main.js</code> file in your <code>dist</code> directory, but now note that it is <strong>not</strong> minified.</p>
<p>Lastly, run <code>yarn start</code> to start up the development server. This will open up the app on <code>http://localhost:8080/</code>. No more having to view the files directly by just pulling them into your browser! We now have a real live development server!</p>
<p>The output you see should still look the same as it always has:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-27-at-3.10.23-PM-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Demo app output 4 - no changes</em></p>
<h2 id="heading-making-changes-during-development">Making Changes During Development</h2>
<p>Now that we have a working dev server, let's experiment with making some simple changes to our <code>./src/index.js</code> file. Instead of outputting "Hello from webpack!", let's change it to say "Hello from dev server!".</p>
<p>Save the file, and then see the page on your dev server automatically reload and update for you! That'll be a nice boost to your developer productivity.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-27-at-4.16.13-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Demo app output 5 - hello from dev server</em></p>
<h2 id="heading-dont-repeat-yourself-dry">Don't Repeat Yourself (DRY)</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-183.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@tobey_j?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Tobias Jelskov / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>Now that we have two separate webpack config files, one for development and one for production, you may have noticed that we have a lot of duplicated code between the two files.</p>
<p>Every developer out there has had the DRY principle drilled into their heads since day one: Don't repeat yourself. If you find yourself writing the same code in multiple places, it may be a good idea to turn that into shared code that can be written in one place and then used in multiple places. That way when you need to make changes, you only need to implement those changes in one place.</p>
<p>So, how can we clean up the duplication in our webpack config files? There's a plugin for that!</p>
<h2 id="heading-webpackmerge">WebpackMerge</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/merge.png" alt="Merge" width="600" height="400" loading="lazy">
<em>Merge</em></p>
<p>We can use the <a target="_blank" href="https://github.com/survivejs/webpack-merge">webpack-merge</a> plugin to manage shared code that multiple config files rely on. To do this, we'll first install the package:</p>
<pre><code class="lang-bash">yarn add --dev webpack-merge
</code></pre>
<p>Now we'll create a third webpack config file called <code>webpack.config.common.js</code>. This is where we'll keep our shared code. Right now, our development and production config files share the same entry point, output, and plugins. All that differs between the two files are the mode, source map, and dev server.</p>
<p>So, the contents of our <code>webpack.config.common.js</code> file will be:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)
<span class="hljs-keyword">const</span> { CleanWebpackPlugin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'clean-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> CleanWebpackPlugin(),
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'index.html'</span>,
      <span class="hljs-attr">inject</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">template</span>: path.resolve(__dirname, <span class="hljs-string">'src'</span>, <span class="hljs-string">'index.html'</span>),
    }),
  ]
}
</code></pre>
<p>And now, we can merge this shared config object into our development config like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-merge'</span>)
<span class="hljs-keyword">const</span> commonConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./webpack.config.common'</span>)

<span class="hljs-built_in">module</span>.exports = merge(commonConfig, {
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'development'</span>,
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">'inline-source-map'</span>,
  <span class="hljs-attr">devServer</span>: {
    <span class="hljs-attr">contentBase</span>: <span class="hljs-string">'./dist'</span>,
  },
})
</code></pre>
<p>And we can merge the shared config object into our production config like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-merge'</span>)
<span class="hljs-keyword">const</span> commonConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./webpack.config.common'</span>)

<span class="hljs-built_in">module</span>.exports = merge(commonConfig, {
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'production'</span>,
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">'source-map'</span>,
})
</code></pre>
<p>Look how much shorter and cleaner those two files look! Beautiful!</p>
<h2 id="heading-styling-our-app">Styling Our App</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-184.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@madebyvadim?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Vadim Sherbakov / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>Things are looking pretty good with our webpack configs so far. We have a working dev server and we've split out our code into development, production, and shared configuration files.</p>
<p>Let's start working on our actual app code now. The plain black and white page is a little boring to look at. Let's style it up!</p>
<p>In our <code>src</code> directory, let's create an <code>index.css</code> file and place the following lines of CSS inside it:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background</span>: deeppink;
  <span class="hljs-attribute">color</span>: white;
}
</code></pre>
<p>Then, in our <code>./src/index.js</code> file, let's import that CSS file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">'./index.css'</span>
</code></pre>
<p>Now, run <code>yarn start</code> to get our development server running again.</p>
<p>Oh no! We get an error!</p>
<pre><code>ERROR <span class="hljs-keyword">in</span> ./src/index.css <span class="hljs-number">1</span>:<span class="hljs-number">5</span>
Module parse failed: Unexpected token (<span class="hljs-number">1</span>:<span class="hljs-number">5</span>)
You may need an appropriate loader to handle <span class="hljs-built_in">this</span> file type, currently no loaders are configured to process <span class="hljs-built_in">this</span> file. See https:<span class="hljs-comment">//webpack.js.org/concepts#loaders</span>
&gt; body {
|   background: deeppink;
|   color: white;
 @ ./src/index.js <span class="hljs-number">1</span>:<span class="hljs-number">0</span><span class="hljs-number">-20</span>
</code></pre><p>What are these "loaders" it speaks of?</p>
<h2 id="heading-webpack-loaders">Webpack Loaders</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-185.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@kevin_butz?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Kevin Butz / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>Earlier, we discussed webpack plugins, which let you extend the webpack build process. There is also an ecosystem of webpack "<a target="_blank" href="https://webpack.js.org/loaders/">loaders</a>", which help webpack know how to understand and load different file types. Out of the box, webpack understands how to handle our JavaScript files, but it doesn't know what to do with CSS files yet. Let's fix that.</p>
<h2 id="heading-styleloader-and-cssloader">StyleLoader and CSSLoader</h2>
<p>There are two loaders in particular that will be helpful for us here: <a target="_blank" href="https://webpack.js.org/loaders/style-loader/">style-loader</a> and <a target="_blank" href="https://webpack.js.org/loaders/css-loader/">css-loader</a>. Let's get those included in our project and then discuss how they work.</p>
<p>To start, as always, we'll need to install those two dependencies:</p>
<pre><code class="lang-bash">yarn add --dev style-loader css-loader
</code></pre>
<p>Then we can add them to our <code>webpack.config.common.js</code> file in the module rules section down at the bottom:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)
<span class="hljs-keyword">const</span> { CleanWebpackPlugin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'clean-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> CleanWebpackPlugin(),
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'index.html'</span>,
      <span class="hljs-attr">inject</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">template</span>: path.resolve(__dirname, <span class="hljs-string">'src'</span>, <span class="hljs-string">'index.html'</span>),
    }),
  ],
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/</span>,
        use: [<span class="hljs-string">'style-loader'</span>, <span class="hljs-string">'css-loader'</span>]
      }
    ]
  }
}
</code></pre>
<p>This section sets up rules for webpack so it knows what to do with each file it encounters. The <code>test</code> property is a regular expression that webpack checks against the file name. In this case, we want to handle files with a <code>.css</code> extension.</p>
<p>Then, the <code>use</code> property tells webpack what loader or loaders to use to handle files matching the criteria. Note that the order here matters!</p>
<p>Webpack loaders are read from right to left. So first the <code>css-loader</code> will be applied, and then the <code>style-loader</code> will be applied.</p>
<p>Now, what do these loaders actually do for us?</p>
<p><code>css-loader</code> interprets and resolves imported CSS files that you reference in your JavaScript. So in this case, <code>css-loader</code> helps make this line work:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">'./index.css'</span>
</code></pre>
<p>Next, <code>style-loader</code> injects the CSS into the DOM. By default, <code>style-loader</code> takes the CSS it encounters and adds it to the DOM inside a <code>style</code> tag.</p>
<p>Let's restart our dev server by killing the current process (if you still have it running) and then starting it again with <code>yarn start</code>. Now, in the web browser, you should see this on <code>https://localhost:8080/</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-28-at-1.07.03-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Demo app output 6 - adds pink and white colors</em></p>
<p>Oooh, so colorful!</p>
<h2 id="heading-a-note-on-other-webpack-loaders">A Note on Other Webpack Loaders</h2>
<p>We won't cover loaders for other file types in this article, but be aware that there's a loader for everything imaginable! You can use <a target="_blank" href="https://webpack.js.org/loaders/file-loader/">file-loader</a> or <a target="_blank" href="https://webpack.js.org/loaders/url-loader/">url-loader</a> for loading images and other assets. You can use <a target="_blank" href="https://webpack.js.org/loaders/sass-loader/">sass-loader</a> to handle converting Sass/SCSS files to CSS before piping that output to <code>css-loader</code> and <code>style-loader</code>. Webpack can handle Less files too with <a target="_blank" href="https://webpack.js.org/loaders/less-loader/">less-loader</a> if that's your preference.</p>
<p>The moral of the story is: For any given file type, there's a loader that can handle it.</p>
<h2 id="heading-babelloader">BabelLoader</h2>
<p>Ok, back to our demo app. We've written just a few lines of JavaScript so far. It'd be nice if we could write our JavaScript using new features that aren't well-supported in every browser yet. <a target="_blank" href="https://babeljs.io/">Babel</a> is a JavaScript compiler that can turn ES6+ code into ES5 code. </p>
<p>And (you guessed it), there's a loader for that: <a target="_blank" href="https://babeljs.io/setup#installation">babel-loader</a>.</p>
<p>To set up <code>babel-loader</code>, we'll follow the instructions on their installation guide linked above.</p>
<p>First, we'll install our dependencies:</p>
<pre><code class="lang-bash">yarn add --dev babel-loader @babel/core
</code></pre>
<p>Next, we'll add a new rule to our module rules array in our <code>webpack.config.common.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)
<span class="hljs-keyword">const</span> { CleanWebpackPlugin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'clean-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> CleanWebpackPlugin(),
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'index.html'</span>,
      <span class="hljs-attr">inject</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">template</span>: path.resolve(__dirname, <span class="hljs-string">'src'</span>, <span class="hljs-string">'index.html'</span>),
    }),
  ],
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/</span>,
        use: [<span class="hljs-string">'style-loader'</span>, <span class="hljs-string">'css-loader'</span>]
      },
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(js|jsx)$/</span>,
        exclude: <span class="hljs-regexp">/[\\/]node_modules[\\/]/</span>,
        use: {
          <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>,
        },
      },
    ]
  }
}
</code></pre>
<p>This will tell webpack that when it encounters <code>.js</code> or <code>.jsx</code> files to use Babel to transform the code. We use the <code>exclude</code> property to make sure Babel doesn't try to transform JavaScript files in our <code>node_modules</code> directory. Those are third-party dependencies that should already have been taken care of by their creators.</p>
<p>Next, we'll add one more dependency for a Babel preset:</p>
<pre><code class="lang-bash">yarn add --dev @babel/preset-env
</code></pre>
<p>And then we'll create a <code>.babelrc</code> file where we can do other Babel configuration as needed. We'll keep our file pretty simple and just specify the Babel preset that we want to use:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"presets"</span>: [<span class="hljs-string">"@babel/preset-env"</span>]
}
</code></pre>
<p>And finally, let's write some ES6 code in our <code>./src/index.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> <span class="hljs-string">'./index.css'</span>

<span class="hljs-keyword">const</span> p = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'p'</span>)
p.textContent = <span class="hljs-string">'Hello from webpack!'</span>
<span class="hljs-built_in">document</span>.body.appendChild(p)

<span class="hljs-keyword">const</span> p2 = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'p'</span>)
<span class="hljs-keyword">const</span> numbers1 = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>]
<span class="hljs-keyword">const</span> numbers2 = [<span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">10</span>]
<span class="hljs-keyword">const</span> numbers3 = [...numbers1, ...numbers2]
p2.textContent = numbers3.join(<span class="hljs-string">' '</span>)
<span class="hljs-built_in">document</span>.body.appendChild(p2)
</code></pre>
<p>This is a really trivial example, but we're using the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread operator</a> here to concatenate two arrays.</p>
<p>Now, if we kill our running process and run <code>yarn start</code> again, we should see this in the browser:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-28-at-1.25.19-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Demo app output 7 - adds numbers</em></p>
<p>Great! Everything is working nicely.</p>
<h2 id="heading-temporarily-missing-styles">Temporarily Missing Styles</h2>
<p>If you disable the cache in your browser and reload the page for our demo app, you may notice a slight blip in which the page appears with just the un-styled HTML, and then the page background turns pink and the text turns white as the styles are applied.</p>
<p>This behavior results from how <code>style-loader</code> works. As mentioned above, <code>style-loader</code> takes CSS and places it in a <code>style</code> tag in your HTML. Because of that, there's a brief period of time in which the <code>style</code> tag hasn't been appended yet!</p>
<p>Now, this is OK for a development environment, but we definitely wouldn't want this kind of behavior occurring in production. Let's fix that.</p>
<h2 id="heading-minicssextractplugin">MiniCssExtractPlugin</h2>
<p>Rather than injecting CSS into our HTML as <code>style</code> tags, we can use the <a target="_blank" href="https://webpack.js.org/plugins/mini-css-extract-plugin/">MiniCssExtractPlugin</a> to generate separate CSS files for us. We'll use this in our production config while still just using <code>style-loader</code> in our development config.</p>
<p>First, let's install the dependency in our project:</p>
<pre><code class="lang-bash">yarn add --dev mini-css-extract-plugin
</code></pre>
<p>Now in our <code>webpack.config.common.js</code> file let's remove the CSS rule since we'll be handling this differently in development and production. We're left with this in our shared config:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)
<span class="hljs-keyword">const</span> { CleanWebpackPlugin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'clean-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'main.js'</span>,
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> CleanWebpackPlugin(),
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'index.html'</span>,
      <span class="hljs-attr">inject</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">template</span>: path.resolve(__dirname, <span class="hljs-string">'src'</span>, <span class="hljs-string">'index.html'</span>),
    }),
  ],
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(js|jsx)$/</span>,
        exclude: <span class="hljs-regexp">/[\\/]node_modules[\\/]/</span>,
        use: {
          <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>,
        },
      },
    ]
  }
}
</code></pre>
<p>Now, in our <code>webpack.config.dev.js</code> file, let's add back in <code>style-loader</code> and <code>css-loader</code> that we just removed from our shared config:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-merge'</span>)
<span class="hljs-keyword">const</span> commonConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./webpack.config.common'</span>)

<span class="hljs-built_in">module</span>.exports = merge(commonConfig, {
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'development'</span>,
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">'inline-source-map'</span>,
  <span class="hljs-attr">devServer</span>: {
    <span class="hljs-attr">contentBase</span>: <span class="hljs-string">'./dist'</span>,
  },
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/</span>,
        use: [<span class="hljs-string">'style-loader'</span>, <span class="hljs-string">'css-loader'</span>]
      },
    ]
  }
})
</code></pre>
<p>And finally, in our <code>webpack.config.prod.js</code> file, let's add in our new <code>mini-css-extract-plugin</code>:</p>
<pre><code><span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-merge'</span>)
<span class="hljs-keyword">const</span> MiniCssExtractPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mini-css-extract-plugin'</span>);
<span class="hljs-keyword">const</span> commonConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./webpack.config.common'</span>)

<span class="hljs-built_in">module</span>.exports = merge(commonConfig, {
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'production'</span>,
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">'source-map'</span>,
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/</span>,
        use: [
          MiniCssExtractPlugin.loader,
          <span class="hljs-string">'css-loader'</span>,
        ],
      },
    ],
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> MiniCssExtractPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'[name].[contenthash].css'</span>,
    }),
  ]
})
</code></pre><p>This one is a little different because it actually is both a plugin <em>and</em> a loader, so it goes in the module rules and in the plugins sections.</p>
<p>Also note that we use the square brackets in our file name to dynamically set the <code>name</code> to the original source file's name and also include the <code>contenthash</code>, which is a hash (an alphanumeric string) that represents the file's contents.</p>
<p>Now if you run <code>yarn build</code> this time to generate the production build, you should get some output in your terminal that looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-28-at-1.57.28-PM.png" alt="Webpack production build output" width="600" height="400" loading="lazy">
<em>Webpack production build output</em></p>
<p>Note that it actually generates a CSS file now, and the content hash is included in the file name.</p>
<p>Alright, problem solved! No more blip when the page loads in production since we have the styles included as a <code>link</code> tag to an actual CSS file.</p>
<h2 id="heading-cache-busting">Cache Busting</h2>
<p>Since we've included the content hash in the generated CSS file, now is a good time to talk about cache busting. Why, you ask, would we want the content hash included in our file names? To help the browser understand when a file has changed!</p>
<p>Your browser tries to be helpful by caching files it has seen before. For example, if you've visited a website, and your browser had to download assets like JavaScript, CSS, or image files, your browser may cache those files so that it doesn't have to request them from the server again.</p>
<p>This means that if you visit the site again, your browser can use the cached files instead of requesting them again, so you get a faster page load time and a better experience.</p>
<p>So, what's the problem here? Imagine if we had a file called <code>main.js</code> used in our app. Then, a user visits your app and their browser caches the <code>main.js</code> file. </p>
<p>Now, at some later point in time, you've released new code for your app. The contents of the <code>main.js</code> file have changed. But, when this same user visits your app again, the browser sees that it needs a <code>main.js</code> file, notes that it has a cached <code>main.js</code> file, and just uses the cached version. The user doesn't get your new code!</p>
<p>To solve this problem, a common practice is to include the content hash in each file's name. As discussed earlier, the content hash is a string representation of the file's contents. If the file's contents don't change, the content hash doesn't change. But, if the file's contents <em>do</em> change, then the content hash <em>also</em> changes.</p>
<p>Because the file name will now change when the code changes, the browser will download the new file since it won't have that specific file name in its cache.</p>
<h2 id="heading-including-the-content-hash">Including the Content Hash</h2>
<p>To include the content hash in our JavaScript file names, we'll modify just one line of code in our <code>webpack.config.common.js</code> file. This line:</p>
<pre><code class="lang-javascript">filename: <span class="hljs-string">'main.js'</span>
</code></pre>
<p>Will change to this line:</p>
<pre><code class="lang-javascript">filename: <span class="hljs-string">'[name].[contenthash].js'</span>
</code></pre>
<p>So that the entire file looks like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)
<span class="hljs-keyword">const</span> { CleanWebpackPlugin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'clean-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>)

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: <span class="hljs-string">'./src/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'[name].[contenthash].js'</span>, <span class="hljs-comment">// this line is the only difference</span>
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">'dist'</span>)
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> CleanWebpackPlugin(),
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'index.html'</span>,
      <span class="hljs-attr">inject</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">template</span>: path.resolve(__dirname, <span class="hljs-string">'src'</span>, <span class="hljs-string">'index.html'</span>),
    }),
  ],
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(js|jsx)$/</span>,
        exclude: <span class="hljs-regexp">/[\\/]node_modules[\\/]/</span>,
        use: {
          <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>,
        },
      },
    ]
  }
}
</code></pre>
<p>Now if you run <code>yarn build</code>, you'll see that both your JavaScript and your CSS have content hashes included:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-28-at-2.12.27-PM.png" alt="Webpack production build output with content hashes included" width="600" height="400" loading="lazy">
<em>Webpack production build output with content hashes included</em></p>
<p>If you run <code>yarn build</code> again and compare your new output to your old output, you'll notice that the content hashes are exactly the same both times.</p>
<p>But, if you edit your <code>./src/index.js</code> file in any way and then run <code>yarn build</code> again, you'll get a new content hash because the content has changed! Try it!</p>
<h2 id="heading-minifying-css">Minifying CSS</h2>
<p>Last but not least, we may want to minify our CSS. We're already minifying our JavaScript for the production build, but we're not minifying our CSS yet. Let's do that.</p>
<p>We can minimize our CSS by using the <a target="_blank" href="https://github.com/NMFR/optimize-css-assets-webpack-plugin">optimize-css-assets-webpack-plugin</a>. Let's install that dependency now:</p>
<pre><code class="lang-bash">yarn add --dev optimize-css-assets-webpack-plugin
</code></pre>
<p>Now we can add that to an optimization section of our <code>webpack.config.prod.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-merge'</span>)
<span class="hljs-keyword">const</span> MiniCssExtractPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mini-css-extract-plugin'</span>)
<span class="hljs-keyword">const</span> OptimizeCssAssetsPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'optimize-css-assets-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> commonConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./webpack.config.common'</span>)

<span class="hljs-built_in">module</span>.exports = merge(commonConfig, {
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'production'</span>,
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">'source-map'</span>,
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/</span>,
        use: [
          MiniCssExtractPlugin.loader,
          <span class="hljs-string">'css-loader'</span>,
        ],
      },
    ],
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> MiniCssExtractPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'[name].[contenthash].css'</span>,
    }),
  ],
  <span class="hljs-attr">optimization</span>: {
    <span class="hljs-attr">minimizer</span>: [
      <span class="hljs-keyword">new</span> OptimizeCssAssetsPlugin({
        <span class="hljs-attr">cssProcessorOptions</span>: {
          <span class="hljs-attr">map</span>: {
            <span class="hljs-attr">inline</span>: <span class="hljs-literal">false</span>,
            <span class="hljs-attr">annotation</span>: <span class="hljs-literal">true</span>,
          },
        },
      }),
    ],
  },
})
</code></pre>
<p>Now if we run <code>yarn build</code> and then check out the contents of our <code>dist</code> directory, we can see that the resulting CSS is minified. Nice!</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span>{<span class="hljs-attribute">background</span>:<span class="hljs-number">#ff1493</span>;<span class="hljs-attribute">color</span>:<span class="hljs-number">#fff</span>}
<span class="hljs-comment">/*# sourceMappingURL=main.66e0d6aeae6f3c6fb895.css.map */</span>
</code></pre>
<p>But wait! If we look at our resulting JavaScript file, it's not minified! Hmmm. It <em>was</em> minified before, so what happened here?</p>
<p>The issue is that we're now manually configuring the optimization minimizer section of our webpack config. When that section isn't in the webpack config file, webpack defaults to using its own minimizer preferences, which includes minifying JavaScript when the <code>mode</code> is set to <code>production</code>.</p>
<p>Since we're now overriding those defaults by adding in our preferences for minifying CSS assets, we'll need to also explicitly include instructions for how we want webpack to minify JavaScript assets.</p>
<h2 id="heading-terserwebpackplugin">TerserWebpackPlugin</h2>
<p>We can minify our JavaScript files using the <a target="_blank" href="https://webpack.js.org/plugins/terser-webpack-plugin/">TerserWebpackPlugin</a>. Let's start by installing that dependency:</p>
<pre><code class="lang-bash">yarn add --dev terser-webpack-plugin
</code></pre>
<p>Then, in our <code>webpack.config.prod.js</code> file, let's add the <code>terser-webpack-plugin</code> to our optimization minimizer settings at the bottom of the file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-merge'</span>)
<span class="hljs-keyword">const</span> MiniCssExtractPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mini-css-extract-plugin'</span>)
<span class="hljs-keyword">const</span> OptimizeCssAssetsPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'optimize-css-assets-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> TerserPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'terser-webpack-plugin'</span>)
<span class="hljs-keyword">const</span> commonConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./webpack.config.common'</span>)

<span class="hljs-built_in">module</span>.exports = merge(commonConfig, {
  <span class="hljs-attr">mode</span>: <span class="hljs-string">'production'</span>,
  <span class="hljs-attr">devtool</span>: <span class="hljs-string">'source-map'</span>,
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.css$/</span>,
        use: [
          MiniCssExtractPlugin.loader,
          <span class="hljs-string">'css-loader'</span>,
        ],
      },
    ],
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> MiniCssExtractPlugin({
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'[name].[contenthash].css'</span>,
    }),
  ],
  <span class="hljs-attr">optimization</span>: {
    <span class="hljs-attr">minimizer</span>: [
      <span class="hljs-keyword">new</span> OptimizeCssAssetsPlugin({
        <span class="hljs-attr">cssProcessorOptions</span>: {
          <span class="hljs-attr">map</span>: {
            <span class="hljs-attr">inline</span>: <span class="hljs-literal">false</span>,
            <span class="hljs-attr">annotation</span>: <span class="hljs-literal">true</span>,
          },
        },
      }),
      <span class="hljs-keyword">new</span> TerserPlugin({
        <span class="hljs-comment">// Use multi-process parallel running to improve the build speed</span>
        <span class="hljs-comment">// Default number of concurrent runs: os.cpus().length - 1</span>
        <span class="hljs-attr">parallel</span>: <span class="hljs-literal">true</span>,
        <span class="hljs-comment">// Enable file caching</span>
        <span class="hljs-attr">cache</span>: <span class="hljs-literal">true</span>,
        <span class="hljs-attr">sourceMap</span>: <span class="hljs-literal">true</span>,
      }),
    ],
  },
})
</code></pre>
<p>Now if we run <code>yarn build</code> and look at the output in the <code>dist</code> directory, we should see that both our CSS files and our JavaScript files are minified. There we go!</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>If you've followed along this far, I commend you!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-186.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@katya?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Katya Austin / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>Let's review what we've learned so far:</p>
<ul>
<li>Webpack is a build tool for asset bundling and dependency management.</li>
<li>Webpack can be configured by a config file.</li>
<li>Plugins modify and extend the webpack build process.</li>
<li>Loaders instruct webpack how to handle different file types.</li>
<li>The <code>clean-webpack-plugin</code> can be used to remove old build artifacts from the <code>dist</code> directory.</li>
<li>The <code>html-webpack-plugin</code> helps manage the HTML file, including injecting JavaScript into the file via <code>script</code> tags.</li>
<li><code>webpack-dev-server</code> creates a dev server to make local development easier.</li>
<li>It's helpful to have separate webpack configs for development and production. You can share and merge config files using the <code>webpack-merge</code> plugin.</li>
<li>We can handle styling our app by including loaders like <code>css-loader</code>, <code>style-loader</code>, <code>sass-loader</code>, <code>less-loader</code>, and the <code>mini-css-extract-plugin</code> (which functions as both a plugin and a loader).</li>
<li>We can include new JavaScript syntax and features by using Babel and <code>babel-loader</code>.</li>
<li>We can include content hashes in our file names to help with cache busting and managing new versions of our released code.</li>
<li>We can minify our CSS with the <code>optimize-css-assets-webpack-plugin</code>.</li>
<li>We can minify our JavaScript with the <code>terser-webpack-plugin</code>.</li>
</ul>
<h2 id="heading-whats-next">What's Next?</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-187.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@tomparkes?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Tom Parkes / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>Throughout this article, we've created a pretty respectable webpack config. All of these techniques we've discussed are industry standards and are common to use in enterprise-level projects.</p>
<p>But there's still more! Other advanced webpack topics include <a target="_blank" href="https://webpack.js.org/guides/code-splitting/">code splitting</a>, <a target="_blank" href="https://webpack.js.org/guides/lazy-loading/">lazy loading</a>, <a target="_blank" href="https://webpack.js.org/guides/tree-shaking/">tree shaking</a>, and more!</p>
<p>If you're interested in exploring webpack more on your own, I'd highly recommend reading through the official <a target="_blank" href="https://webpack.js.org/guides/">webpack guides</a>.</p>
<p>Again, all of the code we've gone through in this tutorial can be found in GitHub. The <a target="_blank" href="https://github.com/thawkin3/webpack-training-1/tree/demo/start">starting point is found here</a>, and the <a target="_blank" href="https://github.com/thawkin3/webpack-training-1">finished result is found here</a>.</p>
<p>Thanks for reading, and happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to share variables across HTML, CSS, and JavaScript using Webpack ]]>
                </title>
                <description>
                    <![CDATA[ By Adrien Zaganelli Earlier this week, I read an article explaining how CSS-in-JS slows down the rendering of some React apps and how static CSS is faster. But CSS-in-JS is very popular because, among other features, you can style dynamically using J... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-share-variables-across-html-css-and-javascript-using-webpack/</link>
                <guid isPermaLink="false">66d45d5fb3016bf139028d0d</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 20 Dec 2019 00:30:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/12/4kzz7px14mtv34rcfp73.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adrien Zaganelli</p>
<p>Earlier this week, I read <a target="_blank" href="https://calendar.perfplanet.com/2019/the-unseen-performance-costs-of-css-in-js-in-react-apps/">an article</a> explaining how CSS-in-JS slows down the rendering of some React apps and how static CSS is faster. But CSS-in-JS is very popular because, among other features, you can style dynamically using JavaScript variables.</p>
<p>In this tutorial, I will show you how to recreate this perk in any of your web projects thanks to Webpack (and I assume you know how to use it). To start, we want Webpack to bundle our source files into a static <code>dist/</code> folder .</p>
<p>You can check out the <a target="_blank" href="https://glitch.com/~shared-variables-webpack">source code here</a>.</p>
<h2 id="heading-1-set-up-our-app">1. Set up our app</h2>
<h3 id="heading-the-boring-part">The boring part</h3>
<p>Create a folder for this tutorial, open your terminal, and init a project:</p>
<pre><code>npm init -y
</code></pre><p>First things first, if it’s not already done, install <a target="_blank" href="https://nodejs.org/en/">node.js</a> and <a target="_blank" href="https://webpack.js.org/">Webpack</a>:</p>
<pre><code>npm install webpack webpack-cli --save-dev
</code></pre><p>Let’s create a script in our <code>package.json</code> that tells Webpack to use our config file:</p>
<pre><code class="lang-json">  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"webpack --config webpack.config.js"</span>
  }
</code></pre>
<p>At the root of your folder, create a <code>globals.js</code> file, where our shared variables will be stored:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">myTitle</span>: <span class="hljs-string">'Hello freeCodeCamp!'</span>,
  <span class="hljs-attr">myColor</span>: <span class="hljs-string">'#42ff87'</span>,
};
</code></pre>
<p>The Webpack config file looks like this (<code>webpack.config.js</code>). Create it at the root of your folder:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: __dirname + <span class="hljs-string">'/app/index.js'</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">path</span>: __dirname + <span class="hljs-string">'/dist'</span>,
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'index_bundle.js'</span>
  },
};
</code></pre>
<p>Our source code will be located in an <code>app</code> folder. Create it like this:</p>
<pre><code>mkdir app &amp;&amp; cd app
</code></pre><p>You’ll need <code>index.html</code> and <code>index.js</code> files at this point. Create those files in the <code>app</code> folder:</p>
<pre><code>touch index.html index.js
</code></pre><p>Perfect! You’re all set. ?</p>
<p>Your folder should look like this:</p>
<pre><code>|-- node_modules/
|-- package.json
|-- webpack.config.js
|-- globals.js
|-- app/
    |-- index.html
    |-- index.js
</code></pre><h2 id="heading-2-render-our-html-files-with-the-html-webpack-plugin">2. Render our HTML files with the <code>html-webpack-plugin</code></h2>
<p>This <code>app/index.html</code> is empty. Let’s add some markup in it and then add a custom variable:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Webpack shared variables!<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">%=</span> <span class="hljs-attr">myTitle</span> %&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>As you can see, we are trying to print a variable in our HTML... which is impossible! To make it work we’ll use the <a target="_blank" href="https://github.com/jantimon/html-webpack-plugin">html-webpack-plugin</a> that gives us the ability to use <a target="_blank" href="https://ejs.co/">EJS</a> syntax and <strong>inject data into it</strong>.</p>
<p>The plugin will generate a valid HTML file. In the meantime, you should rename your <code>app/index.html</code> file to <code>app/index.ejs</code>.</p>
<pre><code>npm install --save-dev html-webpack-plugin
</code></pre><p>Let’s go back to our configuration file. <code>html-webpack-plugin</code> has an interesting <code>templateParameters</code> option that allows us to pass an object as parameter. Enable the plugin as follows in <code>webpack.config.js</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>);
<span class="hljs-keyword">const</span> globals = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./globals.js'</span>)

<span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-comment">// ... previous config, entry, output...</span>
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">template</span>: <span class="hljs-string">'app/index.ejs'</span>,
      <span class="hljs-attr">templateParameters</span>: globals,
    })
  ]
};
</code></pre>
<p>Run <code>npm run build</code> and <em>ta-daaaaa</em> « &lt;%= myTitle %&gt; » became « Hello freeCodeCamp » ! The work is done by Webpack during the compilation when it runs the <code>html-webpack-plugin</code>.</p>
<p>See? This was pretty simple with the right tool: HTML ✅</p>
<h2 id="heading-3-use-our-variables-in-javascript">3.  Use our variables in JavaScript</h2>
<p>Phew, so many lines just to print a variable! ?With Webpack, things often get complicated. Well, this one is very simple: in JavaScript just import your file. In your <code>app/index.js</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> globals <span class="hljs-keyword">from</span> <span class="hljs-string">'../globals.js'</span>

<span class="hljs-built_in">document</span>.write(
<span class="hljs-string">'&lt;pre&gt;'</span> +
  <span class="hljs-built_in">JSON</span>.stringify(globals, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>) +
<span class="hljs-string">'&lt;/pre&gt;'</span>
);
</code></pre>
<p>This will print our globals object on the page. Now let’s move on to the CSS.</p>
<h2 id="heading-4-use-shared-variables-in-our-css">4. Use shared variables in our CSS</h2>
<p>Here is our final boss ?</p>
<p>Okay guys you got me… I lied. We can’t use our globals directly in CSS – we must use a pre-processor. In this example, we will use <a target="_blank" href="https://sass-lang.com/">SASS</a>.</p>
<p>On the Webpack side, a plugin will not be enough. We must use a <a target="_blank" href="https://webpack.js.org/loaders/">loader</a> to convert SASS into CSS. In this case we need the <a target="_blank" href="https://github.com/webpack-contrib/sass-loader">sass-loader</a> package, so install it according to the docs:</p>
<pre><code>npm install sass-loader node-sass css-loader style-loader --save-dev
</code></pre><p>Back to coding. Now that we have SASS, create your style sheet file, <code>app/style.scss</code>:</p>
<pre><code class="lang-scss"><span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-variable">$myColor</span>;
}
</code></pre>
<p>Our SASS is set up – now how can we inject data into it? The <code>sass-loader</code> package has a <a target="_blank" href="https://github.com/webpack-contrib/sass-loader#prependdata">prependData</a> option! But it takes a string as a parameter, which means that your data should look like this: <code>"$myColor: red; myTitle: '...'";</code>.</p>
<p>We have to automate that and convert a JavaScript object into a string. I didn’t find a package on <code>npm</code> that satisfied me, so I wrote <a target="_blank" href="https://gist.github.com/adrienZ/0257e37bf4788b903ba76fa82dac1ed1">my own converter</a>. Download the file and add it to your project (in my example it's <code>utils/jsToScss.js</code>).</p>
<p>Your final <code>webpack.config.js</code> should look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> globals = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./globals.js"</span>);
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"html-webpack-plugin"</span>);
<span class="hljs-keyword">const</span> jsToScss = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./utils/jsToScss.js"</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>: __dirname + <span class="hljs-string">"/app/index.js"</span>,
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">path</span>: __dirname + <span class="hljs-string">"/dist"</span>,
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"index_bundle.js"</span>
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">template</span>: <span class="hljs-string">"app/index.ejs"</span>,
      <span class="hljs-attr">templateParameters</span>: globals
    })
  ],
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.s[ac]ss$/i</span>,
        use: [
          <span class="hljs-comment">// Creates `style` nodes from JS strings</span>
          <span class="hljs-string">"style-loader"</span>,
          <span class="hljs-comment">// Translates CSS into CommonJS</span>
          <span class="hljs-string">"css-loader"</span>,
          <span class="hljs-comment">// Compiles Sass to CSS</span>
          {
            <span class="hljs-attr">loader</span>: <span class="hljs-string">"sass-loader"</span>,
            <span class="hljs-attr">options</span>: {
              <span class="hljs-attr">prependData</span>: jsToScss(globals)
            }
          }
        ]
      }
    ]
  }
};
</code></pre>
<p>Here is what you should see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/12/Capture-d-e-cran-2019-12-23-23.44.11.png" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://glitch.com/edit/#!/shared-variables-webpack?path=webpack.config.js">https://glitch.com/edit/#!/shared-variables-webpack?path=webpack.config.js</a></em></p>
<p>If you are still reading this tutorial, thanks for your attention. I hope it helps you! Webpack is a very powerful tool you should dig more into ?</p>
<p>NB: In your <code>dist/</code> folder you can see there isn't any CSS generated. That's because I use the <code>style-loader</code> to keep this demo simple. To generate the CSS file, take a look at the <a target="_blank" href="https://webpack.js.org/plugins/mini-css-extract-plugin/">mini-css-extract-plugin</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn webpack to simplify and speed up your website ]]>
                </title>
                <description>
                    <![CDATA[ Wepback is a JavaScript module bundler and is useful in many development workflows. Learn Webpack from Colt Steele in this full course. The course begins with a simple question: "What is webpack?"  Then you will learn about installing Webpack, config... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/webpack-course/</link>
                <guid isPermaLink="false">66b2070deea9870582e16cea</guid>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 19 Jun 2019 15:10:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/webpack.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Wepback is a JavaScript module bundler and is useful in many development workflows. Learn Webpack from Colt Steele in this full course.</p>
<p>The course begins with a simple question: "What is webpack?"  Then you will learn about installing Webpack, configuring it, and adding loaders for CSS, SASS, HTML, and Files. </p>
<p>The course covers cache busting, setting up a dev server, and splitting up your development and production config files. You will learn about multiple Webpack plugins including clean-webpack-plugin, mini-css-extract-plugin,  optimize-css-assets-webpack-plugin, terser-webpack-plugin, and html-webpack-plugin.</p>
<p>You can watch the full video course on the <a target="_blank" href="https://www.youtube.com/watch?v=MpGLUVbqoYQ">freeCodeCamp.org YouTube channel</a> (2 hour watch).</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to improve performance in your apps with Lighthouse, Webpack, and React Loadable Components ]]>
                </title>
                <description>
                    <![CDATA[ By Adam Henson An overview of modern concepts, tools and example strategies to improve web page performance Not Impressed at Penn Station In March of 2018 Google confirmed rumors by announcing the migration of sites for “mobile-first” indexing. What... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/taming-performance-in-todays-web-app-with-lighthouse-webpack-and-react-loadable-components-b2d3fa04e0ab/</link>
                <guid isPermaLink="false">66c3603fc337fbd10a4b5973</guid>
                
                    <category>
                        <![CDATA[ Lighthouse ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 27 Feb 2019 13:57:16 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*9I7geT-jjXNgvszViOfLQA.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adam Henson</p>
<h4 id="heading-an-overview-of-modern-concepts-tools-and-example-strategies-to-improve-web-page-performance">An overview of modern concepts, tools and example strategies to improve web page performance</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*9I7geT-jjXNgvszViOfLQA.jpeg" alt="Image" width="800" height="468" loading="lazy">
<em>Not Impressed at Penn Station</em></p>
<p>In March of 2018 Google confirmed rumors by announcing the migration of sites for <a target="_blank" href="https://webmasters.googleblog.com/2018/03/rolling-out-mobile-first-indexing.html">“mobile-first” indexing</a>.</p>
<h3 id="heading-what-this-means">What this Means</h3>
<blockquote>
<p>Mobile-first indexing means Google will predominantly use the mobile version of the content for indexing and ranking. Historically, the index primarily used the desktop version of a page’s content when evaluating the relevance of a page to a user’s query. Since the majority of users now access Google via a mobile device, the index will primarily use the mobile version of a page’s content going forward. We aren’t creating a separate mobile-first index. We continue to use only one index.~[Prepare for mobile-first indexing](http://Mobile-first indexing means Google will predominantly use the mobile version of the content for indexing and ranking. Historically, the index primarily used the desktop version of a page's content when evaluating the relevance of a page to a user's query. Since the majority of users now access Google via a mobile device, the index will primarily use the mobile version of a page's content going forward. We aren't creating a separate mobile-first index. We continue to use only one index.)</p>
</blockquote>
<p>“Yikes!” — you may be thinking. This is a reasonable reaction for anyone owning a website relying on organic search results for its success. Consider extreme examples of websites that drive millions of dollars a day who’ve come to depend on such rankings. Many of these websites weren’t necessarily built to support mobile devices as the highest priority.</p>
<h3 id="heading-confronting-performance">Confronting Performance</h3>
<p>The first step in ensuring optimal performance of a web page on a mobile device is to understand key metrics in modern testing. We can go straight to the source by utilizing <a target="_blank" href="https://developers.google.com/web/tools/lighthouse/">Lighthouse</a>, Google’s open-source tool. You can run it in Chrome DevTools, from the command line, or as a Node module.</p>
<p>Lighthouse has a variety of options to allow performance testing under a variety of conditions, specifically notable being device and connection type.</p>
<h4 id="heading-lighthouse-metrics-and-scoring">Lighthouse Metrics and Scoring</h4>
<p>In a Lighthouse performance audit, results are provided as a set of metrics with values. The score is a number between 0 and 100 where the higher number is better. Score is calculated by a weighted group of select metrics as explained in the <a target="_blank" href="https://developers.google.com/web/tools/lighthouse/v3/scoring">documentation</a>.</p>
<blockquote>
<p>Load is not a single moment in time — it’s an experience that no one metric can fully capture. There are multiple moments during the load experience that can affect whether a user perceives it as “fast” or “slow”.</p>
<p>~ <a target="_blank" href="https://w3c.github.io/paint-timing/">Paint Timing Spec</a></p>
</blockquote>
<p>Not only does each metric capture a characteristic of page load, but each metric can encompass the results of others.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*_hTRAwcLq5BHF_YMPkcBjw.jpeg" alt="Image" width="800" height="396" loading="lazy">
<em>Nobody is perfect — an audit of the Lighthouse’s own documentation page</em></p>
<h3 id="heading-opportunities-for-improvement-and-solutions">Opportunities for Improvement and Solutions</h3>
<p>I’ve identified a few commonly low metrics with fairly straightforward solutions, depending on complexity. “<a target="_blank" href="https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive">Time to Interactive</a>” is one of the most important.</p>
<h4 id="heading-time-to-interactive">Time to Interactive</h4>
<p>At the time of this writing, the “Time to Interactive” metric is weighted highest in its influence on the overall performance score.</p>
<blockquote>
<p>The Time to Interactive (TTI) metric measures how long it takes a page to become interactive. “Interactive” is defined as the point where:</p>
<p>The page has displayed useful content, which is measured with <a target="_blank" href="https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint">First Contentful Paint</a>.</p>
<p>Event handlers are registered for most visible page elements.</p>
<p>The page responds to user interactions within 50 milliseconds.</p>
<p>To improve your TTI score, defer or remove unnecessary JavaScript work that occurs during page load. See <a target="_blank" href="https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/javascript-startup-optimization/">Optimize JavaScript Bootup</a> and <a target="_blank" href="https://developers.google.com/web/fundamentals/performance/optimizing-javascript/tree-shaking/">Reduce JavaScript Payloads with Tree Shaking</a>, and <a target="_blank" href="https://developers.google.com/web/fundamentals/performance/optimizing-javascript/code-splitting/">Reduce JavaScript Payloads with Code Splitting</a>.</p>
<p>~<a target="_blank" href="https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive">Time to Interactive</a></p>
</blockquote>
<h4 id="heading-improving-time-to-interactive">Improving Time to Interactive</h4>
<p>Webpack provides sophisticated customization nowadays to improve optimization. It provides out of the box configuration options to split code and prevent duplication as illustrated in the <a target="_blank" href="https://webpack.js.org/guides/code-splitting/#prevent-duplication">documentation</a>. By using <a target="_blank" href="https://github.com/webpack-contrib/webpack-bundle-analyzer">Webpack Bundle Analyzer</a>, we can visualize the outcome of a “prevent duplication” code splitting approach.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Kh0cpk3G0KKWym0ZC_ZLcg.png" alt="Image" width="800" height="339" loading="lazy">
<em>Webpack Bundle Analyzer: Standard code splitting of a “vendors” bundle</em></p>
<p>Okay, well… could be worse ?! The important part is we separated common code. By doing this alone we relieve work from the main execution thread, provide asset caching potential, and other interesting things a<a target="_blank" href="https://developers.google.com/web/fundamentals/performance/optimizing-javascript/code-splitting/">s detailed by Addy Osmani and Jeremy Wagner.</a> But wait… there’s more!</p>
<h4 id="heading-dynamic-code-splitting">Dynamic Code Splitting</h4>
<p>We talked about one approach above. Another code splitting technique supported by Webpack involves the use of <a target="_blank" href="https://webpack.js.org/guides/code-splitting/#dynamic-imports">dynamic imports</a>. I accomplished this fairly easily with staggering results by using <a target="_blank" href="https://github.com/smooth-code/loadable-components">Loadable Components</a> to handle rendering in my “universal” app. I chose this library in its support of “Server Side Rendering” and <a target="_blank" href="https://www.smooth-code.com/open-source/loadable-components/docs/server-side-rendering/">documentation of it</a>. It provides a <a target="_blank" href="https://www.smooth-code.com/open-source/loadable-components/docs/api-loadable-webpack-plugin/">Babel Plugin</a> (which delegates chunks under the hood during build) and a <a target="_blank" href="https://www.smooth-code.com/open-source/loadable-components/docs/api-loadable-server/#chunkextractor">Chunk Extractor</a> — to collect chunks server side and provide script tags on page render. This seems confusing, so enough with the words… let’s role up our sleeves!</p>
<p>Imagine a page component, defined with a dynamic import.</p>
<p>And to process and delegate Loadable Components during build, we can configure Webpack with the Babel plugin (mentioned above).</p>
<p>In our client side render entry, we wrap in <a target="_blank" href="https://www.smooth-code.com/open-source/loadable-components/docs/server-side-rendering/#4-add-loadableready-client-side">Loadable Ready</a>. Loadable Components loads all your scripts asynchronously to ensure optimal performance. All scripts are loaded in parallel, so you have to wait for them to be ready using <code>loadableReady</code> .</p>
<p>On server side render, Loadable Components <code>ChunkExtractor</code> provides only the script tags used by initial page load and the rest asynchronously, client side! JS is loaded on-demand, behind the scenes.</p>
<p>Dynamically extracting script and style tags needed by a particular page is quite powerful. I used dynamic imports in all page components and components that uniquely import heavy libraries. What a difference! ?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Po8Fa2q8eV-s6XCkIAioGQ.png" alt="Image" width="800" height="388" loading="lazy">
<em>Webpack Bundle Analyzer: Dynamic code splitting</em></p>
<p>We reduced the main vendor bundle by more than 100kb. The blue squares in the image above represent bundles created with dynamically imported page components. The large violet square in the top middle is a vendor split bundle from one specific component I identified as uniquely importing large libraries.</p>
<h4 id="heading-okay-did-we-actually-do-anything">Okay, Did We Actually Do Anything?</h4>
<p>The short answer is — yes!! We can see how JS is loaded by examining the network panel in Chrome Dev Tools. Let’s assume a request to a home page.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*CPgpl5GFDBkqb6H8zrauiw.jpeg" alt="Image" width="800" height="120" loading="lazy">
<em>Chrome Dev Tools network panel: An example home page</em></p>
<p>Okay, wait… it’s all coming back now…</p>
<blockquote>
<p>An alternative to large bundles is code-splitting, which is where JavaScript is split into smaller chunks. This enables sending the minimal code required to provide value upfront, improving page-load times. The rest can be loaded on demand.</p>
<p>~ <a target="_blank" href="https://developers.google.com/web/fundamentals/performance/optimizing-javascript/code-splitting/">Reduce JavaScript Payloads with Code Splitting</a></p>
</blockquote>
<p>Aha, we can see this in action here as a user navigates to another route client side. Assume the user navigates to a “dashboard” page from the home page. <code>Dashboard.fc4871b3.js</code> is downloaded on demand!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*3fDQdS0c-CAd9dRTuOL3KQ.jpeg" alt="Image" width="800" height="104" loading="lazy">
<em>Chrome Dev Tools network panel: An example home page and client side navigation to a “dashboard” page</em></p>
<p>And… Google loves it! With the above changes, I saw a Lighthouse score improvement of more than 10 points. ?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*RC7X-N0kf8qOKnGRVwmPWw.jpeg" alt="Image" width="800" height="405" loading="lazy">
<em>A Lighthouse audit with success written all over it!</em></p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>By utilizing a recipe of modern tools and features, we can effectively identify, measure, visualize and address web page performance. This is important in accommodating Google’s mobile-first indexing. Key metrics documented by Google to measure performance, such as “<a target="_blank" href="https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive">Time to Interactive</a>”, can help us pinpoint opportunities for improvement.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to configure Webpack 4 with Angular 7: a complete guide ]]>
                </title>
                <description>
                    <![CDATA[ By Samuel Teboul The Angular CLI makes it easy to create an application that already works, right out of the box. It is a great tool, but have you never thought: "How does it work? How can I build an application without the CLI?" Those questions came... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-configure-webpack-4-with-angular-7-a-complete-guide-9a23c879f471/</link>
                <guid isPermaLink="false">66c350b130aba6677fb9fa22</guid>
                
                    <category>
                        <![CDATA[ Angular ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 15 Jan 2019 21:52:12 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*uNX5QUpeczuU_CjXouZxnA.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Samuel Teboul</p>
<p>The Angular CLI makes it easy to create an application that already works, right out of the box. It is a great tool, but have you never thought: <em>"How does it work? How can I build an application without the CLI?"</em></p>
<p>Those questions came to my mind when Angular 7 was released. I started to look for answers on the web and what I found was not up-to-date for my purpose. Indeed, as Angular and webpack are always evolving, so dependencies and configurations.</p>
<p>In this article you are about to learn:</p>
<ul>
<li>How to setup an Angular 7 basic application, from scratch</li>
<li>How to configure webpack for development mode (Just-in-Time compilation)</li>
<li>How to configure webpack for production mode (Ahead-of-Time compilation)</li>
</ul>
<h3 id="heading-angular-7-setup-a-basic-app">Angular 7: setup a basic app</h3>
<p>Create a new <code>package.json</code> file and add the following lines to install Angular and its dependencies.</p>
<pre><code class="lang-json"><span class="hljs-string">"dependencies"</span>: 
  <span class="hljs-string">"@angular/animations"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/common"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/compiler"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/compiler-cli"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/core"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/forms"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/http"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/platform-browser"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/platform-browser-dynamic"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/platform-server"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/router"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"@angular/upgrade"</span>: <span class="hljs-string">"~7.0"</span>,
  <span class="hljs-string">"core-js"</span>: <span class="hljs-string">"~2.5"</span>,
  <span class="hljs-string">"rxjs"</span>: <span class="hljs-string">"~6.3"</span>,
  <span class="hljs-string">"zone.js"</span>: <span class="hljs-string">"~0.8"</span>
}
</code></pre>
<p>I have struggled for a long time to find the best folder structure that fits every Angular project, especially when the application grows in size. This <a target="_blank" href="https://medium.com/@motcowley/angular-folder-structure-d1809be95542">article</a> has taught me a lot on the subject.</p>
<p>Create a new <code>src</code> folder and the following folders/files inside it. All our Angular app business logic will be in this folder.</p>
<pre><code class="lang-bash">src
|__ app
    |__ modules
        |__ menu
            |__ components
                |__ menu
                    |__ menu.component.html
                    |__ menu.component.scss
                    |__ menu.component.ts
            |__ menu.module.ts
            |__ menu-routing.module.ts
|__ shared
         |__ components
             |__ home
                 |__ home.component.html
                 |__ home.component.scss
                 |__ home.component.ts
|__ app.component.html
        |__ app.component.scss        
        |__ app.component.ts
        |__ app.module.ts
        |__ app-routing.module.ts
|__ index.html
|__ main.ts
</code></pre>
<p>Every application has at least one Angular module, the <em>root</em> module that you bootstrap to launch the application. By convention, it is usually called <code>AppModule</code>. I create another module, the <code>MenuModule</code> to show you how you can use lazy loading in your project, especially for production.</p>
<p>Some important points :</p>
<ul>
<li><code>index.html</code></li>
</ul>
<p>Add <code>&lt;base href=”/”&gt;</code> tells our Angular router how to compose navigation URLs . This line means that your app will start from root folder i.e locally it would consider <code>localhost:3000/</code> and on server it would consider root folder.</p>
<ul>
<li><code>app-routing.module.ts</code></li>
</ul>
<p>There are three main steps to setting up a lazy loaded feature module:</p>
<ol>
<li>Create the feature module</li>
<li>Create the feature module’s routing module</li>
<li>Configure the routes</li>
</ol>
<p><code>{path: ‘menu’, loadChildren:’./modules/menu/menu.module#MenuModule’}</code> tells Angular to lazy load our feature module <code>MenuModule</code> by the time the user visit the <code>/menu</code> route.</p>
<h3 id="heading-typescript-configuration">TypeScript configuration</h3>
<p>Add the following lines to your <code>package.json</code> file:</p>
<pre><code class="lang-json"><span class="hljs-string">"devDependencies"</span>: {
  <span class="hljs-attr">"@types/core-js"</span>: <span class="hljs-string">"~2.5"</span>,
  <span class="hljs-attr">"@types/node"</span>: <span class="hljs-string">"~10.12"</span>,
  <span class="hljs-attr">"typescript"</span>: <span class="hljs-string">"~3.1"</span>
}
</code></pre>
<p>Create in your root project folder a <code>tsconfig.json</code> file:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"target"</span>: <span class="hljs-string">"es5"</span>,
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"commonjs"</span>,
    <span class="hljs-attr">"moduleResolution"</span>: <span class="hljs-string">"node"</span>,
    <span class="hljs-attr">"sourceMap"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"emitDecoratorMetadata"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"experimentalDecorators"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"noImplicitAny"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"suppressImplicitAnyIndexErrors"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"lib"</span>: [<span class="hljs-string">"es6"</span>, <span class="hljs-string">"dom"</span>],
    <span class="hljs-attr">"typeRoots"</span>: [<span class="hljs-string">"node_modules/@types"</span>]
  },
  <span class="hljs-attr">"exclude"</span>: [<span class="hljs-string">"node_modules"</span>]
}
</code></pre>
<p>This is a basic TypeScript configuration file. It’s essential to install <code>node</code> and <code>core-js</code> types definition. Without it, TypeScript won’t be able to compile our Angular application to JavaScript.</p>
<h3 id="heading-webpack-configuration-for-development-mode-just-in-time-compilation">Webpack configuration for development mode (Just-in-Time compilation)</h3>
<p>First of all, what does <em>compilation</em> means ? It doesn’t mean compiling TypeScript files to JavaScript, this is not related to Angular. Angular itself needs to compile your HTML templates into JavaScript and this can occurred at 2 different points of time:</p>
<ul>
<li>After your app is downloaded in the Browser (JiT)</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/sRk7L8PTi7CphpbxdOxOGoHPvMx3jfskkjii" alt="Image" width="513" height="294" loading="lazy">
<em>JiT compilation</em></p>
<ul>
<li>Right after development, at build time, before your app is downloaded in the Browser (AoT)</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/eGuSnScvGTy4JzYxa6Vmo8JXcVZSLTn2H84h" alt="Image" width="498" height="278" loading="lazy"></p>
<h4 id="heading-what-is-webpack">What is webpack?</h4>
<p>According to Wikipedia:</p>
<blockquote>
<p>Webpack is an open source JavaScript module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset. Webpack takes modules with dependencies and generates static assets representing those modules. It’s a module bundler primarily for JavaScript, but it can transform front-end assets like HTML, CSS, even images if the corresponding plugins are included.</p>
</blockquote>
<p>To tell webpack how to bundle our application we have to configure what we call the <a target="_blank" href="https://webpack.js.org/concepts/">Core Concepts</a>:</p>
<p><strong>Entry —</strong> An entry point indicates which module webpack should use to begin building out its internal <a target="_blank" href="https://webpack.js.org/concepts/dependency-graph/">dependency graph</a>. Webpack will figure out which other modules and libraries that entry point depends on (directly and indirectly).</p>
<p><strong>Output —</strong> The output property tells webpack where to emit the bundles it creates and how to name these files. It defaults to <code>./dist/main.js</code> for the main output file and to the <code>./dist</code> folder for any other generated file.</p>
<p><strong>Loaders —</strong> At a high level, loaders have two properties in your webpack configuration:</p>
<ul>
<li>The test property identifies which file or files should be transformed.</li>
<li>The use property indicates which loader should be used to do the transforming.</li>
</ul>
<p><strong>Plugins —</strong> While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management, and injection of environment variables.</p>
<p>All of these must be set up in the webpack configuration file <code>webpack.config.js.</code></p>
<h4 id="heading-configuring-webpack">Configuring webpack</h4>
<p>In the <code>src</code> folder we need to create 2 more files:</p>
<ul>
<li><code>vendor.ts</code> that only imports the application's third-party modules.</li>
<li><code>polyfills.ts</code> we need polyfills to run an Angular application in most browsers as explained in the <a target="_blank" href="https://v5.angular.io/guide/browser-support">Browser Support</a> guide. This bundle file will load first so this is a good place to configure the browser environment for production or development.</li>
</ul>
<p>Create a new <code>config</code> folder and the following files inside:</p>
<ul>
<li><code>webpack.config.common.js</code> : configuration that we will use for development and production.</li>
</ul>
<p><strong>Entry —</strong> For this application (and for most of them actually) we have 3 different entry points : <code>vendor.ts</code> <code>polyfills.ts</code> and <code>main.ts.</code></p>
<pre><code class="lang-json">entry: {
    vendor: './src/vendor.ts',
    polyfills: './src/polyfills.ts',
    main: './src/main.ts'
}
</code></pre>
<p><strong>Loaders —</strong> We load <code>.html</code> files with <code>html-loader</code> which is pretty standard. Loading <code>.scss</code> files is a bit tricky for an Angular app and I struggled for many hours to figure out how to do it.</p>
<p>First of all, we must load sass files by using two loaders <code>sass-loader</code> and <code>css-loader.</code> If you want to make debugging easy, especially in development mode, it’s really important to add <code>sourceMap: **true**</code> as options. In an Angular application we add styles to component by passing a file path to <code>styleUrls</code> array as follow <code>styleUrls: ["./path/styles.scss"]</code> but we need to have style as a string and <code>to-string-loader</code> will do it for us and cast the output to a string.</p>
<pre><code class="lang-json">{
    test: /\.html$/,
    loader: 'html-loader'
},
{
    test: /\.(scss|sass)$/,
    use: [
        'to-string-loader',
        { 
            loader: 'css-loader', 
            options: { 
                sourceMap: <span class="hljs-literal">true</span> 
            } 
        },
        { 
            loader: 'sass-loader', 
            options: { 
                sourceMap: <span class="hljs-literal">true</span> 
            } 
        }
    ],
    include: helpers.root('src', 'app')
}
</code></pre>
<p><strong>Plugins —</strong> <code>CleanWebpackPlugin</code> will remove/clean your build folder(s) before building again. <code>HtmlWebpackPlugin</code> plugin will generate an HTML5 file for you that includes all your webpack bundles in the body using script tags. It only requires path to the template.</p>
<pre><code class="lang-js"><span class="hljs-keyword">new</span> CleanWebpackPlugin(
    helpers.root(<span class="hljs-string">'dist'</span>),
    {
        <span class="hljs-attr">root</span>: helpers.root(),
        <span class="hljs-attr">verbose</span>: <span class="hljs-literal">true</span>
    }
),
<span class="hljs-keyword">new</span> HtmlWebpackPlugin({
    <span class="hljs-attr">template</span>: <span class="hljs-string">'src/index.html'</span>
})
</code></pre>
<ul>
<li><code>webpack.config.dev.js</code> is our webpack configuration that we will use for development mode only.</li>
</ul>
<pre><code class="lang-js">mode: <span class="hljs-string">"development"</span>
</code></pre>
<p>In webpack 4, chosen mode tells webpack to use its built-in optimizations accordingly.</p>
<pre><code>devtool: <span class="hljs-string">'cheap-module-eval-source-map'</span>
</code></pre><p>This option controls if and how source maps are generated. By using <code>cheap-module-eval-source-map</code> Source Maps from loaders are processed for better results. However, loader Source Maps are simplified to a single mapping per line.</p>
<pre><code class="lang-js">output: {
    <span class="hljs-attr">path</span>: helpers.root(<span class="hljs-string">'dist'</span>),
    <span class="hljs-attr">publicPath</span>: <span class="hljs-string">'/'</span>,
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'[name].bundle.js'</span>,
    <span class="hljs-attr">chunkFilename</span>: <span class="hljs-string">'[id].chunk.js'</span>
}
</code></pre>
<p>The <code>output</code> key contains a set of options instructing webpack on how and where it should output your bundles, assets and anything else you bundle or load with webpack. Here we tell webpack to output our bundles to the <code>dist</code> folder.</p>
<pre><code class="lang-js">optimization: {
    <span class="hljs-attr">noEmitOnErrors</span>: <span class="hljs-literal">true</span>
}
</code></pre>
<p>Skips the emitting phase whenever there are errors while compiling. This ensures that no erroring assets are emitted. The <code>optimization</code> key has many others options that are set by default depending on your webpack configuration mode (development/production). You can read more about it <a target="_blank" href="https://webpack.js.org/configuration/optimization/#optimization-noemitonerrors">here</a>.</p>
<pre><code class="lang-json">{
    test: /\.ts$/,
    loaders: [
        'babel-loader',
        {
            loader: 'awesome-typescript-loader',
            options: {
                configFileName: helpers.root('tsconfig.json')
            }
        },
        'angular2-template-loader',
        'angular-router-loader'
    ],
    exclude: [/node_modules/]
}
</code></pre>
<p><code>angular-router-loader</code> is a webpack loader that enables string-based module loading with the Angular Router.</p>
<p><code>angular2-template-loader</code> is a chain-to loader that inlines all html and styles in Angular components.</p>
<p><code>awesome-typescript-loader</code> is currently the faster webpack TypeScript loader. It uses dependency resolution to build modules dependency graph. This relatively speeds up the build process.</p>
<p><code>babel-loader</code> allows transpiling JavaScript files.</p>
<pre><code class="lang-js">devServer: {
    <span class="hljs-attr">historyApiFallback</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">stats</span>: <span class="hljs-string">'minimal'</span>
}
</code></pre>
<p>When using the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/History">HTML5 History API</a>, the <code>index.html</code> page will likely have to be served in place of any <code>404</code> responses. For that we need to enable <code>historyApiFallback.</code></p>
<p><code>stats</code> option lets you precisely control what bundle information gets displayed. This can be a nice middle ground if you want some bundle information, but not all of it.</p>
<h4 id="heading-adding-scripts">Adding scripts</h4>
<p>Add the following lines to your <code>package.json</code> file:</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {
  <span class="hljs-attr">"build:dev"</span>: <span class="hljs-string">"webpack-dev-server --inline --hot --progress --port 8080"</span>
}
</code></pre>
<p><code>--hot</code> enables webpack Hot Module Replacement (HMR). It exchanges, adds, or removes <a target="_blank" href="https://webpack.js.org/concepts/modules/">modules</a> while an application is running, without a full reload. This can significantly speed up development in a few ways:</p>
<ul>
<li>Retain application state which is lost during a full reload.</li>
<li>Save valuable development time by only updating what’s changed.</li>
<li>Modifications made to CSS/JS in the source code results in an instant browser update which is almost comparable to changing styles directly in the browser’s dev tools.</li>
</ul>
<p>Now you are all setup! You can run <code>npm run build:dev</code> open your browser and navigate to <code>localhost:8080.</code></p>
<h3 id="heading-webpack-configuration-for-production-mode-ahead-of-time-compilation">Webpack configuration for production mode (Ahead-of-Time compilation)</h3>
<h4 id="heading-advantages-of-aot-compilation">Advantages of AoT compilation</h4>
<ul>
<li>With AoT, the browser downloads a pre-compiled version of the application. The browser loads executable code so it can render the application immediately, without waiting to compile the app first.</li>
<li>The compiler inlines external HTML templates and CSS style sheets within the application JavaScript, eliminating separate AJAX requests for those source files.</li>
<li>There’s no need to download the Angular compiler if the app is already compiled. The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload.</li>
<li>The AoT compiler detects and reports template binding errors during the build step before users can see them.</li>
<li>AoT compiles HTML templates and components into JavaScript files long before they are served to the client. With no templates to read and no risky client-side HTML or JavaScript evaluation, there are fewer opportunities for injection attacks.</li>
</ul>
<h4 id="heading-configuring-webpack-1">Configuring webpack</h4>
<p>In your <code>config</code> folder create a new file <code>webpack.config.prod.js</code></p>
<pre><code class="lang-js">mode: <span class="hljs-string">'production'</span>
</code></pre>
<p>We usually proceed to AoT compilation in production mode and, as I wrote previously, in webpack 4, chosen mode tells webpack to use its built-in optimizations accordingly.</p>
<pre><code class="lang-js">output: {
    <span class="hljs-attr">path</span>: helpers.root(<span class="hljs-string">'dist'</span>),
    <span class="hljs-attr">publicPath</span>: <span class="hljs-string">'/'</span>,
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'[hash].js'</span>,
    <span class="hljs-attr">chunkFilename</span>: <span class="hljs-string">'[id].[hash].chunk.js'</span>
}
</code></pre>
<p>We also tell webpack to output our bundles to the <code>dist</code> folder. We include a hash to the file names to leverage client level cache efficiently. This way webpack knows whether or not a file has changed. Webpack provides <strong>placeholders</strong> for this purpose. These strings are used to attach specific information to outputs. The most valuable ones are:</p>
<ul>
<li><code>[id]</code> returns the chunk id.</li>
<li><code>[path]</code> returns the file path.</li>
<li><code>[name]</code> returns the file name.</li>
<li><code>[ext]</code> returns the extension. <code>[ext]</code> works for most available fields.</li>
<li><code>[hash]</code> returns the build hash. If any portion of the build changes, this changes as well.</li>
<li><code>[chunkhash]</code> returns an entry chunk-specific hash. Each <code>entry</code> defined in the configuration receives a hash of its own. If any portion of the entry changes, the hash will change as well. <code>[chunkhash]</code> is more granular than <code>[hash]</code> by definition.</li>
<li><code>[contenthash]</code> returns a hash generated based on content.</li>
</ul>
<p>It’s preferable to use particularly <code>hash</code> and <code>chunkhash</code> only for production as hashing is not essential during development.</p>
<pre><code class="lang-js">optimization: {
    <span class="hljs-attr">noEmitOnErrors</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">splitChunks</span>: {
        <span class="hljs-attr">chunks</span>: <span class="hljs-string">'all'</span>
    },
    <span class="hljs-attr">runtimeChunk</span>: <span class="hljs-string">'single'</span>,
    <span class="hljs-attr">minimizer</span>: [
        <span class="hljs-keyword">new</span> UglifyJsPlugin({
            <span class="hljs-attr">cache</span>: <span class="hljs-literal">true</span>,
            <span class="hljs-attr">parallel</span>: <span class="hljs-literal">true</span>
        }),

         <span class="hljs-keyword">new</span> OptimizeCSSAssetsPlugin({
             <span class="hljs-attr">cssProcessor</span>: cssnano,
             <span class="hljs-attr">cssProcessorOptions</span>: {
                 <span class="hljs-attr">discardComments</span>: {
                     <span class="hljs-attr">removeAll</span>: <span class="hljs-literal">true</span>
                 }
             },
             <span class="hljs-attr">canPrint</span>: <span class="hljs-literal">false</span>
         })
    ]
}
</code></pre>
<ul>
<li>As in development mode, we want to skip the emitting phase whenever there are errors while compiling. This ensures that no erroring assets are emitted.</li>
<li><code>chunks: ‘all’</code> indicates which chunks will be selected for optimization. Providing <code>all</code> can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks.</li>
<li>Imported modules are initialized for each runtime chunk separately. As <a target="_blank" href="https://webpack.js.org/configuration/optimization/#optimization-runtimechunk">webpack</a> suggests, while working on a project with <strong>multiple entry points</strong> you want to have only one runtime instance. For that you need to set it to <code>‘single’</code>.</li>
<li><code>UglifyJsPlugin</code> uses <a target="_blank" href="https://github.com/mishoo/UglifyJS2">uglify-js</a> to minify your JavaScript files. We set <code>cache</code> and <code>parallel</code> properties to <code>true</code> in order to enable file caching and to use multi-process parallel running to improve the build speed. There are more options available and I invite you to learn more about <a target="_blank" href="https://webpack.js.org/plugins/uglifyjs-webpack-plugin/">this plugin</a>.</li>
<li><code>OptimizeCSSAssetsPlugin</code> will search for CSS assets during the webpack build and will optimize and minimize it. The CSS processor used for optimization is <code>cssnano.</code> All comments will be removed from our minified CSS and no messages will be print to the console.</li>
</ul>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>: {
    <span class="hljs-attr">rules</span>: [
        {
            <span class="hljs-attr">test</span>: <span class="hljs-regexp">/(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/</span>,
            loader: <span class="hljs-string">'@ngtools/webpack'</span>
        }
    ]
}

<span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> ngw.AngularCompilerPlugin({
        <span class="hljs-attr">tsConfigPath</span>: helpers.root(<span class="hljs-string">'tsconfig.aot.json'</span>),
        <span class="hljs-attr">entryModule</span>: helpers.root(<span class="hljs-string">'src'</span>, <span class="hljs-string">'app'</span>, <span class="hljs-string">'modules'</span>, <span class="hljs-string">'app'</span>, <span class="hljs-string">'app.module#AppModule'</span>)
    })
]
</code></pre>
<p><code>@ngtools/webpack</code> is the official plugin that AoT compiles your Angular components and modules. The loader works with webpack plugin to compile your TypeScript. It’s important to include both, and to not include any other TypeScript compiler loader.</p>
<h4 id="heading-adding-mainaotts-file">Adding main.aot.ts file</h4>
<p>In the <code>src</code> folder add <code>main.aot.ts</code> file:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { enableProdMode } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { platformBrowser } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/platform-browser'</span>;

<span class="hljs-keyword">import</span> { AppModuleNgFactory } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app/app.module.ngfactory'</span>;

enableProdMode();

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
</code></pre>
<p>Your <code>main</code> entry is a bit different in production mode and AoT compilation:</p>
<ul>
<li>Import <code>enableProdMode</code> to disable Angular’s development mode, which turns off assertions and other checks within the framework.</li>
<li>Import <code>platformBrowser</code> <strong>AND NOT</strong> <code>platformBrowserDynamic</code> because in AoT compilation your application is shipped to the browser already compiled whereas in JiT compilation it occurs at the browser level.</li>
<li>Instead of importing <code>AppModule</code> you need to import <code>AppModuleFactory</code> which is your compiled application generated by our Angular compiler.</li>
</ul>
<h4 id="heading-adding-scripts-1">Adding scripts</h4>
<p>Add the following scripts to your <code>package.json</code> file :</p>
<pre><code class="lang-json"><span class="hljs-string">"webpack-prod"</span>: <span class="hljs-string">"cross-env NODE_ENV=production webpack --mode production"</span>

<span class="hljs-string">"build:prod"</span>: <span class="hljs-string">"npm run build:clean &amp;&amp; ngc &amp;&amp; npm run webpack-prod &amp;&amp; npm run build:clean"</span>

<span class="hljs-string">"build:clean"</span>: <span class="hljs-string">"del-cli 'src/**/*.js' 'src/**/*.js.map' 'src/**/*.ngsummary.json' 'src/**/*.metadata.json' 'src/**/**/*.ngfactory.ts' 'src/**/*.ngstyle.ts' 'src/**/*.shim.ts'"</span>

<span class="hljs-string">"serve"</span>: <span class="hljs-string">"lite-server"</span>
</code></pre>
<ul>
<li><code>build:clean</code>: the Angular compiler generates many files in order to compile your application. To stay clean in our project, we delete all these files before compilation and after generating bundles.</li>
<li><code>build:prod</code>: run the Angular compiler with <code>ngc</code> command and then run webpack in production mode to generate your bundles.</li>
<li><code>serve</code>: I use lite-server to serve our application and see what it looks like. Of course, you won’t need it in a real world project because your app will be serve by the cloud.</li>
</ul>
<p>Now, you can run <code>npm run build:prod</code> to compile your Angular application and build your bundles. Then, run <code>npm run serve</code> to serve your app to the browser.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/39EEGVKAPyVpEV4COWHMG5OkhLsj0s8b-ljg" alt="Image" width="800" height="449" loading="lazy">
<em>Hugh Jackman enjoying the article</em></p>
<p>I hope you enjoyed this article! If you have any questions/suggestions, let me know in the comments below.</p>
<p>The project files are on my GitHub:</p>
<p><a target="_blank" href="https://github.com/samteb/Angular-7-Webpack-4"><strong>samteb/Angular-7-Webpack-4</strong></a><br><a target="_blank" href="https://github.com/samteb/Angular-7-Webpack-4">_Contribute to samteb/Angular-7-Webpack-4 development by creating an account on GitHub._github.co</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ An intro to Webpack: what it is and how to use it ]]>
                </title>
                <description>
                    <![CDATA[ By Ashish Nandan Singh Introduction Okay, so I assume you have heard of webpack — that’s why you are here, right? The real question is what do you know about it? You might know a few things about it, like how it works, or you might have absolutely no... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/an-intro-to-webpack-what-it-is-and-how-to-use-it-8304ecdc3c60/</link>
                <guid isPermaLink="false">66c3440bf9d371e3aae2681a</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 15 Jan 2019 17:37:32 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*6ItHoU8x6M-m7-Pt2UG7cw.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ashish Nandan Singh</p>
<h3 id="heading-introduction">Introduction</h3>
<p>Okay, so I assume you have heard of webpack — that’s why you are here, right? The real question is what do you know about it? You might know a few things about it, like how it works, or you might have absolutely no clue. Either way, I can assure you that after reading this article, you’ll likely feel comfortable enough with the whole <strong>webpack situation</strong>.</p>
<p>After all — <strong>necessity</strong> is the mother of <strong>invention…</strong></p>
<p>A perfect way to say why webpack exists is the above quote. But to understand it better we need to go back, way back, to when JavaScript was not the new sexy thing, in those old timey ages when a website was just a small bundle of good old _._html, CSS, and probably one or a few JavaScript files in some cases. But very soon all of this was going to change.</p>
<h4 id="heading-what-was-the-problem">What was the problem?</h4>
<p>The entire dev community was involved in a constant quest of improving the overall user and developer experience around using and building javascript/web applications. Therefore, we saw a lot of new <strong>libraries and frameworks</strong> introduced.</p>
<p>A few <strong>design patterns</strong> also evolved over time to give developers a better, more powerful yet very simple way of writing complex JavaScript applications. Websites before were no more just a small package with an odd number of files in them. They stated getting bulky, with the introduction of <strong>JavaScript modules</strong>, as writing encapsulated small chunks of code was the new trend. Eventually all of this lead to a situation where we had 4x or 5x he of files in the overall application package.</p>
<p><strong>Not only was the overall size of the application a challenge,</strong> but also there was a huge gap in the kind of code developers were writing and the kind of code browsers could understand. Developers had to use a lot of helper code called <strong>polyfills</strong> to make sure that the browsers were able to interpret the code in their packages.</p>
<p>To answer these issues, webpack was created. <strong>Webpack is a static module bundler.</strong></p>
<h4 id="heading-so-how-was-webpack-the-answer">So how was Webpack the answer?</h4>
<p>In brief, Webpack goes through your package and creates what it calls a <strong>dependency graph</strong> which consists of various <strong>modules</strong> which your webapp would require to function as expected. Then, depending on this graph, it creates a new package which consists of the very bare minimum number of files required, often just a single bundle.js file which can be plugged in to the html file easily and used for the application.</p>
<p>Over the next part part of this article I will take you through the step by step setup of webpack. By the end of it, I hope you understand the basics of Webpack. So lets get this rolling…</p>
<h3 id="heading-what-are-we-building">What are we building ?</h3>
<p>You have probably heard of <strong>ReactJS.</strong> If you know reactJS, you likely know what <strong>create-react-app</strong> is. For those of you who have no idea what either of those two things are, <strong>ReactJS is a UI library</strong> which is very helpful in building intelligent complex UIs, and <strong>create-react-app is a CLI tool</strong> for setting up or bootstrapping a boilerplate dev setup to make React applications.</p>
<p>Today we will be creating a simple React application but without using the create-react-app CLI. I hope this sounds fun enough to you. :)</p>
<h3 id="heading-installation-phase">Installation Phase</h3>
<h4 id="heading-npm-int">npm int</h4>
<p>Thats right, thats how almost all good things start: plain old npm init. I will be using VS Code, but feel free to use any code editor you like to get things started.</p>
<p>Before you can do any of this, thought, make sure you have the latest <a target="_blank" href="https://nodejs.org/en/download/">nodeJS</a> and the <a target="_blank" href="https://www.npmjs.com/get-npm">npm</a> version installed locally on your machine. Click on each of those links to know more about the process.</p>
<pre><code>$ npm init
</code></pre><p>This will create a starter package and add a package.json file for us. This is where all the dependencies required to build this application will be mentioned.</p>
<p>Now for creating a simple React application, we need two main libraries: React and ReactDOM. So let’s get them added as dependencies into our application using npm.</p>
<pre><code>$ npm i react react-dom --save
</code></pre><p>Next up we need to add webpack, so we can bundle our app together. Not only bundle, but we will also require hot reloading which is possible using the webpack dev server.</p>
<pre><code>$ npm i webpack webpack-dev-server webpack-cli --save--dev
</code></pre><p>The <code>--save--dev</code> is to specify that these modules are just dev dependencies. Now since we are working with React, we must keep in mind that React uses ES6 classes and import statements, something that all the browsers may not be able to understand. To make sure that the code is readable by all browsers, we need a tool like babel to transpile our code to normal readable code for browsers.</p>
<pre><code>$ npm i babel-core babel-loader @babel/preset-react     @babel/preset-env html-webpack-plugin --save-dev
</code></pre><p>Well what can I say, that was the maximum number of installs I promise. In the case of babel, we have loaded the core babel library first, then the loader, and finally 2 plugins or presets to work specifically with React and all the new ES2015 and ES6 onwards code.</p>
<p>Moving on, let’s add some code and let’s get the webpack configuration started.</p>
<p>This is how the package.json file should look after all the installations so far. You might have a different version number depending on when you are following this article.</p>
<h3 id="heading-the-code">The Code</h3>
<p>Let’s start by adding a <strong>webpack.config.js</strong> file in the root of our application structure. Add the following code in your webpack.config file.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">//This property defines where the application starts</span>
  <span class="hljs-attr">entry</span>:<span class="hljs-string">'./src/index.js'</span>,

  <span class="hljs-comment">//This property defines the file path and the file name which will be used for deploying the bundled file</span>
  <span class="hljs-attr">output</span>:{
    <span class="hljs-attr">path</span>: path.join(__dirname, <span class="hljs-string">'/dist'</span>),
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'bundle.js'</span>
  },

  <span class="hljs-comment">//Setup loaders</span>
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>, 
        exclude: <span class="hljs-regexp">/node_modules/</span>,
        use: {
          <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>
        }
      }
    ]
  },

  <span class="hljs-comment">// Setup plugin to use a HTML file for serving bundled js files</span>
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">template</span>: <span class="hljs-string">'./src/index.html'</span>
    })
  ]
}
</code></pre>
<p>Okay so let’s understand the lines above.</p>
<p>First we start by requiring the default path module to access the file location and make changes to the file location.</p>
<p>Next we require the HTMLWebpackPlugin to generate an HTML file to be used for serving bundled JavaScript file/files. Read more about <a target="_blank" href="https://github.com/jantimon/html-webpack-plugin">HTMLWebpackPlugin</a> by clicking the link.</p>
<p>Then we have the export.module object with some properties in them. The first one is the <strong>entry property,</strong> which is used to specify which file webpack should start with to get the internal dependency graph created.</p>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">entry</span>:<span class="hljs-string">'./src/index.js'</span>
}
</code></pre>
<p>Next up is the output property specifying where the bundled file should be generated and what the name of the bundled file would be. This is done by the <strong>output.path</strong> and <strong>output.filename</strong> properties.</p>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">//This property defines the file path and the file name which will be used for deploying the bundled file</span>
  <span class="hljs-attr">output</span>:{
    <span class="hljs-attr">path</span>: path.join(__dirname, <span class="hljs-string">'/dist'</span>),
    <span class="hljs-attr">filename</span>: <span class="hljs-string">'bundle.js'</span>
  },
}
</code></pre>
<p>Next up are the loaders. This is to specify what webpack should do for a specific type for file. Remember that webpack out of box only understands JavaScript and JSON, but if your project has any other language used, this would be the place to specify what to do with that new language.</p>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">//Setup loaders</span>
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>, 
        exclude: <span class="hljs-regexp">/node_modules/</span>,
        use: {
          <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>
        }
      }
    ]
  }
}
</code></pre>
<p>The information should be specified in an object for each module property, which further has an array of rules. There will be an object for every case. I have also specified to exclude everything in my node_modules folder.</p>
<p>Next up is the plugin property. This is used to extend the capabilities of webpack. Before a plugin can be used in the plugin array inside the module exports object, we need to require the same.</p>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// Setup plugin to use a HTML file for serving bundled js files</span>
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">template</span>: <span class="hljs-string">'./src/index.html'</span>
    })
  ]
}
</code></pre>
<p>This particular plugin, as explained earlier, will use the specified file in our src folder. It’ll then use that as a template for our HTML file where all the bundled files will be automatically injected. There are a lot of other out of the box plugins that we could use — checkout the <a target="_blank" href="https://webpack.js.org/plugins/">official page</a> for more information.</p>
<p>The last thing we need to do is create a .babelrc file to use the babel preset we installed and take care of the ES6 classes and import statements in our code. Add the following lines of code to the .babelrc file.</p>
<pre><code>{
  <span class="hljs-string">"presets"</span>: [<span class="hljs-string">"env"</span>, <span class="hljs-string">"react"</span>]
}
</code></pre><p>And just like that, now babel will be able to use those presets. Okay so enough of the setup — let’s add some React code to see how this works.</p>
<h3 id="heading-react-code">React Code</h3>
<p>Since the starting point for the application is the index.js file in src folder, let’s start with that. We will start by requiring both <strong>React</strong> and <strong>ReactDOM</strong> for our use in this case. Add the below code in your index.js file.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./Components/App'</span>;

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'app'</span>));
</code></pre>
<p>So we simply import another file from our components folder, which you will create, and add another file in the folder called App.js. So let’s see what’s inside the App.js file:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{
  render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Webpack + React setup<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    )
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>We are almost done. The only thing left now is to enable hot reloading. This means that every time a change is detected, the browser auto reloads the page and has the ability to build and bundle the entire application when the time comes.</p>
<p>We can do this by adding script values in the package.json file. Remove the test property in the scripts object of your package.json file and add these two scripts:</p>
<pre><code class="lang-json"><span class="hljs-string">"start"</span>: <span class="hljs-string">"webpack-dev-server --mode development --open --hot"</span>,
<span class="hljs-string">"build"</span>: <span class="hljs-string">"webpack --mode production"</span>
</code></pre>
<p>You are all set! Go to your terminal, navigate to the root folder, and run <strong>npm start.</strong> It should start a dev server on your computer and serve the HTML file in your browser. If you make any minor/major changes and save the code, your browser will be automatically refreshed to show the latest set of changes.</p>
<p>Once you think you are ready to get the app bundled, you just need to hit the command, <strong>npm build,</strong> and webpack will create an optimised bundle in your project folder which can be deployed on any web server.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>This is just a small application or use case of webpack and babel, but the applications are limitless. I hope you are excited enough to explore more options and ways of doing things with webpack and babel. Please refer to their official websites to know more and read in depth.</p>
<p>I have created a Github repo with all the code in it, so please refer to it incase of any questions.</p>
<p><a target="_blank" href="https://github.com/ashishcodes4/webpack-react-setup"><strong>ashishcodes4/webpack-react-setup</strong></a><br><a target="_blank" href="https://github.com/ashishcodes4/webpack-react-setup">_Setting a react application from scratch without using CLI - ashishcodes4/webpack-react-setup_github.com</a></p>
<p>My two cents about webpack? Well, at times you may think that it’s nothing more than a tool, and why should you bother too much for a tool? But trust me when I say this: the initial struggle while learning your way around webpack will save you an enormous number of hours you would otherwise invest developing without webpack.</p>
<p>That’s all for now, hope to be back with yet another interesting article very soon. I hope you have enjoyed reading this one!</p>
<p>In case you face any difficulty or issues while following any of the above mentioned steps/processes, please feel free to get in touch and leave comments.</p>
<p>LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/ashish-nandan-singh-490987130/">https://www.linkedin.com/in/ashish-nandan-singh-490987130/</a></p>
<p>Twitter: <a target="_blank" href="https://twitter.com/ashishnandansin">https://twitter.com/ashishnandansin</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to build modern applications with WEBPACK ]]>
                </title>
                <description>
                    <![CDATA[ By Samuel Omole How far can we get with Webpack’s default configuration? I had the privilege of speaking at GDG Devfest last month with a talk that was centered around using webpack in our modern day applications. You can check out the slides here. D... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-modern-applications-with-webpack-c81ccf6dd54f/</link>
                <guid isPermaLink="false">66d460f63a8352b6c5a2ab0d</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 09 Jan 2019 19:01:17 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9ca69a740569d1a4ca716e.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Samuel Omole</p>
<p>How far can we get with Webpack’s default configuration?</p>
<p>I had the privilege of speaking at GDG Devfest last month with a talk that was centered around using webpack in our modern day applications. You can check out the slides <a target="_blank" href="https://docs.google.com/presentation/d/1LcQYBh0VyM0iE_LuJS11wjJQeT45cApde9SdJQg9mVw/edit?usp=sharing">here</a>.</p>
<p>Daily, I get to work as an Engineer and/or consultant with amazing and fast-paced teams, and webpack seems like the recurring factor throughout these teams (we use ReactJs for most of our applications). Initially, my talk was supposed to focus on using webpack with frontend frameworks/libraries like ReactJS, Vue, Angular etc.</p>
<p>Before submitting my proposal, I decided to run a mini survey to know what people thought about webpack. To my surprise, a lot of people labeled webpack as “Only used with frameworks” which was far from the truth. Still others said that “setting up webpack was daunting”. This led me to focus more on using webpack with Vanilla JS and seeing how far we could go with webpack’s default configuration.</p>
<p>But first:</p>
<h3 id="heading-what-is-webpack">WHAT IS WEBPACK?</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/M4slVGkwKmV0e8F2ODUCR-twvwi6foMoM0cD" alt="Image" width="800" height="438" loading="lazy"></p>
<blockquote>
<p><em>I personally define webpack as a tool that takes many Javascript modules and merges them into one Javascript module that can be sent off to the browser.</em></p>
</blockquote>
<p>I know, it’s an oversimplification of what webpack does, but people seem to understand it. To explain more, webpack is a bundler that looks for Javascript modules with dependencies (basically, Javascript files that need code from other Javascript files), squashes them together, and then produces a Javascript file or files that have no dependencies. That way they can easily be shipped to the browser.</p>
<h3 id="heading-history-of-webpack">History of Webpack</h3>
<p>To understand the problems that webpack tries to solve, we need to know a little bit about the history of webpack itself. To keep this section very short, I’ve just outlined two important tools and one concept:</p>
<ul>
<li><a target="_blank" href="http://www.gwtproject.org/">Google Web Toolkit</a>: This is a framework from Google that converts Java to Javascript (I know, right?). It has one feature that seems to be my personal favorite feature in webpack which is “code splitting”. (I will explain code splitting in a subsequent article.)</li>
<li><a target="_blank" href="https://github.com/medikoo/modules-webmake">Modules_Webmake</a>: This is the library that webpack originates from. It’s essentially a tool that allows us to organize our Javascript files for the browser the same way we do for NodeJS (awesome).</li>
<li>IIFE: means immediately invoked function expression. This is basically a Javascript function that is called or invoked the same time as it was created.</li>
</ul>
<h4 id="heading-immediately-invoked-function-expression">Immediately Invoked Function Expression</h4>
<p>I broke this into its own section because I had to explain further. This is an example of an IIFE:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/xwE0cAzV6-TF1c8Fc3Iqpdky6-LVVxKe7zyl" alt="Image" width="800" height="412" loading="lazy"></p>
<p>If we were to place this function in our script tag, this would run immediately. The script tag is loaded by the browser. It’s kind of equivalent to attaching a function to <code>window.onload</code> but with an added advantage.</p>
<p>Because of the way closures work in Javascript, all the variables that were declared in the IIFE are scoped within that function. This means I wouldn’t have issues like namespace clashes in my codebase but at the same time, I still have access to the functions exposed by the IIFE.</p>
<h3 id="heading-why-webpack">Why Webpack?</h3>
<p>So, what are the problems we face today that webpack helps us solve?</p>
<p>First, we have the issue of script tags. I have worked on a codebase where each HTML page has at the very least 30 script tags arranged in a very precise order. I know some might say that isn’t really an issue, but the browser will have to make one request per file which can hurt your “time to load”. Also the script tags can get hard to manage, where rearranging just one could break the application (I tried that ?).</p>
<p>Second, we still have the issue of namespacing where the global namespace can get cluttered. I know we are very creative people especially when it comes to naming variables, but then when you work on a larger team there are times where the variable names just clash with each other. Or even your future self might think of the same name again (yeah it happens).</p>
<p>I know some organizations that make it habit for their developers to always keep their variables within the scope of their function, but we can’t always rely on that (or on <code>_this_</code><em>).</em> In the end, it just makes separation of concern difficult.</p>
<p>Third, remember I mentioned that webpack originated from modules_webmake. Because webpack allows us to organize our files the same way we do in NodeJS (using CommonJS), we have the added benefit of writing modular code which scales really well (just ask people that use frontend frameworks).</p>
<h3 id="heading-commonjs">CommonJS</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/KjF9FAXBSSZNuiHgzhmjAReSYI1zlggAOPqO" alt="Image" width="800" height="272" loading="lazy"></p>
<p>I won’t explain too much about CJS as this isn’t the point of the article. But you can say it’s a JS module system used in <a target="_blank" href="https://nodejs.org/en/">NodeJS</a>.</p>
<p>Webpack allows us to use this module and even the “better” ES module system in the browser without any issue (Webpack handles it in a smart way). This helps us write really modular and maintainable code where a JS file can handle a single functionality (Single Responsibility Principle).</p>
<h3 id="heading-es-modules-esm">ES Modules (ESM)</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/e48UD39h8gVqn49uUSrf1BkZ9dx6VkT86BAT" alt="Image" width="800" height="262" loading="lazy"></p>
<p>This is another module system that, believe it or not, is already implemented by current browsers. But unfortunately, it has it’s limitations there. Webpack also allows us to use this module with no issue (as webpack still converts it in the end), but I found that using ESM makes most codebases I have worked on more readable. I would have loved to dive deeper into this but that isn’t the aim of this article. For a better explanation I would recommend this amazing <a target="_blank" href="https://medium.com/webpack/the-state-of-javascript-modules-4636d1774358">article</a>.</p>
<h3 id="heading-how-does-webpack-work">How does Webpack work?</h3>
<p>I know I said earlier that Webpack is magic but I lied. To put it as simply as possible:</p>
<ul>
<li>Webpack takes a path to a single entry point, which is a JS file, and looks for import statements (it could either be ESM or CJS).</li>
<li>It then traverses the imported file, also looking for more import statements, while it creates a dependency graph in the process.</li>
</ul>
<p>To explain better, take a look at the image:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1RXjLCpnyfAVTfB1JRwvK6jNyZlBI1NgiK3e" alt="Image" width="800" height="444" loading="lazy">
<em>J.K.</em></p>
<p>I have two files there, <code>index.js</code> and <code>helpers.js</code> These two files perform different functions, but I am importing and using the function in helpers.js in my index.js file. By default, Webpack’s entry point is <code>./src/index.js</code> and from there it tries to build the dependency graph as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/slsswDXppG0L7O5s5tEtG5oRnQGa8rx6-Tzx" alt="Image" width="800" height="405" loading="lazy"></p>
<h3 id="heading-how-to-get-started">How to get started</h3>
<p>To get a better understanding of how webpack works, we are going to build a simple TODO app. It will have just the basic add and delete functionality and we are going to bundle it using Webpack’s default configuration (so no webpack config file). This is what the app will look like:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/XHRBMREv6mSxjWYIYhmKsBIEASYIJvxUfdd-" alt="Image" width="539" height="500" loading="lazy">
<em>J.K.</em></p>
<p>The first step is to create a new project directory and create two folders, a folder named <code>dist</code> and another named <code>src</code> . By default, Webpack’s entry point is the path <code>./src/index.js</code> and it outputs the bundled JS into <code>./dist/main.js</code> — that’s why we are creating the two folders.</p>
<p>In the <code>dist</code> folder you can create the <code>index.html</code> file. This is not necessary for webpack as the file can be placed anywhere within the project directory and you can just make reference to the <code>main.js</code> file. In the end, your project structure should look like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/qz9bu3IEW6cV2awAF8GZ3qkwQ7VBch1hfRfa" alt="Image" width="233" height="201" loading="lazy"></p>
<p>In the <code>src</code> folder we will create the <code>index.html</code> file where we will start the implementation of our TO-DO app’s functionalities. But first, let’s populate the <code>index.html</code> file. Since creating a TO-DO app isn’t part of this tutorial I will just show the code below:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Todo App<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"new-task"</span>&gt;</span>Add Item<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"new-task"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"addTask"</span>&gt;</span>Add<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Todo<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tasks"</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"main.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Let us now make it functional. We are going to break the two functions (Add and Delete) into their own files and then import them into <code>index.js</code> . We will create two files in our <code>src</code> folder named <code>addTask.js</code> and <code>deleteTask.js</code> . Your project structure should now look like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/bYBUgOjdT0BdNHZXrV1e2vB2odF9KHI4ROpd" alt="Image" width="323" height="369" loading="lazy"></p>
<p>We can now start adding the necessary logic, so let’s implement the <code>deleteTask.js</code> first because it has no dependencies. Paste this in your <code>deleteTask.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> deleteTask = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Delete Task..."</span>, e);
  <span class="hljs-comment">//Remove the parent list item from the ul</span>
  <span class="hljs-keyword">var</span> listItem = e.target.parentNode;
  <span class="hljs-keyword">var</span> ul = listItem.parentNode;
  ul.removeChild(listItem);
};


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> deleteTask;
</code></pre>
<p>All that is going on in that file is we are creating the <code>deleteTask</code> function and then exporting it as a default export.</p>
<p>We can now implement the <code>addTask</code> function. In the <code>addTask.js</code> file add the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> deleteTask <span class="hljs-keyword">from</span> <span class="hljs-string">"./deleteTask"</span>;


<span class="hljs-keyword">const</span> createNewTaskElement = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">taskString</span>) </span>{

  <span class="hljs-keyword">const</span> listItem = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"li"</span>);
  <span class="hljs-keyword">const</span> label = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"label"</span>);
  <span class="hljs-keyword">const</span> deleteButton = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"button"</span>);
deleteButton.innerText = <span class="hljs-string">"Delete"</span>;
  deleteButton.className = <span class="hljs-string">"delete"</span>;
  deleteButton.addEventListener(<span class="hljs-string">"click"</span>, deleteTask);

    label.innerText = taskString;
    listItem.appendChild(label);
      listItem.appendChild(deleteButton);
    <span class="hljs-keyword">return</span> listItem;
};


<span class="hljs-keyword">const</span> addTask = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
  <span class="hljs-keyword">const</span> taskList = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"tasks"</span>);
  <span class="hljs-keyword">const</span> task = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"new-task"</span>);
  <span class="hljs-keyword">if</span> (task.value !== <span class="hljs-string">""</span>) {
    <span class="hljs-keyword">const</span> newTaskItem = createNewTaskElement(task.value);
    taskList.appendChild(newTaskItem);
    task.value = <span class="hljs-string">""</span>;
  }
};


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> addTask;
</code></pre>
<p>In this one, we first of all import the <code>deleteTask.js</code> file. By default, if no extension is specified in the import, webpack automatically assumes that it’s a <code>.js</code> file. Then we have the function that creates the list item containing the task that was entered in the form. The only thing to note is that we are attaching the delete function to the click handler of the delete button. Then we create the actual addTask function and export it.</p>
<p>We will then need to import our <code>addTask</code> function into <code>index.js</code> . Paste the code below into your <code>index.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> addTask <span class="hljs-keyword">from</span> <span class="hljs-string">'./addTask'</span>;

<span class="hljs-keyword">const</span> addTaskButton = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"addTask"</span>);

addTaskButton.addEventListener(<span class="hljs-string">"click"</span>, addTask);
</code></pre>
<p>This is pretty straightforward: we are importing the <code>addTask</code> function and attaching it to the click handler for the <code>addTaskButton</code> . If you followed the steps above you should be good to go.</p>
<p>Finally, to get our <code>main.js</code> file we need to run Webpack through our codebase. For this step, make sure you have <a target="_blank" href="https://nodejs.org/en/">NodeJS</a> installed on your system, then we will install webpack globally using this command:</p>
<pre><code>npm install -g webpack OR sudo npm install -g webpack
</code></pre><p>Once it’s done installing run the following command:</p>
<pre><code>webpack
</code></pre><p>It will bundle up our file successfully but we should see a warning in the terminal like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/zDIK8WvPOHW1207f33J-wEZ-hY7IHDIlif1W" alt="Image" width="800" height="227" loading="lazy"></p>
<p>Webpack is just warning us that we didn’t specify a <a target="_blank" href="https://webpack.js.org/concepts/#mode">mode</a>. We could leave it as is and run the code, everything should work fine. But if you don’t like the warning then you can run Webpack like this:</p>
<pre><code>webpack --mode=development
</code></pre><p>And you’re good to go.</p>
<h3 id="heading-wrapping-up">Wrapping up</h3>
<p>If you got lost along the way you can always use the GitHub <a target="_blank" href="https://github.com/samie820/todo">repo</a> for reference (It has some CSS styling in it, though).</p>
<p>I hope this article was able to show you what Webpack has to offer (just the basics, with no configuration whatsoever). In subsequent articles, I will try to show how to set up various custom configurations for features like <a target="_blank" href="https://webpack.js.org/guides/code-splitting/">code splitting</a>, <a target="_blank" href="https://webpack.js.org/guides/lazy-loading/">lazy loading</a> and configuring Webpack to work with multi-page applications.</p>
<p>In order to keep this article as basic as possible, I avoided the use of a <code>package.json</code> file in the article. The use of a <code>package.json</code> file and installing webpack locally is the most scalable way of using webpack and I will go into it in my next article on using Webpack.</p>
<p>To help navigate the coming articles, it will really help if you can drop a comment of what you would like to see explained or implemented regarding Webpack. ??</p>
<p><em>I will like to especially thank <a target="_blank" href="https://www.freecodecamp.org/news/how-to-build-modern-applications-with-webpack-c81ccf6dd54f/undefined">Sean T. Larkin</a>, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-build-modern-applications-with-webpack-c81ccf6dd54f/undefined">Israel Obiagba</a> and <a target="_blank" href="https://www.freecodecamp.org/news/how-to-build-modern-applications-with-webpack-c81ccf6dd54f/undefined">Hassan Sani</a> for their feedback in making the article better than initially planned. You all rock!</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to create a Vue.js app using Single-File Components, without the CLI. ]]>
                </title>
                <description>
                    <![CDATA[ An understanding of Vue’s single-file components (SFCs) and Node Package Manager (NPM) will be helpful for this article. A framework’s command line interface, or CLI, is the preferred method to scaffo ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-vue-js-app-using-single-file-components-without-the-cli-7e73e5b8244f/</link>
                <guid isPermaLink="false">66d46177d1ffc3d3eb89de7e</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[  Single Page Applications  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Vue.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Tue, 04 Dec 2018 20:48:42 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*L2343t5yIriMN69KY6jWEw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><em>An understanding of Vue’s single-file components (SFCs) and Node Package Manager (NPM) will be helpful for this article.</em></p>
<p>A framework’s command line interface, or CLI, is the preferred method to scaffold a project. It provides a starting point of files, folders, and configuration. This scaffolding also provides a development and build process. A development process provides a way to see updates occurring as you edit your project. The build process creates the final version of files to be used in production.</p>
<p>Installing and running Vue.js (“Vue”) can be done with a script tag that points to the Vue content delivery network (CDN). No build or development process is necessary. But, if you use Vue single-file components (SFCs), you need to convert those files into something the browser can understand. The files need to be converted to Hyper-Text Markup Language (HTML), Cascading Style Sheets (CSS), and JavaScript (JS). In this case, a development and build process must be used.</p>
<p>Instead of relying on the Vue CLI to scaffold our project and provide us with a development and build process, we will build a project from scratch. We will create our own development and build process using Webpack.</p>
<h4 id="heading-what-is-webpack">What is Webpack?</h4>
<p>Webpack is a module bundler. It merges code from multiple files into one. Before Webpack, the user included a script tag for each JavaScript file. Although browsers are <em>slowly</em> supporting ES6 modules, Webpack continues to be the preferred way to build modular code.</p>
<p>Besides being a module bundler, Webpack can also transform code. For example, Webpack can take modern JavaScript (ECMAScript 6+) and convert it into ECMAScript 5. While Webpack <em>bundles</em> the code itself, it transforms the code with loaders and plugins. Think of loaders and plugins as add-ons for Webpack.</p>
<h4 id="heading-webpack-and-vue">Webpack and Vue</h4>
<p>Single-file components allow us to build an entire component (structure, style, and function) in one file. And, most code editors provide syntax highlighting and linting for these SFCs.</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*anBAz9QzClNtmAxp4ujdGA.png" alt="Image" width="800" height="879" loading="lazy">

<p>_[Vue Single File Component](<a href="https://vuejs.org/v2/guide/single-file-components.html">https://vuejs.org/v2/guide/single-file-components.html</a>" rel="noopener" target="<em>blank" title="): notice the .vue extension.</em></p>
<p><em>Notice the file ends with .vue. The browser doesn’t know what to do with that extension. Webpack, through the use of loaders and plugins, transforms this file into the HTML, CSS, and JS the browser can consume.</em></p>
<h3 id="heading-the-project-build-a-hello-world-vue-application-using-single-file-components">The Project: Build a Hello World Vue Application Using Single-File Components.</h3>
<h4 id="heading-step-1-create-the-project-structure">Step 1: Create the project structure</h4>
<p>The most basic Vue project will include an HTML, JavaScript, and a Vue file (the file ending in <em>.vue</em>). We will place these files in a <strong>folder called</strong> <code>src</code><strong>.</strong> The source folder will help us separate the code we are writing from the code Webpack will eventually build.</p>
<p>Since we will be using Webpack, we need <strong>a Webpack configuration file.</strong></p>
<p>Additionally, we will use a compiler called Babel. Babel allows us to write ES6 code which it then compiles into ES5. Babel is one of those “add-on features” for Webpack. <strong>Babel also needs a configuration file.</strong></p>
<p>Finally, since we are using NPM, we will also have <strong>a node_modules folder</strong> and <strong>a package.json file.</strong> Those will be created automatically when we initialize our project as an NPM project and begin installing our dependencies.</p>
<p>To get started, create a folder called <code>hello-world</code>. From the command line, change to that directory and run <code>npm init</code>. Follow the on-screen prompts to create the project. Then, create the rest of the folders (except for <code>node_modules</code><em>)</em> as described above. Your project structure should look like this:</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*jLNggGBoQ6A6xnqVyltFEA.png" alt="Image" width="660" height="438" loading="lazy">

<p><em>The simplest Vue SFC project structure.</em></p>
<h4 id="heading-step-2-install-the-dependencies">Step 2: Install the dependencies</h4>
<p>Here is a quick rundown of the dependencies we are using:</p>
<p><strong>vue</strong>: The JavaScript framework</p>
<p><strong>vue-loader and vue-template-compiler</strong>: Used to convert our Vue files into JavaScript.</p>
<p><strong>webpack</strong>: The tool that will allow us to pass our code through some transformations and bundle it into one file.</p>
<p><strong>webpack-cli:</strong> Needed to run the Webpack commands.</p>
<p><strong>webpack-dev-server</strong>: Although not needed for our small project (since we won’t be making any HTTP requests), we will still “serve” our project from a development server.</p>
<p><strong>babel-loader</strong>: Transform our ES6 code into ES5. (It needs help from the next two dependencies.)</p>
<p><strong>@babel/core and @babel/preset-env</strong>: Babel by itself doesn’t do anything to your code. These two “add-ons” will allow us to transform our ES6 code into ES5 code.</p>
<p><strong>css-loader:</strong> Takes the CSS we write in our <code>.vue</code> files or any CSS we might import into any of our JavaScript files and resolve the path to those files. In other words, figure out where the CSS is. This is another loader that by itself won’t do much. We need the next loader to actually do something with the CSS.</p>
<p><strong>vue-style-loader</strong>: Take the CSS we got from our <code>css-loader</code> and inject it into our HTML file. This will create and inject a style tag in the head of our HTML document.</p>
<p><strong>html-webpack-plugin</strong>: Take our <em>index.html</em> and inject our bundled JavaScript file in the head. Then, copy this file into the <code>dist</code> folder.</p>
<p><strong>rimraf</strong>: Allows us, from the command line, to delete files. This will come in handy when we build our project multiple times. We will use this to delete any old builds.</p>
<p>Let’s install these dependencies now. From the command line, run:</p>
<pre><code class="language-bash">npm install vue vue-loader vue-template-compiler webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env css-loader vue-style-loader html-webpack-plugin rimraf -D
</code></pre>
<p><em><strong>Note:</strong></em> <em>The “-D” at the end marks each dependency as a development dependency in our package.json. We are bundling all dependencies in one file, so, for our small project, we have no production dependencies.</em></p>
<h4 id="heading-step-3-create-the-files-except-for-our-webpack-configuration-file">Step 3: Create the files (Except for our Webpack configuration file).</h4>
<pre><code class="language-js">&lt;template&gt;
  &lt;div id="app"&gt;
    {{ message }}
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  data() {
    return {
      message: 'Hello World',
    };
  },
};
&lt;/script&gt;

&lt;style&gt;
#app {
  font-size: 18px;
  font-family: 'Roboto', sans-serif;
  color: blue;
}
&lt;/style&gt;
</code></pre>
<pre><code class="language-html">&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Vue Hello World&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id="app"&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<pre><code class="language-js">import Vue from 'vue';
import App from './App.vue';

new Vue({
  el: '#app',
  render: h =&gt; h(App),
});
</code></pre>
<pre><code class="language-js">module.exports = {
  presets: ['@babel/preset-env'],
}
</code></pre>
<p>Up to this point, nothing should look too foreign. I’ve kept each file very basic. I’ve only added minimal CSS and JS to see our workflow in action.</p>
<h4 id="heading-step-4-instructing-webpack-what-to-do">Step 4: Instructing Webpack what to do</h4>
<p>All the configuration Webpack needs access to is now present. We need to do two final things: Tell Webpack what to do and run Webpack.</p>
<p>Below is the Webpack configuration file (<code>webpack.config.js</code>). Create this file in the projects root directory. Line-by-line we’ll discuss what is occurring.</p>
<pre><code class="language-js">const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
  entry: './src/main.js',
  module: {
    rules: [
      { test: /\.js$/, use: 'babel-loader' },
      { test: /\.vue$/, use: 'vue-loader' },
      { test: /\.css$/, use: ['vue-style-loader', 'css-loader']},
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
    new VueLoaderPlugin(),
  ]
};
</code></pre>
<p><strong>Lines 1 and 2:</strong> We are importing the two plugins we use below. Notice, our loaders don’t normally need to be imported, just our plugins. And in our case, the <code>vue-loader</code> (which we use in line 9) also needs a plugin to work (however, Babel, for example, does not).</p>
<p><strong>Line 4:</strong> We export our configuration as an object. This gives us access to it when we run the Webpack commands.</p>
<p><strong>Line 5:</strong> This is our entry module. Webpack needs a place to start. It looks in our <code>main.js</code> file and then starts to comb through our code from that point.</p>
<p><strong>Line 6 and 7:</strong> This is the module object. Here, we primarily pass in an array of rules. Each rule tells Webpack how to handle certain files. So, while Webpack uses the entry point of <code>main.js</code> to start combing through our code, it uses the rules to transform our code.</p>
<p><strong>Line 8 (rule):</strong> This rule instructs Webpack to use the <code>babel-loader</code> on any files which end with <code>.js</code><em>.</em> Remember, Babel will transform ES6+ to ES5.</p>
<p><strong>Line 9 (rule):</strong> This rule instructs Webpack to use <code>vue-loader</code> (and don’t forget the associated plugin on line 17) to transform our <code>.vue</code> files into JavaScript.</p>
<p><strong>Line 10 (rule):</strong> Sometimes we want to pass a file through two loaders. Counterintuitively, Webpack will pass the file from right to left instead of left to right. Here we are using two loaders and saying to Webpack: “get my CSS from my Vue file or any JavaScript files(<code>css-loader</code>) and inject it into my HTML as a style tag (<code>vue-style-loader</code>).</p>
<p><strong>Lines 11 and 12:</strong> Close out our rules array and module object.</p>
<p><strong>Lines 13:</strong> Create a plugins array. Here we will add the two plugins we need.</p>
<p><strong>Line: 14 -16 (plugin):</strong> The <code>HtmlWebpackPlugin</code> takes the location of our <em>index.html</em> file and adds our bundled JavaScript file to it via a script tag. This plugin will also copy the HTML file to our distribution folder when we build our project.</p>
<p><strong>Line 17 (plugin):</strong> The <code>VueLoaderPlugin</code> works with our <code>vue-loader</code> to parse our <code>.vue</code> files.</p>
<p><strong>Line 18:</strong> Close out the plugins array.</p>
<p><strong>Line 19:</strong> Close out the Webpack object that we are exporting.</p>
<h4 id="heading-step-5-setting-up-our-packagejson-file-so-we-can-run-webpack">Step 5: Setting up our package.json file so we can run Webpack</h4>
<p>Our configuration is complete, now we want to see our application. Ideally, as we make changes to our application, the browser would update automatically. This is possible with <code>webpack-dev-server</code>.</p>
<p>Delete the <code>test</code> script in our <code>package.json</code> file, and replace it with a script to serve our application:</p>
<pre><code class="language-json">
{
  "name": "hello-world",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "serve": "webpack-dev-server --mode development"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.1.6",
    "@babel/preset-env": "^7.1.6",
    "babel-loader": "^8.0.4",
    "css-loader": "^1.0.1",
    "html-webpack-plugin": "^3.2.0",
    "rimraf": "^2.6.2",
    "vue": "^2.5.17",
    "vue-loader": "^15.4.2",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.26.0",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  },
  "dependencies": {}
}
</code></pre>
<p>The name of this command is your choice. I chose to call mine <code>serve</code> since we will be <em>serving</em> our application.</p>
<p>From our terminal or command line, we can run <code>npm run serve</code> and that in turn will run <code>webpack-dev-server --mode development</code> .</p>
<p><em>The</em> <code>--mode development</code> is what’s called a flag or option. We haven’t talked about this, but it essentially instructs Webpack that you are in development mode. We can also pass in <code>--mode production</code> which we will do when we build our project. These aren’t necessarily required for Webpack to work. Without these, you will get a warning message telling you to provide a mode when you run Webpack .</p>
<p><em>I say “necessarily required” because Webpack will minimize our code in production mode but not in development. So, don’t think those commands don’t do anything–they do.</em></p>
<p>Let’s run <code>npm run serve</code> and see what happens.</p>
<p>When we run <code>npm run serve</code> we get some output in our terminal. And, if everything goes well:</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*UNoqxigEpgvVZRjs2VqxTA.png" alt="Image" width="493" height="85" loading="lazy">

<p>And if we scroll up a bit:</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*ye4_gCeGPXcwgPcGUQf_rg.png" alt="Image" width="800" height="112" loading="lazy">

<p>Point your browser to <code>http://localhost:8080</code>. You will see your Blue Hello World message in Roboto font.</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*kKYxmKJ_rTBzT7rOvjZtgg.png" alt="Image" width="800" height="129" loading="lazy">

<p>Now, let’s update the project and change the message to <code>Hello Universe</code>. Notice that the webpage refreshes automatically. That’s great, right? Can you think of a downside?</p>
<p>Let’s change the application just a bit and include an input which we will bind a variable to (with <code>v-model</code>). We will output the variable in an <code>&lt;h2&gt;</code>tag below the input. I’ve also updated the styling section to style the message now. Our <code>App.vue</code> file should look like this:</p>
<pre><code class="language-js">&lt;template&gt;
  &lt;div id="app"&gt;
    &lt;input
      v-model="message"
      type="text"&gt;
      &lt;h2 class="message"&gt;{{ message }}&lt;/h2&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  data() {
    return {
      message: 'Hello world!',
    };
  },
};
&lt;/script&gt;

&lt;style&gt;
.message {
  font-size: 18px;
  font-family: 'Roboto', sans-serif;
  color: blue;
}
&lt;/style&gt;
</code></pre>
<p>When we serve our application, we will have an input with a message of <code>Hello World</code> below it. The input is bound to the <code>message</code> variable, so as we type, we change the <code>&lt;h2&gt;</code> content. Go ahead, type into the input to change the <code>&lt;h2&gt;</code>content.</p>
<p>Now go back to your editor, and below the <code>&lt;h2&gt;</code>tag, add the following:</p>
<p><code>&lt;h3&gt;Some Other Message&lt;/h3&gt;</code></p>
<p>Save your <code>App.vue</code> and watch what happens.</p>
<p>The <code>h2</code> we just updated by typing in our input reverted back to <code>Hello World</code>. This is because the browser actually refreshes, and the script tag and page are loaded again. In other words, we were not able to maintain the state of our application. This may not seem like a big deal, but as you are testing your application and adding data to it, it will be frustrating if your app “resets” every time. Fortunately, Webpack offers us a solution called Hot Module Replacement.</p>
<p>The hot module replacement is a plugin provided by Webpack itself. Up until this point, we have not used the Webpack object itself in our configuration file. However, we will now import Webpack so we can access the plugin.</p>
<p>In addition to the plugin, we will pass one additional option to Webpack, the <code>devServer</code> option. In that option, we will set <code>hot</code> to <code>true</code>. Also, we will make an (optional) update to our build workflow: We will open the browser window automatically when we run <code>npm run serve</code>. We do this by setting <code>open</code> to <code>true</code> which is also inside the <code>devServer</code> option.</p>
<pre><code class="language-js">const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack');

module.exports = {
  entry: './src/main.js',
  module: {
    rules: [
      { test: /\.js$/, use: 'babel-loader' },
      { test: /\.vue$/, use: 'vue-loader' },
      { test: /\.css$/, use: ['vue-style-loader', 'css-loader']},
    ]
  },
  devServer: {
    open: true,
    hot: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
    new VueLoaderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  ]
};
</code></pre>
<p>Notice that we’ve imported Webpack so we could access the <code>hotModuleReplacementPlugin</code>. We’ve added that to the <code>plugins</code> array, and then told Webpack to use it with <code>hot: true</code>. We open the browser window automatically when we serve the application with <code>open: true</code>.</p>
<p>Run <code>npm run serve</code>:</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*59LVTDT3pEk3RzQ7dodmvw.png" alt="Image" width="800" height="161" loading="lazy">

<p>The browser window should open, and if you open your dev tools, you should notice a slight change in the output. It now tells us hot module replacement is enabled. Let’s type in our input to change the <code>&lt;h2&gt;</code> content. Then, change the<code>h3</code> tag to read: <code>One More Message</code>.</p>
<p>Save your file and notice what happens.</p>
<p>The browser doesn't refresh, but our <code>&lt;h3&gt;</code>change is reflected! The message we typed in the input remains, but the <code>h3</code> updates. This allows our application to keep it’s state while we edit it.</p>
<h4 id="heading-step-7-building-our-project">Step 7: Building our project</h4>
<p>So far, we’ve served our application. But, what if we want to build our application so we can distribute it?</p>
<p>If you noticed, when we serve our application, no files are created. Webpack creates a version of these files that only exist in temporary memory. If we want to distribute our Hello World app to our client, we need to <em>build</em> the project.</p>
<p>This is very simple. Just like before, we will create a script in our package.json file to tell Webpack to build our project. We will use <code>webpack</code> as the command instead of <code>webpack-dev-server</code>. We will pass in the <code>--mode production</code> flag as well.</p>
<p>We will also use the <code>rimraf</code> package first to delete any previous builds we may have. We do this simply by <code>rimraf dist</code>.</p>
<p><code>_dist_</code> <em>is the folder Webpack will automatically create when it builds our project. “Dist” is short for distribution–i.e. we are “distributing” our applications code.</em></p>
<p>The <code>rimraf dist</code> command is telling the <code>rimraf</code> package to delete the <code>dist</code> directory. <strong>Make sure you don’t</strong> <code>rimraf src</code> <strong>by accident!</strong></p>
<p><em>Webpack also offers a plugin that will accomplish this cleaning process called</em> <code>clean-webpack-plugin</code>. I chose <code>dist</code> show an alternative way.</p>
<p>Our package.json file should look like this:</p>
<pre><code class="language-json">{
  "name": "hello-world",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "clean": "rimraf dist",
    "build": "npm run clean &amp;&amp; webpack --mode production",
    "serve": "webpack-dev-server --mode development"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.1.6",
    "@babel/preset-env": "^7.1.6",
    "babel-loader": "^8.0.4",
    "css-loader": "^1.0.1",
    "html-webpack-plugin": "^3.2.0",
    "rimraf": "^2.6.2",
    "vue": "^2.5.17",
    "vue-loader": "^15.4.2",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.5.17",
    "webpack": "^4.26.0",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  },
  "dependencies": {}
}
</code></pre>
<p>There are three things to notice:</p>
<ol>
<li><p>I’ve created a separate <code>clean</code> script so we can run it independently of our build script.</p>
</li>
<li><p><code>npm run build</code> will call the independent <code>clean</code> script we’ve created.</p>
</li>
<li><p>I have <code>&amp;&amp;</code> between <code>npm run clean</code> and <code>webpack</code>. This instruction says: “run <code>npm run clean</code> first, <em>then</em> run <code>webpack</code>”.</p>
</li>
</ol>
<p>Let’s build the project.</p>
<p><code>npm run build</code></p>
<p>Webpack creates a <code>dist</code> directory, and our code is inside. Since our code makes no HTTP requests, we can simply open our <code>index.html</code> file in our browser and it will work as expected.</p>
<p><em>If we had code that was making HTTP requests, we would run into some cross-origin errors as we made those requests. We would need to run that project from a server for it to work.</em></p>
<p>Let’s examine the <code>index.html</code> that Webpack created in the browser and the code editor.</p>
<img src="https://cdn-media-1.freecodecamp.org/images/1*Y0hwAs2CRmCuBrn7h1pFUw.png" alt="Image" width="800" height="128" loading="lazy">

<p><em>R</em></p>
<p>If we open it in our editor or take a look at the source code in our dev tools you will see Webpack injected the script tag. In our editor though, you won’t see the styles because the style tag is injected dynamically at runtime with JavaScript!</p>
<p>Also, notice our development console information is no longer present. This is because we passed the <code>--production</code> flag to Webpack.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Understanding the build process behind the frameworks you use will help you to better understand the framework itself. Take some time to try to build an Angular, React or another Vue Project without the use of the respective CLIs. Or, just build a basic three-file site (index.html, styles.css, and app.js), but use Webpack to serve and build a production version.</p>
<p>Thanks for reading!</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to combine Webpack 4 and Babel 7 to create a fantastic React app ]]>
                </title>
                <description>
                    <![CDATA[ By Adeel Imran _Photo by [Unsplash](https://unsplash.com/@visualsbydanny?utm_source=ghost&utm_medium=referral&utm_campaign=api-credit">daniel odame / <a href="https://unsplash.com/?utm_source=ghost&utm_medium=referral&utmcampaign=api-credit) I previ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-combine-webpack-4-and-babel-7-to-create-a-fantastic-react-app-845797e036ff/</link>
                <guid isPermaLink="false">66d45d652472e5ed2fa07ba5</guid>
                
                    <category>
                        <![CDATA[ Babel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 11 Oct 2018 21:21:57 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*CU4VcsMlDhlRLrCEkjNUvw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adeel Imran</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-250.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@visualsbydanny?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;daniel odame / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>I previously wrote an article called <strong>“<a target="_blank" href="https://medium.freecodecamp.org/how-to-conquer-webpack-4-and-build-a-sweet-react-app-236d721e6745">How to conquer Webpack 4 and build a sweet React app</a>.”</strong> Soon after I wrote the article, babel swooped in with a major breaking change and many of the packages got deprecated. So I decided to write a new tutorial.</p>
<p>I will focus on setting up <strong>webpack</strong> with r<strong>eact</strong> which will have <strong>.scss</strong> support along with <strong>code splitting</strong></p>
<p>The purpose for writing this again is simple: I want everyone to feel comfortable. Because setting up webpack can be really daunting. Especially for new developers out there. Follow along, and what seemed difficult and maybe scary will seem like a piece of cake.</p>
<p>Before we start, here is the <a target="_blank" href="https://github.com/adeelibr/react-starter-kit"><strong>source code</strong></a>. I know this has loads of things in it. I plan to use the same code base to talk about webpack, react, SCSS, hot module replacement, testing with jest and enzyme, linting code, and adding a code formatter like prettier in other articles to come, so I will continuously keep on updating this code base. I will not bloat this code base — I promise.</p>
<p>Note: If you feel like making a PR for the <a target="_blank" href="https://github.com/adeelibr/react-starter-kit">repository</a>, you are more than welcome :) So let’s get started.</p>
<p>For simplicity sake, this article is only going to focus on;</p>
<ul>
<li>Setting up Webpack 4 with Babel 7 for React</li>
<li>Support for .SCSS</li>
<li>Code Splitting</li>
<li>Development environment with HMR (Hot Module Replacement)</li>
<li>Production configuration</li>
<li>Dividing your Webpack configuration into chunks</li>
<li>Handling staging, demo, production, test and other environments in code</li>
<li>Generating a visualizer in production build to check which chunk of code took how much size and what are the dependencies of the chunks. Super useful.</li>
</ul>
<h3 id="heading-prerequisite">Prerequisite</h3>
<p>You need to have node installed in order to use npm (node package manager).</p>
<p>First things first, create a folder called <code>app</code> then open up your terminal and go into that <code>app</code> folder and type:</p>
<pre><code>npm init -y
</code></pre><p>This will create a <code>package.json</code> file for you.</p>
<p>Second create a folder called <code>src</code> in your <code>app</code> folder. Inside <code>app/src</code> create a file called <code>index.js</code> and write the following code.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.warn(<span class="hljs-string">'I am a Star Trek nerd'</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'So through out this tutorial, you will see a lot of Star Trek quotes'</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Starting now'</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Compassion: that’s the one thing no machine ever had. Maybe it’s the one thing that keeps men ahead of them. -Dr McCoy"</span>);
</code></pre>
<p>You can write anything above of course. I chose Star Trek.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*YPG3f4mWE9454CRPt53RiQ.jpeg" alt="Image" width="600" height="443" loading="lazy">
<em>Change is the essential process of all existence. — Spock</em></p>
<p>Next we need to install a couple of dependencies. You can just copy the <code>dependencies</code> &amp; <code>devDependencies</code> from the <code>package.json</code> below into your own and do an <code>**npm install**</code><strong>:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"react-boiler-plate"</span>,
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"A react boiler plate"</span>,
  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"src/index.js"</span>,
  <span class="hljs-attr">"author"</span>: <span class="hljs-string">"Adeel Imran"</span>,
  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"MIT"</span>,
  <span class="hljs-attr">"scripts"</span>: {
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"a script will come here"</span>
  },
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"react"</span>: <span class="hljs-string">"^16.5.2"</span>,
    <span class="hljs-attr">"react-dom"</span>: <span class="hljs-string">"^16.5.2"</span>
  },
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"@babel/core"</span>: <span class="hljs-string">"^7.0.0"</span>,
    <span class="hljs-attr">"@babel/plugin-proposal-class-properties"</span>: <span class="hljs-string">"^7.0.0"</span>,
    <span class="hljs-attr">"@babel/plugin-proposal-export-namespace-from"</span>: <span class="hljs-string">"^7.0.0"</span>,
    <span class="hljs-attr">"@babel/plugin-proposal-throw-expressions"</span>: <span class="hljs-string">"^7.0.0"</span>,
    <span class="hljs-attr">"@babel/plugin-syntax-dynamic-import"</span>: <span class="hljs-string">"^7.0.0"</span>,
    <span class="hljs-attr">"@babel/polyfill"</span>: <span class="hljs-string">"^7.0.0-beta.51"</span>,
    <span class="hljs-attr">"@babel/preset-env"</span>: <span class="hljs-string">"^7.0.0-beta.51"</span>,
    <span class="hljs-attr">"@babel/preset-react"</span>: <span class="hljs-string">"^7.0.0-beta.51"</span>,
    <span class="hljs-attr">"babel-loader"</span>: <span class="hljs-string">"^8.0.0-beta.0"</span>,
    <span class="hljs-attr">"copy-webpack-plugin"</span>: <span class="hljs-string">"^4.5.1"</span>,
    <span class="hljs-attr">"css-loader"</span>: <span class="hljs-string">"^0.28.11"</span>,
    <span class="hljs-attr">"html-webpack-plugin"</span>: <span class="hljs-string">"^3.2.0"</span>,
    <span class="hljs-attr">"mini-css-extract-plugin"</span>: <span class="hljs-string">"^0.4.3"</span>,
    <span class="hljs-attr">"node-sass"</span>: <span class="hljs-string">"^4.8.3"</span>,
    <span class="hljs-attr">"optimize-css-assets-webpack-plugin"</span>: <span class="hljs-string">"^4.0.0"</span>,
    <span class="hljs-attr">"sass-loader"</span>: <span class="hljs-string">"^7.0.3"</span>,
    <span class="hljs-attr">"style-loader"</span>: <span class="hljs-string">"^0.21.0"</span>,
    <span class="hljs-attr">"uglifyjs-webpack-plugin"</span>: <span class="hljs-string">"^1.2.5"</span>,
    <span class="hljs-attr">"webpack"</span>: <span class="hljs-string">"^4.12.0"</span>,
    <span class="hljs-attr">"webpack-cli"</span>: <span class="hljs-string">"^3.0.8"</span>,
    <span class="hljs-attr">"webpack-dev-server"</span>: <span class="hljs-string">"^3.1.4"</span>,
    <span class="hljs-attr">"webpack-merge"</span>: <span class="hljs-string">"^4.1.3"</span>,
    <span class="hljs-attr">"webpack-visualizer-plugin"</span>: <span class="hljs-string">"^0.1.11"</span>
  }
}
</code></pre>
<p>Yes I know, I know! That’s a lot to create a hello world react app. But wait, this is all you will need. Even if you want to create a enterprise level app. (Maybe one or two more things depending on your requirements, but this is the backbone for it.)</p>
<p>So let’s talk about each and everyone of them before we dive deep into the code.</p>
<p><a target="_blank" href="http://webpack.js.org">webpack</a>: We need Webpack to bundle our code.</p>
<p><a target="_blank" href="https://github.com/webpack/webpack-cli">webpack-cli</a>: We will be using some CLI features of Webpack to make our lives easier while writing some scripts.</p>
<p><a target="_blank" href="https://github.com/webpack/webpack-dev-server">webpack-dev-server</a>: I will create a server using the webpack-dev-server package. This is only meant to be used in the development environment, and not for production. This means while developing and working on my code, I don’t need a separate server like NodeJS to setup manually.</p>
<p><a target="_blank" href="https://github.com/survivejs/webpack-merge">webpack-merge</a>: To divide our configuration into chunks, more on this later</p>
<p><a target="_blank" href="https://github.com/chrisbateman/webpack-visualizer#readme">webpack-visualizer-plugin</a>: To see a visual representation of each of our bundle size — how much space they are taking and what are their dependencies.</p>
<p><a target="_blank" href="https://github.com/webpack-contrib/style-loader">style-loader</a>: This adds CSS to the DOM by injecting a <code>&lt;script</code> /&gt; tag in the header</p>
<p><a target="_blank" href="https://github.com/webpack-contrib/sass-loader">sass-loader</a>: For SCSS support</p>
<p><a target="_blank" href="https://github.com/sass/node-sass">node-sass</a>: A dependency for sass-loader</p>
<p><a target="_blank" href="https://github.com/webpack-contrib/css-loader">css-loader</a>: To convert our .scss files into .css</p>
<p><a target="_blank" href="https://github.com/webpack-contrib/mini-css-extract-plugin">mini-css-extract-plugin</a>: This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS.</p>
<p><a target="_blank" href="https://github.com/webpack-contrib/uglifyjs-webpack-plugin">uglifyjs-webpack-plugin</a>: To minify JavaScript code for production</p>
<p><a target="_blank" href="https://github.com/NMFR/optimize-css-assets-webpack-plugin">optimize-css-assets-webpack-plugin</a> To minify CSS code for production</p>
<p><a target="_blank" href="https://github.com/jantimon/html-webpack-plugin">html-webpack-plugin</a>: This does more then generate an HTML file, it supports on demand .css and .js files automatically added to your HTML files on demand</p>
<p><a target="_blank" href="https://webpack.js.org/plugins/copy-webpack-plugin/">copy-webpack-plugin</a>: Copies files/folders to your build folder.</p>
<p><a target="_blank" href="https://github.com/babel/babel-loader">babel-loader</a>: This is the loader that helps webpack compile .js files</p>
<p><a target="_blank" href="https://github.com/babel/babel/tree/master/packages/babel-core">@babel/core</a>: Babel core compiler, this is a dependency that lets you use babel-loader</p>
<p><a target="_blank" href="https://www.npmjs.com/package/@babel/preset-react">@babel/preset-react</a> Babel preset for React code</p>
<p><a target="_blank" href="https://github.com/babel/babel/tree/master/packages/babel-preset-env">@babel/preset-env</a>: Babel preset that allows you to use the latest JavaScript</p>
<p><a target="_blank" href="https://babeljs.io/docs/en/next/babel-polyfill.html">@babel/pollyfill</a>: Babel includes a <a target="_blank" href="https://en.wikipedia.org/wiki/Polyfill_(programming)">polyfill</a> that includes a custom <a target="_blank" href="https://github.com/facebook/regenerator/blob/master/packages/regenerator-runtime/runtime.js">regenerator runtime</a> and <a target="_blank" href="https://github.com/zloirock/core-js">core-js</a>. This will emulate a full ES2015+ environment. This means support for <code>async/await</code> type of cool syntax sugar.</p>
<blockquote>
<p><em>Up till now this is pretty much what I wrote in <a target="_blank" href="https://medium.freecodecamp.org/how-to-conquer-webpack-4-and-build-a-sweet-react-app-236d721e6745"><strong>How to conquer Webpack 4 and build a sweet React app</strong></a><strong>.</strong></em></p>
</blockquote>
<p><strong>So what changed?</strong></p>
<p>Well! Babel introduced a breaking change (for the greater good, believe me) which you can read more here: <a target="_blank" href="https://babeljs.io/blog/2018/07/27/removing-babels-stage-presets"><strong>Removing Babel’s Stage Preset</strong></a><strong>.</strong> What this meant was that before if you included babel-preset-stage-2 let’s say, it would include all proposals related to stage-2, which would bloat your code. But you just might need one specific feature of stage-2.</p>
<p>So in order to combat this, babel deprecated all those preset plugins and shipped individual features. You now have to set those up manually. <strong>Cool right?</strong> So let’s talk a bit about those individual packages and what they do.</p>
<p><a target="_blank" href="https://babeljs.io/docs/en/next/babel-plugin-proposal-class-properties.html">@babel/plugin-proposal-class-properties</a>: Coverts your <code>class</code> syntax into a <code>function</code> for browsers that don’t support <code>class</code> syntax</p>
<p><a target="_blank" href="https://babeljs.io/docs/en/next/babel-plugin-proposal-export-namespace-from.html">@babel/plugin-proposal-export-namespace-from</a> Supports syntax like <code>import * as ns from '../path/to/module';</code></p>
<p><a target="_blank" href="https://github.com/tc39/proposal-throw-expressions">@babel/plugin-proposal-throw-expressions</a> New syntax to throw exceptions from within an expression context. <strong>I love this feature :D</strong></p>
<p><a target="_blank" href="https://babeljs.io/docs/en/next/babel-plugin-syntax-dynamic-import.html">@babel/plugin-syntax-dynamic-import</a> This is what helps with code splitting. Webpack ships with code splitting by default (Since webpack 1). But when you want to code split in webpack while you are using <strong>babel,</strong> then you need to use this plugin.</p>
<p>Note: for this tutorial you won’t need<code>@babel/plugin-proposal-export-namsespace-from</code> &amp; <code>@babel/plugin-proposal-throw-expressions</code></p>
<blockquote>
<p><em>Also here is a list of all babel plugins. I mean all of them. Check out the list <a target="_blank" href="https://babeljs.io/docs/en/plugins"><strong>here</strong></a><strong>.</strong></em></p>
</blockquote>
<p>And now that you know why we need what we need — nothing extra — you’ll feel more confident implementing the webpack configuration.</p>
<p>Let’s start by adding a <code>.babelrc</code> file in the root of out <code>app</code> folder:</p>
<pre><code>{
  <span class="hljs-string">"presets"</span>: [
    <span class="hljs-string">"@babel/preset-env"</span>,
    <span class="hljs-string">"@babel/preset-react"</span>
  ],
  <span class="hljs-string">"plugins"</span>: [
    <span class="hljs-string">"@babel/plugin-syntax-dynamic-import"</span>,
    <span class="hljs-string">"@babel/plugin-proposal-class-properties"</span>,
    <span class="hljs-string">"@babel/plugin-proposal-export-namespace-from"</span>,
    <span class="hljs-string">"@babel/plugin-proposal-throw-expressions"</span>
  ]
}
</code></pre><p>We have 2 main presets <code>preset-env</code> &amp; <code>preset-react</code> . The rest are our plugins to add “<strong>wings</strong>” to our code.</p>
<p>And to quote Captain Kirk from Star Trek (because why not):</p>
<blockquote>
<p><em>Perhaps man wasn’t meant for paradise. Maybe he was meant to claw, to scratch all the way. Captain Kirk</em></p>
</blockquote>
<p>In his defense, Captain Kirk was up against the likes of General Change, Khan, The Borg and so many dangerous foes. All we are up against is the beautiful <strong>Webpack</strong> and <strong>Babel</strong>. So perhaps we developers are meant for paradise.</p>
<p>So let’s set our webpack up.</p>
<p>Create a <code>config</code> folder in your <code>app</code> . If you feel lost you can at any time refer to the GitHub r<a target="_blank" href="https://github.com/adeelibr/react-starter-kit/tree/master/config">epository</a> for this. Now inside our <code>config</code> folder let’s create a file called <code>webpack.base.config.js</code> The reason I call this <code>base</code> is because it is going to be used for our development and for production. <em>Because why write the same thing twice?</em> Again if this isn’t making much sense, just bear with me a few more minutes.</p>
<p>In your <code>config/webpack.base.config.js</code> write this:  </p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,
        exclude: <span class="hljs-regexp">/node_modules/</span>,
        use: {
          <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>
        }
      },
    ]
  }
}
</code></pre>
<p>Once you have it in place, run this command in your root <code>app</code> directory. (I’ll tell you what this command does a bit later with the code we wrote above, I promise.)</p>
<pre><code>$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
</code></pre><p>Once you run this command, you will see this screen:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*nAW_kvzNLvtce5cyTsbaVg.png" alt="Image" width="800" height="385" loading="lazy">
<em>Oh! A Fancy Error!</em></p>
<p>So what happened here? Well when we ran the webpack command, it did find our <code>index.js</code> file that we wrote earlier in <code>app/src/index.js</code> — but it didn’t have a <code>.html</code> to run it in. So let’s create an <code>index.html</code> file in our <code>app/src</code> folder:</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">HTML</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"Content-Type"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"text/html; charset=UTF-8"</span> /&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">base</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Tutorial<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Let’s update our <code>webpack.base.config.js</code> as well:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,
        exclude: <span class="hljs-regexp">/node_modules/</span>,
        use: {
          <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>
        }
      }
    ]
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({ 
      <span class="hljs-attr">template</span>: <span class="hljs-string">'./src/index.html'</span>, 
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'./index.html'</span> 
    })
  ]
}
</code></pre>
<p>Let’s run that command again now:</p>
<pre><code>$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
</code></pre><p>Your browser will open up. If you are using Google Chrome, press <code>ctrl+shift+j</code> and your browser console will open up. You will see something like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*qXyjH3FzHCPHZqBeJTDbIg.png" alt="Image" width="800" height="165" loading="lazy">
<em>Hey look at that, this is what I wrote in my console! You should see something like this at your end as well.</em></p>
<p>So let’s talk what happened here. Our <code>webpack.base.config.js</code> has two main things: modules and plugins. A module can have multiple rules, and each rule is applied to certain file type. The certain file type that we want to apply that rule to is in <code>test</code> of that rule:</p>
<pre><code class="lang-javascript">rules: [      
  {        
    <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,        
    exclude: <span class="hljs-regexp">/node_modules/</span>,        
    use: {          
      <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>        
    }      
  },    
]
</code></pre>
<p>Here by saying <code>test: /\.js$./,</code> we are telling webpack to apply this rule only for <code>.js</code> files. The other thing is <code>exclude</code> which also takes in a regex expression of what not not to include. This is where we tell it not to compile <code>node_modules</code> because this will compile all of it, and there are loads of dependencies installed. Check the <code>node_modules</code> yourself. The last part is <code>use</code>.</p>
<p>Now webpack knows where to apply the rule using <code>test</code> and where not to apply the rule using <code>exclude</code> — but what is the rule exactly? That is where <code>use</code> comes into play: here we specify <code>loader: 'babel-loader'</code>. Now what <code>babel-loader</code> does is that it looks for <code>.babelrc</code> file that we wrote earlier. And all the presets &amp; plugins we wrote there. It takes all of them and applies those to our <code>.js</code> files.</p>
<p>Which brings us to the next question: how does <strong>Webpack 4</strong> find those files? Well Webpack 4 ships with loads of default stuff already set up for you. Two of those are <code>entry</code> and <code>output</code> .</p>
<p><code>entry</code> point by default is the <code>src</code> directory that we wrote in our <code>app</code> folder.</p>
<p><code>output</code> point is where all the compiled bundled code is generated, which is going to be <code>dist</code> folder in out <code>app</code> folder. (You won’t see that now, because we haven’t compiled our code yet for production.)</p>
<p>Next we’ll talk about <code>html-webpack-plugin</code> The purpose of this plugin is simple as the name suggests. It creates HTML files to serve all of your bundled files. (All of it — .js, .css, .scss, .img etc)</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*9KgKgHb2QFjZY_Gk05OtkA.gif" alt="Image" width="500" height="281" loading="lazy">
<em>If you have followed along up till yet. You guys are great</em></p>
<p>Let’s talk about when we run the following:</p>
<pre><code>$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
</code></pre><p>This command will open up port <code>[http://localhost:8080](http://localhost:8080)</code> or another port if <code>8080</code> is taken. (I’ll talk more about what this command does later — for now let’s move on).</p>
<p>The <em>index.html</em> that is generated looks like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*nm_1jPCBvb0lXTTWuAl5XQ.png" alt="Image" width="800" height="432" loading="lazy">
<em>I simply clicked <strong>ctrl + shift + i</strong> this opened up the inspect element in my chrome browser</em></p>
<p><strong>Blue part:</strong> The blue part is simply where I put in my meta tags and defined a title for the app.</p>
<p><strong>Yellow part:</strong> The yellow part highlighted is the hard coded part that we wrote in our <code>**index.html**</code> file. This is where our future React app will reside.</p>
<p><strong>Red Part:</strong> The part I underlined in red is the most interesting part. We never wrote this in our index.html file, so where did it come from?</p>
<p>Webpack is very smart. It took that file in your <code>**index.js**</code> , bundled it all up nicely, and added it up all neatly in the file called <code>**main.js**</code> . Then it injected it in our <code>**index.html**</code> file. Super Cool!</p>
<blockquote>
<p><em>We are almost 60% <strong>done!</strong> Believe me the hard part is over…</em></p>
</blockquote>
<h3 id="heading-lets-add-react">Let’s Add React</h3>
<p>The cool thing is, all our dependencies are already installed. And everything is already configured. So in your <code>app/src/index.js</code> remove all the code and replace it with this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
        We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequently
        have my doubts. I dont. Not any more. And maybe in a thousand years or so, we will be able
        to prove it.
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- Captain Kirk<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'app'</span>));
</code></pre>
<p>Now if your terminal is still running the <code>webpack-dev-server</code> script, just check the browser out. If not, here is the script. I don’t want you to scroll all the way up again.</p>
<pre><code>$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
</code></pre><p>This is what you will see:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*k2GbkHxf8qrs3lqM6R-bAg.png" alt="Image" width="800" height="101" loading="lazy">
<em>This is our React application live.</em></p>
<p>Now make sure you don’t close the terminal, and go in your <code>app/src/index.js</code> and make some changes to your <code>&lt;App</code> /&gt; component. Try changing the sentence in the paragraph. Once changed, go back to your browser and the content is already there updated. How cool is that? :D</p>
<blockquote>
<p><em>This sums up 70% of our tutorial — only 30% more to go. You are doing great.</em></p>
</blockquote>
<h3 id="heading-lets-add-scss-support"><strong>Let’s Add SCSS Support</strong></h3>
<p>Let’s start by updating our <code>config/webpack.base.config.js</code> by adding another rule for <code>.scss</code> files</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">module</span>: {
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,
        exclude: <span class="hljs-regexp">/node_modules/</span>,
        use: {
          <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>
        }
      },
      {
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.scss$/</span>,
        use: [
          <span class="hljs-string">'style-loader'</span>,
          <span class="hljs-string">'css-loader'</span>,
          <span class="hljs-string">'sass-loader'</span>
        ]
      },
    ]
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
      <span class="hljs-attr">template</span>: <span class="hljs-string">'./src/index.html'</span>,
      <span class="hljs-attr">filename</span>: <span class="hljs-string">'./index.html'</span>
    }),
  ]
}
</code></pre>
<p>So the <code>use</code> I use here takes an array instead of an object like what I did for the <code>.js</code> files. This is because we need to apply a set of rules here:</p>
<pre><code>use: [ <span class="hljs-string">'style-loader'</span>,<span class="hljs-string">'css-loader'</span>,<span class="hljs-string">'sass-loader'</span> ]
</code></pre><p>So let’s read the <code>use</code> array from <code>right to left</code> — this is <strong>important.</strong> What we are telling Webpack is to take any <code>.scss</code> files it finds and parse it for its own understanding using the <strong>sass-loader.</strong> Once it has converted it into sass, we then ask Webpack to convert the sass into CSS. For that we apply <strong>css-loader</strong>.</p>
<p>As of this point we have converted the .scss into .css. But there is no way for us to add the converted files into our <code>.html</code>. For this we use the last loader called <strong>style-loader</strong> which takes all the converted .css and injects it into our <code>index.html</code> file.</p>
<p>So let’s add some <code>.scss</code> to test this out. In your <code>src/</code> folder add a file called <code>myStyles.scss</code> Mine looks like the one below:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background-color</span>: skyblue;
  <span class="hljs-attribute">color</span>: black;
}

<span class="hljs-selector-class">.app</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">450px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
  <span class="hljs-attribute">padding-top</span>: <span class="hljs-number">50px</span>;
}
</code></pre>
<p>And my <code>src/index.js</code> file looks like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">'./myStyles.scss'</span>;;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"app"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
        We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequently
        have my doubts. I dont. Not any more. And maybe in a thousand years or so, we will be able
        to prove it.
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- Captain Kirk<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'app'</span>));
</code></pre>
<p>Restart your <code>webpack-dev-server</code> by running this command again:</p>
<pre><code>$ node_modules/.bin/webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback
</code></pre><blockquote>
<p><em>This was the last time I’ll make you manually write that script up. After this we will move this command into our <code>scripts</code> section in our <code>package.json</code>.</em></p>
</blockquote>
<p>Your browser will open up, this is what it looks like now:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*_S0JUOyiRMMbXQKfl_lv1Q.png" alt="Image" width="800" height="273" loading="lazy">
<em>Nice! huh.</em></p>
<p>Now in your <code>myStyles.scss</code> file, try making some changes. Like make the <code>font-size: white;</code> come back to your browser. It reflects those changes. You don’t have to restart your server again — just for the <code>.scss</code> to compile.</p>
<p>With this, most of our development configuration is done. Our React application is live, and has hot module replacement for <code>.js</code> files as well as <code>.scss</code> files</p>
<p>So before we move further, let’s add the <code>webpack-dev-server</code> script in our <code>package.json</code>. In your <code>**scripts**</code> section, add the following code:</p>
<pre><code class="lang-json"><span class="hljs-string">"scripts"</span>: {
    <span class="hljs-attr">"start"</span>: <span class="hljs-string">"webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback --env.PLATFORM=local --env.VERSION=stag"</span>,
    <span class="hljs-attr">"prebuild"</span>: <span class="hljs-string">"webpack --mode production --config config/webpack.prod.config.js --env.PLATFORM=production --env.VERSION=stag --progress"</span>,
    <span class="hljs-attr">"build"</span>: <span class="hljs-string">"node server"</span>,
},
</code></pre>
<p>For now I’ll talk about the <code>start</code> command. I’ll talk about the <code>prebuild</code> and <code>build</code> scripts later in the production configuration section.</p>
<p>So what does this command do: <code>npm run start</code></p>
<pre><code><span class="hljs-string">"start"</span>: <span class="hljs-string">"webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback"</span>
</code></pre><p>Let’s break this down. When we run <code>npm run start</code> we’re telling it to run a package called <code>webpack-dev-server</code>. Then we pass it some configurations.</p>
<ul>
<li><code>webpack-dev-server</code> serves a webpack app and updates the browser on changes.</li>
<li><code>--mode development</code> tells <code>webpack</code> to compile the code in development mode. This is basically to make the compilation time faster.</li>
<li><code>--config config/webpack.base.config.js</code> So by default if you have <code>webpack.config.js</code> file in your root <code>app</code> folder, you don’t have to supply the <code>--config</code> flag to it. But since I want to explicitly add all my webpack related configurations in the <code>config</code> folder, I pass in <code>--config</code> option that tells webpack where to look for the configuration</li>
<li><code>--open</code> command opens the browser, when webpack is done with its compilation.</li>
<li><code>--hot</code> flag tells webpack to actively watch for code changes in the <code>src</code> folder. If any changes happen, it reloads the browser.</li>
<li><code>--history-api-fallback</code> This option enables <a target="_blank" href="https://github.com/bripkens/connect-history-api-fallback">History API Fallback</a> support in <code>webpack-dev-server</code>, effectively asking the server to fallback to <code>index.html</code> in the event that a requested resource cannot be found.</li>
<li><code>--env.PLATFORM</code> &amp; <code>--env.VERSION</code> are custom flags that I pass in my configuration (more on this later).</li>
</ul>
<p>Now that we are done, let move onto our <strong>production</strong> configurations.</p>
<p>But before we do that, let’s talk about <code>webpack-merge</code>. Now this is a real winner. It takes in one configuration and another one and merges them both together to give us one. The way it works is you need to wrap your configuration with <code>merge</code> like the one below. Let’s start off by making our <code>webpack.base.config.js</code> file into a <code>webpack-merge</code> usable chunk:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> webpack = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack'</span>);
<span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">"webpack-merge"</span>);

<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-params">env</span> =&gt;</span> {
  <span class="hljs-keyword">const</span> { PLATFORM, VERSION } = env;
  <span class="hljs-keyword">return</span> merge([
      {
        <span class="hljs-attr">module</span>: {
          <span class="hljs-attr">rules</span>: [
            {
              <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,
              exclude: <span class="hljs-regexp">/node_modules/</span>,
              use: {
                <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>
              }
            },
            {
              <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.scss$/</span>,
              use: [
                <span class="hljs-string">'style-loader'</span>,
                <span class="hljs-string">'css-loader'</span>,
                <span class="hljs-string">'sass-loader'</span>
              ]
            }
          ]
        },
        <span class="hljs-attr">plugins</span>: [
          <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
            <span class="hljs-attr">template</span>: <span class="hljs-string">'./src/index.html'</span>,
            <span class="hljs-attr">filename</span>: <span class="hljs-string">'./index.html'</span>
          }),
          <span class="hljs-keyword">new</span> webpack.DefinePlugin({ 
            <span class="hljs-string">'process.env.VERSION'</span>: <span class="hljs-built_in">JSON</span>.stringify(env.VERSION),
            <span class="hljs-string">'process.env.PLATFORM'</span>: <span class="hljs-built_in">JSON</span>.stringify(env.PLATFORM)
          }),
        ],
    }
  ])
};
</code></pre>
<p>Previously where we where exporting an <code>object</code>, now we are exporting a <code>function</code> which returns <code>merge</code> and takes in the configuration.</p>
<p>Let’s break this down as to what this is doing.The first thing we talk about is this:</p>
<pre><code><span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">env</span>) </span>{}
</code></pre><p>The new flags added in our <code>start</code> command <code>— env.PLATFORM=local — env.VERSION=stag</code> are passed to our webpack configurations, which we can access with the <code>env</code> param in <code>module.exports = function (env) {}</code>. So what can we do with this?</p>
<ul>
<li>We can set up a conditional statement in our webpack configuration, that if a certain condition is met, then do this or that (more on this later). Basically we will change our configuration on compile time to cater to whichever environment is being run — production or development.</li>
<li>The other thing that we can do here is pass them in our code as well. So what do I mean by pass in our code? One new plugin I added for this is called <code>**new webpack.DefinePlugin**</code><strong>.</strong> (Also that is why I had to include webpack at the top of <code>webpack.base.config.js</code>.) What this does is: “<em>The <code>DefinePlugin</code> allows you to create global constants which can be configured at compile time.</em>” You can read more about this <a target="_blank" href="https://webpack.js.org/plugins/define-plugin/"><strong>here</strong></a><strong>.</strong></li>
</ul>
<p>Next we return a configuration inside the function like this:</p>
<pre><code><span class="hljs-keyword">return</span> merge({ 
   <span class="hljs-comment">// our webpack configuration here</span>
});
</code></pre><p>Well not much has changed here. All we did was wrap our configuration in <code>merge</code>. This gives us the ability to <code>merge</code> this entire configuration into the other one that we will create.</p>
<p>One thing added is a new plugin called <code>DefinePlugin</code> which I already talked about.</p>
<blockquote>
<p><em>If you are a nerd like me and want to dig deeper into <code>webpack-merge</code> I suggest you dive in <a target="_blank" href="https://github.com/survivejs/webpack-merge"><strong>here</strong></a> <strong>—</strong> this was developed by the cool folks at <code>[**SurviveJS**](https://survivejs.com/)</code><strong>.</strong></em></p>
</blockquote>
<p>Before moving to the <code>production</code> settings, let’s check if our base configurations are working.</p>
<p>In your <code>src/index.js</code> file add this somewhere:</p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'process.env.VERSION'</span>, process.env.VERSION);
</code></pre><pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'process.env.PLATFORM'</span>, process.env.PLATFORM);
</code></pre><pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'process.env.NODE_ENV'</span>, process.env.NODE_ENV);
</code></pre><p>In your terminal run <code>npm run start</code>. Wait for your browser to load up. Open up your terminal.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*1XyF_YqUH8LZflGjtBSC1w.png" alt="Image" width="800" height="208" loading="lazy">
<em>Click <strong>ctrl+shift+j</strong> to open up the console in your browser</em></p>
<p>The first two you see in the console is the result of us passing the <code>--env</code> flags from our script to our webpack configuration and setting it with DefinePlugin. The third one is with the <code>--mode</code> flag that we pass in our script. If mode is development or production, then that is set up in our <code>process.env.NODE_ENV</code> flag.</p>
<p>Now that that’s cleared up, let’s move on.</p>
<p>In your <code>config</code> folder, create a new file called <code>webpack.prod.config.js</code> and add the following code into it as shown below:</p>
<pre><code><span class="hljs-keyword">var</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-merge'</span>);

<span class="hljs-comment">// Plugins</span>
<span class="hljs-keyword">var</span> OptimizeCssAssetsPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'optimize-css-assets-webpack-plugin'</span>);
<span class="hljs-keyword">var</span> UglifyJsPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'uglifyjs-webpack-plugin'</span>);
<span class="hljs-keyword">var</span> Visualizer = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-visualizer-plugin'</span>);

<span class="hljs-keyword">var</span> baseConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./webpack.base.config'</span>);

<span class="hljs-keyword">const</span> prodConfiguration = <span class="hljs-function"><span class="hljs-params">env</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> merge([
    {
      <span class="hljs-attr">optimization</span>: {
        <span class="hljs-attr">runtimeChunk</span>: <span class="hljs-string">'single'</span>,
        <span class="hljs-attr">splitChunks</span>: {
          <span class="hljs-attr">cacheGroups</span>: {
            <span class="hljs-attr">vendor</span>: {
              <span class="hljs-attr">test</span>: <span class="hljs-regexp">/[\\/]node_modules[\\/]/</span>,
              name: <span class="hljs-string">'vendors'</span>,
              <span class="hljs-attr">chunks</span>: <span class="hljs-string">'all'</span>
            }
          }
        },
        <span class="hljs-attr">minimizer</span>: [<span class="hljs-keyword">new</span> UglifyJsPlugin()],
      },
      <span class="hljs-attr">plugins</span>: [
        <span class="hljs-keyword">new</span> OptimizeCssAssetsPlugin(),
        <span class="hljs-keyword">new</span> Visualizer({ <span class="hljs-attr">filename</span>: <span class="hljs-string">'./statistics.html'</span> })
      ],
    },
  ]);
}

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-params">env</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> merge(baseConfig(env), prodConfiguration(env));
}
</code></pre><p>Let’s start from the bottom with <code>module.exports = env =&gt;</code> {}</p>
<p>We merge two configurations: one is our <code>baseConfig</code> and the other is <code>prodConfiguration</code> . The <code>--env</code> flags we pass in our scripts are passed on as an object in the <code>env =&gt;</code> {} params in our function. We then pass them onto both t<code>he baseCon</code>fig <code>&amp; prodCon</code>fig.</p>
<blockquote>
<p>So what is <code>prodConfig</code> ?</p>
</blockquote>
<p>It is basically a list of the optimizations we want to perform when our code goes up for production.</p>
<p>The <code>optimization.minimizer</code> takes in a <code>new UglifyJsPlugin</code>. What this does is uglify and minify our .js files.</p>
<p>The <code>optimization.splitChunks</code> actually takes all of your common code and creates a <code>vendor.bundle.js</code> file. It is not going to make one now. But as our code base grows, we have multiple routes, and there are different modules being used like <code>date-fns</code> <code>moment</code> <code>lodash</code> <code>material-ui</code> etc. It will take all the common code from entire app and make a common file called <code>vendor.bundle.js</code> . This way, the repeated code isn’t used again &amp; again. (I am against this approach, but for educational purposes I described it here.)</p>
<p>Going forward I’ll comment the <code>optimization.splitChunks</code> but, it will exist there in the code repository if you want to use it. You just have to uncomment this section. I prefer to split my code based on routes. Having common code chunked out into a separate module means that your entire common code is going to be loaded first. This can be huge, and as a result the user’s first time interaction will take longer (because now all of these dependencies are being loaded, which might not need to be in the respective page that the user is seeing/viewing).</p>
<p>Next up, we have a couple of plugins. One of them happens to be <code>new OptimizeCssAssetsPlugin()</code>. All it does is take all of our generated <code>.css</code> and minify/optimize it. This doesn’t work right now, because we are using <code>style-loader</code> and style loader directly injects the generated <code>.css</code> into the DOM.</p>
<p>First, we need tell webpack to extract all the generated <code>.css</code> into a separate file, and then the optimizations added by this plugin are applied. (We’ll do this a bit later.)</p>
<p>The other plugin added here is called <code>new Visualizer({ filename: ‘./statistics.html’ })</code> .This plugin is awesome: it generates a <code>statistics.html</code> file in the <code>dist/</code> folder for you. Open the file, and you’ll see a graphic like the one below.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*V5_yljYjlwuTgQIiTtzkCQ.png" alt="Image" width="600" height="559" loading="lazy">
_Image taken from [https://github.com/chrisbateman/webpack-visualizer](https://github.com/chrisbateman/webpack-visualizer" rel="noopener" target="<em>blank" title=")</em></p>
<p>Right now we only have a single module called <code>main.js</code>. But with time, as we add more modules, and have code splitting added to it. More modules will start showing up here and we can actually see what modules take what size. This can be really useful when you are trying to reduce the size of your application.</p>
<p>Coming back to <code>OptimizeCssAssetsPlugin()</code> . In order to optimize the .css generated, we need to move this into a separate module. For that I am going to use <code>mini-css-extract-plugin</code> This will require us to make changes in both of our webpack files, the <code>.base</code> and <code>.prod</code> files.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// webpack.base.config.js</span>
<span class="hljs-keyword">const</span> webpack = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack'</span>);
<span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">"webpack-merge"</span>);

<span class="hljs-keyword">const</span> MiniCssExtractPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mini-css-extract-plugin"</span>);
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>);

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-params">env</span> =&gt;</span> {
  <span class="hljs-keyword">const</span> { PLATFORM, VERSION } = env;
  <span class="hljs-keyword">return</span> merge([
      {
        <span class="hljs-attr">module</span>: {
          <span class="hljs-attr">rules</span>: [
            {
              <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,
              exclude: <span class="hljs-regexp">/node_modules/</span>,
              use: {
                <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>
              }
            },
            {
              <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.scss$/</span>,
              use: [
                PLATFORM === <span class="hljs-string">'production'</span> ? MiniCssExtractPlugin.loader : <span class="hljs-string">'style-loader'</span>,
                <span class="hljs-string">'css-loader'</span>,
                <span class="hljs-string">'sass-loader'</span>
              ]
            }
          ]
        },
        <span class="hljs-attr">plugins</span>: [
          <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
            <span class="hljs-attr">template</span>: <span class="hljs-string">'./src/index.html'</span>,
            <span class="hljs-attr">filename</span>: <span class="hljs-string">'./index.html'</span>
          }),
          <span class="hljs-keyword">new</span> webpack.DefinePlugin({ 
            <span class="hljs-string">'process.env.VERSION'</span>: <span class="hljs-built_in">JSON</span>.stringify(env.VERSION),
            <span class="hljs-string">'process.env.PLATFORM'</span>: <span class="hljs-built_in">JSON</span>.stringify(env.PLATFORM)
          }),
        ],
    }
  ])
};
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">// webpack.prod.config.js</span>
<span class="hljs-comment">/* eslint-disable */</span>
<span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-merge'</span>);
<span class="hljs-comment">// Plugins</span>
<span class="hljs-keyword">const</span> MiniCssExtractPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mini-css-extract-plugin"</span>);
<span class="hljs-keyword">const</span> OptimizeCssAssetsPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'optimize-css-assets-webpack-plugin'</span>);
<span class="hljs-keyword">const</span> UglifyJsPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'uglifyjs-webpack-plugin'</span>);
<span class="hljs-keyword">const</span> Visualizer = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack-visualizer-plugin'</span>);
<span class="hljs-comment">// Configs</span>
<span class="hljs-keyword">const</span> baseConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./webpack.base.config'</span>);

<span class="hljs-keyword">const</span> prodConfiguration = <span class="hljs-function"><span class="hljs-params">env</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> merge([
    {
      <span class="hljs-attr">optimization</span>: {
        <span class="hljs-comment">// runtimeChunk: 'single',</span>
        <span class="hljs-comment">// splitChunks: {</span>
        <span class="hljs-comment">//   cacheGroups: {</span>
        <span class="hljs-comment">//     vendor: {</span>
        <span class="hljs-comment">//       test: /[\\/]node_modules[\\/]/,</span>
        <span class="hljs-comment">//       name: 'vendors',</span>
        <span class="hljs-comment">//       chunks: 'all'</span>
        <span class="hljs-comment">//     }</span>
        <span class="hljs-comment">//   }</span>
        <span class="hljs-comment">// },</span>
        <span class="hljs-attr">minimizer</span>: [<span class="hljs-keyword">new</span> UglifyJsPlugin()],
      },
      <span class="hljs-attr">plugins</span>: [
        <span class="hljs-keyword">new</span> MiniCssExtractPlugin(),
        <span class="hljs-keyword">new</span> OptimizeCssAssetsPlugin(),
        <span class="hljs-keyword">new</span> Visualizer({ <span class="hljs-attr">filename</span>: <span class="hljs-string">'./statistics.html'</span> })
      ],
    },
  ]);
}

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-params">env</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> merge(baseConfig(env), prodConfiguration(env));
}
</code></pre>
<p>Let’s talk about the changes I made in <code>webpack.base.config.js</code> .Only one module was added called <code>const MiniCssExtractPlugin = require(“mini-css-extract-plugin”);</code>. Then in our <code>.scss</code> rules we checked if the <code>PLATFORM</code> flag passed has the value <code>production</code>. If so, we add <code>MiniCssExtractPlugin.loader</code>, and otherwise we add the <code>style-loader</code>.</p>
<p><code>style-loader</code> is used to actively watch and change our compiled <code>.css</code> in development mode, while <code>MiniCssExtractPlugin.loader</code> is used when we need to extract that generated CSS into a separate module. This is only for production.</p>
<p>In the other file <code>webpack.prod.config.js</code> we have these two plugins added:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">new</span> MiniCssExtractPlugin(),
<span class="hljs-keyword">new</span> OptimizeCssAssetsPlugin(),
</code></pre>
<p>The first will extract this into a separate module called <code>main.css</code> and the other will minify/uglify the generated CSS.</p>
<p>Having done this, we are almost 90% done. If you have stayed this far, kudos to you.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*vJuq08E4psbspTTfzRcHig.gif" alt="Image" width="200" height="150" loading="lazy">
<em>Awesome!</em></p>
<p>Before we proceed further, here is what Captain Kirk has to say</p>
<blockquote>
<p><em>You know the greatest danger facing us is ourselves, and irrational fear of the unknown. There is no such thing as the unknown. Only things temporarily hidden, temporarily not understood.</em></p>
<ul>
<li>James T. Kirk, The Corbomite Maneuver</li>
</ul>
</blockquote>
<p>Let’s add more functionality, to our code. Now there are two ways to add files in your code. One is by using another loader called <code>file-loader</code> which will help you add files of any type into your .js files like we did with .scss files.</p>
<p>I want to talk about another approach here, because I think assets like fonts, images and others should be loaded in parallel rather than in your .js files. This helps provide a better experience for the user. So for that propose we will load our images statically.</p>
<p>For this we will use a plugin called <code>copy-webpack-plugin</code>. The best thing about all this is you already have this installed. In your <code>webpack.base.config.js</code> add another plugin, like the below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> CopyWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'copy-webpack-plugin'</span>); <span class="hljs-comment">// Add this in top</span>

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-params">env</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> merge([
      {
        <span class="hljs-attr">module</span>: {},
        <span class="hljs-attr">plugins</span>: [
          <span class="hljs-keyword">new</span> CopyWebpackPlugin([ { <span class="hljs-attr">from</span>: <span class="hljs-string">'src/static'</span> } ]), <span class="hljs-comment">// Add this in the plugins section</span>
        ],
    }
  ])
};
</code></pre>
<p>The <code>copy-webpack-plugin</code> takes in an argument called <code>from</code>. This tells the plugin where to locate the static files and then copy them in the <code>dist</code> folder. Here I am telling it to look for a folder called <code>src/static</code> and copy all of its content in the <code>dist/</code> folder.</p>
<p>Once you have added this and set it up, all you have to do is, in your <code>app/src</code> folder, create a new folder called <code>static</code> . In this folder, create another folder called <code>images</code> so your folder will have a directory like this: <code>app/src/static/images</code></p>
<p>I am going to put an image here called <code>header.jpg</code>, but you can call it whatever you like. This is the image I am using: <a target="_blank" href="https://unsplash.com/photos/Idi6I490p7I">https://unsplash.com/photos/Idi6I490p7I</a> (Photo by <a target="_blank" href="https://unsplash.com/photos/Idi6I490p7I?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Felix Mittermeier</a> on <a target="_blank" href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>).</p>
<p>Now in order for this to work, you need to run the <code>npm run prebuild</code> command (I’ll talk more about <code>npm run prebuild</code> &amp; <code>npm run build</code> later when we set up our NodeJS server with ExpressJS) because we need our <code>static</code> files to be copied. The <code>npm run start</code> command won’t copy this to the <code>dist/</code> folder because it doesn’t compile code to the <code>dist/</code> folder.</p>
<p>Once you have run the <code>npm run prebuild</code> command this is what you will see:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*IC58DnGCTt_KH7FMEmFNFg.png" alt="Image" width="547" height="473" loading="lazy">
<em>As you can see we have a images folder and inside that folder we have <code>header.jpg</code> file</em></p>
<p>So how can we access this file in our code?</p>
<p>I am going to make some changes in my <code>index.js</code> file along with <code>myStyles.scss</code> .You can follow along as well — we’re just adding an <code>&lt;img</code> /&gt; along with <code>some</code> .scss</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">'./myStyles.scss'</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"app"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"header"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/dist/images/header.jpg"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"app-header"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
        We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequently
        have my doubts. I dont. Not any more. And maybe in a thousand years or so, we will be able
        to prove it.
      <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- Captain Kirk<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'app'</span>));
</code></pre>
<pre><code class="lang-scss"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background-color</span>: skyblue;
  <span class="hljs-attribute">color</span>: black;
}

<span class="hljs-selector-class">.app</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">450px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
  <span class="hljs-attribute">padding-top</span>: <span class="hljs-number">50px</span>;

  &amp; <span class="hljs-selector-class">.app-header</span> {
    <span class="hljs-attribute">height</span>: <span class="hljs-number">250px</span>;
    <span class="hljs-attribute">width</span>: inherit;
    <span class="hljs-selector-tag">object</span>-fit: cover;
  }
}
</code></pre>
<p>The only thing to note here is in the <code>index.js</code> file where I add an image:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">img</span>    
  <span class="hljs-attr">alt</span>=<span class="hljs-string">"header"</span>   
  <span class="hljs-attr">src</span>=<span class="hljs-string">"/dist/images/header.jpg"</span>
  <span class="hljs-attr">className</span>=<span class="hljs-string">"app-header"</span>
/&gt;</span>
</code></pre>
<p>The main thing is the path we give in the <code>src</code>.</p>
<p>Once you have added this, let’s check how this looks in the browser. Go and run <code>npm run start</code> command.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*EzP9VCYITSrahax4nkw8Dg.png" alt="Image" width="800" height="269" loading="lazy">
<em>Hey! Look Ma! I added an image. With this added, our webpack configuration is done.</em></p>
<h4 id="heading-lets-recap-what-we-have-accomplished-so-far">Let’s recap what we have accomplished so far</h4>
<ul>
<li>Setting up Webpack 4 with Babel 7 for React</li>
<li>Support for .SCSS</li>
<li>Development environment with HMR [For both .js &amp; .scss]</li>
<li>Production configuration</li>
<li>Dividing your Webpack configuration into chunks</li>
<li>Generating a visualizer in production build to check which chunk of code is how big and what are the dependencies of the chunks. Super useful.</li>
<li>Support for static files</li>
</ul>
<h4 id="heading-things-we-still-need-to-accomplish">Things We Still Need To Accomplish</h4>
<ul>
<li>Add support for <code>async/await</code> in our code</li>
<li>Create a NodeJS server using ExpressJS for our production build</li>
<li>Code Splitting</li>
</ul>
<p>Let’s start with <code>async/await</code> first. For this purpose I am going to make a smart <code>&lt;App</code> /&gt; component. Inside this component I am going to call an API that gets me information about Captain Kirk, because he is awesome. So in our <code>index.js</code> add the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">'./myStyles.scss'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  state = {
    <span class="hljs-attr">CaptainKirkBio</span>: {},
  };

  componentDidMount() {
    <span class="hljs-built_in">this</span>.onGetKirkBio();
  }

  onGetKirkBio = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> URL = <span class="hljs-string">'http://stapi.co/api/v1/rest/character/search'</span>;
      <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> fetch(URL, {
        <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
        <span class="hljs-attr">headers</span>: {
          <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span>,
        },
        <span class="hljs-attr">body</span>: {
          <span class="hljs-attr">title</span>: <span class="hljs-string">'James T. Kirk'</span>,
          <span class="hljs-attr">name</span>: <span class="hljs-string">'James T. Kirk'</span>,
        },
      });
      <span class="hljs-keyword">const</span> resultJSON = <span class="hljs-keyword">await</span> result.json();
      <span class="hljs-keyword">const</span> character = resultJSON.characters[<span class="hljs-number">0</span>];
      <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">CaptainKirkBio</span>: character });
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'error'</span>, error);
    }
  };

  render() {
    <span class="hljs-keyword">const</span> { CaptainKirkBio } = <span class="hljs-built_in">this</span>.state;
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"app"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"header"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/dist/images/header.jpg"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"app-header"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
          We are a most promising species, Mr. Spock, as predators go. Did you know that? I
          frequently have my doubts. I dont. Not any more. And maybe in a thousand years or so, we
          will be able to prove it.
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- Captain Kirk<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>
          {Object.values(CaptainKirkBio).length === 0 ? (
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading User Information<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          ) : (
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">wordBreak:</span> '<span class="hljs-attr">break-all</span>' }}&gt;</span>{JSON.stringify(CaptainKirkBio)}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          )}
        <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }
}

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'app'</span>));
</code></pre>
<p>All I am doing here is calling an API using <code>try/catch</code> <code>async/await</code> and getting information about Captain Kirk. Simple right? This should work. Let’s fire this up in the browser.</p>
<p>Run the command:</p>
<pre><code>npm run start
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/1*EI1U0MLC_mu5i__W-ZzIsg.png" alt="Image" width="800" height="341" loading="lazy">
<em>Our app crashed here! Wonder why?</em></p>
<p>If you hit <code>ctrl+shift+j</code> your console will open up, and you will see an error there called <code>**regeneratorRuntime**</code> <strong>.</strong> So what is this error and how do we get rid of it?</p>
<p>This error gets thrown when the browser doesn’t support <code>async/await</code> or <code>generators</code> for that matter.</p>
<blockquote>
<p>But <strong>Adeel</strong>! That’s the only reason we are using babel right?</p>
</blockquote>
<p>Yes! Here’s what <a target="_blank" href="https://twitter.com/left_pad"><strong>Henry Zhu</strong></a>, the awesome dude behind babel, has to say about this:</p>
<blockquote>
<p>If you are using generators/async and the environment doesn’t support it natively we compile using regenerator which <strong>uses</strong> a runtime. So you’ll have to include regeneratorRuntime either yourself or use babel-polyfill.</p>
<p>Reference taken from an <a target="_blank" href="https://github.com/babel/babel-preset-env/issues/92#issuecomment-266869180"><strong>issue</strong></a>.</p>
</blockquote>
<p>Now you know why this exists, so let’s solve it. We need to make some changes to our <code>webpack.base.config.js</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
<span class="hljs-keyword">const</span> webpack = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack'</span>);
<span class="hljs-keyword">const</span> merge = <span class="hljs-built_in">require</span>(<span class="hljs-string">"webpack-merge"</span>);

<span class="hljs-keyword">const</span> MiniCssExtractPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mini-css-extract-plugin"</span>);
<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>);
<span class="hljs-keyword">const</span> CopyWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'copy-webpack-plugin'</span>);

<span class="hljs-keyword">const</span> APP_DIR = path.resolve(__dirname, <span class="hljs-string">'../src'</span>); <span class="hljs-comment">// &lt;===== new stuff added here</span>

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-params">env</span> =&gt;</span> {
  <span class="hljs-keyword">const</span> { PLATFORM, VERSION } = env;
  <span class="hljs-keyword">return</span> merge([
      {
        <span class="hljs-attr">entry</span>: [<span class="hljs-string">'@babel/polyfill'</span>, APP_DIR], <span class="hljs-comment">// &lt;===== new stuff added here</span>
        <span class="hljs-attr">module</span>: {
          <span class="hljs-attr">rules</span>: [
            {
              <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.js$/</span>,
              exclude: <span class="hljs-regexp">/node_modules/</span>,
              use: {
                <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel-loader'</span>
              }
            },
            {
              <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.scss$/</span>,
              use: [
                PLATFORM === <span class="hljs-string">'production'</span> ? MiniCssExtractPlugin.loader : <span class="hljs-string">'style-loader'</span>,
                <span class="hljs-string">'css-loader'</span>,
                <span class="hljs-string">'sass-loader'</span>
              ]
            }
          ]
        },
        <span class="hljs-attr">plugins</span>: [
          <span class="hljs-keyword">new</span> HtmlWebpackPlugin({
            <span class="hljs-attr">template</span>: <span class="hljs-string">'./src/index.html'</span>,
            <span class="hljs-attr">filename</span>: <span class="hljs-string">'./index.html'</span>
          }),
          <span class="hljs-keyword">new</span> webpack.DefinePlugin({ 
            <span class="hljs-string">'process.env.VERSION'</span>: <span class="hljs-built_in">JSON</span>.stringify(env.VERSION),
            <span class="hljs-string">'process.env.PLATFORM'</span>: <span class="hljs-built_in">JSON</span>.stringify(env.PLATFORM)
          }),
          <span class="hljs-keyword">new</span> CopyWebpackPlugin([ { <span class="hljs-attr">from</span>: <span class="hljs-string">'src/static'</span> } ]),
        ],
    }
  ])
};
</code></pre>
<p>Check <code>line no.8</code> and <code>line no.14</code> in the snippet added above.</p>
<p>By default Webpack 4 takes in entry point of <code>src/</code>. But if we want to have multiple entry points, we can customize the <code>entry</code> point as well. In my entry point I am just telling it two things:</p>
<pre><code>entry: [<span class="hljs-string">'@babel/polyfill'</span>, APP_DIR],
</code></pre><ul>
<li><code>@babel/polyfill</code> Babel plugin that includes a <a target="_blank" href="https://en.wikipedia.org/wiki/Polyfill_(programming)">polyfill</a> that includes a custom <a target="_blank" href="https://github.com/facebook/regenerator/blob/master/packages/regenerator-runtime/runtime.js">regenerator runtime</a> and <a target="_blank" href="https://github.com/zloirock/core-js">core-js</a>.</li>
<li><code>APP_DIR</code> the path to our <code>src/</code> folder which I wrote on <code>line no.8</code> <code>const APP_DIR = path.resolve(__dirname, ‘../src’);</code> All this line is doing is pointing to the path of <code>src/</code> folder in our <code>app/</code> folder.</li>
</ul>
<p>So the <code>entry</code> just takes in “points” as to what to compile.</p>
<p>Now that this is cleared up, let’s run the <code>npm run start</code> command again.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*KU6jA1T_EPqnCaV6JXQj-Q.png" alt="Image" width="800" height="344" loading="lazy">
<em>Our async/await method is working. Great :D</em></p>
<p>So far so good!</p>
<h4 id="heading-now-that-everything-is-set-up-lets-create-a-nodejs-server-using-expressjs">Now that everything is set up, let’s create a NodeJS server using ExpressJS.</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*RxqfJ9N01QH_K4BR-MRydg.gif" alt="Image" width="450" height="223" loading="lazy">
<em>In the immortal words of <strong>Khan Noonien Singh</strong></em></p>
<p>The first thing we have to install is Express, so in your terminal write this:</p>
<pre><code>npm install express --save
</code></pre><p>Or if you use <strong>yarn</strong> (like I do):</p>
<pre><code>yarn add express
</code></pre><p>Next in the root <code>app</code> folder create a new folder called <code>server</code>. Inside the folder create a <code>index.js</code> file like the one shown below:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);

<span class="hljs-keyword">const</span> app = express();

<span class="hljs-comment">// Point static path to dist</span>
app.use(<span class="hljs-string">'/'</span>, express.static(path.join(__dirname, <span class="hljs-string">'..'</span>, <span class="hljs-string">'dist'</span>)));
app.use(<span class="hljs-string">'/dist'</span>, express.static(path.join(__dirname, <span class="hljs-string">'..'</span>, <span class="hljs-string">'dist'</span>)));

<span class="hljs-keyword">const</span> routes = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./routes'</span>);

app.use(<span class="hljs-string">'/'</span>, routes);

<span class="hljs-comment">/** Get port from environment and store in Express. */</span>
<span class="hljs-keyword">const</span> port = process.env.PORT || <span class="hljs-string">'3000'</span>;
app.set(<span class="hljs-string">'port'</span>, port);

<span class="hljs-comment">/** Create HTTP server. */</span>
<span class="hljs-keyword">const</span> server = http.createServer(app);
<span class="hljs-comment">/** Listen on provided port, on all network interfaces. */</span>
server.listen(port, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server Running on port <span class="hljs-subst">${port}</span>`</span>));
</code></pre>
<p>Let’s discuss this code before we proceed further.</p>
<p>We instantiate our app with <code>express()</code> and then set up a static public folder called <code>**dist**</code><strong>.</strong> This is the same folder created by Webpack when we run our production command.</p>
<p>We include our <code>**routes**</code> file — we will create that in a second — and set the <code>**routes**</code> file to the <code>/</code> directory.</p>
<p>Next we set up a port. If none is provided via the node CLI, we use port <code>3000</code>. After that, we create an HTTP server and listen on that server via the port. At the very last, we console to our terminal that we are running the server on that certain port.</p>
<p>Let’s create our last file called <code>**routes/index.js**:</code></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
<span class="hljs-keyword">const</span> router = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>).Router();

router.get(<span class="hljs-string">'*'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> route = path.join(__dirname, <span class="hljs-string">'..'</span>, <span class="hljs-string">'..'</span>, <span class="hljs-string">'dist'</span>, <span class="hljs-string">'index.html'</span>);
  res.sendFile(route);
});

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<p>Here we check that whatever the user comes on, the path redirects the user to the <code>**dist/index.html**</code> where our React application lives.</p>
<p>And that’s it. We are done.</p>
<p>Now go in your terminal and type:</p>
<pre><code>npm run build
</code></pre><p>This will take a moment. It will show you the progress while it compiles. After that, it consoles a message that it is <code>listening to port 3000</code> if no port is provided.</p>
<p>Now go to your browser <code>http:localhost:3000/</code> and your application is alive.</p>
<p>Since we are at it, let’s talk in detail about what <code>npm run prebuild</code> and <code>npm run build</code> do.</p>
<p>Basically if we write the word <code>pre</code> for a script, in this case <code>prebuild</code>, every time we run our command <code>npm run build</code> it will first execute <code>npm run prebuild</code> and then run the script <code>npm run build</code> .</p>
<p>All <code>npm run build</code> does is run <code>node server/index.js</code> (You don’t have to write /index.js) in the command. NodeJS is smart enough to know it needs to run the <code>index.js</code> inside the <code>server</code> folder.</p>
<p>This sums up our NodeJS application setup as well.</p>
<p>One last topic to go. I’ll give a very brief overview on code splitting, and how you can achieve it.</p>
<h3 id="heading-code-splitting">Code Splitting</h3>
<p>At the start of this tutorial, we added <code>@babel/plugin-syntax-dynamic-import</code> This gives us the ability to lazily load our code inside our application.</p>
<p>Inside my <code>src/</code> folder, I am going to create a component called <code>Foo.js</code> which looks something like this.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> () =&gt; (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>I am Foo! Pleasure to meet you.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
);
</code></pre>
<p>Nothing special about Foo here.</p>
<p>The special thing starts when we include this component in our <code>src/index.js</code> file.</p>
<p>You might be thinking something like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> Foo <span class="hljs-keyword">from</span> <span class="hljs-string">'./Foo'</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
   state = {};
   render() {
      <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>I am App<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Foo</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
      )
   }
}
</code></pre>
<p>Well no, for a dynamic import we have to do this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">'./myStyles.scss'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  state = {
    <span class="hljs-attr">CaptainKirkBio</span>: {},
    <span class="hljs-attr">Foo</span>: <span class="hljs-literal">null</span>, <span class="hljs-comment">// Foo is out component</span>
  };

  componentDidMount() {
    <span class="hljs-built_in">this</span>.onGetKirkBio();
    <span class="hljs-keyword">import</span>(<span class="hljs-comment">/* webpackChunkName: 'Foo' */</span> <span class="hljs-string">'./Foo'</span>).then(<span class="hljs-function"><span class="hljs-params">Foo</span> =&gt;</span> {
      <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">Foo</span>: Foo.default });
    });
  }

  onGetKirkBio = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'http://stapi.co/api/v1/rest/character/search'</span>, {
        <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
        <span class="hljs-attr">headers</span>: {
          <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/x-www-form-urlencoded'</span>,
        },
        <span class="hljs-attr">body</span>: {
          <span class="hljs-attr">title</span>: <span class="hljs-string">'James T. Kirk'</span>,
          <span class="hljs-attr">name</span>: <span class="hljs-string">'James T. Kirk'</span>,
        },
      });
      <span class="hljs-keyword">const</span> resultJSON = <span class="hljs-keyword">await</span> result.json();
      <span class="hljs-keyword">const</span> character = resultJSON.characters[<span class="hljs-number">0</span>];
      <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">CaptainKirkBio</span>: character });
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'error'</span>, error);
    }
  };

  render() {
    <span class="hljs-keyword">const</span> { CaptainKirkBio, Foo } = <span class="hljs-built_in">this</span>.state;
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"app"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"header"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/dist/images/header.jpg"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"app-header"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
          We are a most promising species, Mr. Spock, as predators go. Did you know that? I
          frequently have my doubts. I dont. Not any more. And maybe in a thousand years or so will
          be able to prove it.
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>- Captain Kirk<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">section</span>&gt;</span>
          {Object.values(CaptainKirkBio).length === 0 ? (
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading User Information<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          ) : (
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">wordBreak:</span> '<span class="hljs-attr">break-all</span>' }}&gt;</span>{JSON.stringify(CaptainKirkBio)}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          )}
        <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
        {Foo ? <span class="hljs-tag">&lt;<span class="hljs-name">Foo</span> /&gt;</span> : <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Foo is loading<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }
}

ReactDOM.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'app'</span>));
</code></pre>
<p>Things to note here are in <code>line 9</code> <code>line 14, 15, 16</code> <code>line 40</code> <code>line 57</code>:</p>
<ul>
<li><code>Line 9</code>: We Set <code>Foo</code> as <code>null</code></li>
<li><code>Line 14, 15, 16</code> : As soon as our component mounts, we import our <code>&lt;Foo</code> /&gt; component</li>
</ul>
<p>Let’s talk more about this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span>(<span class="hljs-comment">/* webpackChunkName: 'Foo' */</span> <span class="hljs-string">'./Foo'</span>).then(<span class="hljs-function"><span class="hljs-params">Foo</span> =&gt;</span> {     
   <span class="hljs-built_in">this</span>.setState({<span class="hljs-attr">Foo</span>: Foo.default });    
})
</code></pre>
<p>Let’s break this down even more.</p>
<p><code>import(/* webpackChunkName: ‘Foo’ */ ‘./Foo’)</code> : This has 2 parts to it, we set a chunk name called <code>Foo</code> in <code>/* webpackChunkName: ‘Foo’ */</code>. You can call this whatever you want. What this does is when your application loads the <code>./Foo</code> file, it will get loaded by the name of <code>Foo</code> as defined in <code>/* webpackChunkName: ‘Foo’ */</code></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*DXWGMYT736qRci3pjmoz3A.png" alt="Image" width="800" height="247" loading="lazy">
<em><code>/* webpackChunkName: ‘Foo’ */ Try changing Foo to something else in the /* */</code> comment</em></p>
<p>This feature is called magic comments in webpack, because it’s lets you name the file when you load it in your code.</p>
<p>The other part of <code>import(/* webpackChunkName: ‘Foo’ */ ‘./Foo’)</code> is the <code>‘./Foo’</code> at the very end of the statement. This is the path from where we include our file.</p>
<p>This returns us a promise <code>.then(Foo =&gt;</code> {}). Since our export <code>of &lt;</code>Foo /<code>&gt; was expor</code>t default when we set our <code>sta</code>te of Foo we s<code>et it to this.setState({Foo: Foo.de</code>fault }); in order to assign the Foo component to the state variable Foo.</p>
<p><code>line 57</code> : This is where we display our <code>&lt;Foo</code> /&gt; component. Unless it is not loaded i.e, it is null, we show a loading message. And once we hav<code>e the &amp;</code>lt;Foo /&gt; component we show it.</p>
<p>And that, my friends, is code splitting.</p>
<p>I really do hope this was helpful for you. If it was please do let me know so that I can write more stuff like this. You can always reach me out on <a target="_blank" href="https://twitter.com/adeelibr"><strong>Twitter</strong></a> and again if you followed along till the end, I am really proud of you guys. YOU GUYS ARE ROCKING IT!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Blqgt4v2Nz8jUdg8O2RQTA.gif" alt="Image" width="488" height="200" loading="lazy"></p>
<hr>
<p>This article was originally published in Freecodecamp publication previously on Medium. <a target="_blank" href="https://medium.com/free-code-camp/how-to-combine-webpack-4-and-babel-7-to-create-a-fantastic-react-app-845797e036ff">Read here</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to use ReactJS with Webpack 4, Babel 7, and Material Design ]]>
                </title>
                <description>
                    <![CDATA[ By Nazare Emanuel Ioan For the past year and some, I have been working with React at Creative Tim. I have been using create-react-app for developing some nice products. There have been a lot of clients asking how can someone migrate our product templ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-reactjs-with-webpack-4-babel-7-and-material-design-ff754586f618/</link>
                <guid isPermaLink="false">66c355cad372f14b49bdcb62</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 10 Oct 2018 16:06:50 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*3XcVWZvLKvLukdJ2zbDDpQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nazare Emanuel Ioan</p>
<p>For the past year and some, I have been working with React at <a target="_blank" href="https://www.creative-tim.com/">Creative Tim</a>. I have been using <a target="_blank" href="https://github.com/facebook/create-react-app">create-react-app</a> for developing some nice products. There have been a lot of clients asking how can someone migrate our product templates on Webpack.</p>
<p>So after a number of requests, we created this little tutorial about how to start using <a target="_blank" href="https://reactjs.org/tutorial/tutorial.html">React</a> with <a target="_blank" href="https://webpack.js.org/concepts/">Webpack 4</a> and <a target="_blank" href="https://babeljs.io/docs/en">Babel 7</a>. At the end of the tutorial, I am going to show you guys how to add <a target="_blank" href="https://www.creative-tim.com/product/material-dashboard-react">Material Dashboard React</a> on top of the newly created app.</p>
<p>Before we get started please make sure you have the latest versions of <a target="_blank" href="https://www.npmjs.com/get-npm">npm</a> and <a target="_blank" href="https://nodejs.org/en/">Nodejs</a> installed globally on your machine. At the time of writing this post, the latest versions were 6.4.1 for npm and 8.12.0 (lts) for Nodejs on my machine.</p>
<h3 id="heading-creating-a-new-project-folder-with-packagejson">Creating a new project folder with package.json</h3>
<p>First things first, let’s create a <strong>new folder</strong> for our new <strong>app</strong> and enter it:</p>
<pre><code>mkdir react-webpack-babel-tutorialcd react-webpack-babel-tutorial
</code></pre><p>Now that we have created <strong>the folder</strong> in which we are going to develop the <strong>app</strong>, we need to add a <strong>package.json</strong> file to it. We can do this two ways and you should choose one of them:</p>
<ol>
<li>just create the <strong>package.json</strong> file without any other configuration:</li>
</ol>
<pre><code>npm init -y
</code></pre><p>As you can see, the <strong>package.json</strong> file has been created with some very basic information in it.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/C6yK7U8NQyAzlbp8UVom5nih2sDoa4uWSgGd" alt="Image" width="800" height="492" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/SxwoqQVgiOTRJMKEsCLYLaHZxOqX2ze-r1L6" alt="Image" width="800" height="408" loading="lazy">
<em><strong>npm init -y</strong> output</em></p>
<ol start="2">
<li>create the <strong>package.json</strong> file with some extra config settings</li>
</ol>
<pre><code>npm init
</code></pre><p>I’ve added some stuff to our newly created <strong>package.json</strong> file, such as some nice <strong>keywords</strong>, <strong>a repo</strong> and so on…</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/EwG79ZpRTwXbKsLwLRTQ0oG6IaJ2r7TYFUux" alt="Image" width="800" height="1058" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/kQl4c2u06gAReYzAZHUFJHQ0q7nKtyb13A4p" alt="Image" width="800" height="536" loading="lazy">
<em><strong>npm init</strong> output</em></p>
<p>After this, let’s add an <strong>index.html</strong> and <strong>index.js</strong> files to our new project folder, inside an <strong>src</strong> folder.</p>
<ol>
<li>Linux/MacOS commands</li>
</ol>
<pre><code>mkdir srctouch src/index.htmltouch src/index.js
</code></pre><ol start="2">
<li>Windows commands</li>
</ol>
<pre><code>mkdir srcecho <span class="hljs-string">""</span> &gt; src\index.htmlecho <span class="hljs-string">""</span> &gt; src\index.js
</code></pre><p>After this, let’s add the following template inside the <strong>index.html.</strong></p>
<pre><code>&lt;!DOCTYPE html&gt;&lt;html lang="en"&gt;  &lt;head&gt;    &lt;meta charset="utf-8"&gt;    &lt;meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"&gt;    &lt;meta name="theme-color" content="#000000"&gt;    &lt;title&gt;React Tutorial&lt;/title&gt;  &lt;/head&gt;  &lt;body&gt;    &lt;noscript&gt;      You need to enable JavaScript to run this app.    &lt;/noscript&gt;    &lt;div id="root"&gt;&lt;/div&gt;    &lt;!--      This HTML file is a template.      If you open it directly in the browser, you will see an empty page.      You can add webfonts, meta tags, or analytics to this file.      The build step will place the bundled scripts into the &lt;body&gt; tag.    --&gt;  &lt;/body&gt;&lt;/html&gt;
</code></pre><p>Let’s add something inside the <strong>index.js</strong> just for the sake of some showcase that we are going to see a bit further down.</p>
<pre><code>(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"hey mister"</span>);}());
</code></pre><p>And this is what we’ve got so far:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/S7g7x-2CQxrd7FMWFHhCeHBbhZnh0YCOsdNb" alt="Image" width="520" height="268" loading="lazy">
<em>folder project structure</em></p>
<h3 id="heading-adding-webpack-to-the-project">Adding Webpack to the project</h3>
<p>Let’s start adding all the <strong>Webpack</strong> packages that we are going to need. We are going to install them as <strong>devDependencies</strong> since they will be only used in development mode.</p>
<pre><code>npm install --save-dev webpack webpack-cli webpack-dev-server
</code></pre><ul>
<li><a target="_blank" href="https://www.npmjs.com/package/webpack"><strong>webpack</strong></a>  </li>
<li>used to configure our new app  </li>
<li>at the time of this post, the version was <strong><em>4.19.0</em></strong></li>
<li><a target="_blank" href="https://www.npmjs.com/package/webpack-cli"><strong>webpack-cli</strong></a>  </li>
<li>used so that we can use Webpack in the command line  </li>
<li>at the time of this post, the version was <strong><em>3.1.0</em></strong></li>
<li><a target="_blank" href="https://www.npmjs.com/package/webpack-dev-server"><strong>webpack-dev-server</strong></a>  </li>
<li>used so that when we make a change to a file inside our new app, we won’t need to refresh the page. It refreshes the browser page automatically every time we change a file in our app  </li>
<li>as its name says, it’s a server that is working non-stop  </li>
<li>at the time of this post, the version was <strong><em>3.1.8</em></strong></li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/3glsVLrGXniNvJktKumKkM5BSjuYUIyJyS92" alt="Image" width="800" height="180" loading="lazy">
<em><strong>npm install — save-dev webpack webpack-cli webpack-dev-server</strong> output</em></p>
<p>If we take a look inside the <strong>package.json</strong> file, we are going to see that these three packages were added to this file like so:</p>
<pre><code><span class="hljs-string">"devDependencies"</span>: {  <span class="hljs-string">"webpack"</span>: <span class="hljs-string">"^4.19.0"</span>,  <span class="hljs-string">"webpack-cli"</span>: <span class="hljs-string">"^3.1.0"</span>,  <span class="hljs-string">"webpack-dev-server"</span>: <span class="hljs-string">"^3.1.8"</span>}
</code></pre><p>I’m going to go ahead and delete the <strong><em>^</em></strong> (caret) from each version. This is because I can’t tell whether the next version of these plugins is still going to work with what I am building. I think this is something that should be common sense. When creating a new app, use the available versions and then, maybe make some updates to newer versions. You might not know what a new version will break in your app.</p>
<p>As you will see, the installation of these plugins made some changes to our project folder. It added <strong>node_modules</strong> folder and <strong>package-lock.json</strong> to it.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/qiz12CYpaSzAXjliX2tvca9fNMTUvD7bDDjj" alt="Image" width="480" height="380" loading="lazy">
<em>project folder after installing <strong>webpack</strong></em></p>
<p>Now, we need to add a new file to our project, the config file for <strong>Webpack</strong> called <strong>webpack.config.js</strong>:</p>
<ol>
<li>Linux/MacOS command</li>
</ol>
<pre><code>touch webpack.config.js
</code></pre><ol start="2">
<li>Windows command</li>
</ol>
<pre><code>echo <span class="hljs-string">""</span> &gt; webpack.config.js
</code></pre><p>Or you can simply manually create the new file if you do not want to use the command line.</p>
<p>Before we go ahead and start messing with the <strong>Webpack config</strong> file, let’s first install some stuff that we are going to need in our app.</p>
<p>First, we are going to work with some paths inside the Webpack config file. Let’s install <strong>path</strong> in our project as a <strong>devDependency.</strong></p>
<pre><code>npm install --save-dev path
</code></pre><p>Also, since we don’t want to manually inject the <strong>index.js</strong> file inside the HTML one, we are going to need a plugin called <strong>html-webpack-plugin. This plugin</strong> will inject the <strong>index.js</strong> inside the HTML file without any manual operation.</p>
<pre><code>npm install --save-dev html-webpack-plugin
</code></pre><p>Once again, I am going to edit my <strong>package.json</strong> file and delete all the <strong>^</strong> (caret) occurrences from it.</p>
<p>One more edit that we are going to make to our <strong>package.json</strong> is to add some new scripts inside the <strong>scripts</strong> object, after the <strong>test</strong> script (See the second example below).</p>
<pre><code><span class="hljs-string">"webpack"</span>: <span class="hljs-string">"webpack"</span>,<span class="hljs-string">"start"</span>: <span class="hljs-string">"webpack-dev-server --open"</span>
</code></pre><p>This is what your <strong>package.json</strong> should look like at this point:</p>
<pre><code>{  <span class="hljs-string">"name"</span>: <span class="hljs-string">"react-webpack-babel-tutorial"</span>,  <span class="hljs-string">"version"</span>: <span class="hljs-string">"1.0.0"</span>,  <span class="hljs-string">"description"</span>: <span class="hljs-string">"This is a Tutorial to showcase the usage of React with Webpack and Babel"</span>,  <span class="hljs-string">"main"</span>: <span class="hljs-string">"index.js"</span>,  <span class="hljs-string">"scripts"</span>: {    <span class="hljs-string">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,    <span class="hljs-string">"webpack"</span>: <span class="hljs-string">"webpack"</span>,    <span class="hljs-string">"start"</span>: <span class="hljs-string">"webpack-dev-server --open"</span>  },  <span class="hljs-string">"repository"</span>: {    <span class="hljs-string">"type"</span>: <span class="hljs-string">"git"</span>,    <span class="hljs-string">"url"</span>: <span class="hljs-string">"git+https://github.com/creativetimofficial/react-webpack-babel-tutorial.git"</span>  },  <span class="hljs-string">"keywords"</span>: [    <span class="hljs-string">"react"</span>,    <span class="hljs-string">"webpack"</span>,    <span class="hljs-string">"babel"</span>,    <span class="hljs-string">"creative-tim"</span>,    <span class="hljs-string">"material-design"</span>  ],  <span class="hljs-string">"author"</span>: <span class="hljs-string">"Creative Tim &amp;lt;hello@creative-tim.com&gt; (https://www.creative-tim.com/)"</span>,  <span class="hljs-string">"license"</span>: <span class="hljs-string">"MIT"</span>,  <span class="hljs-string">"bugs"</span>: {    <span class="hljs-string">"url"</span>: <span class="hljs-string">"https://github.com/creativetimofficial/react-webpack-babel-tutorial/issues"</span>  },  <span class="hljs-string">"homepage"</span>: <span class="hljs-string">"https://github.com/creativetimofficial/react-webpack-babel-tutorial#readme"</span>,  <span class="hljs-string">"devDependencies"</span>: {    <span class="hljs-string">"html-webpack-plugin"</span>: <span class="hljs-string">"3.2.0"</span>,    <span class="hljs-string">"path"</span>: <span class="hljs-string">"0.12.7"</span>,    <span class="hljs-string">"webpack"</span>: <span class="hljs-string">"4.19.0"</span>,    <span class="hljs-string">"webpack-cli"</span>: <span class="hljs-string">"3.1.0"</span>,    <span class="hljs-string">"webpack-dev-server"</span>: <span class="hljs-string">"3.1.8"</span>  }}
</code></pre><p>Let’s go ahead and run these commands one by one and see what happens.</p>
<pre><code>npm run webpack
</code></pre><p><strong>Webpack</strong> will automatically take the <strong>src/index.js</strong> file, compile it, and output it inside <strong>dist/main.js</strong> and will minify that code. This is because we haven’t yet configured the <strong>Webpack config</strong> file. Also, since we haven’t configured the file, we are going to have some warnings in our console.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/v15-OCKAfjb8luDhCWn5AwUSUw5ycEhKGhG1" alt="Image" width="800" height="388" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/bNMwYyHV30uBZh72CRyEwmK5OwxaQZ32u7Pu" alt="Image" width="536" height="500" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/GXJDfTYb1lD7ShgiDXWUmG1k2zS7CrefyiaX" alt="Image" width="800" height="207" loading="lazy">
<em><strong>npm run webpack</strong> output</em></p>
<p>If we run the other command</p>
<pre><code>npm start
</code></pre><p><strong>webpack-dev-server</strong> will automatically start a server and open the default browser with this server. But once again, since we do not have our <strong>webpack.config.js</strong> file configured, the output will not be the expected one.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/i3-94F8yjyeIuQK7BYDwf8cznxfp-30I4v7i" alt="Image" width="800" height="743" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/ekoyHmE44SRFZNtwnELPLhyHHlLgPKQMFH2I" alt="Image" width="774" height="556" loading="lazy">
<em>npm start output</em></p>
<p>If you want to stop the server, just press at the same time the <strong>CTRL</strong> + <strong>C</strong> keys while in the command line.</p>
<p>Let’s add the following template inside our <strong>Webpack config</strong> file:</p>
<pre><code><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);<span class="hljs-keyword">const</span> HtmlWebpackPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">'html-webpack-plugin'</span>);<span class="hljs-built_in">module</span>.exports = {  <span class="hljs-attr">entry</span>: path.join(__dirname,<span class="hljs-string">'src'</span>,<span class="hljs-string">'index.js'</span>),  <span class="hljs-attr">output</span>: {    <span class="hljs-attr">path</span>: path.join(__dirname,<span class="hljs-string">'build'</span>),    <span class="hljs-attr">filename</span>: <span class="hljs-string">'index.bundle.js'</span>  },  <span class="hljs-attr">mode</span>: process.env.NODE_ENV || <span class="hljs-string">'development'</span>,  <span class="hljs-attr">resolve</span>: {    <span class="hljs-attr">modules</span>: [path.resolve(__dirname, <span class="hljs-string">'src'</span>), <span class="hljs-string">'node_modules'</span>]  },  <span class="hljs-attr">devServer</span>: {    <span class="hljs-attr">contentBase</span>: path.join(__dirname,<span class="hljs-string">'src'</span>)  },  <span class="hljs-attr">plugins</span>: [    <span class="hljs-keyword">new</span> HtmlWebpackPlugin({      <span class="hljs-attr">template</span>: path.join(__dirname,<span class="hljs-string">'src'</span>,<span class="hljs-string">'index.html'</span>)    })  ]};
</code></pre><ul>
<li><strong>entry</strong> and <strong>output</strong><br>— these are used to tell our server what has to be compiled and from where (<em>entry: path.join(__dirname,’src’,’index.js’),</em>). It also tells where to put the outputted compiled version (<em>output</em> — the folder and the filename)</li>
<li><strong>mode</strong><br>— this is the mode of our output. We are setting it to ‘<em>development</em>’. If in the scripts we specify the <strong>NODE_ENV</strong> variable, it will take that one instead. See the below example on how to use <strong>NODE_ENV</strong> <em>(note that the below changes will not be made inside the <strong>package.json</strong> file in this tutorial, it is just an example for you to see how it works)</em></li>
</ul>
<pre><code><span class="hljs-string">"webpack"</span>: <span class="hljs-string">"NODE_ENV=production webpack"</span>,
</code></pre><ul>
<li><strong>resolve</strong><br>— this is used so that we can import anything from <strong>src</strong> folder in relative paths instead of absolute ones. It is the same for the <strong>node_modules.</strong> We can import anything from node_modules directly without absolute paths</li>
<li><strong>devServer</strong><br>— this tells the <strong>webpack-dev-server</strong> what files are needed to be served. Everything from our <strong>src</strong> folder needs to be served (outputted) in the browser</li>
<li><strong>plugins</strong><br>— here we set what plugins we need in our app. As of this moment we only need the <strong>html-webpack-plugin</strong> which tells the server that the <strong>index.bundle.js</strong> should be injected (or added if you will) to our <strong>index.html</strong> file</li>
</ul>
<p>If we now run the earlier commands we will see some differences.</p>
<pre><code>npm run webpack
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/5yaSP7i-hw1ukwiuQqM5S1YqtG7dmaO3vSTq" alt="Image" width="800" height="528" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/MpUjyMVp0Ia9P8rUNboekHJXeWUzzHOMjqjH" alt="Image" width="250" height="272" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/v9rZ1x9m41pTHXDHunyTa-pEi92Z0UBNYPNO" alt="Image" width="800" height="433" loading="lazy">
<em><strong>npm run webpack</strong> output with <strong>webpack.config.js</strong></em></p>
<p>We’ve changed where the output should be (from <strong>dist</strong> folder to <strong>build</strong> folder). By changing the <strong>mode</strong> of <strong>Webpack</strong>, now the code has a different look. It is not <strong>minified</strong> as the last time with no <strong>config</strong>.</p>
<pre><code>npm start
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/L43AkjlELlcrnI-pfDrNXo-XEvjTlvyY3GfP" alt="Image" width="800" height="922" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/vGrdllxByyx9DfMu2fvTlwwQYpoUOAV4kNTd" alt="Image" width="800" height="502" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/lZkAY5xg3uGXH7JLUf9wN3-mZKLm2X5183jx" alt="Image" width="800" height="502" loading="lazy">
<em><strong>npm start</strong> output with <strong>webpack.config.js</strong></em></p>
<p>The <strong>webpack-dev-server</strong> took everything from the <strong>src</strong> folder and outputted it to our browser.</p>
<p>We are on the right path, but we’ve only added Webpack to our project. Where are React and Babel? Well, that is what we are going to do next.</p>
<h3 id="heading-react-babel-and-some-nice-loaders-for-styles">React, Babel and some nice loaders for styles</h3>
<p>Add <strong>React</strong> and <strong>ReactDOM</strong> to our project as <strong>normal dependencies</strong>.</p>
<pre><code>npm install --save react react-dom
</code></pre><p>At this moment in our development, if we were to add <strong>React</strong> code inside our JS file, <strong>Webpack</strong> will give us an error. It doesn’t know how to compile <strong>React</strong> inside the <strong>bundle.js</strong> file.</p>
<p>Let’s modify the <strong>index.js</strong> file as follows:</p>
<pre><code><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom"</span>;<span class="hljs-keyword">let</span> HelloWorld = <span class="hljs-function">() =&gt;</span> {  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello there World!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>}ReactDOM.render(  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">HelloWorld</span>/&gt;</span></span>,  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>));
</code></pre><p>And after that let’s start the server again.</p>
<pre><code>npm start
</code></pre><p>And this is the error:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/WnrYazPSPDnZvmlOOvAIdz9GCagpszoEycZO" alt="Image" width="800" height="673" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/i4DEG4wPgI2a176rOq5CjXTydAUfJkMBWK0p" alt="Image" width="481" height="356" loading="lazy">
<em><strong>webpack</strong> error for not having appropriate <strong>loaders</strong> for <strong>react</strong></em></p>
<p>So this is where <strong>Babel</strong> comes to our aid. <strong>Babel</strong> will tell <strong>Webpack</strong> how to compile our <strong>React</strong> code.</p>
<p>Let’s go ahead and add a bunch of Babel packages to our app as <strong>devDependencies</strong>.</p>
<pre><code>npm install --save-dev @babel/core @babel/node @babel/preset-env @babel/preset-react babel-loader
</code></pre><ul>
<li><strong>@babel/core</strong><br>— this is used to compile <strong>ES6</strong> and above into <strong>ES5</strong></li>
<li><strong>@babel/node</strong><br>— this is used so that we can <strong>import</strong> our plugins and packages inside the <strong>webpack.config.js</strong> rather than <strong>require</strong> them (it’s just something that I like, and maybe you’ll like it too)</li>
<li><strong>@babel/preset-env</strong><br>— this will determinate which transformations or plugins to use and polyfills (i.e it provides modern functionality on older browsers that do not natively support it) based on the browser matrix you want to support</li>
<li><strong>@babel/preset-react</strong><br>— this is going to compile the <strong>React</strong> code into <strong>ES5</strong> code</li>
<li><strong>babel-loader</strong><br>— this is a <strong>Webpack</strong> helper that transforms your <strong>JavaScript</strong> dependencies with <strong>Babel</strong> (i.e. will transform the <strong>import</strong> statements into <strong>require</strong> ones)</li>
</ul>
<p>Since you are probably going to need to add some styles to your project (I know that I need them), we are going to add a loader that will let us <strong>import</strong> and use <strong>CSS</strong> files and <strong>SCSS</strong> files.</p>
<pre><code>npm install --save-dev style-loader css-loader sass-loader node-sass
</code></pre><ul>
<li><strong>style-loader</strong><br>— this will add to the <strong>DOM</strong> the styles (will inject a <strong>&lt;sty</strong>le&gt; tag insid<strong>e th</strong>e HTML file)</li>
<li><strong>css-loader</strong><br>— will let us import <strong>CSS</strong> files into our project</li>
<li><strong>sass-loader</strong><br>— will let us import <strong>SCSS</strong> files into our project</li>
<li><strong>node-sass</strong><br>— will compile the <strong>SCSS</strong> files into normal <strong>CSS</strong> files</li>
</ul>
<p>We are going to create a new <strong>SCSS</strong> file and add it to our folders.</p>
<ol>
<li>Linux/MacOS command</li>
</ol>
<pre><code>touch src/index.scss
</code></pre><ol start="2">
<li>Windows command</li>
</ol>
<pre><code>echo <span class="hljs-string">""</span> &gt; src/index.scss
</code></pre><p>And also add some nice styles to it.</p>
<pre><code>body {  div#root{    background-color: #<span class="hljs-number">222</span>;    color: #<span class="hljs-number">8</span>EE4AF;  }}
</code></pre><p>And change our <strong>index.js</strong> by adding an import for the <strong>SCSS</strong> file.</p>
<pre><code><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom"</span>;
</code></pre><pre><code><span class="hljs-comment">// this line is new// we now have some nice styles on our react appimport "index.scss";</span>
</code></pre><pre><code><span class="hljs-keyword">let</span> HelloWorld = <span class="hljs-function">() =&gt;</span> {  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello there World!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>}
</code></pre><pre><code>ReactDOM.render(  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">HelloWorld</span>/&gt;</span></span>,  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>));
</code></pre><p>Don’t forget to delete the carets (^) from <strong>package.json</strong>.</p>
<p>This is how your <strong>package.json</strong> should look like:</p>
<pre><code>{  <span class="hljs-string">"name"</span>: <span class="hljs-string">"react-webpack-babel-tutorial"</span>,  <span class="hljs-string">"version"</span>: <span class="hljs-string">"1.0.0"</span>,  <span class="hljs-string">"description"</span>: <span class="hljs-string">"This is a Tutorial to showcase the usage of React with Webpack and Babel"</span>,  <span class="hljs-string">"main"</span>: <span class="hljs-string">"index.js"</span>,  <span class="hljs-string">"scripts"</span>: {    <span class="hljs-string">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,    <span class="hljs-string">"webpack"</span>: <span class="hljs-string">"webpack"</span>,    <span class="hljs-string">"start"</span>: <span class="hljs-string">"webpack-dev-server --open"</span>  },  <span class="hljs-string">"repository"</span>: {    <span class="hljs-string">"type"</span>: <span class="hljs-string">"git"</span>,    <span class="hljs-string">"url"</span>: <span class="hljs-string">"git+https://github.com/creativetimofficial/react-webpack-babel-tutorial.git"</span>  },  <span class="hljs-string">"keywords"</span>: [    <span class="hljs-string">"react"</span>,    <span class="hljs-string">"webpack"</span>,    <span class="hljs-string">"babel"</span>,    <span class="hljs-string">"creative-tim"</span>,    <span class="hljs-string">"material-design"</span>  ],  <span class="hljs-string">"author"</span>: <span class="hljs-string">"Creative Tim &amp;lt;hello@creative-tim.com&gt; (https://www.creative-tim.com/)"</span>,  <span class="hljs-string">"license"</span>: <span class="hljs-string">"MIT"</span>,  <span class="hljs-string">"bugs"</span>: {    <span class="hljs-string">"url"</span>: <span class="hljs-string">"https://github.com/creativetimofficial/react-webpack-babel-tutorial/issues"</span>  },  <span class="hljs-string">"homepage"</span>: <span class="hljs-string">"https://github.com/creativetimofficial/react-webpack-babel-tutorial#readme"</span>,  <span class="hljs-string">"devDependencies"</span>: {    <span class="hljs-string">"@babel/core"</span>: <span class="hljs-string">"7.0.1"</span>,    <span class="hljs-string">"@babel/node"</span>: <span class="hljs-string">"7.0.0"</span>,    <span class="hljs-string">"@babel/preset-env"</span>: <span class="hljs-string">"7.0.0"</span>,    <span class="hljs-string">"@babel/preset-react"</span>: <span class="hljs-string">"7.0.0"</span>,    <span class="hljs-string">"babel-loader"</span>: <span class="hljs-string">"8.0.2"</span>,    <span class="hljs-string">"css-loader"</span>: <span class="hljs-string">"1.0.0"</span>,    <span class="hljs-string">"html-webpack-plugin"</span>: <span class="hljs-string">"3.2.0"</span>,    <span class="hljs-string">"node-sass"</span>: <span class="hljs-string">"4.9.3"</span>,    <span class="hljs-string">"path"</span>: <span class="hljs-string">"0.12.7"</span>,    <span class="hljs-string">"sass-loader"</span>: <span class="hljs-string">"7.1.0"</span>,    <span class="hljs-string">"style-loader"</span>: <span class="hljs-string">"0.23.0"</span>,    <span class="hljs-string">"webpack"</span>: <span class="hljs-string">"4.19.0"</span>,    <span class="hljs-string">"webpack-cli"</span>: <span class="hljs-string">"3.1.0"</span>,    <span class="hljs-string">"webpack-dev-server"</span>: <span class="hljs-string">"3.1.8"</span>  },  <span class="hljs-string">"dependencies"</span>: {    <span class="hljs-string">"react"</span>: <span class="hljs-string">"16.5.1"</span>,    <span class="hljs-string">"react-dom"</span>: <span class="hljs-string">"16.5.1"</span>  }}
</code></pre><p>If we run any of the above commands again, the error will still persist. We haven’t yet told <strong>Webpack</strong> that it should use <strong>Babel</strong> and the style loaders to compile our <strong>React</strong> and <strong>SCSS</strong> code.</p>
<p>Next thing to do is add a configuration file for <strong>Babel</strong>. For this we need to create a file named <strong>.babelrc</strong> in which we will configure <strong>Babel</strong>.</p>
<p>I’ve heard that you can add the configuration for <strong>Babel</strong> directly in the <strong>webpack.config.js</strong> file. For this, you can take a look at the <a target="_blank" href="https://github.com/babel/babel-loader">official babel-loader docs</a>. As far as I am concerned, I think it’s best to have the <strong>Babel</strong> config in its own file. That way you do not overcrowd your <strong>Webpack</strong> config.</p>
<p>So, let’s run in the command line the following:</p>
<ol>
<li>Linux/MacOS command</li>
</ol>
<pre><code>touch .babelrc
</code></pre><ol start="2">
<li>Windows command</li>
</ol>
<pre><code>echo <span class="hljs-string">""</span> &gt; .babelrc
</code></pre><p>And add the following code inside <strong>.babelrc</strong> so that <strong>babel-loader</strong> will know what to use to compile the code:</p>
<pre><code>{  <span class="hljs-string">"presets"</span>: [    <span class="hljs-string">"@babel/env"</span>,    <span class="hljs-string">"@babel/react"</span>  ]}
</code></pre><p>After these steps, we will need to add something to our project so we can import all sorts of files such as images. We will also need to add a plugin that will let us work with classes and much more. Let us add class properties in our classes. Basically, it will let us work with <a target="_blank" href="https://en.wikipedia.org/wiki/Object-oriented_programming">Object Oriented Programming</a> — nice.</p>
<pre><code>npm install --save-dev file-loader @babel/plugin-proposal-<span class="hljs-class"><span class="hljs-keyword">class</span>-<span class="hljs-title">properties</span></span>
</code></pre><p>Now that we have done this, we need to make some changes inside <strong>webpack.config.js</strong> so that <strong>Webpack</strong> will now use <strong>Babel</strong>. We’ll also configure <strong>Webpack</strong> to listen for <strong>style</strong> files and we are going to change the <strong>require</strong> statements to <strong>import</strong> ones.</p>
<p>So this being said, let’s change our <strong>webpack.config.js</strong> to the following (I’ve also added some comments, maybe they will help you):</p>
<pre><code><span class="hljs-comment">// old// const path = require('path');// const HtmlWebpackPlugin = require('html-webpack-plugin');// newimport path from 'path';import HtmlWebpackPlugin from 'html-webpack-plugin';module.exports = {  entry: path.join(__dirname,'src','index.js'),  output: {    path: path.join(__dirname,'build'),    filename: 'index.bundle.js'  },  mode: process.env.NODE_ENV || 'development',  resolve: {    modules: [path.resolve(__dirname, 'src'), 'node_modules']  },  devServer: {    contentBase: path.join(__dirname,'src')  },  module: {    rules: [      {        // this is so that we can compile any React,        // ES6 and above into normal ES5 syntax        test: /\.(js|jsx)$/,        // we do not want anything from node_modules to be compiled        exclude: /node_modules/,        use: ['babel-loader']      },      {        test: /\.(css|scss)$/,        use: [          "style-loader", // creates style nodes from JS strings          "css-loader", // translates CSS into CommonJS          "sass-loader" // compiles Sass to CSS, using Node Sass by default        ]      },      {        test: /\.(jpg|jpeg|png|gif|mp3|svg)$/,        loaders: ['file-loader']      }    ]  },  plugins: [    new HtmlWebpackPlugin({      template: path.join(__dirname,'src','index.html')    })  ]};</span>
</code></pre><p>There’s one more change we need to do to the <strong>package.json</strong> file. We need to tell our scripts that inside the config files of <strong>Webpack</strong>, we use <strong>import</strong> instead of <strong>require</strong> statements. Else it will give us an error that it doesn’t know what <strong>import</strong> stands for.</p>
<pre><code>{  <span class="hljs-string">"name"</span>: <span class="hljs-string">"react-webpack-babel-tutorial"</span>,  <span class="hljs-string">"version"</span>: <span class="hljs-string">"1.0.0"</span>,  <span class="hljs-string">"description"</span>: <span class="hljs-string">"This is a Tutorial to showcase the usage of React with Webpack and Babel"</span>,  <span class="hljs-string">"main"</span>: <span class="hljs-string">"index.js"</span>,  <span class="hljs-string">"scripts"</span>: {    <span class="hljs-string">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,    <span class="hljs-string">"webpack"</span>: <span class="hljs-string">"babel-node ./node_modules/webpack/bin/webpack"</span>,    <span class="hljs-string">"start"</span>: <span class="hljs-string">"babel-node ./node_modules/webpack-dev-server/bin/webpack-dev-server --open"</span>  },  <span class="hljs-string">"repository"</span>: {    <span class="hljs-string">"type"</span>: <span class="hljs-string">"git"</span>,    <span class="hljs-string">"url"</span>: <span class="hljs-string">"git+https://github.com/creativetimofficial/react-webpack-babel-tutorial.git"</span>  },  <span class="hljs-string">"keywords"</span>: [    <span class="hljs-string">"react"</span>,    <span class="hljs-string">"webpack"</span>,    <span class="hljs-string">"babel"</span>,    <span class="hljs-string">"creative-tim"</span>,    <span class="hljs-string">"material-design"</span>  ],  <span class="hljs-string">"author"</span>: <span class="hljs-string">"Creative Tim &lt;hello@creative-tim.com&gt; (https://www.creative-tim.com/)"</span>,  <span class="hljs-string">"license"</span>: <span class="hljs-string">"MIT"</span>,  <span class="hljs-string">"bugs"</span>: {    <span class="hljs-string">"url"</span>: <span class="hljs-string">"https://github.com/creativetimofficial/react-webpack-babel-tutorial/issues"</span>  },  <span class="hljs-string">"homepage"</span>: <span class="hljs-string">"https://github.com/creativetimofficial/react-webpack-babel-tutorial#readme"</span>,  <span class="hljs-string">"devDependencies"</span>: {    <span class="hljs-string">"@babel/core"</span>: <span class="hljs-string">"7.0.1"</span>,    <span class="hljs-string">"@babel/node"</span>: <span class="hljs-string">"7.0.0"</span>,    <span class="hljs-string">"@babel/plugin-proposal-class-properties"</span>: <span class="hljs-string">"7.0.0"</span>,    <span class="hljs-string">"@babel/preset-env"</span>: <span class="hljs-string">"7.0.0"</span>,    <span class="hljs-string">"@babel/preset-react"</span>: <span class="hljs-string">"7.0.0"</span>,    <span class="hljs-string">"babel-loader"</span>: <span class="hljs-string">"8.0.2"</span>,    <span class="hljs-string">"css-loader"</span>: <span class="hljs-string">"1.0.0"</span>,    <span class="hljs-string">"file-loader"</span>: <span class="hljs-string">"2.0.0"</span>,    <span class="hljs-string">"html-webpack-plugin"</span>: <span class="hljs-string">"3.2.0"</span>,    <span class="hljs-string">"node-sass"</span>: <span class="hljs-string">"4.9.3"</span>,    <span class="hljs-string">"path"</span>: <span class="hljs-string">"0.12.7"</span>,    <span class="hljs-string">"sass-loader"</span>: <span class="hljs-string">"7.1.0"</span>,    <span class="hljs-string">"style-loader"</span>: <span class="hljs-string">"0.23.0"</span>,    <span class="hljs-string">"webpack"</span>: <span class="hljs-string">"4.19.0"</span>,    <span class="hljs-string">"webpack-cli"</span>: <span class="hljs-string">"3.1.0"</span>,    <span class="hljs-string">"webpack-dev-server"</span>: <span class="hljs-string">"3.1.8"</span>  },  <span class="hljs-string">"dependencies"</span>: {    <span class="hljs-string">"react"</span>: <span class="hljs-string">"16.5.1"</span>,    <span class="hljs-string">"react-dom"</span>: <span class="hljs-string">"16.5.1"</span>  }}
</code></pre><p>Another thing that we will have to still add is the <strong>@babel/plugin-proposal-class-properties</strong> to the <strong>.babelrc</strong> file. Babel will know how to deal with class properties.</p>
<pre><code>{  <span class="hljs-string">"presets"</span>: [    <span class="hljs-string">"@babel/env"</span>,    <span class="hljs-string">"@babel/react"</span>  ],  <span class="hljs-string">"plugins"</span>: [    <span class="hljs-string">"@babel/plugin-proposal-class-properties"</span>  ]}
</code></pre><p>Now we are done. We can run either one of the above commands and it should not give us any errors. Let’s see them in action.</p>
<pre><code>npm run webpack
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/2e1EkHvGTSgkr6K8q0owtTeKfJgy9zaWv3qL" alt="Image" width="800" height="528" loading="lazy">
<em><strong>npm run webpack</strong> with no errors</em></p>
<p>And now let’s see the main script of our app.</p>
<pre><code>npm start
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/ZxgR7MwCMF07iPeCjljtUhjPho2POqJHttYP" alt="Image" width="800" height="920" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/wr9GAci8MufySHuCI9wf7IgfcBctM1Nc5TKo" alt="Image" width="600" height="400" loading="lazy">
<em><strong>npm start</strong> output</em></p>
<h3 id="heading-add-material-design-to-our-new-react-with-webpack-and-babel-project">Add Material Design to our new React with Webpack and Babel project</h3>
<p>As I’ve told you at the beginning of this post, we are not going to create from scratch styles for Material Design. That would require a lot of work. We don’t have time for that.</p>
<p>Instead, we are going to add a nice product that implements <a target="_blank" href="https://material.io/design/">Google’s Material Design</a> with some minor touches from the <a target="_blank" href="https://www.creative-tim.com/presentation">Creative Tim staff</a>. We are going to add <a target="_blank" href="https://www.creative-tim.com/product/material-dashboard-react">Material Dashboard React</a> to it.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/j0jyL4PSfmiVRF6ja4nue98YAAazqxWVM5P7" alt="Image" width="800" height="487" loading="lazy"></p>
<p>First things first, you need to get the product. Here are a few ways of getting the product:</p>
<ul>
<li>Clone the repo inside another folder:</li>
</ul>
<pre><code>git clone https:<span class="hljs-comment">//github.com/creativetimofficial/material-dashboard-react.git</span>
</code></pre><ul>
<li><a target="_blank" href="https://github.com/creativetimofficial/material-dashboard-react/archive/master.zip">Download from Github</a></li>
<li><a target="_blank" href="https://www.creative-tim.com/product/material-dashboard-react">Download from Creative Tim</a></li>
</ul>
<p>Ok, so now we have both projects — Material Dashboard React and our newly created one with <strong>Webpack</strong> and <strong>Babel —</strong> with <strong>React</strong>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/2vNjpDKZYsJcMG2FkMpEh3D1NMcE-l7zW9iM" alt="Image" width="540" height="144" loading="lazy">
<em><strong>material-dashboard-react</strong> and <strong>react-webpack-babel-tutorial</strong></em></p>
<p>Now, we can’t simply copy the src folder from <strong>Material Dashboard React</strong> into our new project. That will give us a lot of errors. Such as errors for missing dependencies, module not found, you get the point, a lot of errors.</p>
<p>So, I suggest that we start with adding the dependencies from <strong>Material Dashboard React</strong>’s <strong>package.json</strong> to our <strong>package.json</strong>. We do not need all the dependencies from <strong>Material Dashboard React’s</strong> packages, since we have built our own server using <strong>Webpack.</strong> We have added other style loaders beyond what the product has.</p>
<p>So this being said, we need the following:</p>
<pre><code>npm install --save @material-ui/core@<span class="hljs-number">3.1</span><span class="hljs-number">.0</span> @material-ui/icons@<span class="hljs-number">3.0</span><span class="hljs-number">.1</span> @types/googlemaps@<span class="hljs-number">3.30</span><span class="hljs-number">.11</span> @types/markerclustererplus@<span class="hljs-number">2.1</span><span class="hljs-number">.33</span> chartist@<span class="hljs-number">0.10</span><span class="hljs-number">.1</span> classnames@<span class="hljs-number">2.2</span><span class="hljs-number">.6</span> perfect-scrollbar@<span class="hljs-number">1.4</span><span class="hljs-number">.0</span> react-chartist@<span class="hljs-number">0.13</span><span class="hljs-number">.1</span> react-google-maps@<span class="hljs-number">9.4</span><span class="hljs-number">.5</span> react-router-dom@<span class="hljs-number">4.3</span><span class="hljs-number">.1</span> react-swipeable-views@<span class="hljs-number">0.12</span><span class="hljs-number">.15</span>
</code></pre><p>We are not going through all of them. They can be found on <a target="_blank" href="https://www.npmjs.com/">npmjs.com</a> with all the details and their own documentation.</p>
<p>Once again, we go inside the <strong>package.json</strong> file and delete the carets (^) from the packages that we just installed.</p>
<p>Ok, we are almost done. We are going to copy all the contents of the <strong>src</strong> folder from <strong>Material Dashboard React</strong> inside our project’s <strong>src</strong> folder and override the <strong>index.js</strong> file. But keep it in the <strong>index.html</strong> file.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/lu9OnRtupBWtPeeIjyHgyfYaxXTosauatNAR" alt="Image" width="532" height="532" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/23WMOaVa6tr6cHawZi1FIbUX8leJuTAc1kJL" alt="Image" width="554" height="842" loading="lazy">
<em>Folder structure before and after adding the Material Dashboard React <strong>src</strong> folder</em></p>
<p>Now we need to add some styles and fonts cdns inside our <strong>index.html</strong>.</p>
<pre><code>&lt;!DOCTYPE html&gt;&lt;html lang="en"&gt;  &lt;head&gt;    &lt;meta charset="utf-8"&gt;    &lt;meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"&gt;    &lt;meta name="theme-color" content="#000000"&gt;    &lt;link rel="stylesheet" href="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css"&gt;    &lt;script src="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"&gt;&lt;/script&gt;    &lt;link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons"&gt;    &lt;link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"&gt;    &lt;title&gt;React Tutorial&lt;/title&gt;  &lt;/head&gt;  &lt;body&gt;    &lt;noscript&gt;      You need to enable JavaScript to run this app.    &lt;/noscript&gt;    &lt;div id="root"&gt;&lt;/div&gt;    &lt;!--      This HTML file is a template.      If you open it directly in the browser, you will see an empty page.      You can add webfonts, meta tags, or analytics to this file.      The build step will place the bundled scripts into the &lt;body&gt; tag.    --&gt;  &lt;/body&gt;&lt;/html&gt;
</code></pre><p>And we are almost there. We still have a small problem. When we refresh the page, we have an error <strong>Cannot GET /dashboard<em>.</em></strong> If we navigate to another page we will get, for example, <strong>Cannot GET /user</strong> and so on. So basically, our routes do not work. We need to make some changes inside either <strong>src/index.js</strong> or inside our <strong>webpack.config.js</strong>.</p>
<p>I will choose the first option since it is pretty straightforward and easy to understand.</p>
<p>We navigate inside the new index.js and we change the history type. We put <strong>createHashHistory()</strong> instead of <strong>createBrowserHistory()</strong>.</p>
<p>This will allow us to refresh the page without any other errors. Now we are done.</p>
<pre><code><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom"</span>;<span class="hljs-keyword">import</span> { createHashHistory } <span class="hljs-keyword">from</span> <span class="hljs-string">"history"</span>;<span class="hljs-keyword">import</span> { Router, Route, Switch } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-router-dom"</span>;<span class="hljs-keyword">import</span> <span class="hljs-string">"assets/css/material-dashboard-react.css?v=1.5.0"</span>;<span class="hljs-keyword">import</span> indexRoutes <span class="hljs-keyword">from</span> <span class="hljs-string">"routes/index.jsx"</span>;<span class="hljs-keyword">const</span> hist = createHashHistory();ReactDOM.render(  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span> <span class="hljs-attr">history</span>=<span class="hljs-string">{hist}</span>&gt;</span>    <span class="hljs-tag">&lt;<span class="hljs-name">Switch</span>&gt;</span>      {indexRoutes.map((prop, key) =&gt; {        return <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">{prop.path}</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{prop.component}</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{key}</span> /&gt;</span>;      })}    <span class="hljs-tag">&lt;/<span class="hljs-name">Switch</span>&gt;</span>  <span class="hljs-tag">&lt;/<span class="hljs-name">Router</span>&gt;</span></span>,  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>));
</code></pre><p>I really hope you’ve liked this tutorial and I am very keen on hearing your thoughts about it. Just give this thread a comment and I’ll be more than happy to reply.</p>
<p>Special thanks should also go to <a target="_blank" href="https://pinglinh.com/">Linh Nguyen My</a> for her <a target="_blank" href="https://medium.freecodecamp.org/part-1-react-app-from-scratch-using-webpack-4-562b1d231e75">tutorial</a> which has given me some much needed understanding on <strong>Webpack</strong>.</p>
<p>Useful links:</p>
<ul>
<li>Get the code for this tutorial from <a target="_blank" href="https://github.com/creativetimofficial/react-webpack-babel-md-tutorial">Github</a></li>
<li>Read more about ReactJS on <a target="_blank" href="https://reactjs.org/">their official website</a></li>
<li>Read more about <a target="_blank" href="https://webpack.js.org/">Webpack here</a></li>
<li>Read more about Babel on <a target="_blank" href="https://babeljs.io/">this link here</a></li>
<li>Read more about <a target="_blank" href="https://material.io/">Material Design</a></li>
<li>Check out our platform to see <a target="_blank" href="https://www.creative-tim.com/">what we are doing</a> and <a target="_blank" href="https://www.creative-tim.com/presentation">who we are</a></li>
<li>Get Material Dashboard React from <a target="_blank" href="https://www.creative-tim.com/product/material-dashboard-react">www.creative-tim.com</a> or from <a target="_blank" href="https://github.com/creativetimofficial/material-dashboard-react">Github</a></li>
<li>Read more about <a target="_blank" href="https://material-ui.com/">Material-UI</a>, the core of Material Dashboard React</li>
</ul>
<p>Find me on:</p>
<ul>
<li>Email: <a target="_blank" href="mailto:manu@creative-tim.com">manu@creative-tim.com</a></li>
<li>Facebook: <a target="_blank" href="https://www.facebook.com/NazareEmanuel">https://www.facebook.com/NazareEmanuel</a></li>
<li>Instagram: <a target="_blank" href="https://www.instagram.com/manu.nazare/">https://www.instagram.com/manu.nazare/</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to setup TinyMCE in your Rails app using Webpack ]]>
                </title>
                <description>
                    <![CDATA[ By Joanna Gaudyn The popularity of using Webpack to deal with your assets in Rails is steadily increasing. Getting started is really straightforward. If you are starting a new app, you simply run rails new my_app --webpack and Rails takes care of the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-setup-tinymce-in-your-rails-app-using-webpack-edf030915332/</link>
                <guid isPermaLink="false">66c354b1c45f383e42e907ae</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rails ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 19 Sep 2018 07:08:22 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*5d_eDFKTmlTdYafG9dahdw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Joanna Gaudyn</p>
<p>The popularity of using Webpack to deal with your assets in Rails is steadily increasing. Getting started is really straightforward. If you are starting a new app, you simply run <code>rails new my_app --webpack</code> and Rails takes care of the rest.</p>
<p>Thanks to the <a target="_blank" href="https://github.com/rails/webpacker">webpacker gem</a>, adding Webpack to your existing application is also pretty uncomplicated. You add the gem to your Gemfile, bundle, and finally install webpacker:</p>
<pre><code>gem <span class="hljs-string">'webpacker'</span>, <span class="hljs-string">'~&gt; 3.5'</span>bundlebundle exec rails webpacker:install
</code></pre><p>This is pretty sweet. Now all you need to do is link your JavaScript pack and the CSS imported in it into the head of your <code>application.html.haml</code>:</p>
<pre><code>&lt;%= javascript_pack_tag <span class="hljs-string">'application'</span> %&gt; &lt;!-- js <span class="hljs-keyword">from</span> app/javascript/packs/application.js --&gt;
</code></pre><pre><code>&lt;%= stylesheet_pack_tag <span class="hljs-string">'application'</span> %&gt; &lt;!-- CSS imported via Wbpack --&gt;
</code></pre><p>Once this is done, you are ready to write your modern JavaScript code and make use of all the great libraries out there.</p>
<h3 id="heading-what-is-tinymce">What is tinyMCE?</h3>
<p>TinyMCE is a rich text editor in the cloud. To put it simply, it’s like Word that can be implemented into your app.</p>
<p>The project I am working on uses it to let admins edit the content of the front page. Thanks to TinyMCE, it isn’t necessary to build a separate admin interface for that purpose. But the editor’s usage can be much more versatile. Think, for example, of what Wordpress or Evernote allows you to do thanks to their build in tools.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*lUWdaoq0bkq3vDCrlzn4zQ.png" alt="Image" width="616" height="246" loading="lazy">
<em>Example use of TinyMCE. The power is in the user’s hands now.</em></p>
<h3 id="heading-usage-via-cdn">Usage via CDN</h3>
<p>We originally implemented the editor via CDN (e.g. linking the script in the head of our <code>application.html.haml</code>) like this:</p>
<pre><code>!!!%html  %head    %meta ... &lt;!-- some meta content --&gt;    %title ... &lt;!-- MyApp --&gt;    = csrf_meta_tags
</code></pre><pre><code>    %script{<span class="hljs-attr">src</span>: <span class="hljs-string">'https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=gexncjni90zx3qf0m5rr7kl8l40wd5yuly2xjza0g3kwrljt'</span>}    = stylesheet_link_tag <span class="hljs-string">'application'</span>, <span class="hljs-attr">media</span>: <span class="hljs-string">'all'</span>    = javascript_include_tag <span class="hljs-string">'application'</span>  %body    &lt;!-- the usual body stuff --&gt;
</code></pre><p>This required adding a file with our customized function in <code>app/assets/javascript/tinyMce.js</code>. Note that we are also using jQuery.</p>
<pre><code>$( <span class="hljs-built_in">document</span> ).on(<span class="hljs-string">'turbolinks:load'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
</code></pre><pre><code>    tinyMCE.init({         <span class="hljs-attr">selector</span>: <span class="hljs-string">'textarea.tinymce'</span>,             <span class="hljs-comment">// some other settings, like height, language,         // order of buttons on your toolbar etc.             plugins: [            'table', 'lists' // whatever plugins you want to add        ]    });});</span>
</code></pre><p>In addition to that, we had to include a <a target="_blank" href="https://www.tiny.cloud/download/language-packages/">translation file</a> (which is not necessary if you’re using English in your app). For everything to display correctly in production, you’ll also need to get a free <a target="_blank" href="https://apps.tiny.cloud/signup/">Tiny Cloud API key</a> .</p>
<h3 id="heading-webpack-and-tinymce">Webpack and tinyMCE</h3>
<p>Everything was working great for a couple of months, but we decided that it was time for the transition towards Webpack.</p>
<p>Webpack is supposed to make your life easier and, coupled with yarn, lets you focus on the important stuff. Say you want to use package A. It so happens, that package A relies on packages B and C. And package B depends on D, E and F. Rather than spending hours figuring out what the dependencies are and installing them all individually, what you want is to say <code>yarn add package-A</code>, and have it figured out for you. And this is <em>almost</em> the case.</p>
<p>This transition when it came to tinyMCE was way more painful than it should have been. And that’s why I decided to write this post. I hope it saves someone some time and frustration.</p>
<p><strong>If you previously had tinyMCE implemented via CDN</strong>, you’d like to get rid of some stuff, to start clean. Remove the script link from <code>application.html.haml</code>. Then comment out the content of the <code>tinyMce.js</code> file (and the language file if you’re using one). I also decided to get rid of the jQuery dependency (in our case it meant removing <code>gem 'jquery-rails'</code> from the Gemfile, and in the <code>app/assets/javascripts/application.js</code> removing <code>//= require jquery</code> and replacing <code>//= require jquery_ujs</code> with <code>//= require rails-ujs</code>).</p>
<p>Note: Proceed with caution if you have more external libraries in your project that rely on jQuery (e.g. Bootstrap or Select2). Ultimately your goal would probably be to move all of them to Webpack, but the bigger the project, the more complex that task could be, so just bear it in mind. Nothing stops you from keeping your traditional implementation parallel with the Webpack one. In that case I would still recommend commenting it out for the time of tinyMCE implementation.</p>
<p>All these steps will ensure that things we’ll be implementing from now on work, and the old implementation doesn’t function as a fallback.</p>
<h4 id="heading-step-1-if-you-want-to-use-jquery-via-webpack"><strong>Step 1. If you want to use jQuery via webpack</strong></h4>
<p>Adding jQuery through Webpack is as simple as running <code>yarn add jquery</code> and adding the following code to the <code>config/webpack/environment.js</code>:</p>
<pre><code><span class="hljs-keyword">const</span> { environment } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@rails/webpacker'</span>)<span class="hljs-keyword">const</span> webpack = <span class="hljs-built_in">require</span>(<span class="hljs-string">'webpack'</span>)environment.plugins.prepend(<span class="hljs-string">'Provide'</span>,  <span class="hljs-keyword">new</span> webpack.ProvidePlugin({    <span class="hljs-attr">$</span>: <span class="hljs-string">'jquery'</span>,    <span class="hljs-attr">jQuery</span>: <span class="hljs-string">'jquery'</span>  }))<span class="hljs-built_in">module</span>.exports = environment
</code></pre><h4 id="heading-step-2-get-the-tinymce-package"><strong>Step 2. Get the tinyMCE package</strong></h4>
<p>That is also pretty straightforward: run <code>yarn add tinymce</code>.</p>
<p>Then create a new file where we’ll place our function. I ended up with <code>app/javascript/vendor/tinyMce.js</code> with the following content:</p>
<pre><code><span class="hljs-keyword">import</span> tinymce <span class="hljs-keyword">from</span> <span class="hljs-string">'tinymce/tinymce'</span>;<span class="hljs-keyword">import</span> <span class="hljs-string">'tinymce/themes/modern/theme'</span>;<span class="hljs-keyword">import</span> <span class="hljs-string">'tinymce/plugins/table'</span>;<span class="hljs-keyword">import</span> <span class="hljs-string">'tinymce/plugins/lists'</span>;
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tinyMce</span>(<span class="hljs-params"></span>) </span>{    tinymce.init({        <span class="hljs-attr">selector</span>: <span class="hljs-string">'textarea.tinymce'</span>,
</code></pre><pre><code>        <span class="hljs-comment">// some other settings, like height, language,         // order of buttons on your toolbar etc.</span>
</code></pre><pre><code>        plugins: [            <span class="hljs-string">'table'</span>, <span class="hljs-string">'lists'</span>        ]    });}
</code></pre><pre><code><span class="hljs-comment">// if you're using a language file, you can place its content here</span>
</code></pre><pre><code><span class="hljs-keyword">export</span> { tinyMce };
</code></pre><h4 id="heading-step-3-import-everything-to-the-applicationjs"><strong>Step 3. Import everything to the <code>application.js</code></strong></h4>
<p>We can import our function like so:</p>
<p><code>import { tinyMce } from "../vendor/tinyMce";</code></p>
<p>and then call it:</p>
<pre><code><span class="hljs-built_in">document</span>.addEventListener(“turbolinks:load”, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{    tinyMce(); });
</code></pre><p>As you can see, we also replaced the jQuery code with ES6.</p>
<h4 id="heading-step-4-get-the-tinymce-skin-to-work"><strong>Step 4. Get the tinyMCE skin to work</strong></h4>
<p>If you run your <code>webpack-dev-server</code> and <code>rails s</code> you might be surprised to see that your text editor is not there. One look in the console and you’ll see the following error:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*fCntK4ZDJtVxvGobG4V0oA.png" alt="Image" width="710" height="53" loading="lazy"></p>
<p>This is because tinyMCE will not work without a skin, and pulling it in through Webpack requires its explicit import. We can do this by including this line in our <code>tinyMce.js</code> file, right after the other import statements. The path is relative to the <code>node_modules</code> folder:</p>
<pre><code><span class="hljs-keyword">import</span> ‘tinymce/skins/lightgray/skin.min.css’;
</code></pre><p><strong>At this point you should have your editor working.</strong></p>
<p>But… if you look into the console, you might be disappointed to see that you are still getting 2 errors:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*uOpqUB3N2qAIzuDH1zRNOw.png" alt="Image" width="800" height="59" loading="lazy"></p>
<p>Don’t despair! There is an easy fix. Just add <code>skin: false</code> to your <code>function tinyMce()</code> config and it should do the trick. This will prevent the default files from loading.</p>
<p>Congrats! You just got your tinyMCE up and running!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Webpack by example: simple code-splitting in a vanilla JavaScript app ]]>
                </title>
                <description>
                    <![CDATA[ By Kalalau Cantrell Using webpack 4 and dynamic imports A tasty split This article is part of an episodic guide for learning Webpack through various examples. If you need a refresher on what loaders and plugins are as far as Webpack goes, or what a ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-webpack-by-example-simple-code-splitting-in-a-vanilla-javascript-app-b366798336a4/</link>
                <guid isPermaLink="false">66c359edd372f14b49bdcbe5</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UX ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 10 Sep 2018 19:00:23 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*omrsDb09E3ZcHc9lQmTCJw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Kalalau Cantrell</p>
<h4 id="heading-using-webpack-4-and-dynamic-imports">Using webpack 4 and dynamic imports</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*omrsDb09E3ZcHc9lQmTCJw.jpeg" alt="Image" width="800" height="533" loading="lazy">
<em>A tasty split</em></p>
<p>This article is part of an episodic guide for learning Webpack through various examples. If you need a refresher on what <strong>loaders</strong> and <strong>plugins</strong> are as far as Webpack goes, or what a basic <code>webpack.config.js</code> file looks like, check out <a target="_blank" href="https://medium.freecodecamp.org/learn-webpack-by-example-blurred-placeholder-images-4ad8b1751709">this article</a> I wrote that focuses on those basics.</p>
<p>If you are like I was, you have heard the term code-splitting before and have <a target="_blank" href="https://webpack.js.org/guides/code-splitting/">read some</a> about it. But perhaps you kept running into posts about how to do it with this or that framework, rather than explanations of what is it for, and a basic example showing that purpose.</p>
<p>Although I highly value frameworks and the speed and structure they bring to coding, especially within teams, I also value understanding programming concepts as deeply as is practically possible.</p>
<p>This often means that if I’m trying to learn a new concept, I will try to decompose that concept into smaller sub-concepts and then study each in isolation before integrating them all together.</p>
<p>To use a non-programming example, if wanted to learn how to longboard, I’d want to focus heavily on just keeping my balance while standing on the longboard before I worry about going fast, doing tricks, or customizing my longboard setup.</p>
<p>So, to learn about code-splitting, I decided that I wanted to make as small and easy of an app as possible, which for me meant no frameworks and nothing fancy.</p>
<h3 id="heading-app-overview">App overview</h3>
<p>I want to share the little app that I made to help me explore code-splitting with Webpack. My hope is that it may help you better understand the topic as well. All we’re going to do is make the single page app depicted in the below gif.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*PAgEvQIem4yR82UpPZfpVg.gif" alt="Image" width="800" height="625" loading="lazy">
<em>A tasty route</em></p>
<p>If you want to follow along in your code editor, check out the code in the <code>code-split</code> branch of <a target="_blank" href="https://github.com/klcantrell/webpack-through-example-blog">this repo</a>. Once you install the packages, <code>npm start</code> will run a development server for you if you want to see the code-splitting in action.</p>
<p>Our app has two routes — a <strong>home</strong> route, which the user starts off on, and a <strong>tasty</strong> route. The view for the <strong>home</strong> route is very basic — just a header and a link to the <strong>tasty</strong> route.</p>
<p>The view for the <strong>tasty</strong> route, however, has much more going on. It features a delightful donut animation made with SVG and all the markup and CSS that goes along with that kind of thing. That is a lot of code compared to our <strong>home</strong> route. P.S. thanks <a target="_blank" href="https://codepen.io/benvisser/">Ben Visser</a> for creating the animation.</p>
<p>Does it make sense to have the user download <em>all</em> the code for this app right away, including the code for the <strong>tasty</strong> route and its animation? Only if you were interested in causing slow initial load times and frustration, not to mention fear of missing out on what could have happened if the user stuck around for your app to load ;). So, let’s figure out how to code-split this thing.</p>
<p>First, however, is a high-level overview of the code behind the app. The app is written in vanilla JS. I only used one external library, <code>[navigo](https://www.npmjs.com/package/navigo)</code>, to handle our client-side routing. Let’s look at the <code>index.js</code> file:</p>
<p>And here’s what the <code>App</code> module does:</p>
<p>And here’s an example of a UI component, our <code>Home</code> component:</p>
<h3 id="heading-no-code-splitting">No code-splitting</h3>
<p>Without code-splitting, you would be sending your user one big bundle of code when they initially load your app. Let’s establish a baseline by looking at the size of our bundle here with no code-splitting.</p>
<p>You can see in the image below that the size of our bundle is <strong>22.8K</strong>. Although that’s not very big compared to real apps in the world, let’s pretend it is for the sake of learning.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*_nm-Y524qO9uVDh-NEr5EQ.gif" alt="Image" width="800" height="416" loading="lazy"></p>
<h3 id="heading-code-splitting-with-dynamic-imports">Code-splitting with dynamic imports</h3>
<p>Now let’s bring in the code-splitting! Remember, what we want to do is keep the user from having to download the code needed to render the <strong>tasty</strong> route until it is needed.</p>
<p>To accomplish this, we our going to use a feature that is coming to JavaScript called <strong>dynamic imports</strong>. Even though the feature hasn’t landed in the ECMAScript spec yet, Webpack and Babel allow us to use it now.</p>
<p>A dynamic import allows us to asynchronously fetch a module. It returns a promise. Within the promise callback, we can specify what to do with the module once it’s loaded. The syntax for a dynamic import looks like this:</p>
<pre><code><span class="hljs-keyword">import</span>(<span class="hljs-string">'./path/to/module'</span>)
</code></pre><p>When Webpack sees a dynamic import like this, it does not bundle up the imported module into the current bundle. Instead, it splits the bundle into two smaller chunks.</p>
<p>The current chunk may be synchronously loaded (like our initial page load), but the module that is imported by our dynamic import is asynchronously loaded. In our case, the module for the <strong>tasty</strong> route is loaded when the user vists that route.</p>
<p>In order to access the dynamic import feature, we’ll need to <code>npm install</code> a few Babel packages into our build process: <code>babel-core</code>, <code>babel-loader</code> and <code>babel-plugin-syntax-dynamic-import</code> are definitely needed.</p>
<p>Depending on the browser you’re using, you may not need <code>babel-preset-env</code> (i.e. the current version of Chrome supports all the other JavaScript syntax we’re using) but let’s get it anyway just for good measure.</p>
<p>Then, we configure Webpack for Babel:</p>
<p>So finally, we can write our dynamic import:</p>
<p>Here’s what this code says to do: when the <strong>tasty</strong> route is triggered, first fetch the <code>Tasty</code> component. Then, once it finishes loading, render it to the page.</p>
<p>Let’s see what this does for us. In the image below, you can see that the initial page load now downloads a bundle that’s <strong>10.8K</strong> instead of <strong>22.8K</strong> — much better! Then, when the user clicks to go to the <strong>tasty</strong> route, another bundle chunk of <strong>13.6K</strong> is downloaded.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*AcjPAOjrzFkj0eVZ9FINKQ.gif" alt="Image" width="800" height="390" loading="lazy"></p>
<p>Webpack automatically names these chunks — if you want control over that, check out <a target="_blank" href="https://webpack.js.org/api/module-methods/#import-">this section</a> of the webpack docs.</p>
<h3 id="heading-ux-improvements">UX improvements</h3>
<p>It’s great that we’ve saved the user from having to wait extra time for the page to initially load. But, can you guess what would happen if the user was on a super slow connection and tried to load the <strong>tasty</strong> route?</p>
<p>With the way we currently have things setup, the page would just hang there until the <code>Tasty</code> module fully loaded. These few moments of hanging might leave the user wondering if our app was even working.</p>
<p>Let’s improve this experience by giving the user some signal that our app is doing something while they wait:</p>
<p>Now, our app will show a loading spinner while the <code>Tasty</code> component loads. While this may increase the size of our initial bundle some, it gives the user an indication that something is going on while they wait.</p>
<p>This trade off exchanges some performance for a better user experience — finding that balance is what it’s all about!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*rVRdOSa88XmWID8yzDwl2Q.gif" alt="Image" width="800" height="391" loading="lazy"></p>
<h3 id="heading-conclusion-and-further-reading">Conclusion and further reading</h3>
<p>I hope this example served as a simple portrayal of the benefit of code-splitting as well as how to use a tool like Webpack to help you do it.</p>
<p>I also hope it showed that code-splitting is not a technique that’s useful just for certain frameworks. In fact, vanilla JS apps can make use of code-splitting, and even apps that are mostly server-rendered but have interactive widgets embedded here and there can make use of the technique.</p>
<p>If you want to dive deeper into some granular code-splitting that webpack lets you do, look into the <code>[optimization.splitChunks](https://webpack.js.org/plugins/split-chunks-plugin/)</code> plugin that comes with webpack 4.</p>
<p><strong>Please clap if this helped you learn something, comment below with any questions, and feel free to say hi to <a target="_blank" href="https://twitter.com/kalalaucantrell">me</a> on Twitter.</strong></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to compile Sass files in Visual Studio and Webpack ]]>
                </title>
                <description>
                    <![CDATA[ By Esau Silva Sass is a very popular CSS pre-processor. The intent of this tutorial is to show you how to compile Sass files within Visual Studio using Webpack. Our discussion will include minification and autoprefixing for production. Visual Studio... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-compile-sass-files-in-visual-studio-and-webpack-6e45cdc1c14c/</link>
                <guid isPermaLink="false">66d45e3c9208fb118cc6cf8f</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Sass ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ visual studio ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webpack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 07 Sep 2018 16:38:25 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*-rQU7AOJC3p-ZbiEQnYYlw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Esau Silva</p>
<p>Sass is a very popular CSS pre-processor. The intent of this tutorial is to show you how to compile Sass files within Visual Studio using Webpack. Our discussion will include minification and autoprefixing for production.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/3k12b5dvlT4iN20sLPdB9W064Z6R7tSYIuX7" alt="Image" width="800" height="197" loading="lazy">
<em>Visual Studio meets Sass</em></p>
<p>Sure, there are some plug-ins in the Visual Studio Marketplace, and it can be nice to just install a plug-in and forget about configuration. But what happens if the plug-in is not supported anymore and stops working with newer Visual Studio versions? Well, too bad. This is the case with one of the most popular compiler plug-ins on the market.</p>
<p>By configuring the compilation yourself, you will have total control over the output. Also, vendor prefixes will be added automatically to your CSS rules. How cool is that?</p>
<h4 id="heading-prerequisites">Prerequisites</h4>
<p>You will need to have Node installed, and you can grab it <a target="_blank" href="https://nodejs.org/en/">here</a>. That’s it really. You’ll also need npm, but it will also be installed with Node.</p>
<h3 id="heading-creating-the-project">Creating the Project</h3>
<p><strong>Note:</strong> We will be creating a .NET Core MVC app, but the same principles apply to any ASP.NET MVC app. You would just need to modify the Webpack configuration a little bit to output the CSS file to the <code>Content</code> directory.</p>
<p>Open Visual Studio and create a new <strong>ASP.NET Core Web Application</strong>, then select <strong>Web Application (Model-View-Controller)</strong>. I’m naming my project <em>netcore-sass-webpack</em>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/aiZk0QmUZvH0pLbYz4NJQDjsubLYGjSu3D7S" alt="Image" width="800" height="555" loading="lazy">
<em>Creating the project</em></p>
<p>Create a <code>Styles</code> folder within the root of the project. Inside it, create a Sass file and name it <code>site.scss</code>. Open this new Sass file and copy the following:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\ 
for details on configuring this project to bundle and minify static web assets. */</span>
<span class="hljs-selector-tag">body</span> {
    <span class="hljs-attribute">padding-top</span>: <span class="hljs-number">50px</span>;
    <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#D69655</span> <span class="hljs-built_in">url</span>(<span class="hljs-string">'../wwwroot/images/pattern.png'</span>) repeat;
}

<span class="hljs-comment">/* Wrapping element */</span>
<span class="hljs-comment">/* Set some basic padding to keep content from hitting the edges */</span>
<span class="hljs-selector-class">.body-content</span> {
    <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">15px</span>;
    <span class="hljs-attribute">padding-right</span>: <span class="hljs-number">15px</span>;
}

<span class="hljs-comment">/* Carousel */</span>
<span class="hljs-selector-class">.carousel-caption</span> <span class="hljs-selector-tag">p</span> {
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.4</span>;
}

<span class="hljs-comment">/* Make .svg files in the carousel display properly in older browsers */</span>
<span class="hljs-selector-class">.carousel-inner</span> <span class="hljs-selector-class">.item</span> <span class="hljs-selector-tag">img</span><span class="hljs-selector-attr">[src$=<span class="hljs-string">".svg"</span>]</span> {
    <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
}

<span class="hljs-comment">/* QR code generator */</span>
<span class="hljs-selector-id">#qrCode</span> {
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">15px</span>;
}

<span class="hljs-comment">/* Hide/rearrange for smaller screens */</span>
<span class="hljs-keyword">@media</span> screen <span class="hljs-keyword">and</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">767px</span>) {
    <span class="hljs-comment">/* Hide captions */</span>
    <span class="hljs-selector-class">.carousel-caption</span> {
        <span class="hljs-attribute">display</span>: none;
    }
}
</code></pre>
<p>You will notice that this is the same CSS provided by Visual Studio when we created the project, with the exception of the <code>background</code> rule in the <code>body</code> tag. Now delete the provided CSS located under <code>wwwroot/css</code> (both files: <code>site.css</code> and <code>site.min.css</code>). Don’t worry, we will auto-generate these with Webpack.</p>
<p>Now, download <a target="_blank" href="https://github.com/esausilva/netcore-sass-webpack/tree/master/netcore-sass-webpack/wwwroot/images">pattern.png</a> and place it under <code>wwwroot/images</code>.</p>
<p>Create an empty JavaScript file under the root of the application and name it <code>webpack.config.js</code>. We will take care of this later. You should end up with the following project structure:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/jLrFCNq5AeHVD47jJDIveoOzJgDw6zkryxt3" alt="Image" width="305" height="567" loading="lazy">
<em>Project Structure</em></p>
<p><strong>Note:</strong> You don’t need to do the following two steps for every project, just once (unless you un-install and re-install Visual Studio).</p>
<p>You will need to provide Visual Studio with the Node installation path. Go back to your project and select <strong>Tools -&gt; Optio</strong>ns on the left pa<strong>ne Projects and Solutions -&gt; Web Package Mana</strong>gement and add the path to Node installation at the top of the l<code>ist ( C:\Program Files\</code>node<code>js or C:\Program Files (x86)\</code>nodejs, depending if you installed the x64 or x86 version).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/J8sJYylsXyYm2gZ2V3Nma4bvABRfJdefnldJ" alt="Image" width="800" height="233" loading="lazy">
<em>Node path</em></p>
<p>Finally download <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=MadsKristensen.NPMTaskRunner">NPM Task Runner</a> and install it — but you will need to close Visual Studio first.</p>
<h3 id="heading-webpack-and-npm-dependencies">Webpack and NPM Dependencies</h3>
<p>Open <strong>Command Prompt</strong> and navigate to the root of the project and install the needed dependencies:</p>
<pre><code>cd netcore-sass-webpack\netcore-sass-webpack
npm init -y
npm i -D webpack webpack-cli node-sass postcss-loader postcss-preset-env sass-loader css-loader cssnano mini-css-extract-plugin cross-env file-loader
</code></pre><p>The first <code>npm</code> command initializes your <code>package.json</code> and the second installs your dependencies.</p>
<ul>
<li><strong>webpack, webpack-cli</strong> — Module bundler</li>
<li><strong>node-sass</strong> — Bindings for Node to LibSass; provides support for Sass</li>
<li><strong>postcss-loader, postcss-preset-env</strong> — PostCSS loader for Webpack to process autoprefixing and minification</li>
<li><strong>sass-loader, css-loader</strong> — Webpack needs specific loaders to support Sass and CSS</li>
<li><strong>cssnano</strong> — CSS minifier</li>
<li><strong>mini-css-extract-plugin</strong> — Extracts the CSS to a separate file</li>
<li><strong>cross-env</strong> — Provides support to Windows users for environment variables. We will use NODE_ENVenvironment variable</li>
<li><strong>file-loader</strong> — Provides support for files (images) in our CSS rules</li>
</ul>
<p>At this point you can re-open the project in Visual Studio. After the project finishes loading, open <code>package.json</code> and add the following scripts:</p>
<pre><code class="lang-js"><span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"dev"</span>: <span class="hljs-string">"webpack --watch"</span>,
    <span class="hljs-string">"build"</span>: <span class="hljs-string">"cross-env NODE_ENV=production webpack"</span>
  },
</code></pre>
<ul>
<li><strong>dev</strong> — We will bind this script whenever the project opens, and Webpack will continually watch for changes to the source Sass files, compile them, and output the separate CSS file</li>
<li><strong>build</strong> — We will bind this script before each project build and will produce the production CSS file, including minification and autoprefixing</li>
</ul>
<p><strong>Note:</strong> The NPM scripts will run automatically using the <strong>Task Runner</strong> window. More on that later.</p>
<p>It is time to work on our Webpack configuration. Open <code>webpack.config.js</code> and copy the following:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);
<span class="hljs-keyword">const</span> MiniCssExtractPlugin = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mini-css-extract-plugin"</span>);
<span class="hljs-keyword">const</span> postcssPresetEnv = <span class="hljs-built_in">require</span>(<span class="hljs-string">"postcss-preset-env"</span>);
<span class="hljs-comment">// We are getting 'process.env.NODE_ENV' from the NPM scripts</span>
<span class="hljs-comment">// Remember the 'dev' script?</span>
<span class="hljs-keyword">const</span> devMode = process.env.NODE_ENV !== <span class="hljs-string">"production"</span>;
<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-comment">// Tells Webpack which built-in optimizations to use</span>
  <span class="hljs-comment">// If you leave this out, Webpack will default to 'production'</span>
  <span class="hljs-attr">mode</span>: devMode ? <span class="hljs-string">"development"</span> : <span class="hljs-string">"production"</span>,
<span class="hljs-comment">// Webpack needs to know where to start the bundling process,</span>
  <span class="hljs-comment">// so we define the Sass file under './Styles' directory</span>
  <span class="hljs-attr">entry</span>: [<span class="hljs-string">"./Styles/site.scss"</span>],
<span class="hljs-comment">// This is where we define the path where Webpack will place</span>
  <span class="hljs-comment">// a bundled JS file. Webpack needs to produce this file,</span>
  <span class="hljs-comment">// but for our purposes you can ignore it</span>
  <span class="hljs-attr">output</span>: {
    <span class="hljs-attr">path</span>: path.resolve(__dirname, <span class="hljs-string">"wwwroot"</span>),
<span class="hljs-comment">// Specify the base path for all the styles within your</span>
    <span class="hljs-comment">// application. This is relative to the output path, so in</span>
    <span class="hljs-comment">// our case it will be './wwwroot/css'</span>
    <span class="hljs-attr">publicPath</span>: <span class="hljs-string">"/css"</span>,
<span class="hljs-comment">// The name of the output bundle. Path is also relative</span>
    <span class="hljs-comment">// to the output path, so './wwwroot/js'</span>
    <span class="hljs-attr">filename</span>: <span class="hljs-string">"js/sass.js"</span>
  },
  <span class="hljs-attr">module</span>: {
    <span class="hljs-comment">// Array of rules that tells Webpack how the modules (output)</span>
    <span class="hljs-comment">// will be created</span>
    <span class="hljs-attr">rules</span>: [
      {
        <span class="hljs-comment">// Look for Sass files and process them according to the</span>
        <span class="hljs-comment">// rules specified in the different loaders</span>
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(sa|sc)ss$/</span>,
<span class="hljs-comment">// Use the following loaders from right-to-left, so it will</span>
        <span class="hljs-comment">// use sass-loader first and ending with MiniCssExtractPlugin</span>
        use: [
          {
            <span class="hljs-comment">// Extracts the CSS into a separate file and uses the</span>
            <span class="hljs-comment">// defined configurations in the 'plugins' section</span>
            <span class="hljs-attr">loader</span>: MiniCssExtractPlugin.loader
          },
          {
            <span class="hljs-comment">// Interprets CSS</span>
            <span class="hljs-attr">loader</span>: <span class="hljs-string">"css-loader"</span>,
            <span class="hljs-attr">options</span>: {
              <span class="hljs-attr">importLoaders</span>: <span class="hljs-number">2</span>
            }
          },
          {
            <span class="hljs-comment">// Use PostCSS to minify and autoprefix with vendor rules</span>
            <span class="hljs-comment">// for older browser compatibility</span>
            <span class="hljs-attr">loader</span>: <span class="hljs-string">"postcss-loader"</span>,
            <span class="hljs-attr">options</span>: {
              <span class="hljs-attr">ident</span>: <span class="hljs-string">"postcss"</span>,
<span class="hljs-comment">// We instruct PostCSS to autoprefix and minimize our</span>
              <span class="hljs-comment">// CSS when in production mode, otherwise don't do</span>
              <span class="hljs-comment">// anything.</span>
              <span class="hljs-attr">plugins</span>: devMode
                ? <span class="hljs-function">() =&gt;</span> []
                : <span class="hljs-function">() =&gt;</span> [
                    postcssPresetEnv({
                      <span class="hljs-comment">// Compile our CSS code to support browsers</span>
                      <span class="hljs-comment">// that are used in more than 1% of the</span>
                      <span class="hljs-comment">// global market browser share. You can modify</span>
                      <span class="hljs-comment">// the target browsers according to your needs</span>
                      <span class="hljs-comment">// by using supported queries.</span>
                      <span class="hljs-comment">// https://github.com/browserslist/browserslist#queries</span>
                      <span class="hljs-attr">browsers</span>: [<span class="hljs-string">"&gt;1%"</span>]
                    }),
                    <span class="hljs-built_in">require</span>(<span class="hljs-string">"cssnano"</span>)()
                  ]
            }
          },
          {
            <span class="hljs-comment">// Adds support for Sass files, if using Less, then</span>
            <span class="hljs-comment">// use the less-loader</span>
            <span class="hljs-attr">loader</span>: <span class="hljs-string">"sass-loader"</span>
          }
        ]
      },
      {
        <span class="hljs-comment">// Adds support to load images in your CSS rules. It looks for</span>
        <span class="hljs-comment">// .png, .jpg, .jpeg and .gif</span>
        <span class="hljs-attr">test</span>: <span class="hljs-regexp">/\.(png|jpe?g|gif)$/</span>,
        use: [
          {
            <span class="hljs-attr">loader</span>: <span class="hljs-string">"file-loader"</span>,
            <span class="hljs-attr">options</span>: {
              <span class="hljs-comment">// The image will be named with the original name and</span>
              <span class="hljs-comment">// extension</span>
              <span class="hljs-attr">name</span>: <span class="hljs-string">"[name].[ext]"</span>,
<span class="hljs-comment">// Indicates where the images are stored and will use</span>
              <span class="hljs-comment">// this path when generating the CSS files.</span>
              <span class="hljs-comment">// Example, in site.scss I have</span>
              <span class="hljs-comment">// url('../wwwroot/images/pattern.png') and when generating</span>
              <span class="hljs-comment">// the CSS file, file-loader will output as</span>
              <span class="hljs-comment">// url(../images/pattern.png), which is relative</span>
              <span class="hljs-comment">// to '/css/site.css'</span>
              <span class="hljs-attr">publicPath</span>: <span class="hljs-string">"../images"</span>,
<span class="hljs-comment">// When this option is 'true', the loader will emit the</span>
              <span class="hljs-comment">// image to output.path</span>
              <span class="hljs-attr">emitFile</span>: <span class="hljs-literal">false</span>
            }
          }
        ]
      }
    ]
  },
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-comment">// Configuration options for MiniCssExtractPlugin. Here I'm only</span>
    <span class="hljs-comment">// indicating what the CSS output file name should be and</span>
    <span class="hljs-comment">// the location</span>
    <span class="hljs-keyword">new</span> MiniCssExtractPlugin({
      <span class="hljs-attr">filename</span>: devMode ? <span class="hljs-string">"css/site.css"</span> : <span class="hljs-string">"css/site.min.css"</span>
    })
  ]
};
</code></pre>
<p>Refer to the comments in the code to understand the configuration. (More readable file <a target="_blank" href="https://github.com/esausilva/netcore-sass-webpack/blob/master/netcore-sass-webpack/webpack.config.js">here</a>.)</p>
<p>Now we need to create some bindings in <strong>Task Runner Explorer</strong>. Navigate to <strong>View -&gt; Other Windows -&gt; Task Runner Exp</strong>lorer. The window will show at the bottom and you will see the scripts you created in <code>package.json</code> listed there <strong>under</strong> Custom. You will also see some tasks <strong>under De</strong>faults, but you can just ignore them.</p>
<p>We need two bindings:</p>
<ul>
<li>Right click <strong>build -&gt; Bindings -&gt; Before</strong> Build — Visual Studio will run this task before each build. Remember this npm script runs Webpack for production and will optimize the CSS file.</li>
<li>Right click <strong>dev -&gt; Bindings -&gt; Projec</strong>t Open — Visual Studio will run this task when you open the project. Remember this npm script runs Webpack in watch mode and <em>will</em> watch for any changes in your Sass files and output the processed CSS file.</li>
</ul>
<p><strong>Task Runner Explorer</strong> should look like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/cEQsi3RjNiBTTQr1tAhSoAARAmhkc79kQRza" alt="Image" width="392" height="209" loading="lazy">
<em>Task Runner Explorer</em></p>
<p><strong>Note:</strong> For some reason, Visual Studio sometimes will fail to start the <strong>dev</strong> task upon opening the project. If that happens, just open the Task Explorer and run the task manually.</p>
<p>You can get the full code from the <a target="_blank" href="https://github.com/esausilva/netcore-sass-webpack">GitHub repository</a>.</p>
<h3 id="heading-final-thoughts">Final Thoughts</h3>
<p>And that’s all there is too it. Since you already have Visual Studio open, none of the tasks are running. Go ahead and <em>right click</em> the <strong>dev</strong> task and select run. You will see the task loading and when it finishes you will see that a <code>site.css</code> file was created under <code>wwwroot/css</code> directory. Open <code>site.scss</code>, make a change and save it. Now open <code>site.css</code>, you will see your change reflected there. Cool!!</p>
<p>Run your project by pressing <strong>Ctrl + F5</strong>, you will see a <code>site.min.css</code> file created under <code>wwwroot/css</code> directory. This file was created when Task Runner <em>ran</em> the <code>build</code> script before it built the project.</p>
<p>The final site should look like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/CBTg3rcS670jv5PSQzM35LZ9awQdUfzS2Nb3" alt="Image" width="800" height="527" loading="lazy">
<em>Final site</em></p>
<p>I know, I know, the background is very cheesey…but I needed an image to show the Webpack <code>file-loader</code> in action.</p>
<p>With this configuration, you can even add support to transpile modern JavaScript (ES6+) to ES5. Look into these: <code>@babel/core</code>, <code>babel-loader</code>, <code>@babel/preset-env</code>.</p>
<p>Thank you for reading, and I hope you enjoyed it. If you have any questions, suggestions, or corrections let me know in the comments below. Don’t forget to give this article a share, and you can follow me on <a target="_blank" href="https://twitter.com/_esausilva">Twitter</a>, <a target="_blank" href="https://github.com/esausilva/">GitHub</a>, <a target="_blank" href="https://medium.com/@_esausilva">Medium</a>, <a target="_blank" href="https://www.linkedin.com/in/esausilva/">LinkedIn</a>.</p>
<p>You can also visit my personal <a target="_blank" href="https://esausilva.com">blogging site</a>.</p>
<hr>
<p><strong>Update 8/25/19:</strong> I have been building a prayer web app called "<strong>My Quiet Time - A Prayer Journal</strong>". If you would like to stay in the loop please sign up through the following link: <a target="_blank" href="http://b.link/mqt">http://b.link/mqt</a>  </p>
<p>The app will be released before the end of the year, I have big plans for this app. To see some mockup screenshots follow the following link: <a target="_blank" href="http://pc.cd/Lpy7">http://pc.cd/Lpy7</a></p>
<p>My DMs on <a target="_blank" href="https://twitter.com/_esausilva">Twitter</a> are open if you have any questions regarding the app ?</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
