Add TemplatedPathPlugin to generically handle asset paths w/ template vars

This consolidates all the areas where webpack is templating asset paths (replacing stuff like [id], [hash], etc.) into one plugin. The benefit of this is that now other plugins could theoretically hook in to this mechanism to support new template variables (for example, see diurnalist/git-sha-webpack-plugin).

Currently, this plugin is applied to the MainTemplate object, under the name "asset-path".

#### Usage
The normal usage remains completely unchanged. This does not add support for chunk hashes where they were not before, nor does it add any new areas where assets are being templated.

#### Variable hash lengths
This also adds a bit of syntactic sugar to the hash variables (`[hash]`, `[chunkhash]`). A developer can now specify how long they want the hash to be.

```javascript
// webpack.config.js
{
  ...
  output: {
    // include the first 6 characters of the build md5 hash
    filename: "[name]-[hash:6].js"
  }
}
```

#### Plugging in
Plugginable via the "asset-path" hook:

```javascript
function MyPlugin() {}
MyPlugin.prototype.apply = function(compiler) {
  compiler.plugin("compilation", function(compilation) {
    compilation.mainTemplate.plugin("asset-path", function(_, templateData) {
      return _.replace(/\[customthing\]/ig, "my-replacement");
    });
};
```
I agree it's a bit confusing. The reason I put this in was to catch the case where `findBundle` erroneously returns a falsy value (because the developer wrote a bad `findBundle` function or something.) This would mean the test would pass, and it wouldn't be obvious if the functionality broke down the line.

So, the assumption is that # of found bundles = # of found webpack configs (`optionsArr.length`). BUT, to make things trickier, there are cases when it's OK for a bundle to not be generated - for example, when there is no entry module found. Hence the extra guard on this if statement.

The error says "should have found at least one bundle"... perhaps it should say "should have found {{optionsArr.length}} bundles" instead. Is that more clear?