Webpack: How To Create A Config File

Posted on Aug 08, 2017

Webpack: How To Create A Config File

 

Previously on our blog, we learned about Webpack, its benefits and drawbacks. We also learned that it is a build tool that takes the source code, processes it, and creates a bundle.

But how does Webpack create this bundle? How does it know what to do with the source code we give it?

The answer for this lies in the Webpack Config File.

One of the most important things that goes into setting up Webpack in an application is the config file. This files specifies all the settings that the build tool will use while processing, packing and bundling the application.

Also keep in mind that using a config file is not mandatory. Webpack can bundle the source even without it. However, using the config file has some crucial advantages:

  • It gives us full control over exactly how we want our code to be processed and bundled
  • As a result, it enables better code maintenance and scalability
  • Hence, it is highly recommended for large applications

Firstly, let’s see what goes inside a Config File. After that, we will put together a sample config using what we have learned.

What is Webpack Config File?

It is a JSON object file to specify settings for Webpack so that they can be used for processing, packing and bundling the application.

This JSON object has the some commonly used keys, such as entry, output, module (loaders or rules), plugins, context etc. Let’s take a look at each of these:

Entry Point

As the name suggests, this is the entry point for the Webpack bundle. It can take string, array or object values.

  • String : It resolves the string to a module which loads upon startup.
  • Array :  It loads all modules upon startup, and exports the last one.
  • Object : It creates multiple entry bundles, where the key is the chunk name. Its value can be a string or an array.
entry: {
  page1: "./page1",
  page2: ["./entry1", "./entry2"]
},
output: {
  // Make sure to use [name] or [id] in output.filename
  //  when using multiple entry points
  filename: "[name].bundle.js",
  chunkFilename: "[id].bundle.js"
}

Output

Similarly, output options specify how the bundler should write the compiled files to disk. While there can be multiple entry points, only one output configuration is specified.

Keys of Output :

  • path: This is the output directory as an absolute path (required). The [hash] gets replaced by the hash of the compilation.
  • publicPath : This is the public URL address of the output files when referenced in a browser
  • filename : This specifies the name of each output file on disk.

Note that, output config can differ based on whether the app has single or multiple entry points:

For single entry :

{
  entry: './src/app.js',
  output: {
    filename: 'bundle.js',
    path: __dirname + '/build'
  }
}

For multiple entry points :

For more than a single “chunk”,  we use substitutions to ensure that each file has a unique name.

  • [name] is replaced by the name of the chunk.
  • [hash] is replaced by the hash of the compilation.
  • [chunkhash] is replaced by the hash of the chunk.
 output: {
    filename: '[name].js',
    path: __dirname + '/build'
  }

Loaders

Loaders are transformations applied on a resource file of the app, usually named with a -loader suffix.

e.g. css-loader (used on CSS files)

Loaders are functions running in node.js that take the source of a resource file and return the transformed source.

Since they are functions, they can be chained, and they can also be bound to extensions or RegExps in the configuration. They accept query parameters and are published and installed through npm. Additionally, plugins can give loaders more features.

Installation:

Since most loaders are available on npm, we can simply download them like this:

$ npm install css-loader --save-dev

Usage:

There are multiple ways to use loaders in your app:

  • via require statement
  • via config file
  • via CLI

Configuration:

You can bind loaders to a RegExp:

{
  module: {
    rules: [
      { test: /\.jade$/, use: "jade-loader" },
      // => "jade" loader is used for ".jade" files
      
      { test: /\.css$/, use: "style-loader!css-loader" },
      // => "style" and "css" loader is used for ".css" files

      // Alternative syntax:
      { test: /\.css$/, use: ["style-loader", "css-loader"] },
    ]
  },
}

Plugins

Plugins add functionality typically related to bundles in webpack. They can also include any third party library in app (like jQuery).

There are usually two types of plugins:

  • Built In Plugins: Webpack has many built in plugins
    (e.g. HotModuleReplacementPlugin, ProvidePlugin etc.)
  • Other Plugins: Similarly as loaders, you can install plugins via npm
    npm install component-webpack-plugin
plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.ProvidePlugin({
      $ : "jquery",
      jQuery : "jquery"
    })
 ]

Create the config file

Finally, we can put together a config file using what we learned in the above sections.

Thus, combining the entry, output, loaders and plugins, here is our resulting sample config file:

var webpack = require('webpack');

module.exports = {
 entry: './src/app.js',
 output: {
   filename: 'bundle.js',
   path: __dirname + '/build',
 },
 module: {
   rules: [
     { test: /\.jade$/, use: "jade-loader" },
     { test: /\.css$/, use: ["style-loader", "css-loader"] },
   ],
 },
 plugins: [
   new webpack.HotModuleReplacementPlugin(),
   new webpack.ProvidePlugin({
     $ : "jquery",
     jQuery : "jquery",
   }),
 ],
};