Getting started with Webpack 3

Written by João Augusto on 26th June 2017

2 comments

Webpack has become one of the most important and popular front-end tools for modern web development. It is a module bundler and was originally created to bundle Javascript files, but it is now being used to bundle all kind of assets. Webpack compiles a bunch of assets and turns that into something that can be used in a browser. There are different ways to use Webpack, but today we going to integrate it with Gulp.

In this post we’ll explain the basics of Webpack and how to get you ready to code a Vue.js app, which we will cover in the next post in the series.

All the files for this blog post can be found in the GitHub repository, on the Webpack branch.

Getting started with Gulp

Let’s start with the gulpfile.js. If you’re familiar with Gulp, then this should be simple to understand. If not, we would recommend reading some blog posts to get you started.

Create a new gulpfile.js in the root directory of your website. Once created we need to then “load” the necessary packages for the project. In this case, we need to load gulp and webpack. We also need the Webpack stream package to run Webpack into a Gulp task. This package allows Webpack to be run in a stream which is what we need.

Load in the packages on your new gulpfile.js as follows:

var gulp = require("gulp"),
    webpack = require('webpack'),
    webpackStream = require('webpack-stream');

These packages don’t exist yet, so we have to download them via NPM or Yarn. On your command line use the following code to install the packages:

$ npm install gulp webpack webpack-stream

Now let’s go back to gulpfile.js and create the default gulp task, so this can be triggered when run gulp from your command line.

gulp.task('default', function() {
  return gulp.src('src/js/app.js')
    .pipe(webpackStream(config, webpack))
    .pipe(gulp.dest('dist/js/'));
});

On a conventional gulp task without webpack, the above code would take app.js and compile it into dist/js, but in this particular case the webpackStream will override the source and destination paths defined in webpack configuration object which we’ll cover later. So we recommend keeping the correct files paths even though they are not going to be used there.

You probably noticed already, there are two parameters been passed into webpackStream. First parameter takes the configuration and the second parameter takes the Webpack package itself. If nothing gets passed in the first parameter this will use the webpack default configuration.

Before we run gulp, we still need to create the folders & files. In src/js create app.js, the main Javascript file. In the same directory create another folder called modules with three javascript files inside. We also need create the destination folder in dist/js for the bundled file. Your file structure should look like this:

/ src / js / app.js
/ src / js / modules / foo.js
/ src / js / modules / bar.js
/ src / js / modules / baz.js
/ dist / js /
/ gulpfile.js

If you’re looking for code examples to go in the module files please use the ones we’ve created in the Liquid Light repository for this purpose.

Set up webpack

The webpack object can be set in different ways. You can either set it all directly in the gulpfile.js or “include” it using the require method. The latter would make the code look tidier and modular, so let’s go with this option.

Firstly create a new webpack.config.js next to your gulpfile - this file will change the way the webpack compile your scripts. As well as the gulpfile.js, we need to require a couple of dependencies - the webpack itself and path (this module provides utilities for working with file and directory paths and is available in Node). The webpack object accepts loads of arguments, but here we going over the basic ones as follows:

var webpack = require('webpack'),
    path = require('path');
 
var srcPath  = path.join(__dirname, '/src/js'),
    distPath = path.join(__dirname, '/dist/js');
 
module.exports = {
    watch: true,
    cache: true,
    devtool: '#cheap-module-eval-source-map',
    context: srcPath,
    entry: {
        app: './app.js',
    },
    output: {
        path: distPath,
        filename: '[name].bundle.js',
    },
    resolve: {
        modules: ["node_modules"],
    },
    plugins: [
        new webpack.NoEmitOnErrorsPlugin()
    ]
};

The options are:

  • watch: Turn on watch mode. This means that after the initial build, webpack will continue to watch for changes in any of the resolved files.
  • cache: Cache the generated webpack modules and chunks to improve build speed.
  • devtool: This option controls if and how Source Maps are generated. See here the different options.
  • context: The base directory, an absolute path, for resolving entry points and loaders from configuration.
  • entry: The point or points to enter the application. At this point the application starts executing. The key will be the name of the compiled file. eg: home: app.js become home.bundle.js
  • output: Output options tell webpack how to write the compiled files to disk. Note, that while there can be multiple entry points, only one output configuration is specified (see output documentation).
  • resolve: Configure how modules are resolved.
    • modules: Tell webpack what directories should be searched when resolving modules.
    • alias: Create aliases to import or require certain modules more easily. The documentation explains very well this parameter.
  • plugins: A list of webpack plugins. For example, when multiple bundles share some of the same dependencies, the CommonsChunkPlugin could be useful to extract those dependencies into a shared bundle to avoid duplication.

These arguments can and should be changed depending on your project, for example, if you want a nicer error message on your compilation screen, you can install a webpack plugin called friendly-errors-webpack-plugin. See here how to use it.

At this point gulpfile.js doesn't know about webpack.config.js yet, so we need to load it. Add var config = require('./webpack.config.js') to gulpfile.js. The config is now the webpack configuration variable and will be passed to webpackStream.

The Webpack is now configured and ready to compile your assets. Running gulp on your command line should display something like this:

$ gulp

[17:55:10] Using gulpfile ~/webpack-project/gulpfile.js
[17:55:10] Starting 'default'...
 DONE  Compiled successfully in 631ms
[17:55:11] Version: webpack 2.5.1
        Asset     Size  Chunks             Chunk Names
app.bundle.js  5.6 kB       0  [emitted]  app
[17:55:11] webpack is watching for changes

If you get a similar message on your command line that means your files are now bundled into one single file in dist/js/ folder. Awesome! If for some reason gulp isn’t compiling feel free to compare your code with the Liquid Light GitHub repository or leave your question in the comment section below.

Further reading:

This article was posted in Development by João Augusto

  • João Augusto

    João Augusto

    A big football, photography and Apple fan - our front-end developer João has not only got the eye for making our websites sparkle, he’s got to have the latest, greatest gear to do it on. @joaoeaugusto

Comments

Great article! Thanks for the explanation

Matthew03/07/2017 15:42

Hie João,

Why would you add an other layer / build tool such as gulp to webpack ? Once you have your webpack.config.js, all you need to do is to run:

./node_modules/.bin/webpack

You can add it to your scripts in your package.json, pass arguments, etc ... no need for gulp.

Tophe12/07/2017 19:05

Post a comment

*
*

Sign up to the Liquid Light newsletter

Subscribe to our Newsletter and stay up to date with all things web related. It's crammed full of useful articles, tips and knowledge, invaluable if you have a website or are starting a new web project.