Table of Contents
Key Takeaways
Prerequisites
Set Up
Transpiling with Babel
Organizing Your Code with ES6 Modules
Export
Named Export
Defult Export
Import
Consuming the Exported Module
Introducing webpack and Integrating it with Babel
Transpiling
Bringing It to the Browser
Home Web Front-end JS Tutorial Setting up an ES6 Project Using Babel and webpack

Setting up an ES6 Project Using Babel and webpack

Feb 15, 2025 pm 01:13 PM

Setting up an ES6 Project Using Babel and webpack

In this article, we’re going to look at creating a build setup for handling modern JavaScript (running in web browsers) using Babel and webpack.

This is needed to ensure that our modern JavaScript code in particular is made compatible with a wider range of browsers than it might otherwise be.

JavaScript, like most web-related technologies, is evolving all the time. In the good old days, we could drop a couple of <script> tags into a page, maybe include jQuery and a couple of plugins, then be good to go.</script>

However, since the introduction of ES6, things have got progressively more complicated. Browser support for newer language features is often patchy, and as JavaScript apps become more ambitious, developers are starting to use modules to organize their code. In turn, this means that if you’re writing modern JavaScript today, you’ll need to introduce a build step into your process.

As you can see from the links beneath, converting down from ES6 to ES5 dramatically increases the number of browsers that we can support.

  • ES6 compatibility
  • ES5 compatibility

The purpose of a build system is to automate the workflow needed to get our code ready for browsers and production. This may include steps such as transpiling code to a differing standard, compiling Sass to CSS, bundling files, minifying and compressing code, and many others. To ensure these are consistently repeatable, a build system is needed to initiate the steps in a known sequence from a single command.

Key Takeaways

  • Utilize Babel and webpack to set up a modern JavaScript project, ensuring ES6 code is compatible across a broader range of web browsers.
  • Begin by creating a project structure with a package.json file, and organize code into src and public directories for source and transpiled JavaScript respectively.
  • Install Babel to transpile ES6 to ES5, targeting specific browser versions, and automate this process using npm scripts.
  • Implement ES6 modules to manage and modularize JavaScript code effectively, although compatibility with older browsers like IE11 remains limited.
  • Integrate webpack to bundle JavaScript modules into single or multiple files, reducing server requests and optimizing load times.
  • Enhance development workflow with webpack’s watching and dev-server features to automatically rebuild and refresh the browser upon code changes.

Prerequisites

In order to follow along, you’ll need to have both Node.js and npm installed (they come packaged together). I would recommend using a version manager such as nvm to manage your Node installation (here’s how), and if you’d like some help getting to grips with npm, then check out SitePoint’s beginner-friendly npm tutorial.

Set Up

Create a root folder somewhere on your computer and navigate into it from your terminal/command line. This will be your folder.

Create a package.json file with this:

<span>npm init -y
</span>
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Note: The -y flag creates the file with default settings, and means you don’t need to complete any of the usual details from the command line. They can be changed in your code editor later if you wish.

Within your folder, make the directories src, src/js, and public. The src/js folder will be where we’ll put our unprocessed source code, and the public folder will be where the transpiled code will end up.

Transpiling with Babel

To get ourselves going, we’re going to install babel-cli, which provides the ability to transpile ES6 into ES5, and babel-preset-env, which allows us to target specific browser versions with the transpiled code.

<span>npm install babel-cli babel-preset-env --save-dev
</span>
Copy after login
Copy after login
Copy after login
Copy after login

You should now see the following in your package.json:

<span>"devDependencies": {
</span>  <span>"babel-cli": "^6.26.0",
</span>  <span>"babel-preset-env": "^1.6.1"
</span><span>}
</span>
Copy after login
Copy after login
Copy after login
Copy after login

Whilst we’re in the package.json file, let’s change the scripts section to read like this:

<span>"scripts": {
</span>  <span>"build": "babel src -d public"
</span><span>},
</span>
Copy after login
Copy after login
Copy after login
Copy after login

This gives us the ability to call Babel via a script, rather than directly from the terminal every time. If you’d like to find out more about npm scripts and what they can do, check out this SitePoint tutorial.

Lastly, before we can test out whether Babel is doing its thing, we need to create a .babelrc configuration file. This is what our babel-preset-env package will refer to for its transpile parameters.

Create a new file in your directory called .babelrc and paste the following into it:

<span>{
</span>  <span>"presets": [
</span>    <span>[
</span>      <span>"env",
</span>      <span>{
</span>        <span>"targets": {
</span>          <span>"browsers": ["last 2 versions", "safari >= 7"]
</span>        <span>}
</span>      <span>}
</span>    <span>]
</span>  <span>]
</span><span>}
</span>
Copy after login
Copy after login
Copy after login

This will set up Babel to transpile for the last two versions of each browser, plus Safari at v7 or higher. Other options are available depending on which browsers you need to support.

With that saved, we can now test things out with a sample JavaScript file that uses ES6. For the purposes of this article, I’ve modified a copy of leftpad to use ES6 syntax in a number of places: template literals, arrow functions, const and let.

<span>"use strict";
</span>
<span>function leftPad(str<span>, len, ch</span>) {
</span>  <span>const cache = [
</span>    <span>"",
</span>    <span>" ",
</span>    <span>"  ",
</span>    <span>"   ",
</span>    <span>"    ",
</span>    <span>"     ",
</span>    <span>"      ",
</span>    <span>"       ",
</span>    <span>"        ",
</span>    <span>"         "
</span>  <span>];
</span>  str <span>= str + "";
</span>  len <span>= len - str.length;
</span>  <span>if (len <= 0) return str;
</span>  <span>if (!ch && ch !== 0) ch = " ";
</span>  ch <span>= ch + "";
</span>  <span>if (ch === " " && len < 10)
</span>    <span>return () => {
</span>      cache<span>[len] + str;
</span>    <span>};
</span>  <span>let pad = "";
</span>  <span>while (true) {
</span>    <span>if (len & 1) pad += ch;
</span>    len <span>>>= 1;
</span>    <span>if (len) ch += ch;
</span>    <span>else break;
</span>  <span>}
</span>  <span>return <span>`<span>${pad}</span><span>${str}</span>`</span>;
</span><span>}
</span>
Copy after login
Copy after login

Save this as src/js/leftpad.js and from your terminal run the following:

<span>npm run build
</span>
Copy after login
Copy after login

If all is as intended, in your public folder you should now find a new file called js/leftpad.js. If you open that up, you’ll find it no longer contains any ES6 syntax and looks like this:

<span>"use strict";
</span>
<span>function leftPad(str<span>, len, ch</span>) {
</span>  <span>var cache = ["", " ", "  ", "   ", "    ", "     ", "      ", "       ", "        ", "         "];
</span>  str <span>= str + "";
</span>  len <span>= len - str.length;
</span>  <span>if (len <= 0) return str;
</span>  <span>if (!ch && ch !== 0) ch = " ";
</span>  ch <span>= ch + "";
</span>  <span>if (ch === " " && len < 10) return function () {
</span>    cache<span>[len] + str;
</span>  <span>};
</span>  <span>var pad = "";
</span>  <span>while (true) {
</span>    <span>if (len & 1) pad += ch;
</span>    len <span>>>= 1;
</span>    <span>if (len) ch += ch;else break;
</span>  <span>}
</span>  <span>return "" + pad + str;
</span><span>}
</span>
Copy after login
Copy after login

Organizing Your Code with ES6 Modules

An ES6 module is a JavaScript file containing functions, objects or primitive values you wish to make available to another JavaScript file. You export from one, and import into the other. Any serious modern JavaScript project should consider using modules. They allow you to break your code into self-contained units and thereby make things easier to maintain; they help you avoid namespace pollution; and they help make your code more portable and reusable.

Whilst the majority of ES6 syntax is widely available in modern browsers, this isn’t yet the case with modules. At the time of writing, they’re available in Chrome, Safari (including the latest iOS version) and Edge; they’re hidden behind a flag in Firefox and Opera; and they’re not available (and likely never will be) in IE11, nor most mobile devices.

In the next section, we’ll look at how we can integrate modules into our build setup.

Export

The export keyword is what allows us to make our ES6 modules available to other files, and it gives us two options for doing so — named and default. With the named export, you can have multiple exports per module, and with a default export you only have one per module. Named exports are particularly useful where you need to export several values. For example, you may have a module containing a number of utility functions that need to be made available in various places within your apps.

So let’s turn our leftPad file into a module, which we can then require in a second file.

Named Export

To create a named export, add the following to the bottom of the leftPad file:

<span>npm init -y
</span>
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

We can also remove the "use strict"; declaration from the top of the file, as modules run in strict mode by default.

Defult Export

As there’s only a single function to be exported in the leftPad file, it might actually be a good candidate for using export default instead:

<span>npm install babel-cli babel-preset-env --save-dev
</span>
Copy after login
Copy after login
Copy after login
Copy after login

Again, you can remove the "use strict"; declaration from the top of the file.

Import

To make use of exported modules, we now need to import them into the file (module) we wish to use them in.

For the export default option, the exported module can be imported under any name you wish to choose. For example, the leftPad module can be imported like so:

<span>"devDependencies": {
</span>  <span>"babel-cli": "^6.26.0",
</span>  <span>"babel-preset-env": "^1.6.1"
</span><span>}
</span>
Copy after login
Copy after login
Copy after login
Copy after login

Or it could be imported as another name, like so:

<span>"scripts": {
</span>  <span>"build": "babel src -d public"
</span><span>},
</span>
Copy after login
Copy after login
Copy after login
Copy after login

Functionally, both will work exactly the same, but it obviously makes sense to use either the same name as it was exported under, or something that makes the import understandable — perhaps where the exported name would clash with another variable name that already exists in the receiving module.

For the named export option, we must import the module using the same name as it was exported under. For our example module, we’d import it in a similar manner to that we used with the export default syntax, but in this case, we must wrap the imported name with curly braces:

<span>{
</span>  <span>"presets": [
</span>    <span>[
</span>      <span>"env",
</span>      <span>{
</span>        <span>"targets": {
</span>          <span>"browsers": ["last 2 versions", "safari >= 7"]
</span>        <span>}
</span>      <span>}
</span>    <span>]
</span>  <span>]
</span><span>}
</span>
Copy after login
Copy after login
Copy after login

The braces are mandatory with a named export, and it will fail if they aren’t used.

It’s possible to change the name of a named export on import if needed, and to do so, we need to modify our syntax a little using an import [module] as [path] syntax. As with export, there’s a variety of ways to do this, all of which are detailed on the MDN import page.

<span>npm init -y
</span>
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Again, the name change is a little nonsensical, but it illustrates the point that they can be changed to anything. You should keep to good naming practices at all times, unless of course you’re writing routines for preparing fruit-based recipes.

Consuming the Exported Module

To make use of the exported leftPad module, I’ve created the following index.js file in the src/js folder. Here, I loop through an array of serial numbers, and prefix them with zeros to make them into an eight-character string. Later on, we’ll make use of this and post them out to an ordered list element on an HTML page. Note that this example uses the default export syntax:

<span>npm install babel-cli babel-preset-env --save-dev
</span>
Copy after login
Copy after login
Copy after login
Copy after login

As we did earlier, run the build script from the directory:

<span>"devDependencies": {
</span>  <span>"babel-cli": "^6.26.0",
</span>  <span>"babel-preset-env": "^1.6.1"
</span><span>}
</span>
Copy after login
Copy after login
Copy after login
Copy after login

Babel will now create an index.js file in the public/js directory. As with our leftPad.js file, you should see that Babel has replaced all of the ES6 syntax and left behind only ES5 syntax. You might also notice that it has converted the ES6 module syntax to the Node-based module.exports, meaning we can run it from the command line:

<span>"scripts": {
</span>  <span>"build": "babel src -d public"
</span><span>},
</span>
Copy after login
Copy after login
Copy after login
Copy after login

Your terminal should now log out an array of strings prefixed with zeros to make them all eight characters long. With that done, it’s time to take a look at webpack.

Introducing webpack and Integrating it with Babel

As mentioned, ES6 modules allow the JavaScript developer to break their code up into manageable chunks, but the consequence of this is that those chunks have to be served up to the requesting browser, potentially adding dozens of additional HTTP requests back to the server — something we really ought to be looking to avoid. This is where webpack comes in.

webpack is a module bundler. Its primary purpose is to process your application by tracking down all its dependencies, then package them all up into one or more bundles that can be run in the browser. However, it can be far more than that, depending upon how it’s configured.

webpack configuration is based around four key components:

  • an entry point
  • an output location
  • loaders
  • plugins

Entry: This holds the start point of your application from where webpack can identify its dependencies.

Output: This specifies where you would like the processed bundle to be saved.

Loaders: These are a way of converting one thing as an input and generating something else as an output. They can be used to extend webpack’s capabilities to handle more than just JavaScript files, and therefore convert those into valid modules as well.

Plugins: These are used to extend webpack’s capabilities into other tasks beyond bundling — such as minification, linting and optimization.

To install webpack, run the following from your directory:

<span>npm init -y
</span>
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

This installs webpack locally to the project, and also gives the ability to run webpack from the command line through the addition of webpack-cli. You should now see webpack listed in your package.json file. Whilst you’re in that file, modify the scripts section as follows, so that it now knows to use webpack instead of Babel directly:

<span>npm install babel-cli babel-preset-env --save-dev
</span>
Copy after login
Copy after login
Copy after login
Copy after login

As you can see, this script is calling on a webpack.config.js file, so let’s create that in our directory with the following content:

<span>"devDependencies": {
</span>  <span>"babel-cli": "^6.26.0",
</span>  <span>"babel-preset-env": "^1.6.1"
</span><span>}
</span>
Copy after login
Copy after login
Copy after login
Copy after login

This is more or less the simplest config file you need with webpack. You can see that it uses the entry and output sections described earlier (it could function with these alone), but also contains a mode: 'development' setting.

webpack has the option of using either “development” or “production” modes. Setting mode: 'development' optimizes for build speed and debugging, whereas mode: 'production' optimizes for execution speed at runtime and output file size. There’s a good explanation of modes in Tobias Koppers’ article “webpack 4: mode and optimization” should you wish to read more on how they can be configured beyond the default settings.

Next, remove any files from the public/js folder. Then rerun this:

<span>"scripts": {
</span>  <span>"build": "babel src -d public"
</span><span>},
</span>
Copy after login
Copy after login
Copy after login
Copy after login

You’ll see that it now contains a single ./public/bundle.js file. Open up the new file, though, and the two files we started with look rather different. This is the section of the file that contains the index.js code. Even though it’s quite heavily modified from our original, you can still pick out its variable names:

<span>{
</span>  <span>"presets": [
</span>    <span>[
</span>      <span>"env",
</span>      <span>{
</span>        <span>"targets": {
</span>          <span>"browsers": ["last 2 versions", "safari >= 7"]
</span>        <span>}
</span>      <span>}
</span>    <span>]
</span>  <span>]
</span><span>}
</span>
Copy after login
Copy after login
Copy after login

If you run node public/js/bundle.js from the folder, you’ll see you get the same results as we had previously.

Transpiling

As mentioned earlier, loaders allow us to convert one thing into something else. In this case, we want ES6 converted into ES5. To do that, we’ll need a couple more packages:

<span>"use strict";
</span>
<span>function leftPad(str<span>, len, ch</span>) {
</span>  <span>const cache = [
</span>    <span>"",
</span>    <span>" ",
</span>    <span>"  ",
</span>    <span>"   ",
</span>    <span>"    ",
</span>    <span>"     ",
</span>    <span>"      ",
</span>    <span>"       ",
</span>    <span>"        ",
</span>    <span>"         "
</span>  <span>];
</span>  str <span>= str + "";
</span>  len <span>= len - str.length;
</span>  <span>if (len <= 0) return str;
</span>  <span>if (!ch && ch !== 0) ch = " ";
</span>  ch <span>= ch + "";
</span>  <span>if (ch === " " && len < 10)
</span>    <span>return () => {
</span>      cache<span>[len] + str;
</span>    <span>};
</span>  <span>let pad = "";
</span>  <span>while (true) {
</span>    <span>if (len & 1) pad += ch;
</span>    len <span>>>= 1;
</span>    <span>if (len) ch += ch;
</span>    <span>else break;
</span>  <span>}
</span>  <span>return <span>`<span>${pad}</span><span>${str}</span>`</span>;
</span><span>}
</span>
Copy after login
Copy after login

To utilize them, the webpack.config.js needs a module section adding to it after the output section, like so:

<span>npm run build
</span>
Copy after login
Copy after login

This uses a regex statement to identify the JavaScript files to be transpiled with the babel-loader, whilst excluding anything in the node_modules folder from that. Lastly, the babel-loader is told to use the babel-preset-env package installed earlier, to establish the transpile parameters set in the .babelrc file.

With that done, you can rerun this:

<span>"use strict";
</span>
<span>function leftPad(str<span>, len, ch</span>) {
</span>  <span>var cache = ["", " ", "  ", "   ", "    ", "     ", "      ", "       ", "        ", "         "];
</span>  str <span>= str + "";
</span>  len <span>= len - str.length;
</span>  <span>if (len <= 0) return str;
</span>  <span>if (!ch && ch !== 0) ch = " ";
</span>  ch <span>= ch + "";
</span>  <span>if (ch === " " && len < 10) return function () {
</span>    cache<span>[len] + str;
</span>  <span>};
</span>  <span>var pad = "";
</span>  <span>while (true) {
</span>    <span>if (len & 1) pad += ch;
</span>    len <span>>>= 1;
</span>    <span>if (len) ch += ch;else break;
</span>  <span>}
</span>  <span>return "" + pad + str;
</span><span>}
</span>
Copy after login
Copy after login

Then check the new public/js/bundle.js and you’ll see that all traces of ES6 syntax have gone, but it still produces the same output as previously.

Bringing It to the Browser

Having built a functioning webpack and Babel setup, it’s time to bring what we’ve done to the browser. A small HTML file is needed, and this should be created in the folder as below:

<span>npm init -y
</span>
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

There’s nothing complicated in it. The main points to note are the

    element, where the array of numbers will be going, and the <script></script> element just before the closing

    The above is the detailed content of Setting up an ES6 Project Using Babel and webpack. For more information, please follow other related articles on the PHP Chinese website!

    Statement of this Website
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

    Hot AI Tools

    Undresser.AI Undress

    Undresser.AI Undress

    AI-powered app for creating realistic nude photos

    AI Clothes Remover

    AI Clothes Remover

    Online AI tool for removing clothes from photos.

    Undress AI Tool

    Undress AI Tool

    Undress images for free

    Clothoff.io

    Clothoff.io

    AI clothes remover

    Video Face Swap

    Video Face Swap

    Swap faces in any video effortlessly with our completely free AI face swap tool!

    Hot Tools

    Notepad++7.3.1

    Notepad++7.3.1

    Easy-to-use and free code editor

    SublimeText3 Chinese version

    SublimeText3 Chinese version

    Chinese version, very easy to use

    Zend Studio 13.0.1

    Zend Studio 13.0.1

    Powerful PHP integrated development environment

    Dreamweaver CS6

    Dreamweaver CS6

    Visual web development tools

    SublimeText3 Mac version

    SublimeText3 Mac version

    God-level code editing software (SublimeText3)

    What should I do if I encounter garbled code printing for front-end thermal paper receipts? What should I do if I encounter garbled code printing for front-end thermal paper receipts? Apr 04, 2025 pm 02:42 PM

    Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

    Demystifying JavaScript: What It Does and Why It Matters Demystifying JavaScript: What It Does and Why It Matters Apr 09, 2025 am 12:07 AM

    JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

    Who gets paid more Python or JavaScript? Who gets paid more Python or JavaScript? Apr 04, 2025 am 12:09 AM

    There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

    How to merge array elements with the same ID into one object using JavaScript? How to merge array elements with the same ID into one object using JavaScript? Apr 04, 2025 pm 05:09 PM

    How to merge array elements with the same ID into one object in JavaScript? When processing data, we often encounter the need to have the same ID...

    Is JavaScript hard to learn? Is JavaScript hard to learn? Apr 03, 2025 am 12:20 AM

    Learning JavaScript is not difficult, but it is challenging. 1) Understand basic concepts such as variables, data types, functions, etc. 2) Master asynchronous programming and implement it through event loops. 3) Use DOM operations and Promise to handle asynchronous requests. 4) Avoid common mistakes and use debugging techniques. 5) Optimize performance and follow best practices.

    How to achieve parallax scrolling and element animation effects, like Shiseido's official website?
or:
How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? How to achieve parallax scrolling and element animation effects, like Shiseido's official website? or: How can we achieve the animation effect accompanied by page scrolling like Shiseido's official website? Apr 04, 2025 pm 05:36 PM

    Discussion on the realization of parallax scrolling and element animation effects in this article will explore how to achieve similar to Shiseido official website (https://www.shiseido.co.jp/sb/wonderland/)...

    The Evolution of JavaScript: Current Trends and Future Prospects The Evolution of JavaScript: Current Trends and Future Prospects Apr 10, 2025 am 09:33 AM

    The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

    The difference in console.log output result: Why are the two calls different? The difference in console.log output result: Why are the two calls different? Apr 04, 2025 pm 05:12 PM

    In-depth discussion of the root causes of the difference in console.log output. This article will analyze the differences in the output results of console.log function in a piece of code and explain the reasons behind it. �...

    See all articles