<?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[ Babel - 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[ Babel - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 26 May 2026 22:47:58 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/babel/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Setup Babel in Node.js ]]>
                </title>
                <description>
                    <![CDATA[ By Alvin Okoro Node.js is one of the most popular back-end technologies out there right now. It is friendly, robust, and well-maintained and it's not going anywhere anytime soon.  To help you learn how to use it effectively, in this article we will c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/setup-babel-in-nodejs/</link>
                <guid isPermaLink="false">66d45d9b680e33282da25e12</guid>
                
                    <category>
                        <![CDATA[ Babel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 16 Aug 2021 13:58:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/08/CREATE.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Alvin Okoro</p>
<p>Node.js is one of the most popular back-end technologies out there right now. It is friendly, robust, and well-maintained and it's not going anywhere anytime soon. </p>
<p>To help you learn how to use it effectively, in this article we will create a simple server using Node with Babel configured in our code. </p>
<p>But before we take a deep dive into building out our server, let's learn more about what Babel is.</p>
<h2 id="heading-what-is-babel">What is Babel?</h2>
<p>Babel is a JavaScript compiler. It's a popular tool that helps you use the newest features of the JavaScript programming language.</p>
<h2 id="heading-why-use-babel-in-nodejs">Why use Babel in Node.js?</h2>
<p>Have you ever opened a back end repo built with Node.js/Express – and the very first thing you saw was the ES6 import and export statements along with some other cool ES6 syntax features? </p>
<p>Well, Babel made all that possible. Remember that Babel is a popular tool that lets you use the newest features of JavaScript. And many frameworks today use Babel under the hood to compile their code.</p>
<p>For example, Node can't use ES6 import and export statements and some other cool features of ES6 syntax without the help of a compiler like Babel. </p>
<p>So in this tutorial, I'll show you how to quickly setup your Node app to be compatible with most ES6 syntax. </p>
<p>Awesome right? Let's dive in.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>This tutorial assumes that that you have the following:</p>
<ul>
<li>Basic knowledge of Node.js</li>
<li>Node installed on your machine</li>
<li>Any code or text editor of your choice</li>
</ul>
<h2 id="heading-getting-started">Getting Started</h2>
<p>Let's setup a basic Node app which we will use for this tutorial.</p>
<p>Create a new folder. For this tutorial, I'll call mine node-babel. Now add the folder to the workspace, and open your terminal. </p>
<p>Let's initialize and create a package.json file for our app:</p>
<pre><code class="lang-js">npm init
</code></pre>
<p>This command will show some setup steps which we want to leave as it is. So hitting the enter or return key throughout the setup will work fine. </p>
<p>Now once you're done, create a new file called "index.js" which will serve as our entry point.</p>
<h3 id="heading-how-to-set-up-and-install-babel">How to Set Up And Install Babel</h3>
<p>Now, we will install three packages from the Babel family which are: </p>
<pre><code class="lang-js">@babel/cli, @babel/core and @babel/preset-env
</code></pre>
<p>To install, we use the command below to install the package:</p>
<pre><code class="lang-js">npm install --save-dev @babel/cli @babel/core @babel/preset-env
</code></pre>
<p>We want to use the <strong>--save-dev</strong> to install them as dependencies for the development of your module.  </p>
<p>So once you're done with the installation, create a new file called <strong>.babelrc</strong> for configuring babel. </p>
<pre><code class="lang-js">touch .babelrc
</code></pre>
<p>This file will host all of the options we want to add to Babel. So for now, let's use the setup which I normally use for development in my app. You can copy it and add to yours:</p>
<pre><code class="lang-js">{
  <span class="hljs-string">"presets"</span>: [
    [<span class="hljs-string">"@babel/env"</span>, {
      <span class="hljs-string">"targets"</span>: {
        <span class="hljs-string">"node"</span>: <span class="hljs-string">"current"</span>
      }
    }]
  ],
  <span class="hljs-string">"plugins"</span>: [
    <span class="hljs-string">"@babel/plugin-proposal-class-properties"</span>,
    <span class="hljs-string">"@babel/plugin-proposal-object-rest-spread"</span>
  ]
}
</code></pre>
<p>The configuration above is what I use to tell Babel that yes, I want to use not only my import and export statements but also the class feature as well as the rest and spread operators from ES6.</p>
<p>Awesome yeah? Let's move on.</p>
<h3 id="heading-how-to-set-up-a-simple-server">How to Set Up A Simple Server</h3>
<p>Now open up the "index.js" file we created earlier, and add this code to generate a simple server:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> http <span class="hljs-keyword">from</span> <span class="hljs-string">'http'</span>;

<span class="hljs-keyword">const</span> server = http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.end(<span class="hljs-string">'Hello from the server'</span>);
}).listen(<span class="hljs-number">4001</span>);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server is up and running'</span>);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> server;
</code></pre>
<p>With the sample code above our server will listen on port 4001 and then send a "Hello from the server" response to us whenever we visit the port.</p>
<h3 id="heading-packagejson-script-configurations">Package.json Script Configurations.</h3>
<p>We now have a simple server. To run this, we have to transpile our code before running with Node. To do this, open the <strong>"package.json"</strong> file and add this build and start script:</p>
<pre><code class="lang-js">  <span class="hljs-string">"scripts"</span>: {
+   <span class="hljs-string">"build"</span>: <span class="hljs-string">"babel index.js -d dist"</span>,
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"npm run build &amp;&amp; node dist/index.js"</span>
  }
</code></pre>
<p>Nice – so let's start our server with this command:</p>
<pre><code class="lang-js">npm start
</code></pre>
<p>You should get this response once you visit localhost:4001</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot_16.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-use-nodemon-to-watch-and-restart-your-server">How to Use Nodemon to Watch and Restart Your Server</h2>
<p>To prevent restarting the server yourself whenever you make changes to your app, we need to install nodemon. You can install nodemon to your application using this command to install it as a dev dependency:</p>
<pre><code class="lang-js">npm install --save-dev nodemon
</code></pre>
<p>And then we  reconfigure our package.json scripts:</p>
<pre><code class="lang-js">  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"build"</span>: <span class="hljs-string">"babel index.js -d dist"</span>,
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"npm run build &amp;&amp; nodemon dist/index.js"</span>
  }
</code></pre>
<p>Awesome, now this is the final code of our Node app and what you should get when you run "npm start" to start up your server.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screenshot_13.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>As you can see from the image above, our server is up and running. You can now make use of the import and export statement from the es6 syntax and other awesome features es6 provides like the rest and spread operators in your Node application.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, we've learned how to use the awesome ES6 syntax in our Node app using Babel. </p>
<p>Note that you can add more configurations in your .babelrc file. It is not limited to what we have in this tutorial – so feel free to tweak or change it.</p>
<p>You can find the sample code here: <a target="_blank" href="https://github.com/Veri5ied/node-babel">https://github.com/Veri5ied/node-babel</a></p>
<p>Happy Hacking!</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[ JavaScript Optional Chaining `?.` Explained - How it Works and When to Use it ]]>
                </title>
                <description>
                    <![CDATA[ What is optional chaining? Optional chaining, represented by ?. in JavaScript, is a new feature introduced in ES2020.  Optional chaining changes the way properties are accessed from deeply nested objects. It fixes the problem of having to do multiple... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-optional-chaining-explained/</link>
                <guid isPermaLink="false">66b99cf194b336889c600476</guid>
                
                    <category>
                        <![CDATA[ Babel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Shruti Kapoor ]]>
                </dc:creator>
                <pubDate>Tue, 25 Aug 2020 15:39:34 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c990e740569d1a4ca1d97.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-what-is-optional-chaining">What is optional chaining?</h2>
<p>Optional chaining, represented by <code>?.</code> in JavaScript, is a new feature introduced in ES2020. </p>
<p>Optional chaining changes the way properties are accessed from deeply nested objects. It fixes the problem of having to do multiple null checks when accessing a long chain of object properties in JavaScript.</p>
<p>Current Status: <code>ECMAScript proposal at stage 4 of the process.</code> : https://github.com/tc39/proposal-optional-chaining</p>
<h2 id="heading-use-cases">Use cases</h2>
<ol>
<li>Accessing potentially <code>null</code> or <code>undefined</code> properties of an object. </li>
<li>Getting results from a variable that may not be available yet.</li>
<li>Getting default values.</li>
<li>Accessing long chains of properties.</li>
</ol>
<p>Imagine you are expecting an API to return an object of this sort:</p>
<pre><code class="lang-javascript">obj = {
  <span class="hljs-attr">prop1</span>: {
    <span class="hljs-attr">prop2</span>: {
      <span class="hljs-attr">someProp</span>: <span class="hljs-string">"value"</span>
    }
  }
};
</code></pre>
<p>But you may not know if each of these fields are available ahead of time. Some of them may not have been sent back by the API, or they may have come back with null values. </p>
<p>Here is an example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//expected</span>
obj = {
  <span class="hljs-attr">id</span>: <span class="hljs-number">9216</span>,
  <span class="hljs-attr">children</span>: [
    { <span class="hljs-attr">id</span>: <span class="hljs-number">123</span>, <span class="hljs-attr">children</span>: <span class="hljs-literal">null</span> },
    { <span class="hljs-attr">id</span>: <span class="hljs-number">124</span>, <span class="hljs-attr">children</span>: [{ <span class="hljs-attr">id</span>: <span class="hljs-number">1233</span>, <span class="hljs-attr">children</span>: <span class="hljs-literal">null</span> }] }
  ]
};

<span class="hljs-comment">//actual</span>
obj = {
  <span class="hljs-attr">id</span>: <span class="hljs-number">9216</span>,
  <span class="hljs-attr">children</span>: <span class="hljs-literal">null</span>
};
</code></pre>
<p>This happens very often with functions that call APIs. You may have seen code in React that tries to safeguard against these issues like this:</p>
<pre><code class="lang-jsx">render = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> obj = {
    <span class="hljs-attr">prop1</span>: {
      <span class="hljs-attr">prop2</span>: {
        <span class="hljs-attr">someProp</span>: <span class="hljs-string">"value"</span>,
      },
    },
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {obj &amp;&amp; obj.prop1 &amp;&amp; obj.prop1.prop2 &amp;&amp; obj.prop1.prop2.someProp &amp;&amp; (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{obj.prop1.prop2.someProp}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
</code></pre>
<p>In order to better prepare for this issue, often times in the past we have used <code>Lodash</code>, specifically the <code>_.get</code> method:</p>
<pre><code class="lang-javascript">_.get(obj, prop1.prop2.someProp);
</code></pre>
<p>This outputs <code>undefined</code> if either of those properties are <code>undefined</code>. <strong>Optional chaining is exactly that</strong>! Now instead of using an external library, this functionality is built-in.</p>
<h2 id="heading-how-does-optional-chaining-work">How does optional chaining work?</h2>
<p><code>?.</code> can be used to chain properties that may be <code>null</code> or <code>undefined</code>.</p>
<pre><code><span class="hljs-keyword">const</span> propNeeded = obj?.prop1?.prop2?.someProp;
</code></pre><p>If either of those chained properties is <code>null</code> or <code>undefined</code>, JavaScript will return <code>undefined</code>. </p>
<p>What if we want to return something meaningful? Try this: </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> familyTree = {
    <span class="hljs-attr">us</span>: {
        <span class="hljs-attr">children</span>: {}
    }
}


<span class="hljs-comment">// with _.get</span>
<span class="hljs-keyword">const</span> grandChildren = _.get(familyTree, <span class="hljs-string">'us.children.theirChildren'</span>, <span class="hljs-string">'got no kids'</span> );

<span class="hljs-comment">//with optional chaining and null coalescing </span>
<span class="hljs-keyword">const</span> nullCoalescing = familyTree?.us?.children?.theirChildren ?? <span class="hljs-string">'got no kids'</span>
<span class="hljs-built_in">console</span>.log(nullCoalescing) <span class="hljs-comment">//got no kids</span>
</code></pre>
<p>It also works for objects that may be <code>null</code> or <code>undefined</code>:</p>
<pre><code><span class="hljs-keyword">let</span> user;
<span class="hljs-built_in">console</span>.log(user?.id) <span class="hljs-comment">// undefined</span>
</code></pre><h2 id="heading-how-to-get-this-newest-feature">How to get this newest feature</h2>
<ol>
<li><p>Try it in your browser's console: This is a recent addition and old browsers may need polyfills. You can try it in Chrome or Firefox in the browser's console. If it doesn't work, try turning on JavaScript experimental features by visiting <code>chrome://flags/</code> and enabling "Experimental JavaScript".</p>
</li>
<li><p>Try it in your Node app by using Babel:</p>
<pre><code>{
<span class="hljs-string">"plugins"</span>: [<span class="hljs-string">"@babel/plugin-proposal-optional-chaining"</span>]
}
</code></pre></li>
</ol>
<h2 id="heading-resources">Resources</h2>
<ol>
<li>https://dmitripavlutin.com/javascript-optional-chaining/</li>
<li>Babel's doc: https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining</li>
</ol>
<h2 id="heading-tldr">TL;DR</h2>
<p>Use optional chaining <code>?.</code> for objects or long chain properties that may be <code>null</code> or <code>undefined</code>. The syntax is as follows:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> user = {};
<span class="hljs-built_in">console</span>.log(user?.id?.name)
</code></pre>
<hr>
<p>Interested in more tutorials and JSBytes from me? <a target="_blank" href="https://tinyletter.com/shrutikapoor">Sign up for my newsletter.</a> or <a target="_blank" href="https://twitter.com/shrutikapoor08">follow me on Twitter</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[ Why We Removed Babel’s Stage Presets: Explicit Opt-In of Experimental Proposals ]]>
                </title>
                <description>
                    <![CDATA[ By Henry Zhu Moving forward with v7, we’ve decided it’s best to stop publishing the Stage presets in Babel (for example,@babel/preset-stage-0). We didn’t make this decision lightly, and wanted to show the context behind the interplay between TC39, Ba... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/why-we-removed-babels-stage-presets-explicit-opt-in-of-experimental-proposals-cd038c69115a/</link>
                <guid isPermaLink="false">66c3673c0cede4e9b1329d64</guid>
                
                    <category>
                        <![CDATA[ Babel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tc39 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 30 Jul 2018 23:12:26 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*XmHUL5DeySv_dGmvbPqdDQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Henry Zhu</p>
<p>Moving forward with v7, we’ve decided it’s best to stop publishing the Stage presets in Babel (for example,<code>@babel/preset-stage-0</code>).</p>
<p>We didn’t make this decision lightly, and wanted to show the context behind the interplay between TC39, Babel, and the community.</p>
<h3 id="heading-some-history">Some History</h3>
<p>A Babel preset is a shareable list of plugins.</p>
<p>The <a target="_blank" href="https://babeljs.io/docs/en/next/presets">official Babel Stage presets</a> tracked the <a target="_blank" href="https://tc39.github.io/process-document/">TC39 Staging process</a> for new <a target="_blank" href="https://github.com/tc39/proposals">syntax proposals</a> in JavaScript.</p>
<p>Each preset (ex. <code>stage-3</code>, <code>stage-2</code>, and so on) included all the plugins for that particular stage and the ones above it. For example, <code>stage-2</code> included <code>stage-3</code>, and so on.</p>
<p>This allowed users who wanted to use experimental syntax to simply add the preset, instead of needing to configure/install each individual plugin.</p>
<p>We actually <a target="_blank" href="https://github.com/babel/babel/pull/2649">added</a> the Stage presets shortly after Babel’s v6 release (it was previously a config flag in v5). Shown below is an older example.</p>
<h3 id="heading-problems">Problems</h3>
<p>These presets were a convenient way to use what we all wanted: the new, shiny, “yet-to-be-determined” future of JavaScript.</p>
<p>Looking back, it worked really well! (Maybe too well?)</p>
<h3 id="heading-too-good-a-job">Too Good a Job?</h3>
<p>Languages like <a target="_blank" href="https://coffeescript.org/">CoffeeScript</a> and tooling like <a target="_blank" href="https://github.com/google/traceur-compiler">Traceur</a> helped establish the idea of compiling JavaScript. Babel made it even easier to both use new/future syntax and integrate with existing tooling. The expectations changed from skepticism and worry to completely embracing the experimental.</p>
<p>We probably wouldn’t be where we are if not for the wide adoption of compilers such as Babel: it accelerated the usage (and teaching) of ES2015 to a much larger audience. The growth of React further fueled usage, as its JSX syntax, class properties, and object rest/spread led to people knowing a bit more about these syntax proposals.</p>
<p>Babel became a one-time setup for people, never to be thought of again. It became the underlying infrastructure, hidden behind other tools until there was a <code>SyntaxError</code>, dependency issues, or integration issues. Simply use <code>stage-0</code>.</p>
<p>This was awesome to see in some ways, as it meant that these ideas were being tested in the wild, even in production environments. However, it also meant that many companies, tools, and people would encounter some trouble if a proposal changed in a significant way (or even got dropped altogether).</p>
<h3 id="heading-back-and-forth">Back and Forth</h3>
<p>Over the years, we’ve raised many issues to discuss what to do with the Stage presets in <a target="_blank" href="https://github.com/babel/babel/issues/4914">#4914</a>, <a target="_blank" href="https://github.com/babel/babel/issues/4955">#4955</a>, <a target="_blank" href="https://github.com/babel/babel/issues/7770">#7770</a>. I even wrote in an older post about Babel 7.0 that said we <strong>weren’t</strong> <a target="_blank" href="https://babeljs.io/blog/2017/12/27/nearing-the-7.0-release">removing them</a> ?.</p>
<p>However, we found that keeping the Stage presets would lead to issues even for Babel itself:</p>
<ul>
<li>It was a common issue to ask something like: <a target="_blank" href="https://github.com/babel/babel/issues/2948">“What presets(s) are needed to use async functions?”</a> It would be unclear for people to know exactly what <code>stage-0</code> meant, and few people would look at its <code>package.json</code> or source.</li>
<li>Removing a proposal plugin in Stage 3 (once it moves to Stage 4) is actually a breaking change. This issue is exacerbated when you are trying to use <code>@babel/preset-env</code> to not compile a natively supported proposal.</li>
</ul>
<h3 id="heading-es7-decorators">“ES7 Decorators”</h3>
<p>Part of the issue is precisely around naming things, and as we often hear, naming things is hard.</p>
<p>There were a lot of names for ES6 itself: Harmony, ES Next, ES6, ES2015. When people hear about new ideas, it makes sense to just pick the latest number and attach the name to it.</p>
<p>It’s completely understandable that this happens without realizing it, but continuing to do so sets different expectations for how the language progresses. It’s nothing to feel guilty about — we learn as a community and remind one another of how JavaScript works.</p>
<p><a target="_blank" href="https://twitter.com/_jayphelps/status/779770321003962369">Jay Phelps</a> wrote a nice <a target="_blank" href="https://medium.com/@jayphelps/please-stop-referring-to-proposed-javascript-features-as-es7-cad29f9dcc4b">article</a> about this subject. He explains it would be best to call them by the “Stage” they are currently at: “Stage 2 Decorators”, or just simply the “Decorators Proposal”.</p>
<p>The reasoning is that saying “ES7 Decorators” assumes that Decorators is expected to be in ES7. I mentioned this in my <a target="_blank" href="https://babeljs.io/blog/2018/06/26/on-consuming-and-publishing-es2015+-packages#staging-process">last post regarding compiling node_modules</a>, but being in a particular Stage doesn’t guarantee much: a proposal can stall, move backward, or get removed entirely.</p>
<p>We wanted to highlight this fact when we decided to <a target="_blank" href="https://babeljs.io/docs/en/next/v7-migration#switch-to-proposal-for-tc39-proposals-blog-2017-12-27-nearing-the-70-releasehtml-renames-proposal">change the names</a> of the proposal plugins from <code>@babel/plugin-transform-</code> to <code>@babel/plugin-proposal-</code>.</p>
<h3 id="heading-babelscript">BabelScript</h3>
<p>Having presets for proposals so early in the process may imply that these proposals are guaranteed to move forward or have a stable implementation.</p>
<p><a target="_blank" href="https://tc39.github.io/process-document/">TC39</a> urges caution when using Stage 2-or below proposals, as it might result in inadvertent pressure from the community to keep the implementation as-is instead of improving it for fear of breaking existing code or ecosystem fragmentation (for example, using a different symbol like <code>#</code> instead of <code>@</code> for decorators).</p>
<p>People joke that developers who use Babel are using “BabelScript” instead of JavaScript, implying that somehow once a Babel plugin is made for a certain feature, that must mean it’s “fixed” or officially part of the language already (which is not true). For some, the first thought for people when they see a new syntax/idea (Stage “-1”) is whether there is a Babel plugin for it.</p>
<h3 id="heading-setting-expectations">Setting Expectations</h3>
<p>After compilers like Babel made it common practice for people to write ES2015, it was natural for developers to want to try out even newer and more experimental “features”. The way this worked in Babel was to use the <code>stage</code> flag in previous versions or the <code>stage-x</code> presets.</p>
<p>Being the most convenient way of opting into any new feature, it quickly became the default for people when configuring Babel (even though in Babel v6 it moved to not doing anything by default, which caused lots of complaints).</p>
<p>There were a lot of good discussions even years ago, but it wasn’t the easiest thing to navigate: we wouldn’t want to penalize users who understood the tradeoffs by putting <code>console.warn</code>s when using it, and not having the option at all seemed unreasonable at the time.</p>
<p>Blindly opting into Stage 0 (whether we had it by default) or people choosing to do so seems dangerous, but also never using any proposals is overly cautious. Ideally, everyone should able to make an informed decision about the kinds of features that seem reasonable to them and use them wisely, regardless of what stage they are in. <a target="_blank" href="https://twitter.com/jugglinmike">Mike Pennisi</a> wrote <a target="_blank" href="https://bocoup.com/blog/javascript-developers-watch-your-language">a great post</a> about these concerns.</p>
<p>It isn’t our intention to threaten, rush, or force specific things into the ecosystem or JavaScript but to faithfully maintain the implementation/discussions around new ideas.</p>
<h3 id="heading-other-considerations">Other Considerations</h3>
<p>We also could have tried to:</p>
<ul>
<li><a target="_blank" href="https://github.com/babel/babel/issues/4914">Rename the presets</a> to better signify the stability level (doesn’t solve the versioning problem)</li>
<li>Better versioning strategies: independently version the presets and update them immediately when needed, maybe use <code>0.x</code></li>
<li>Warn/Error for old out-of-date versions of presets</li>
</ul>
<p>In the end, people would still have to look up what proposals are at what Stage to know which ones to use if we kept the Stages in.</p>
<h3 id="heading-why-now">Why Now?</h3>
<p>Why not remove it earlier? The Stage presets have been part of Babel for years, and there were concerns with adding more “complexity” to using Babel. A lot of tooling, documentation, articles, and knowledge were built around the Stage presets. Earlier, we thought it was better to officially maintain the presets since someone else would (and will) inevitably create them.</p>
<p>We’re trying to determine the right level of feedback: if it’s only the committee that decides what goes into the language, it may lead to well-specified features that are not needed. But if the community expects that in-progress, experimental proposals are considered stable or ok to use in production without consequence, then we’ll have other issues. We all want to move forward and proceed with intention: not rushing, but not being too cautious. Babel is the right place to do that experimentation, but knowing where the boundaries are is necessary.</p>
<p>Removing the presets would be considered a “feature,” since it means someone would have to make an explicit decision to use each proposal. This is reasonable for any proposal, since they all have varying levels of instability, usefulness, and complexity.</p>
<p>We fully expect some initial <a target="_blank" href="https://news.ycombinator.com/item?id=11371906">backlash</a> from this, but ultimately feel that removing the Stage presets is a better decision for us all in the long run. However, removing previous defaults or removing the Stage presets doesn’t mean we don’t care about ease of use, new users, or documentation. We work with what we can to keep the project stable, provide tooling to make things better, and document what we know.</p>
<h3 id="heading-migrating">Migrating</h3>
<blockquote>
<p><em>For a more automatic migration, we have updated <a target="_blank" href="https://github.com/babel/babel-upgrade">babel-upgrade</a> to do this for you (you can run <code>npx babel-upgrade</code>).</em></p>
</blockquote>
<p>The TL;DR is that we’re removing the Stage presets. At some level, people will have to opt-in and know what kinds of proposals are being used instead of assuming what people should use, especially given the unstable nature of some of these proposals. If you use another preset or a toolchain, (e.g. <a target="_blank" href="https://github.com/facebook/create-react-app">create-react-app</a>) it’s possible that this change doesn’t affect you directly.</p>
<p>We have deprecated the Stage presets as of <code>7.0.0-beta.52</code>. If you don't want to change your config now, we would suggest you <strong>pin</strong> the versions to <code>beta.54</code> until you can upgrade. After <code>beta.54</code> we will throw an error with a message saying how to migrate. And check that all your versions are the same while in prerelease.</p>
<p>As an alternative, you are free to make your own preset that contains the same plugins and upgrade them as you please. In the future, we may want to work on a <code>babel-init</code> that can help you set up plugins interactively or update <code>babel-upgrade</code> itself to list and add the current Stage plugins. Maybe Babel should stay a low-level tool and rely on other higher-level/framework tools like <code>create-react-app</code> to handle these choices for people.</p>
<h3 id="heading-preventing-proposal-lock-in">Preventing Proposal Lock-In</h3>
<p><a target="_blank" href="https://twitter.com/JamesDiGioia">James DiGioia</a> wrote a <a target="_blank" href="https://babeljs.io/blog/2018/07/19/whats-happening-with-the-pipeline-proposal">post</a> recently about the changes to using the pipeline operator (<code>|&amp;</code>gt;).</p>
<p>The main point in the post is that the proposal itself is in flux and has a few options to explore. Because we’d like to implement all three of the current possibilities as Babel plugins for both spec feedback and user feedback, we believed the way the plugin is used should change as well. This is a relatively new approach for TC39 and Babel!</p>
<p>Previously, we would add the proposal plugin to the config and that was it. Now, we remove the default behavior and ask users to opt into a flag that shows which proposal is chosen. We make it clear that there isn’t a fixed (or even favored) option at the moment.</p>
<p>This is something that we’d like to continue to do moving forward as another indication that these proposals are open to change and feedback from all of us. The removal of the Stage presets makes this even easier, as before we had to pass down these options even if you didn’t use the syntax.</p>
<h3 id="heading-ecosystem-maintenance-burden">Ecosystem Maintenance Burden</h3>
<p>A language’s “syntax budget” doesn’t just apply to the complexity of the language itself but can extend down to the tooling. Each new syntax addition brings a new <a target="_blank" href="http://jshint.com/blog/new-lang-features/">burden</a> to the maintainers of other JavaScript projects.</p>
<p>Once new syntax is proposed, many things need updating: parsers (<code>babylon</code>), syntax highlighting (<code>language-babel</code>), linters (<code>babel-eslint</code>), test frameworks (<code>jest</code>/<code>ava</code>), formatters (<code>prettier</code>), code coverage (<code>istanbul</code>), minifiers (<code>babel-minify</code>), and more.</p>
<p>There have been many issues brought up on projects like <code>acorn</code>, <code>eslint</code>, <code>jshint</code>, <code>typescript</code>, and others to support Stage 0 proposals because they were in Babel. There aren't many projects that would adhere to a policy that required them to support any proposal, since that would be extremely demanding to maintain. In many ways, it's surprising we even attempt to handle it in Babel itself given the constant updates and churn.</p>
<p>Who is doing that work, and is it our responsibility to make sure everything works? Every one of those projects (mostly volunteers) is lacking in help in almost every aspect, and yet we continually get complaints about this across the board. How are we, as a community, to take responsibility for dealing with our infrastructure (not dissimilar to open source as a whole)?</p>
<p>Babel has taken on the unusual burden of supporting these experimental features. At the same time, it’s reasonable that other projects take a more conservative policy. If you’d like to see new language features are supported across the ecosystem, <a target="_blank" href="https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md">contribute to TC39</a> and this project to bring these proposals to Stage 4.</p>
<h3 id="heading-the-future">The Future</h3>
<p>The purpose of this project is to act as a part of the TC39 process: being a resource for both implementing newer (Stage 0–2) proposals and receiving feedback from users while also supporting older versions of JavaScript. We hope this post sheds more light on how we are trying, as best we can, to better align this project in the JavaScript ecosystem. We will be releasing a RC for v7 soon!</p>
<p>If you appreciate this post and the work we’re doing on Babel, you can support me on <a target="_blank" href="https://www.patreon.com/henryzhu">Patreon</a>, ask your company to sponsor us on <a target="_blank" href="https://opencollective.com/babel">Open Collective</a>, or better yet get your company involved with Babel as part of your work. We’d appreciate the collective ownership.</p>
<p>With thanks to all the <a target="_blank" href="https://github.com/babel/website/pull/1735">reviewers</a>! Feel free to give feedback on <a target="_blank" href="https://twitter.com/left_pad/status/1022877618348146693?s=20">Twitter</a>.</p>
<p><em>Originally published at</em> <a target="_blank" href="https://babeljs.io/blog/2018/07/27/removing-babels-stage-presets">https://babeljs.io/blog/2018/07/27/removing-babels-stage-presets</a><em>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to use Babel macros with React Native ]]>
                </title>
                <description>
                    <![CDATA[ By Karan Thakkar A practical use case for solving an i18n problem using codegen.macro _Background Photo by [Unsplash](https://unsplash.com/photos/6PF6DaiWz48" rel="noopener" target="_blank" title="">Rayi Christian Wicaksono on <a href="https://unspl... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/using-babel-macros-with-react-native-8615aaf5b7df/</link>
                <guid isPermaLink="false">66c36455020f8e9c31066e8b</guid>
                
                    <category>
                        <![CDATA[ Babel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 08 Jun 2018 14:02:42 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*NIQACxrWjnCUOLogiOrW5Q.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Karan Thakkar</p>
<h4 id="heading-a-practical-use-case-for-solving-an-i18n-problem-using-codegenmacro">A practical use case for solving an i18n problem using codegen.macro</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/jfjrz1ddbDi4Zef64CpbkFH3aucozCj7VNNX" alt="Image" width="800" height="478" loading="lazy">
_Background Photo by [Unsplash](https://unsplash.com/photos/6PF6DaiWz48" rel="noopener" target="_blank" title=""&gt;Rayi Christian Wicaksono on &lt;a href="https://unsplash.com" rel="noopener" target="<em>blank" title=")</em></p>
<p>If you follow <a target="_blank" href="https://www.freecodecamp.org/news/using-babel-macros-with-react-native-8615aaf5b7df/undefined">Kent C. Dodds</a> or <a target="_blank" href="https://www.freecodecamp.org/news/using-babel-macros-with-react-native-8615aaf5b7df/undefined">Sunil Pai</a> on Twitter, you may have read tweets every once in a while about babel macros. So did I. But it was only yesterday that I finally understood what the hype is all about. <strong>And it is glorious!</strong></p>
<p>So, coming to the problem: I wanted to add some utility to do locale-based number formatting in React Native. Since there is no consistent support for the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl">Internationalization API</a> in React Native, I used a polyfill for it: <a target="_blank" href="https://github.com/andyearnshaw/Intl.js">https://github.com/andyearnshaw/Intl.js</a>. Now, along with the polyfill, I also needed to import all the supporting locale files. There are two options here:</p>
<ol>
<li><strong>Load all the locales</strong>: This is straightforward, as I can just import one file. This should usually be avoided, since it can unnecessarily bloat your bundle size if you just need to support some locales.</li>
</ol>
<p><img src="https://cdn-media-1.freecodecamp.org/images/m8Pk2rDXI2f6OfOEECt99XwbiR0pw5OxzXXf" alt="Image" width="800" height="276" loading="lazy">
<em>Load all locales provided by Intl.js</em></p>
<ol start="2">
<li><strong>Load only necessary locales</strong>: With this, I only load the locales that my app supports.</li>
</ol>
<p><img src="https://cdn-media-1.freecodecamp.org/images/LzitpUOexDJoOucbHFAbe7kkPP8nOVs2F7k5" alt="Image" width="800" height="410" loading="lazy">
<em>Load only the necessary locales from Intl.js</em></p>
<p>For example, if the app supports 40 locales, I have to manually end up writing 40 imports for each locale. It becomes much harder and more tedious to do this as the list of locales you support increases.</p>
<p>I wanted to automate this in a way that required no manual changes. This is especially useful for us as we have background jobs running on the CI that automatically update our locales file whenever we add support for a new language.</p>
<p>How can I dynamically import multiple files but also allow the React Native packager to have all the file paths at compile time? <a target="_blank" href="https://github.com/kentcdodds/babel-plugin-macros"><strong>babel-plugin-macros</strong></a> and <a target="_blank" href="https://github.com/kentcdodds/codegen.macro"><strong>codegen.macro</strong></a> ?</p>
<h3 id="heading-what-are-thesebabel-things">What are these…babel things?</h3>
<p><a target="_blank" href="https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros">This</a> blog post by <a target="_blank" href="https://www.freecodecamp.org/news/using-babel-macros-with-react-native-8615aaf5b7df/undefined">Kent C. Dodds</a> perfectly describes what <a target="_blank" href="https://github.com/kentcdodds/babel-plugin-macros"><strong>babel-plugin-macros</strong></a> is:</p>
<blockquote>
<p>It’s a “new” approach to code transformation. It enables you to have zero-config, importable code transformations.</p>
</blockquote>
<p><a target="_blank" href="https://github.com/kentcdodds/codegen.macro"><strong>codegen.macro</strong></a> is one such transformation that you can use to “generate code” at build time.</p>
<h3 id="heading-how-do-you-set-it-up">How do you set it up?</h3>
<p>React Native allows you to configure your own babel settings. You can create our own “.babelrc” file at the root of your project. To make sure that you use the default babel configuration that comes with React Native, install <a target="_blank" href="https://github.com/facebook/react-native/tree/master/babel-preset"><strong>babel-preset-react-native</strong></a>.</p>
<p>On top of this you have to install another module: <a target="_blank" href="https://github.com/kentcdodds/codegen.macro"><strong>codegen.macro</strong></a>. The codegen plugin uses <a target="_blank" href="https://github.com/kentcdodds/babel-plugin-macros"><strong>babel-plugin-macros</strong></a> under the hood to do its job. We’ll see in a bit what that is.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/9yAnzljqibKRoDn7rKe5AkGMQ63pPWfp4354" alt="Image" width="800" height="423" loading="lazy">
<em>⬆️️This is how your <strong>.babelrc</strong> file should look</em></p>
<h3 id="heading-what-does-codegenmacro-do">What does codegen.macro do?</h3>
<p>It takes a piece of code, executes it, and replaces itself with the <code>export-ed</code> string. It will make a lot of sense once you see the example below. Given a list of locales and a codegen macro, it generates a list of imports at build time!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1WKwUJ0aFROJGwvTQNckj87aOJOTvadtYTuv" alt="Image" width="800" height="368" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/yj8t50UemnN-BaJUUy0q1XAgggZgMDPgelZz" alt="Image" width="800" height="575" loading="lazy">
<em>LEFT: codegen macro to build imports for all locales · RIGHT: Supported locales list</em></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/yPXysDYsOX2BytVUIzJKeY7pMK9CblD8oMeH" alt="Image" width="800" height="424" loading="lazy">
<em>Output from babel after transpilation</em></p>
<h3 id="heading-but-what-if-i-need-syntax-highlighting">But, what if I need syntax highlighting?</h3>
<p>Since we’re writing all our code in a template string, it is really hard to get proper syntax highlighting. You might end up spending a lot of time trying to figure out why your macro gives an error while transpiling.</p>
<p>Thankfully, babel macros support a <a target="_blank" href="https://github.com/kentcdodds/babel-plugin-codegen#usage">few different ways</a> to use them. My favorite is using a <strong>codegen.require</strong>. With this, you can move the body of your macro into a separate file and require it wherever you want, as shown below:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1PuJiRDOV4A2YT6nx1SOTmeViF9XbpG1-L22" alt="Image" width="800" height="328" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/u1tVA9klTM1XTlJtK5Rj2PE5nxrzkUdtsh9F" alt="Image" width="800" height="298" loading="lazy">
<em>Import the codegen using a special <strong>codegen.require</strong> call</em></p>
<h4 id="heading-advantages-of-using-this-syntax">Advantages of using this syntax:</h4>
<ul>
<li>well, syntax highlighting ??‍</li>
<li>no need to escape any escape sequences you need to use like <strong>\n ?</strong></li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/EVMYOZ1LD-n8SHTuqvfwVNWXr6wghjIFiND3" alt="Image" width="800" height="368" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/zJD4HRaNxhHMHsHlhlINJf64K0B0vHin32jG" alt="Image" width="800" height="298" loading="lazy"></p>
<ul>
<li>use template literals inside your codegen ?</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/MVDROCDmMzE6MY8Osky7BpEJYlh-z5-QO-Ez" alt="Image" width="800" height="368" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/HXwx6D60GMfXD6DiiMmwqUI78dt4lowhLdrw" alt="Image" width="800" height="298" loading="lazy"></p>
<h3 id="heading-note-upgrading-react-native">NOTE: upgrading React Native</h3>
<p>If you choose to override the babel config, whenever you upgrade react-native, you must also bump the version of babel-preset-react-native to match the one being used inside that react-native version.</p>
<p>That’s it folks! You’ve setup babel macros with React Native ?? Check out th<a target="_blank" href="https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/macros.md">ese other available macros i</a>f you wanna try out something different.</p>
<p>PS: Thanks to <a target="_blank" href="https://www.freecodecamp.org/news/using-babel-macros-with-react-native-8615aaf5b7df/undefined">Narendra N Shetty</a>, <a target="_blank" href="https://www.freecodecamp.org/news/using-babel-macros-with-react-native-8615aaf5b7df/undefined">Siddharth Kshetrapal</a> and <a target="_blank" href="https://www.freecodecamp.org/news/using-babel-macros-with-react-native-8615aaf5b7df/undefined">Kent C. Dodds</a> for reviewing the draft and helping shape it better ?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/NeELdCuvtLGOOP54bsUaMrsh3SDAd9cmI3FD" alt="Image" width="154" height="154" loading="lazy"></p>
<p>Hi! ?‍ I’m K<a target="_blank" href="https://twitter.com/geekykaran">aran Thakkar.</a> I work on React Native infrastructure at S<a target="_blank" href="https://www.freecodecamp.org/news/using-babel-macros-with-react-native-8615aaf5b7df/undefined">kyscanner Engineering.</a> Previously, I lead the web team at C<a target="_blank" href="https://www.freecodecamp.org/news/using-babel-macros-with-react-native-8615aaf5b7df/undefined">rowdfire.</a> I like trying out new technologies in my spare time and I’ve built T<a target="_blank" href="https://karanjthakkar.com/projects/tweetify">weetify</a> (using React Native) and S<a target="_blank" href="https://showmyprs.com">how My PR’s</a> (using Golang).</p>
<p>Other articles written by me are:</p>
<ul>
<li><a target="_blank" href="https://medium.freecodecamp.org/an-illustrated-guide-for-setting-up-your-website-using-github-cloudflare-5a7a11ca9465">An illustrated guide for setting up your website using GitHub and Cloudflare</a></li>
<li><a target="_blank" href="https://medium.freecodecamp.org/going-https-on-amazon-ec2-ubuntu-14-04-with-lets-encrypt-certbot-on-nginx-696770649e76">Using the Let’s Encrypt Certbot to get HTTPS on your Amazon EC2 NGINX box</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ We’re nearing the 7.0 Babel release. Here’s all the cool stuff we’ve been doing. ]]>
                </title>
                <description>
                    <![CDATA[ By Henry Zhu 6 months later, the actual release https://twitter.com/left_pad/status/1034204330352500736! Hey there ?! I’m Henry, one of the maintainers on Babel. EDIT: I’ve left Behance and have made a Patreon to try to pursue working on open sour... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/were-nearing-the-7-0-babel-release-here-s-all-the-cool-stuff-we-ve-been-doing-8c1ade684039/</link>
                <guid isPermaLink="false">66c3651dda3c91501890b9fe</guid>
                
                    <category>
                        <![CDATA[ Babel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ open source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 12 Feb 2018 11:06:33 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*vLtFVPTHJGDfw3XOl4C1Sw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Henry Zhu</p>
<blockquote>
<p>6 months later, the actual release <a target="_blank" href="https://twitter.com/left_pad/status/1034204330352500736">https://twitter.com/left_pad/status/1034204330352500736</a>!</p>
</blockquote>
<p>Hey there ?! I’m <a target="_blank" href="http://twitter.com/left_pad">Henry</a>, one of the maintainers on <a target="_blank" href="http://babeljs.io/">Babel</a>.</p>
<blockquote>
<p>EDIT: I’ve <a target="_blank" href="https://www.henryzoo.com/blog/2018/02/15/leaving-behance.html">left Behance</a> and have made a <a target="_blank" href="https://www.patreon.com/henryzhu">Patreon</a> to try to pursue <a target="_blank" href="https://www.henryzoo.com/blog/2018/03/02/in-pursuit-of-open-source-part-1.html">working on open source full time</a>, please consider donating (ask your company).</p>
</blockquote>
<h4 id="heading-a-quick-intro-to-babel">A quick intro to Babel</h4>
<p>Some people like to think of Babel as a tool that lets you write ES6 code. More specifically, a JavaScript compiler than will convert ES6 into ES5 code. That was pretty fitting back when its name was 6to5, but I think Babel has become a lot more than that.</p>
<p>Now let’s back up a bit. The reason why this is even necessary in the first place is because, unlike most languages on the server (even Node.js), the version of JavaScript that you can run depends on your specific browser version. So it doesn’t matter if you are using the latest browsers if your users (that you want to keep) are still on IE. If you want to write the <code>class A {}</code> , for example, then you’re out of luck — some number of your users will get a <code>SyntaxError</code> and a white page.</p>
<p>So that’s why Babel was created. It allows you to write the version of JavaScript you desire, knowing that it will run correctly on all the (older) browsers you support.</p>
<p>But it doesn’t just stop at “ES6” (some people like to say ES2015). Babel has certainly expanded upon its initial goal of only compiling ES6 code, and now compiles whatever ES20xx version you want (the latest version of JavaScript) to ES5.</p>
<h4 id="heading-the-ongoing-process">The ongoing process</h4>
<p>One of the interesting things about the project is that, as long as new JavaScript syntax is added, Babel will need to implement a transform to convert it.</p>
<p>But you might be thinking, why should we even send a compiled version (larger code size) to browsers that do support that syntax? How do we even know what syntax each browser supports?</p>
<p>Well, we made <code>[babel-preset-env](https://babeljs.io/docs/en/babel-preset-env)</code> to help with that issue by creating a tool that lets you specify which browsers you support. It will automatically only transform the things that those browsers don’t support natively.</p>
<p>Beyond that, Babel (because of its usage in the community) has a place in influencing the future of the JavaScript language itself! Given that it is a tool for transforming JS code, it can also be used to implement any of the proposals submitted to <a target="_blank" href="http://2ality.com/2015/11/tc39-process.html">TC39</a> (Ecma Technical Committee 39, the group that moves JavaScript forward as a standard).</p>
<p>There is a whole process a “proposal” goes through, from Stage 0 to Stage 4 when it lands into the language. Babel, as a tool, is in the right place to test out new ideas and to get developers to use it in their applications so they can give feedback to the committee.</p>
<p>This is really important for a few reasons: the committee wants to be confident that the changes they make are what the community wants (consistent, intuitive, effective). Implementing an unspecified idea in the browser is slow (C++ in the browser vs. JavaScript in Babel), costly, and requires users to use a flag in the browser versus changing their Babel config file.</p>
<p>Since Babel is so ubiquitous, there is a good chance that real usage will occur. This will make the proposal much better off than if it was just implemented without any vetting from the developer community at large.</p>
<p>And it is not just useful in production. Our online <a target="_blank" href="https://babeljs.io/repl">REPL</a> is useful for people learning JavaScript itself, and allows them to test things out.</p>
<p>I think Babel is in a great position to be an educational tool for programmers so they can continue to learn how JavaScript works. Through contributing to the project itself, they’ll learn many other concepts such as ASTs, compilers, language specification, and more.</p>
<p>I’m really excited about the future of the project and can’t wait to see where the team can go. Please join and help us!</p>
<h4 id="heading-my-story">My story</h4>
<p>Those are some of the reasons I get excited to work on this project each day, especially as a maintainer. Most of the current maintainers, including myself, didn’t create the project but joined a year after — and it’s still <a target="_blank" href="https://medium.com/@left_pad/ossthanks-some-thoughts-d0267706c2c6">mindblowing</a> to think where I started.</p>
<p>As for me, I recognized a need and an interesting project. I slowly and consistently got more involved, and now I’ve been able to get my employer, <a target="_blank" href="https://www.behance.net/">Behance</a>, to sponsor half my time on Babel.</p>
<p>Sometimes “maintaining” just means fixing bugs, answering questions on our Slack or <a target="_blank" href="https://twitter.com/babeljs/">Twitter</a>, or writing a changelog (it’s really up to each of us). But recently, I’ve decreased my focus on making bug fixes and features. Instead, I’ve been putting some time into thinking about more high level issues like: what’s the future of this project? How do we grow our community in terms of the number of maintainers versus of the number of users? How can we sustain the project in terms of funding? Where do we fit in the JavaScript ecosystem as a whole (education, <a target="_blank" href="https://github.com/tc39/proposals">TC39</a>, tooling)? And is there a role for us to play in helping new people join in open source (<a target="_blank" href="https://twitter.com/left_pad/status/959439119960215552">RGSoC</a> and <a target="_blank" href="https://summerofcode.withgoogle.com/">GSoC</a>)?</p>
<p>Because of these questions, what I’m most excited about with this release isn’t necessarily the particulars in the feature set (which are many: initial implementations of new proposals like the <a target="_blank" href="https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-pipeline-operator">Pipeline Operator (a |&gt; b)</a>, a <a target="_blank" href="https://github.com/babel/babel/tree/master/packages/babel-preset-typescript">new TypeScript preset</a> with help from the TS team, and .babelrc.js files).</p>
<p>Rather, I’m excited about what all those features represent: a year’s worth of hard work trying not to break everything, balancing users’ expectations (why is the build so slow/code output so large, why is the code not spec-compliant enough, why doesn’t this work without configuration, why isn’t there an option for x), and sustaining a solid team of mostly volunteers.</p>
<p>And I know our industry has a huge focus on “major releases,” hyped features, and stars, but that’s just one day that fades. I’d like to suggest we continue thinking about what it takes to be consistent in pushing the ecosystem forward in a healthy fashion.</p>
<p>This could simply mean thinking about the mental and emotional burden of maintainer-ship. It could mean thinking about how to provide mentorship, expectation management, work/life balance advice, and other resources to people wanting to get involved, instead of just encouraging developers to expect immediate, free help.</p>
<h4 id="heading-diving-into-the-changelog">Diving into the changelog</h4>
<p>Well, I hope you enjoy the long changelog ?. If you’re interested in helping us out, please let us know and we’d be glad to talk more.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*zvhm_vD3VWFaWA1c.png" alt="Image" width="800" height="343" loading="lazy"></p>
<p>We started a new <a target="_blank" href="https://babeljs.io/docs/community/videos/">videos page</a>, since people wanted to learn more about how Babel works and contribute back. This page contains videos of conference talks on Babel and related concepts from team members and people in the community.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*8q5nV1APkAFKydrZ.png" alt="Image" width="800" height="341" loading="lazy"></p>
<p>We also created a new <a target="_blank" href="https://babeljs.io/team">team page</a>! We will be updating this page in the future with more information about what people work on and why they are involved. For such a large project, there are many ways to get involved and help out.</p>
<p>Here are some highlights and quick facts:</p>
<ul>
<li>Babel turned 3 years old on <a target="_blank" href="https://babeljs.io/blog/2017/10/05/babel-turns-three">September 28, 2017</a>!</li>
<li>Daniel <a target="_blank" href="https://twitter.com/left_pad/status/926096965565370369">moved</a> <code>babel/babylon</code> and <code>babel/babel-preset-env</code> into the main Babel monorepo, <a target="_blank" href="https://github.com/babel/babel">babel/babel</a>. This includes all Git history, labels, and issues.</li>
<li>We received a <a target="_blank" href="https://twitter.com/left_pad/status/923696620935421953">$1k/month donation</a> from Facebook Open Source!</li>
<li>This the highest monthly donation we have gotten since the start (next highest is $100/month).</li>
<li>In the meantime, we will use our funds to meet in person and to send people to TC39 meetings. These meetings are every 2 months around the world.</li>
<li>If a company wants to specifically sponsor something, we can create separate issues to track. This was difficult before, because we had to pay out of pocket or find a conference to speak at during the same week to help cover expenses.</li>
</ul>
<h4 id="heading-how-you-can-help">How you can help</h4>
<p>If your company would like to <strong>give back</strong> by supporting a fundamental part of JavaScript development and its future, consider donating to our <a target="_blank" href="https://opencollective.com/babel">Open Collective</a>. You can also donate developer time to help maintain the project.</p>
<h4 id="heading-1-help-maintain-the-project-developer-time-at-work">#1: Help maintain the project (developer time at work)</h4>
<p></p><blockquote><p>Engineer: There's a thing in SQL Server Enterprise blocking us<br>Company: Let's set up a call next week with them an ongoing discussion to resolve it next quarter<br><br>Engineer: There's a thing we need in babel, can I spent 2 days with a PR for it<br>Company: lol no it's their job <a href="https://t.co/icgaoJ0dTe">https://t.co/icgaoJ0dTe</a></p>— Shiya (@ShiyaLuo) <a href="https://twitter.com/ShiyaLuo/status/931230821976907776?ref_src=twsrc%5Etfw">November 16, 2017</a></blockquote><p></p>


<p>The best thing for Babel is finding people who are committed to helping out with the project, given the massive amount of work and responsibility it requires. Again, <a target="_blank" href="https://dev.to/hzoo/im-the-maintainer-of-babel-ask-me-anything-282/comments/1k6d">I never felt ready</a> to be a maintainer, but somehow stumbled upon it. But I’m just one person, and our team is just a few people.</p>
<h4 id="heading-2-help-fund-development">#2: Help fund development</h4>
<p></p><blockquote><p>Company: "We'd like to use SQL Server Enterprise"<br>MS: "That'll be a quarter million dollars + $20K/month"<br>Company: "Ok!"<br>...<br>Company: "We'd like to use Babel"<br>Babel: "Ok! npm i babel --save"<br>Company: "Cool"<br>Babel: "Would you like to help contribute financially?"<br>Company: "lol no"</p>— Adam Rackis (@AdamRackis) <a href="https://twitter.com/AdamRackis/status/931195056479965185?ref_src=twsrc%5Etfw">November 16, 2017</a></blockquote><p></p>


<p>We definitely want to be able to fund people on the team so they can work full-time. Logan, in particular, left his job a while ago and is using our current funds to work on Babel part time.</p>
<h4 id="heading-3-contribute-in-other-ways">#3 Contribute in other ways ?</h4>
<p>For example, <a target="_blank" href="https://twitter.com/angustweets">Angus</a> made us an <a target="_blank" href="https://medium.com/@angustweets/hallelujah-in-praise-of-babel-977020010fad">official song</a>!</p>
<h4 id="heading-upgrading">Upgrading</h4>
<p>We will also be working on an upgrade tool that will help <a target="_blank" href="https://github.com/babel/notes/issues/44">rewrite your package.json/.babelrc files</a> and more. Ideally, this means it would modify any necessary version number changes, package renames, and config changes.</p>
<p>Please reach out to help and to post issues when trying to update. This is a great opportunity to get involved and help the ecosystem update!</p>
<h4 id="heading-summary-of-the-previous-posthttpsbabeljsioblog20170912planning-for-70">Summary of the <a target="_blank" href="https://babeljs.io/blog/2017/09/12/planning-for-7.0">previous post</a></h4>
<ul>
<li>Dropped Node 0.10/0.12/5 support.</li>
<li>Updated <a target="_blank" href="https://github.com/babel/proposals/issues">TC39 proposals</a></li>
<li>Numeric Separator: <code>1_000</code></li>
<li>Optional Chaining Operator: <code>a?.b</code></li>
<li><code>import.meta</code> (parseble)</li>
<li>Optional Catch Binding: <code>try { a } catch {}</code></li>
<li>BigInt (parseble): <code>2n</code></li>
<li>Split export extensions into <code>export-default-from</code> and <code>export-ns-form</code></li>
<li><code>.babelrc.js</code> support (a config using JavaScript instead of JSON)</li>
<li>Added a new Typescript Preset and separated the React/Flow presets</li>
<li>Added <a target="_blank" href="https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html">JSX Fragment Support</a> and various Flow updates</li>
<li>Removed the internal <code>babel-runtime</code> dependency for smaller size</li>
</ul>
<h4 id="heading-newly-updated-tc39-proposals">Newly updated TC39 proposals</h4>
<ul>
<li>Pipeline Operator: <code>a |&gt; b</code></li>
<li>Throw Expressions: <code>() =&gt; throw 'hi'</code></li>
<li>Nullish Coalescing Operator: <code>a ?? b</code></li>
</ul>
<h4 id="heading-deprecated-yearly-presets-eg-babel-preset-es20xx">Deprecated yearly presets (e.g. babel-preset-es20xx)</h4>
<p>TL;DR: use <code>babel-preset-env</code>.</p>
<p>What’s better than you having to decide which Babel preset to use? Having it done for you, automatically!</p>
<p>Even though the amount of work that goes into maintaining the lists of data is humongous — again, why we need help — it solves multiple issues. It makes sure users are up to date with the spec. It means less configuration/package confusion. It means an easier upgrade path. And it means fewer issues about what is what.</p>
<p><code>babel-preset-env</code> is actually a pretty <em>old</em> preset that replaces every other syntax preset that you will need (es2015, es2016, es2017, es20xx, latest, and so on).</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*wgAjmRI1MVcI_Veg.png" alt="Image" width="800" height="291" loading="lazy"></p>
<p>It compiles the latest yearly release of JavaScript (whatever is in Stage 4) which replaces all the old presets. But it also has the ability to compile according to target environments you specify: it can handle development mode, like the latest version of a browser, or multiple builds, like a version for IE. It even has another version for evergreen browsers.</p>
<h4 id="heading-not-removing-the-stage-presets-babel-preset-stage-x">Not removing the Stage presets (babel-preset-stage-x)</h4>
<p></p><blockquote><p>Frustration level if we remove the Stage presets in Babel? (in favor explicitly requiring proposal plugins since they aren't JavaScript yet)</p>— Henry Zhu (@left_pad) <a href="https://twitter.com/left_pad/status/873242704364306433?ref_src=twsrc%5Etfw">June 9, 2017</a></blockquote><p></p>



<p>We can always keep it up to date, and maybe we just need to determine a better system than what the current presets are.</p>
<p>Right now, stage presets are just a list of plugins that we manually update after each TC39 meeting. To make this manageable, we need to allow major version bumps for these “unstable” packages. This is partly because the community will re-create these packages anyway. So we might as well do it from an official package, and then have the ability to provide better messaging and so on.</p>
<h4 id="heading-renames-scoped-packages-babelx">Renames: Scoped Packages (<code>@babel/x</code>)</h4>
<p>Here is a poll I put out almost a year ago:</p>
<p></p><blockquote><p>Thoughts on <a href="https://twitter.com/babeljs?ref_src=twsrc%5Etfw">@babeljs</a> using npm scoped packages for 7.0?</p>— Henry Zhu (@left_pad) <a href="https://twitter.com/left_pad/status/821551189166878722?ref_src=twsrc%5Etfw">January 18, 2017</a></blockquote><p></p>



<p>Back then, not a lot of projects used scoped packages, so most people didn’t even know they existed. You might have had to pay for an npm org account back then, whereas now it is free (and supports non-scoped packages, too).</p>
<p>The issues with searching for scoped packages are solved, and download counts work. The only stumbling block left is that some 3rd party registries still don’t support scoped packages. But I think we are at a point where it seems pretty unreasonable to wait on that.</p>
<p>Here’s why we prefer scoped packages:</p>
<ul>
<li>Naming is difficult: we won’t have to check if someone else decided to use our naming convention for their own plugin</li>
<li>We have similar issues with package squatting</li>
<li>Sometimes people create <code>babel-preset-20xx</code> or some other package because it’s funny. We have to make an issue and email to ask for it back.</li>
<li>People have a legit package, but it happens to be the same name as what we wanted to call it.</li>
<li>People see that a new proposal is merging (like optional chaining or pipeline operator) and decide to fork and publish a version of it under the same name. Then, when we publish, it tell us the package was already published ?. So I have to find their email and email both them and npm support to get the package back and republish.</li>
<li>What is an “official” package and what is a user/community package with the same name? We get issue reports of people using misnamed or unofficial packages because they assumed it was part of Babel. One example of this was a report that <code>babel-env</code> was rewriting their <code>.babelrc</code> file. It took them a while to realize it wasn't <code>babel-preset-env</code>.</li>
</ul>
<p>So, it seems pretty clear that we should use scoped packages, and, if anything, we should have done it much earlier ?!</p>
<p>Examples of the scoped name change:</p>
<ul>
<li><code>babel-cli</code> -&gt; <code>@babel/cli</code></li>
<li><code>babel-core</code> -&gt; <code>@babel/core</code></li>
<li><code>babel-preset-env</code> -&gt; <code>@babel/preset-env</code></li>
</ul>
<h4 id="heading-renames-proposal">Renames: <code>-proposal-</code></h4>
<p>Any proposals will be named with <code>-proposal-</code> now to signify that they aren't officially in JavaScript yet.</p>
<p>So <code>@babel/plugin-transform-class-properties</code> becomes <code>@babel/plugin-proposal-class-properties</code>, and we would name it back once it gets into Stage 4.</p>
<h4 id="heading-renames-drop-the-year-from-the-plugin-name">Renames: Drop the year from the plugin name</h4>
<p>Previous plugins had the year in the name, but it doesn’t seem to be necessary now.</p>
<p>So <code>@babel/plugin-transform-es2015-classes</code> becomes <code>@babel/plugin-transform-classes</code>.</p>
<p>Since years were only used for es3/es2015, we didn’t change anything from es2016 or es2017. However, we are deprecating those presets in favor of preset-env, and, for the template literal revision, we just added it to the template literal transform for simplicity.</p>
<h4 id="heading-peer-dependencies-and-integrations">Peer dependencies and integrations</h4>
<p>We are introducing a peer dependencies on <code>@babel/core</code> for all the plugins (<code>@babel/plugin-class-properties</code>), presets (<code>@babel/preset-env</code>), and top level packages (<code>@babel/cli</code>, <code>babel-loader</code>).</p>
<blockquote>
<p>peerDependencies are dependencies expected to be used by your code, as opposed to dependencies only used as an implementation detail. — <a target="_blank" href="https://stackoverflow.com/a/34645112">Stijn de Witt via StackOverflow</a>.</p>
</blockquote>
<p><code>babel-loader</code> already had a <code>peerDependency</code> on <code>babel-core</code>, so this just changes it to <code>@babel/core</code>. This change prevents people from trying to install these packages on the wrong version of Babel.</p>
<p>For tools that already have a <code>peerDependency</code> on <code>babel-core</code> and aren't ready for a major bump (since changing the peer dependency is a breaking change), we have published a new version of <code>babel-core</code> to bridge the changes over with the new version <a target="_blank" href="https://github.com/babel/babel-bridge">babel-core@7.0.0-bridge.0</a>. For more information, check out <a target="_blank" href="https://github.com/facebook/jest/pull/4557#issuecomment-344048628">this issue</a>.</p>
<p>Similarly, packages like <code>gulp-babel</code>, <code>rollup-plugin-babel</code>, and so on all used to have <code>babel-core</code> as a dependency. Now these will just have a <code>peerDependency</code> on <code>@babel/core</code>. Because of this, these packages don’t have to bump major versions when the <code>@babel/core</code> API hasn't changed.</p>
<h4 id="heading-5224httpsgithubcombabelbabelpull5224-independent-publishing-of-experimental-packages"><a target="_blank" href="https://github.com/babel/babel/pull/5224">#5224</a>: independent publishing of experimental packages</h4>
<p>I mention this in <a target="_blank" href="http://babeljs.io/blog/2016/12/07/the-state-of-babel">The State of Babel</a> in the <code>Versioning</code> section. Here’s the <a target="_blank" href="https://github.com/babel/babylon/issues/275">Github Issue</a>.</p>
<p>You might remember that after Babel 6, Babel became a set of npm packages with its own ecosystem of custom presets and plugins.</p>
<p>Since then, however, we have always used a “fixed/synchronized” versioning system (so that no package is on v7.0 or above). When we do a new release, such as <code>v6.23.0</code> , only packages that have updated code in the source are published with the new version. The rest of the packages are left as is. This mostly works in practice because we use <code>^</code> in our packages.</p>
<p>Unfortunately, this kind of system requires a major version to be released for all packages once a single package needs it. This either means that we make a lot small breaking changes (unnecessary), or we batch lots of breaking changes into a single release. Instead, we want to differentiate between the experimental packages (Stage 0, and so on) and everything else (es2015).</p>
<p>Because of this, we intend to make major version bumps to any experimental proposal plugins when the spec changes, rather than waiting to update all of Babel. So anything that is &lt; Stage 4 would be open to breaking changes in the form of major version bumps. The same applies to the Stage presets themselves (if we don’t drop them entirely).</p>
<p>This goes along with our decision to require TC39 proposal plugins to use the <code>-proposal-</code> name. If the spec changes, we will do a major version bump to the plugin and the preset it belongs to (as opposed to just making a patch version which may break for people). Then, we will need to deprecate the old versions and setup an infrastructure which will automatically update people so that they’re up to date on what the spec will become (and so they don't get stuck on something. We haven’t been so lucky with decorators.).</p>
<h4 id="heading-the-env-option-in-babelrc-is-not-being-deprecated">The <code>env</code> option in <code>.babelrc</code> is not being deprecated!</h4>
<p>Unlike in the <a target="_blank" href="https://babeljs.io/blog/2017/09/12/planning-for-7.0#deprecate-the-env-option-in-babelrc">last post</a>, we just fixed the merging behavior to be <a target="_blank" href="https://twitter.com/left_pad/status/936687774098444288">more consistent</a>.</p>
<p>The configuration in <code>env</code> is given higher priority than root config items. And instead of the weird approach of just using both, plugins and presets now merge based on their identity, so you can do this:</p>
<pre><code>{
  <span class="hljs-attr">presets</span>: [
    [<span class="hljs-string">'env'</span>, { <span class="hljs-attr">modules</span>: <span class="hljs-literal">false</span>}],
  ],
  <span class="hljs-attr">env</span>: {
    <span class="hljs-attr">test</span>: {
      <span class="hljs-attr">presets</span>: [
         <span class="hljs-string">'env'</span>
      ],
    }
  },
}
</code></pre><p>with <code>BABEL_ENV=test</code> . It would replace the root env config with the one from test, which has no options.</p>
<h4 id="heading-support-class-a-extends-arrayhttpstwittercomleftpadstatus940723982638157829-oldest-caveat">Support <code>[class A extends Array](https://twitter.com/left_pad/status/940723982638157829)</code> (oldest caveat)</h4>
<p>Babel will automatically wrap any native built-ins like <code>Array</code>, <code>Error</code>, and <code>HTMLElement</code> so that doing this just works when compiling classes.</p>
<h4 id="heading-speed">Speed</h4>
<ul>
<li>Many <a target="_blank" href="https://twitter.com/rauchg/status/924349334346276864">fixes</a> from <a target="_blank" href="https://twitter.com/bmeurer">bmeurer</a> on the v8 team!</li>
<li>60% faster via the <a target="_blank" href="https://github.com/v8/web-tooling-benchmark">web-tooling-benchmark</a> <a target="_blank" href="https://twitter.com/left_pad/status/927554660508028929">https://twitter.com/left_pad/status/927554660508028929</a></li>
</ul>
<h4 id="heading-preset-env-usebuiltins-usage">preset-env: <code>"useBuiltins": "usage"</code></h4>
<p><code>babel-preset-env</code> introduced the idea of compiling syntax to different targets. It also introduced, via the <code>useBuiltIns</code> option, the ability to only add polyfills that the targets don't support.</p>
<p>So with this option, something like:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">"babel-polyfill"</span>;
</code></pre>
<p>can turn into</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">"core-js/modules/es7.string.pad-start"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"core-js/modules/es7.string.pad-end"</span>;
<span class="hljs-comment">// ...</span>
</code></pre>
<p>if the target environment happens to support polyfills other than <code>padStart</code> or <code>padEnd</code>.</p>
<p>But in order to make that even better, we should only import polyfills that are “used” in the codebase itself. Why import <code>padStart</code> if it is not even used in the code?</p>
<p><code>"useBuiltins": "usage"</code> is our first attempt to tackle that idea. It performs an import at the top of each file, but only adds the import if it finds it used in the code. This approach means that we can import the minimum amount of polyfills necessary for the app (and only if the target environment doesn't support it).</p>
<p>So if you use <code>Promise</code> in your code, it will import it at the top of the file (if your target doesn't support it). Bundlers will dedupe the file if it is the same, so this approach won't cause multiple polyfills to be imported.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">"core-js/modules/es6.promise"</span>;
<span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>();

<span class="hljs-keyword">import</span> <span class="hljs-string">"core-js/modules/es7.array.includes"</span>;
[].includes
a.includes
</code></pre>
<p>With type inference we can know if an instance method like <code>.includes</code> is for an array or not. Having a false positive is ok until that logic is better, since it is still better than importing the whole polyfill like before.</p>
<h4 id="heading-misc-updates">Misc updates</h4>
<ul>
<li><code>[babel-template](https://github.com/babel/babel/blob/master/packages/babel-template)</code> is faster and easier to use</li>
<li><a target="_blank" href="https://github.com/facebook/regenerator">regenerator</a> was released under the <a target="_blank" href="https://twitter.com/left_pad/status/938825429955125248">MIT License</a> — it’s the dependency used to compile generators/async</li>
<li>“lazy” option to the <code>modules-commonjs</code> plugin via <a target="_blank" href="https://github.com/babel/babel/pull/6952">#6952</a></li>
<li>You can now use <code>envName: "something"</code> in .babelrc or pass via cli <code>babel --envName=something</code> instead of having to use <code>process.env.BABEL_ENV</code> or <code>process.env.NODE_ENV</code></li>
<li><code>["transform-for-of", { "assumeArray": true }]</code> to make all for-of loops output as regular arrays</li>
<li>Exclude <code>transform-typeof-symbol</code> in loose mode for preset-env <a target="_blank" href="https://github.com/babel/babel/pull/6831">#6831</a></li>
<li><a target="_blank" href="https://twitter.com/left_pad/status/942859244759666691">Landed PR for better error messages with syntax errors</a></li>
</ul>
<h4 id="heading-to-dos-before-release">To-dos Before Release</h4>
<ul>
<li><a target="_blank" href="https://github.com/babel/babel/issues/6766">Handle</a> <code>[.babelrc](https://github.com/babel/babel/issues/6766)</code> <a target="_blank" href="https://github.com/babel/babel/issues/6766">lookup</a> (want this done before first RC release)</li>
<li><a target="_blank" href="https://github.com/babel/babel/pull/7091">“overrides” support</a>: different config based on glob pattern</li>
<li>Caching and invalidation logic in babel-core.</li>
<li>Better story around external helpers.</li>
<li>Either implement or have a plan in place for versioning and handling polyfills independently from helpers, so we aren’t explicitly tied to core-js 2 or 3. People may have things that depend on one or the other, and won’t want to load both a lot of the time.</li>
<li>Either a <a target="_blank" href="https://github.com/babel/babel/pull/6107">working decorator implementation</a>, or functional legacy implementation, with clear path to land current spec behavior during 7.x’s lifetime.</li>
</ul>
<h4 id="heading-thanks">Thanks</h4>
<p>Shoutout to our team of volunteers:</p>
<p><a target="_blank" href="https://twitter.com/loganfsmyth">Logan</a> has been really pushing hard to fix a lot of our core issues regarding configs and more. He’s the one doing all of that hard work.</p>
<p><a target="_blank" href="https://twitter.com/existentialism">Brian</a> has been taking over maintenance of a lot of preset-env work and whatever else I was doing before ?</p>
<p><a target="_blank" href="https://twitter.com/TschinderDaniel">Daniel</a> has always stepped in when we need the help, whether it be maintaining babel-loader or helping move the babylon/babel-preset-env repo’s over. And same with <a target="_blank" href="https://twitter.com/NicoloRibaudo">Nicolo</a>, <a target="_blank" href="https://twitter.com/svensauleau">Sven</a>, <a target="_blank" href="https://twitter.com/yavorsky_">Artem</a>, and <a target="_blank" href="https://twitter.com/kovnsk">Diogo</a> who have stepped up in the last year to help out.</p>
<p>I’m really looking forward to a release (I’m tired too — it’s almost been a year ?). But I also don’t want to rush anything just because. There’s been a lot of ups and downs throughout this release, but I’ve certainly learned a lot and I’m sure the rest of the team has as well.</p>
<p>And if I’ve learned anything at all this year, I should really heed this advice rather than just write about it.</p>
<p></p><blockquote><p>"Before you go maintaining anything else, maintain your own body first" - Mom ?</p>— Henry Zhu (@left_pad) <a href="https://twitter.com/left_pad/status/944313617243099136?ref_src=twsrc%5Etfw">December 22, 2017</a></blockquote><p></p>



<blockquote>
<p>Also thanks to <a target="_blank" href="https://twitter.com/kosamari">Mariko</a> for the <a target="_blank" href="https://twitter.com/kosamari/status/944272286055530496">light push</a> to actually finish this post (2 months in the making)</p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
