Scaffolding

It can be hard to set up a complex webpack configuration for the first time. Writing advanced configurations to optimize performance could be even more difficult. The init feature allows creating a webpack configuration by using customizable third-party initialization packages.

Creating a scaffold

Before writing a webpack-cli scaffold, think about what you're trying to achieve and who is going to use it:

  • Do you want a generic scaffold that could be used by a wide variety of applications and projects?
  • Do you want something specific, like a scaffold that writes both your webpack.config.js and your framework code?
  • Who are the potential users and what user experience will look like for the users of your scaffold?

webpack-cli offers an interactive experience to customize the output accordingly. For example asking questions like: "What is your entry point?".

Writing a scaffold

There are various resources where you can learn how to write a scaffold, you can start by reading Writing a Scaffold tutorial.

webpack-scaffold is a utility suite for creating scaffolds. It contains functions that could be used to create a scaffold.

Running a scaffold

A scaffold can be executed using webpack-cli init:

webpack-cli init <your-scaffold>

Running a scaffold locally

When the scaffold package is in your local file system you should point init to its path:

webpack-cli init path/to/your/scaffold

Or you can create a global module and symlink to the local one:

  • Using npm
cd path/to/my-scaffold
npm link
webpack-cli init my-scaffold
  • Using yarn
cd path/to/my-scaffold
yarn link
webpack-cli init my-scaffold

Running a scaffold from npm

If the package is available from npm, its name must begin with webpack-scaffold and can be used by running:

webpack-cli init webpack-scaffold-yourpackage

API

To create a scaffold, you must create a yeoman-generator. Thanks to it, you can optionally extend your generator to include methods from the Yeoman API. It's worth noting that we support all the properties of a regular webpack configuration. In order for us to do this, there's a thing you need to remember:

Required

Optional

opts.env.configuration(required)

object

This is the entry point your configuration, initialize it inside the constructor of your generator in order for the CLI to work:

class MyScaffold extends Generator {
  constructor(args, opts) {
    super(args, opts);
    opts.env.configuration = {};
  }
}

opts.env.configuration.myObj (required)

object

This is your scaffold, you add the options that the CLI will transform into a webpack configuration here. You can have many different scaffolds named as you prefer, representing different configurations like dev.config or prod.config:

class MyScaffold extends Generator {
  constructor(args, opts) {
    super(args, opts);
    opts.env.configuration = {
      dev: {},
      prod: {},
    };
  }
}

myObj.webpackOptions (required)

object

This object has the same format as a regular webpack configuration. Declare the properties that you want to scaffold here, e.g. entry, output and context. You can initialize this inside a yeoman method:

this.options.env.configuration.dev.webpackOptions = {
  entry: 'app.js',
  output: {},
};

writing (required)

function

For the scaffolding instance to run, you need to write your configuration to a .yo-rc.json file. This could be done using one of the lifecycles in the yeoman generator, such as the writing method:

class MyScaffold extends Generator {
  writing() {
    this.config.set('configuration', myObj);
  }
}

myObj.merge (optional)

string

If you want to use webpack-merge, you can set the merge property of myObj to the name of the configuration you want to merge it with:

this.options.env.configuration.dev.merge = 'myConfig';

myObj.topScope(optional)

[string]

The topScope property is where you write all the code needed by your configuration, like module imports and functions/variables declarations:

this.options.env.configuration.dev.topScope = [
  'const webpack = require("webpack");',
  'const path = require("path");',
];

myObj.configName(optional)

string

configName allows you to customize the name of your configuration file. For example you can name it webpack.base.js instead of the default webpack.config.js:

this.options.env.configuration.dev.configName = 'base';