# Working with webpack

 To make Vue Storefront soo fast and developer friendly we use webpack under the hood to transpile assets, handle .vue files, process all styles and make our code a little bit more maintainable with linting provided by eslint. With that you don't need to worry about configuring it by hand to start working on Vue Storefront or to build your own theme for it. However when you want to tweak it to your special needs there is also possibility to do that with extendable webpack configuration for each theme.

## Core webpack build

All build scripts used by core of the Vue Storefront are available in `core/build` directory. If you want to improve our build or add support for new cases you will probably only need to change files there and sometimes update `package.json`.

Base config for client and server is set up in `webpack.base.config.js`. This configuration is then merged with specific client and server configs in `webpack.client.config.js` and `webpack.server.config.js`.

For development mode (`npm run dev`) `dev-server.js` file is used to run previously mentioned config files (`webpack.client.config.js`, `webpack.server.config.js`) with custom config provided by the theme. We use `webpack-dev-middleware` and `webpack-hot-middleware` to make development of site as fast and easy as possible.

In `vue-loader.config.js` whole configuration for `vue-loader` is stored. If there will be need to change styles processing for single file components you can set it up in this file (if you want to extend the Vue Storefront core).

To build production version of Vue Storefront `webpack.prod.client.config.js` and `webpack.prod.server.config.js` are used by npm `build` script. In these files our base configuration is merged with theme specific extended config.

## Extending core build in themes

Vue Storefront follows technique popularized by [next.js](https://github.com/zeit/next.js/) and [Nuxt](https://nuxtjs.org/) for extending webpack config. For each theme you can configure `webpack.config.js` file that will allow you to have access to base configuration and customize it for your needs without changing core build files.

### Example

Below is a simple example that adds `webpack-bundle-analyzer` to check generated webpack bundles. In addition to analyzer `json5-loader` is used to handle JSON5 files `json5-loader` in project.

``` js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = function (config, { isClient, isDev }) {
  let configLoaders
  if (isClient) {
    configLoaders = config[0].module.rules
    config[0].plugins.push(new BundleAnalyzerPlugin({
      openAnalyzer: false,
      statsFilename: 'test',
      generateStatsFile: true,
      analyzerMode: 'static'
    }))
  } else {
    configLoaders = config.module.rules
  }
  configLoaders.push(
    {
      test: /\.json5$/,
      loader: 'json5-loader'
    }
  )
  return config
}
```

This file should export a function that returns a complete configuration.

This function is executed with 2 arguments. First one is the complete core Vue Storefront webpack configuration. Second is an object that has properties: `isClient` and `isDev`.

Option `isClient` indicates that the configuration is for client bundle.

Option `isDev` is set to `true` if Vue Storefront runs in development mode.

In case of client build (`isClient == true`) config argument is an array with 2 elements. First array element is the client configuration and the second one is used to generate service worker file.

For server build (`isClient == false`) config argument is an standard webpack configuration object.

All loaders and plugins used in extended configuration will be fetched from theme's `node_modules` directory, so make sure you have it saved in theme `package.json` file.
