Home

Awesome

webpack-build

Build Status Dependency Status devDependency Status

Wraps webpack. Does some useful stuff...

Documentation

Installation

npm install webpack-build

Basic usage

var build = require('webpack-build');

build({
  config: '/path/to/webpack.config.js',
  watch: true
}, function(err, data) {
  // ...
});

The data object includes:

Build options

The following options can be passed to build.

{

  // An absolute path to a config file
  config: '',

  // Watching
  // --------

  watch: false,
  aggregateTimeout: 200,
  poll: undefined,

  // Config manipulation
  // -------------------

  outputPath: '', // override for output.path
  publicPath: '', // override for output.publicPath

  // External system integration
  // ---------------------------

  staticRoot: '', // Absolute path to your static root
  staticUrl: '', // Url to your staticRoot

  // Caching
  // -------

  cache: true,
  cacheDir: path.join(process.cwd(), '.webpack_build_cache'),

  // Hot module replacement
  // ----------------------

  hmr: false, // if true, hmr code is injected into the assets
  hmrRoot: '', // The address of the server hosting hmr sockets
  hmrPath: '/__hmr__', // the path to the hmr socket endpoint

}

The above properties indicate the default values. If you want to define defaults, you can bind them to the build.options.defaults object.

Config files

Config files should export a function that returns a config object.

module.exports = function(opts) {
  var config = {
    entry: '...',
    output: {
      // ..
    },
    loaders: [
      // ...
    ]
  };

  if (opts.hmr) {
    config.loaders.push({
      // ...
    });
  }

  return config;
};

The function is provided with one argument: the options object that was passed in to the build function. The object will be updated with the default values for all the config flags, so you can compose your config based on the various build flags.

If you want to pass data down to the function, place it in a context property.

build({
  config: '/path/to/file.js',
  context: {
    entry: './app.js',
    debug: true
  }
}, function(err, data) {
  // ...
});

Your function can then generate a config object reflecting your system

module.exports = function(opts) {
  var config = {
    entry: opts.context.entry
    // ...
  };

  if (opts.context.debug) {
    config.devtool = '...';
  }

  return config;
};

Caching

Once a compilation request has completed successfully, the output is cached and subsequent requests will be served from memory until a compiler invalidates it. To avoid webpack's slow startup, cached output is also written to disk.

The cache tracks file dependencies, package dependencies, and the emitted assets. Whenever cached data is available, the following checks occur before serving it:

If any of the checks fail, requests are handed off to a compiler which will repopulate the cache on completion.

If watch is set to true and cached data is available, requests will still cause a compiler to be spawned in the background. Spawning the compiler early enables webpack's incremental compilation to provide rapid rebuilds.

Workers

Worker processes allow the main process to remain responsive during compilation. As many of the more popular loaders evaluate synchronously, offloading compilation to workers can be essential for performance. Workers enable the main process to focus on assigning work and handling both caching and hmr.

To spawn workers, call build.workers.spawn() before sending any build requests.

var build = require('webpack-build');

build.workers.spawn();

// ...

By default, 2 worker processes will be spawned. You can also pass a number in to specify the number of workers.

var os = require('os');
var build = require('webpack-build');

// Spawn a worker for every CPU core available
build.workers.spawn(os.cpus().length);

New requests are assigned to workers in sequential order. Repeated requests will always be sent to the same worker that previously handled the build, this enables concurrent requests to be batched and served from in-memory caches.

CLI and build server

A CLI interface, webpack-build, is available which exposes a high-level method of interacting with the library.

The following optional arguments are accepted:

The build server also listens for network requests. Incoming HTTP requests are routed via:

Successful builds receive

{
  "error": null,
  "data": {
    // ..
  }
}

Unsuccessful builds receive

{
  "error": {
    // ...
  },
  "data": null
}

Depending on how far the request passed through the build process, the response may or may not have a non-null value for data. If an error was produced by the compiler, there may be multiple errors within data.stats.errors and multiple warnings in data.stats.warnings.

HMR

webpack-build includes hmr functionality comparable to webpack-dev-server. A key difference is that it namespaces the hmr sockets per build - enabling multiple builds to emit hmr signals concurrently.

var build = require('webpack-build');

build({
  config: '/path/to/webpack.config.js',
  watch: true,
  hmr: true
}, function(err, data) {
  // ...
});

When assets are rendered on the front-end, they open sockets to the build server and attempt to hot update whenever possible. If hot updates are not possible, console logs will indicate that updates require a refresh to be applied.

If you are using your own server to expose HMR, you'll need to specify the hmrRoot option with the address of your server, eg: hmrRoot: 'http://127.0.0.1:9009'.

To use the hmr socket handler with an express app

var http = require('http');
var express = require('express');
var build = require('webpack-build');

var app = express();
var server = http.Server(app);
build.hmr.addToServer(server);

Debugging

The environment variable DEBUG is respected by the library's logger. To expose verbose logs to your shell, prepend DEBUG=webpack-build:* to your shell command. For example: DEBUG=webpack-build:* npm test

The project uses babel for ES5 compatibility. If you are using the library's API and you want clearer stack traces, turn on source map support:

npm install source-map-support --save
require('source-map-support').install();

Dev notes

Build the project

npm run build

# or, to continually rebuild

npm run build -- --watch

Running the tests

npm test

Colophon

Large portions of this codebase are heavily indebted to webpack-dev-middleware and webpack-dev-server.

This project stands on the shoulders of giants - specifically, Tobias Koppers and the webpack ecosystem's vast number of contributors.