Skip to content

Create webpack build script

Daniel Bischoff edited this page Apr 3, 2018 · 10 revisions

Add existing webpack build config

We set up our scripts but currently they do nothing. Let's change that.

For our build script, we want it to load our webpack build config and build our project to an output folder.

Create a folder named config. We will put all build configs in it. In most cases you already have webpack config files so this is the moment to copy your config files in this folder. Or if you start from scratch, create a webpack.prod.config file there.

Because these config file(s) are not in the app project(s) themselves, we have to give our configs an absolute path to our app project. Otherwise it will look for our src folder in the build-project but there is no source folder. So it is wise to create a file that contains all paths for us.

Create another file named paths.js under the scripts folder. So whenever you have to provide a new path to any config, add this path to this file and reference it from there. Then add the following content:

scripts/paths.js

'use strict';
const path = require('path');
const fs = require('fs');

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);

module.exports = {
  appPath: resolveApp('.'),
  appBuild: resolveApp('dist'),
  appIndex: resolveApp('src/index.js'),
  appSrc: resolveApp('src'),
  ...
};

The most important line:

const appDirectory = fs.realpathSync(process.cwd());

This line retrieves the app's directory! Because we will always run the command from our app's directory, we can get its directory by calling process.cwd().

In your webpack config, you have to change every relative path to an absolute path. I will show you the most common paths you have to change. If these properties don't exist yet, add these properties to your webpack config.

scripts/webpack.prod.config

const paths = require('./paths');
const babelrcConfig = require('./.babelrc');

const config = {
  entry: paths.appIndex,
  output: {
    path: paths.appBuild,
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        include: paths.appSrc,
        use: [
          {
            loader: 'babel-loader',  
            options: babelrcConfig,            
          },
        ],
      },
    ]
  },
  plugins: [    
    new HtmlWebpackPlugin({
      template: paths.appHtml,
    }),
  ]
};

As you can see, you have to handle two cases on how to provide a new path.

An option to set paths exist

The webpack config file allows you to set the paths required for the build. These paths are documented in the docs. That is the easy way how you can change paths.

There is no option to set paths

If there is no option to set the paths (like in the babel-loader), you can load the config's content in most cases and pass it as an object or as a string to the specific loader. Here we load the config's contents at the top and pass them to the options property of babel-loader.

Add build logic to build.js

In this step, we add the build logic to our build.js file.

'use strict';
process.env.NODE_ENV = 'production';

const webpack = require('webpack');
const config = require('../config/webpack.prod.config');

const compiler = webpack(config);
compiler.run((err, stats) => {
  if (err) {
    console.error(err.stack || err);
    if (err.details) {
      console.error(err.details.join('\n\n'));
    }
    return;
  }

  const info = stats.toJson();

  if (stats.hasErrors()) {
    console.error(info.errors.join('\n\n'));
  }

  if (stats.hasWarnings()) {
    console.warn(info.warnings.join('\n\n'));
  }
});

So what we do here, is importing our webpack build config and using the webpack compiler api to build our project. Feel free to improve the logging of errors and infos in the callback given to the run method. Here I am just doing basic logging.

FAQ

I want to know more about the webpack compile api

See here: https://webpack.js.org/api/node/

How did you know about this api?

It is in the docs: https://webpack.js.org/api/node/

I want to know more about the stats object/improve logging

See here: https://webpack.js.org/api/node/#stats-object