Chapter 5. Tools: webpack and Babel

This chapter covers

  • Using webpack to load Node.js packages via npm in order to use them in browser code
  • Compiling code with Babel using webpack loaders
  • Loading CSS with webpack loaders
  • Using webpack plugins to prepare your code for production
  • Creating multiple configurations to manage builds for multiple environments

The JavaScript ecosystem provides many great libraries and tools to make writing applications faster and easier for developers. To take advantage of them, you need to have tooling in place that can compile, transform, and prepare your code for production. Enter webpack, a build tool that’s entirely configuration driven.

I’m going to be completely honest with you: webpack isn’t an intuitive tool. I found it frustrating to work with at first. But it’s extremely powerful and worth learning. Webpack gives you the ability to include any JavaScript code in your build, even libraries that haven’t been set up to run in the browser (for example, npm packages). It also can take care of many other build steps, including compiling your code with Babel and preparing your code for production. This chapter covers all the basics you need in order to have a good workflow in your isomorphic project.

Note

If you ever want to start a React project with webpack set up for you, I recommend Create React App. This tool generates a base React app with webpack (https://github.com/facebookincubator/create-react-app). Note that it’s not isomorphic!

5.1. Webpack overview

Imagine you’re starting a new isomorphic React project. You want to build a calendar reminder app like the one in figure 5.1. This chapter is about the build tools—so this is just a signpost to help you make sure things are loading.

Figure 5.1. The calendar reminder app you’ll be setting up with webpack in this chapter

In this example, you’ve decided not to build a calendar from scratch. A lot of well-written React calendar packages are available on npm. To use these packages and build your own app on top of them, you need a build tool that will package your Java-Script modules in a way that the browser understands. (Also, this chapter is about the build tool, not making an app, so using a package will let you focus on learning webpack.)

If you’re wondering why you need to learn yet another build tool, give me a few minutes to convince you. Let’s cover the app requirements to establish why a build tool is necessary. That way, you don’t have to take my word for it. Table 5.1 gives an overview of the app requirements and the reasons you need webpack.

Table 5.1. An overview of the various app requirements that make a build tool necessary

Requirement

Webpack required

Reason

Calendar widget (react-big-calendar) Yes Import from npm package. In particular, this is something that can’t be achieved through tools such as Gulp and Grunt or npm build scripts.
ES6 Yes Requires compilation to work in all browsers. This could be achieved with other tools, but webpack loaders make it straightforward.
Load CSS Optional Optimize development flow by including in the webpack build. This can’t be achieved with tools such as Gulp or Grunt.
Environment-specific code Yes Webpack plugins allow you to inject custom variables. This can’t be achieved with Gulp or Grunt.

Additionally, there are many other reasons a build tool is required for the app. You want to use ES6 to write the latest JavaScript code, but cross-browser support for ES6 is mixed. To allow you to use all the latest language features, you need to compile your code.

Finally, in order to load CSS, you need webpack loaders. You also need webpack plugins to inject variables into code. Remember, all the code will run in the server and the browser! (If this reminder is starting to feel repetitive, that’s great—you’re on your way to thinking in isomorphic terms.)

Running the code

All code for this chapter is located on GitHub at https://github.com/isomorphic-dev-js/chapter5-webpack-babel. After you’ve checked out the code with Git, you need to do an npm install:

$ npm install

To run the complete example, run the following command:

$ npm run start

Then you can load the calendar example at http://localhost:3050. You’ll use additional scripts and examples throughout the chapter. I’ll explain them as needed.

Before we dive into the specifics of a webpack configuration, I’m going to show you how to set up your environment to work with webpack, including how to run the webpack command-line interface (CLI). The command-line tool will be useful for debugging issues and is great for working on small projects. Later in the chapter, you’ll learn to use webpack via JSON configuration.

To use webpack, you need to install it (I’ve already set up the repo with webpack). I recommend doing this on a per project basis rather than installing it globally so you can use the version of webpack appropriate to each project.

After webpack is installed, you can use the webpack CLI to generate your first webpack bundle. The syntax is shown next.

Definition

A bundle is the file outputted by the webpack transformation pipeline. You can name a bundle anything you want.

To run this command in the repo, put this command into your terminal:

$ node_modules/.bin/webpack --entry ./src/entry.js --output-filename
     output.js --output-path ./

After running this command, you’ll notice a new file in the root of the project code directory called output.js, shown in listing 5.1. This file contains your compiled code from entry.js and any dependencies. First take a look at the entry.js file contents (written in ES5—later in the chapter, you’ll add Babel to compile ES6). This code is already provided in the repo.

Listing 5.1. Entry.js contents—src/entry.js
var path = require('path');                                1

console.log("path to root", path.resolve('../'));          2

  • 1 Path included as dependency—require() is used instead of import because this code isn’t being compiled by Babel.
  • 2 Log the path to the root folder using path.resolve with the relative path

The compiled version of this code is nearly 400 lines of code, some of which is shown in the next listing. That’s because webpack collects all the referenced files (the node module path, in this case) and includes them in the bundled output.

Listing 5.2. Compiled webpack output, partial view—output.js
/* ...additional file contents */
/******/  // Load entry module and return exports, and additional
/******/polyfills/webpack code
/* WEBPACK VAR INJECTION */}.call(
/***/ exports,
/***/__webpack_require__(1)))                                     1

/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {           1

"use strict";


module.exports = __webpack_require__(31);                         2


/***/ }),
/* 5 */                                                           3
/***/ (function(module, exports, __webpack_require__) {
/* additional file contents... */

  • 1 Webpack wraps modules (your code, any included npm libraries) in JavaScript closures, which allows webpack to control, and rewrite import statements.
  • 2 The require statement for path compiles into a custom webpack require statement. The path module is located by number key.
  • 3 Human-readable comments indicating the number of each module are added to the final output (helps with debugging).

The bundled code includes additional functions that are part of the webpack library. This includes a browser-friendly polyfill of the Node.js process object, which allows you to safely include many npm modules that were originally written for Node.js.

There are some exceptions to this. For example, the Node.js file system (fs) module isn’t safe for isomorphic use. If an npm package relies on the fs module, you shouldn’t use it for browser code. Now that you’ve seen how to use the command line to bundle your code, take a look at figure 5.2. It shows how webpack takes your code and creates a bundled output.

Figure 5.2. The webpack compiler flow

Debugging webpack

Sometimes webpack will fail to compile. You have two helpful command-line options for debugging. The first option, --debug, shows errors in the command line. The second option, --display-error-details, provides an additional level of detail about any errors that occur.

Webpack can also be debugged using node --inspect. This loads a debugging tool with which you can see Node.js code in the Chrome DevTools. Then you can use breakpoints to debug. For more --inspect resources, see https://nodejs.org/en/docs/inspector/.

Now that you’ve seen how to use webpack and explored the parts of a webpack bundle, you’ll learn how to use webpack loaders to compile your code.

5.2. Babel overview

Babel is a tool for compiling JavaScript. It takes code that isn’t yet supported in all JavaScript environments and compiles it into something understandable by browsers. If you want to use the latest and greatest parts of the JavaScript spec (ES6, ES7, or sometimes also referred to as ES2015, ES2016, and so forth), you must use a compiler. It should be noted that the latest versions of Node.js now support most (but not quite all) of the JavaScript spec. But in the browser, support is varied and rolls out more slowly.

In the preceding section, you learned that webpack is a tool that brings together many loaders and plugins to create a single bundled code file. Babel is a library that does a single job: it compiles JavaScript. Babel is one of many loaders you can use with webpack.

5.2.1. Getting started with Babel

Babel compiles to code that can be understood by any browser running ES5 JavaScript. The generated output is human readable, as you can see in the following listing, and includes Babel-injected code that helps convert ES6 syntax into something understood by older JavaScript engines.

Listing 5.3. Babel sample output
'use strict';

var _createClass = function () {/*implementation code*/}();       1

var _react = require('react');                                    2

var _react2 = _interopRequireDefault(_react);                     3

function _interopRequireDefault(obj) {
  /*implementation code*/
}                                                                 4

var Link = function Link(props) {                                 5
  return _react2.default.createElement(
    'a',
    { href: props.link },
    props.children
  );
};

var Button = function (_React$Component) {
  _{/*implementation code*/}
}

_createClass(Button, [{                                           6
    key: 'render',
    value: function render() {{/*implementation code*/}
  }]);

  return Button;
}(_react2.default.Component);

  • 1 Babel-injected function that converts ES6 class into ES5
  • 2 All import statements converted to requires
  • 3 Each import statement converts to two requires: one the standard ES5 require, the other using a special function to ensure the export default feature of ES6 works properly.
  • 4 Babel-injected function that checks for the default export
  • 5 ES6-style functions converted to function() {} syntax
  • 6 Button written as a class in ES6, so here it’s wrapped by Babel _createClass helper function.

The compiled code in listing 5.3 is based on the ES6 code in listing 5.4. Notice that the base code is much simpler and doesn’t include many of the helper functions that Babel adds to help run your code in JavaScript environments that don’t yet support ES6.

Listing 5.4. ES6 code to compile—src/compile-me.js
import React from 'react';                                   1
import classnames from 'classnames';                         1

const Link = (props) => {                                    2
  return (<a href={this.props.link}>
           {this.props.children}
         </a>)
}
class Button extends React.Component {                       3
  constructor(props) {
    super(props);
  }

  render() {
    let classes = 'button';                                  4
    if (this.props.classname) {
      classes = classnames(classes, this.props.classnames);
    }
    return (
      <Button
        className={classnames}
        onClick={this.props.clickHandler}>                   5
        {this.props.children}
      </Button>
    );
  }
}

  • 1 Currently, import statements need to be compiled for all environments (node and browsers).
  • 2 ES6 function syntax with scope of parent rather than caller
  • 3 A class declaration
  • 4 The let variable (or in other cases, const)
  • 5 Babel compiler also compiles the JSX.

5.2.2. The Babel CLI

Babel can be used on its own as a command-line tool. To get started and understand how this tool works, you’ll use the Babel CLI to process the ES6 from listing 5.3:

$ ./node_modules/.bin/babel src/
     compile-me.jsx

Babel takes the input (the code in src/compile-me.js), parses it, transforms it, and then generates a version of the code that’s compatible with standard browser and Node.js environments. Figure 5.3 shows this compile flow. You’ll notice that this flow is similar to webpack’s flow.

Figure 5.3. How the Babel compiler transforms ES6 into browser- and Node.js-compatible code

The command in this section outputs the result to the command line. Later, you’ll use Babel to compile the code as part of the webpack build.

Babel plugins and presets

Out of the box, Babel doesn’t know what rules to use to compile your code. But you can use plugins that tell Babel what to do. Conveniently, these plug-ins are often grouped into presets. Presets and plugins need to be installed from npm. If you wanted to use the Babel React preset, you’d install the following:

$ npm install babel-preset-react

If you’re working with the provided code, all the presets you need for this chapter are already installed. After you’ve installed all the Babel presets you want to use, you can reference them in the .babelrc file, provided in the repo and shown in the following listing.

Listing 5.5. .babelrc configuration file—.babelrc
{
  "presets": ["es2015", "react"]           1
}

  • 1 Tell Babel what presets to use when compiling (you can list multiple presets in an array).

These presets tell Babel to compile everything to ES2015 and properly process JSX. Next we’ll look at the Calendar App code.

5.3. The app code

Throughout the rest of this chapter, when you run webpack, you’ll be compiling the Calendar App code. Two files make up this example: src/app.jsx and src/main.jsx.

The entry point file for the webpack builds is main.jsx. The following listing shows the code that’s provided in the repo.

Listing 5.6. Entry file—src/main.jsx
import React from 'react';                            1
import ReactDOM from 'react-dom';                     1
import App from './app';                              1

ReactDOM.render(
  <App></App>,
  document.getElementById('attach-react')             2

  • 1 Import dependencies including React and App component
  • 2 Attach the root component (App) to the DOM.

The entry point file includes a single component called App from src/app.jsx. Shown in the next listing, this component includes npm packages and renders the React Big Calendar component. It also includes the CSS for the calendar. We’ll talk more about including the CSS in this format when you learn about webpack loaders.

Listing 5.7. App component—src/app.jsx
import React, { Component } from 'react';                   1
import BigCalendar from 'react-big-calendar';               1
import moment from 'moment';                                1
require('react-big-calendar/lib/css/
 react-big-calendar');                                    2

BigCalendar.momentLocalizer(moment);                        3

class App extends Component {                               4
  render() {
    return (
      <div className="calendar-app">
        <BigCalendar                                        5
          events={[]}
         startAccessor='startDate'
          endAccessor='endDate'
          timeslots={3}>
        </BigCalendar>
      </div>
    )
  }
}

export default App;
);

  • 1 Import all dependencies including moment (react-big-calendar requires a date library).
  • 2 Require the CSS that comes with react-big-calendar.
  • 3 Initialize the Calendar component.
  • 4 Create the App component.
  • 5 Render Big Calendar with the required props.

These files are simple but will allow you to learn webpack without the example getting in the way. They require Babel to compile the ES6 features (import, class) and the JSX. You also need to load the CSS properly. The next section shows how to configure webpack from a JavaScript file and introduces using loaders.

5.4. Webpack config with loaders

Earlier in the chapter, you bundled your code with webpack via the command line. But webpack is also configurable with a JavaScript configuration file. This file is called webpack.config.js by convention. (You can use any name you want in your own projects.)

The config file is loaded by the webpack command. By default, the command will look for a file called webpack.config.js. To load the default config, run the following command in Terminal:

$ ./node_modules/.bin/webpack

This loads the configuration file, compiles your code, and outputs a bundle file that can then be loaded in the browser. The most basic configuration file includes an entry point and output information (if you ever find yourself needing a simple configuration like this one, you can also stick to the command-line options introduced at the beginning of the chapter), as shown in the following listing.

Listing 5.8. webpack.config.js
var path = require('path');

module.exports = {
  entry: path.resolve(__dirname + '/src/main.js'),          1
  output: {                                                 2
    path: path.resolve(__dirname + '/'),                    3
    filename: 'webpack-bundle.js'                           4
  }
}

  • 1 Entry point uses Node.js path module to resolve path relative to current directory (helpful for continuous integration tools).
  • 2 Declare output object.
  • 3 Use path module to resolve path to output (in this case, root directory).
  • 4 Declare filename of output.

Next, you’ll add in webpack loaders to compile your ES6 and CSS.

5.4.1. Configuring the Babel loader

To use Babel within webpack, you need two things. First, you still need the .babelrc file you saw earlier in the chapter. This tells Babel what presets to compile with (React and ES6). Second, you need to declare Babel as a loader in the webpack configuration. Listing 5.9 shows the code for the loader.

Tip

Pay close attention to the shape of the configuration object—otherwise, your build will fail silently. This will be followed by a series of apocalyptic events and a sudden dislike for all build tools. In all seriousness, if your webpack build is failing silently, check that you put all your properties in the right place. You can use the --debug and --progress options to help you debug (more info at https://webpack.js.org/api/cli/#debug-options).

Listing 5.9. Adding Babel loader webpack.config.js
var path = require('path');

module.exports = {
  entry: path.resolve(__dirname + '/src/main.js'),
  output: {
    path: path.resolve(__dirname + '/'),
    filename: 'webpack-bundle.js'
  },
  module: {                                             1
    rules: [                                            2
      {
        test: /.(js|jsx)$/,                            3
        exclude: /node_modules/,                        4
        loader: "babel-loader"                          5
      }
    ]
  }
}

  • 1 Add module object.
  • 2 Array of all loaders to use (called rules)
  • 3 Regular expression that determines what files should be processed by this loader—for Babel, we want js and jsx files.
  • 4 You can tell the loader to ignore files, Node.js packages are already compiled, so you don’t need to process them again.
  • 5 Declare which loader should be used for this loader configuration.

Loaders are applied during the resolver step of the webpack compile process. Figure 5.4 shows how this fits into the overall webpack flow. Notice that this will happen many times, as each dependency may pass through one or many loaders.

Figure 5.4. Loaders are applied during the resolver phase of a webpack compile.

Using custom extensions

Often when writing JSX and ES6, it’s nice to be able to declare your files with an extension other than .js. This indicates to other developers (and in some cases, to your IDE) that the file is of a specific syntax type.

It can also be convenient to not have to write an extension on your import statements. This can be a requirement for some testing setups to work properly. In webpack, to cover these uses cases, you add the resolve property and declare an array of extensions to use. See the following listing.

Listing 5.10. Extension list webpack.config.js
module.exports = {
  entry: path.resolve(__dirname + '/src/main.js'),
  output: {},
  module: {},
  resolve: {                                               1
    extensions: ['.js', '.jsx', '.css']                    2
  }
}

  • 1 Add resolve object.
  • 2 Declare array of extensions—for calendar example, you need .js, .jsx, and .css.

5.4.2. Configuring the CSS loader

Webpack can pack almost anything into your JavaScript bundle, including your CSS. This is awesome for development, but for many production use cases you’ll still want to load your CSS and other assets separately (don’t worry, webpack can do that too!). See the next listing.

Listing 5.11. Including CSS with webpack—webpack.config.js
module.exports = {
  ...
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },
      {
        test:/.css/,                                               1
        loaders: ['style-loader', 'css-loader']                     2
      }
    ]
  }
}

  • 1 For this loader you need to process only CSS files, so regular expression looks for .css.
  • 2 This loader uses two webpack loaders, style-loader and CSS-loader—note the key has changed from loader to loaders because list is declared as array of strings.

This code adds two loaders. The CSS loader takes any import and url() references and interprets them as require. The style loader includes the styles in the bundle so your CSS is available in the browser.

By including the CSS, you can take advantage of the component style of writing your CSS. To do this, you create a set of styles for each component and namespace them. Then you don’t have to worry about overwriting common class names such as .button or .active.

Additionally, I’ve found this modular CSS to be easier to reason about for large development teams, though there are trade-offs. One major trade-off is you tend to end up with less DRY (don’t repeat yourself) CSS. But this can be combatted with shared global classes or mixins if you’re using PostCSS or other compiled CSS options (LESS, SASS, and so forth).

Additional loaders

Many more loaders can be used with webpack. You can load all kinds of files, including JSON, HTML, and image assets. You can also preprocess your preferred CSS using LESS/SASS/PostCSS.

You can also use loaders for linting. For example, if you want to use ESLint in your project, there’s a webpack loader for it (the example introduced in chapter 4 uses ESLint). There are loaders for almost anything you can think of doing in a web app project!

For a list of webpack loaders, check out https://webpack.js.org/loaders/.

5.5. Bundling for dev and production

So far, you’ve used only a single configuration file for your development environment. But for a real-world app, you need to prepare your webpack configuration files for multiple environments.

For simplicity, you’ll set up two environment-specific configuration files called dev.config.js and prod.config.js. Because these files are just JavaScript, you can create a base file, called base.config.js. All these files will live in the config folder.

The base file is identical to the webpack.config.js file you’ve already created in this chapter. The other two files require it and then extend the configuration. First you’ll add a webpack plugin to dev.config.js.

5.5.1. Using webpack plugins

A webpack plugin is an additional code module that you can include in the plugins array of your webpack configuration. The webpack library ships with several built-in plugins. Many plugins can also be found on npm, and you even can write your own plugin.

For the dev config, you need the html-webpack-plugin. This plugin autogenerates an HTML file that loads the bundled JavaScript. This is set up in the dev.config.js file, as shown in the following listing.

Listing 5.12. Add a plugin—config/dev.config.js
var baseConfig = require('./base.config.js');                       1
var HtmlWebpackPlugin = require('html-webpack-plugin');             2
module.exports = Object.assign(baseConfig, {                        3
  output: {
    filename: 'dev-bundle.js'                                       4
  },
  plugins: [                                                        5
    new HtmlWebpackPlugin({                                         6
      title: "Calendar App Dev",                                    7
      filename: 'bundle.html'                                       8
    })
  ]
})

  • 1 Require base configuration object.
  • 2 Include html-webpack-plugin that will autogenerate a HTML file.
  • 3 Use Object.assign to merge environment-specific configuration onto baseConfig; keys from this configuration will override base configuration.
  • 4 Declare environment-specific filename.
  • 5 Declare plugins array.
  • 6 Create new instance of HtmlWebpackPlugin.
  • 7 Title property sets <title> tag in HTML template.
  • 8 Output filename for generated HTML.

To use this code, run the following command:

$ npm run dev

Then you can navigate to http://localhost:3050/bundle.html and see the dev bundle.

Plugins can hook into a variety of webpack compiler steps. They can add code at the beginning of the compile step, during the optimization step, during the emit files stage, and at many other phases of the webpack compiler.

The HTML webpack plugin does most of its work during the emit step because its main job is to create a file. The emit step is where the files are created based on all the previous compilation steps.

5.5.2. Creating globals

You can also use plugins to define environment variables. Webpack ships with a plugin called definePlugin that allows you to inject variables into your webpack module, as shown in listing 5.13. You can then access these variables in code:

console.log("current environment: ",  __ENV__);

During the compile step, webpack converts the variable to the injected value. In this case, the code in the bundle will look like this:

console.log("current environment: ", ("dev"));

Listing 5.13. Inject globals—config/dev.config.js
var webpack = require('webpack');                         1

var injectEnvironment = new webpack.DefinePlugin({        2
  __ENV__: JSON.stringify("dev")                          3
});

module.exports = Object.assign(baseConfig, {
  output: {},
  plugins: [
    ...,
    injectEnvironment                                     4
  ]
})

  • 1 Require webpack because Define-Plugin is included with webpack.
  • 2 Create new instance of DefinePlugin.
  • 3 Inject any number of variables here—in this case, set environment value.
  • 4 Load plugin in plugin array.

One gotcha with DefinePlugin is that for strings, it’s important to use JSON.stringify. If you just assign a string (__ENV__: "dev"), then in the bundled version you’ll get the following output:

console.log("current environment: ", (dev));

That will throw a ReferenceError in your browser because it’ll read dev as a JavaScript variable.

5.5.3. Working with sourcemaps

One of the drawbacks of developing with webpack is that the bundled code isn’t human readable and no longer resembles the source code. Fortunately for debugging, webpack provides the ability to enable sourcemaps. Without sourcemaps, it’s difficult to match code errors up to your file structure.

With sourcemaps enabled, webpack generates additional code (sometimes inline and sometimes in a separate file) that maps the generated code back to the original file structure. That’s helpful when debugging, because tools such as Chrome DevTools will allow you to inspect the original code rather than the compiled code. Figure 5.5 shows how Chrome DevTools loads the original file.

Figure 5.5. Chrome DevTools uses the generated sourcemaps to link the compiled code to the source file.

Enabling sourcemaps is straightforward, as shown in listing 5.14. You add the devtool property to your webpack configuration to enable sourcemaps from the webpack configuration file. According to the webpack docs, you can use this sourcemap option for production. For bigger projects, this can have performance impacts, so tread carefully.

Listing 5.14. Adding sourcemaps—config/dev.config.js
module.exports = Object.assign(baseConfig, {
  output: {},
  devtool: 'source-map',
  plugins: []
})

Several valid sourcemap options are available for webpack. Each one makes a trade-off between performance and developer readability. The option in dev.config.js outputs a separate map file and loads the full original source. But it’s on the slower side. If you need to adjust your sourcemap options, I recommend checking out webpack’s documentation for sourcemaps at https://webpack.js.org/configuration/devtool/.

Next we’ll use webpack plugins to create a production-ready configuration.

5.5.4. Preparing the build for production

To prepare a production build, you need to do a few things:

  • Make the bundle as small as possible: add plugins for uglifying and deduping your code
  • Inject production environment variables
  • Output to a different output bundle

The goal is to end up with a non-human-readable, minified file with the smallest footprint possible. It should look something like figure 5.6.

Figure 5.6. Production output compiled with additional webpack plugins

In order to end up with production output, you will use some additional plugins to prepare the code. The following listing shows how to create a webpack configuration file that is ready for production.

Listing 5.15. Production build—config/prod.config.js
var baseConfig = require('./base.config.js');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

var injectEnvironment = new webpack.DefinePlugin({
  __ENV__: JSON.stringify("prod")                           1
});
module.exports = Object.assign(baseConfig, {
  output: {
    filename: 'prod-bundle.js'                              2
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin({                   3
        compress: {
            warnings: false,
            drop_console: true
        }
    }),
    new HtmlWebpackPlugin({
      title: "Calendar App",
      filename: 'prod-bundle.html'                          4
    })
    injectEnvironment
  ]
});

  • 1 Inject prod environment variable.
  • 2 Change bundle name for current environment.
  • 3 Uglify your code—this both compresses and uglifies the code.
  • 4 Change filename of outputted HTML file.

Plugins have many use cases and can help you with everything from configuration to uglifying your output. For this reason, several plugins ship with webpack that can help you prepare your build for production. In addition to the plugins shown in the preceding listing, you can read about other webpack plugins on the webpack site (https://webpack.js.org/configuration/plugins/) and the npm site (www.npmjs.com/search?q=webpack+plugin). As of the latest version of webpack, deduping module includes and occurrence ordering are default behaviors.

Summary

In this chapter, you learned that webpack is a powerful build tool that can be used to compile your project into a browser bundle. You learned to use Babel on its own and as part of webpack via loaders. Both of these tools are useful in many JavaScript contexts and make great additions to your personal toolkit.

  • With webpack, you can compile your JavaScript code, including npm modules.
  • With the Babel compiler you can use the latest features of JavaScript and still run your code in all browsers and Node.js environments.
  • Loaders are add-on modules for webpack that allow you to use additional tools such as Babel to bundle your code.
  • CSS can be loaded and compiled via webpack using loaders.
  • Plugins are powerful add-ons for the webpack compiler that give you access to many additional features, including preparing your build for production and automatically generating HTML wrappers for your webpack code.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.249.105