npm package: @ramster/webpack-tools
Description: Webpack build and dev tools, part of the ramster open-source software toolkit.
Author: Rumen Rumenov
Latest version: 2.0.0
Deprecated: false

![npm](https://img.shields.io/npm/v/@ramster/webpack-tools.svg)
![node](https://img.shields.io/node/v/@ramster/webpack-tools.svg)
![pipeline](https://gitlab.com/ramster-universe/webpack-tools/badges/master/pipeline.svg)
[![Coverage Status](https://coveralls.io/repos/gitlab/ramster-universe/webpack-tools/badge.svg?branch=master)](https://coveralls.io/gitlab/ramster-universe/webpack-tools?branch=master)
![npm](https://img.shields.io/npm/dt/@ramster/webpack-tools.svg)
![npm](https://img.shields.io/npm/dm/@ramster/webpack-tools.svg)
@ramster/webpack-tools
==

Webpack build and dev tools, part of the ramster open-source software toolkit.
<br/>
This module provides a small toolkit for building and running bundles with webpack. It has both a javascript [API](#API) and a [CLI](#CLI).
<br/>
<!-- You can find the full docs <a href='https://ramster.lemmsoft.com/docs/webpack-tools' target='_blank'>here</a>. -->

# API
The javascript API contains 5 methods - [build](#build), [buildFromFile](#buildFromFile), [watch](#watch), [watchFromFile](#watchFromFile) and [injectPluginsInConfig](#injectPluginsInConfig).
<br/>
All examples below use the following [config file](#exampleConfigFile).
<br/><br/>



## build
This method takes a webpack configuration object and generates a webpack bundle for it.
<br/>
<table>
	<tr>
		<td></td>
		<td>Name</td>
		<td>Type</td>
		<td>Description</td>
	</tr>
	<tr>
		<td>@param (required)</td>
		<td>webpackConfig</td>
		<td><a href='https://webpack.js.org/configuration/' target='_blank'>Webpack.Configuration</a></td>
		<td>The config to be passed on to Webpack for building the bundle.</td>
	</tr>
	<tr>
		<td>@returns</td>
		<td></td>
		<td>Promise</td>
		<td>Resolves with true (boolean) when the bundle build is finished or rejects with the error thrown.</td>
	</tr>
</table>

Example:
````javascript
// main.js
const
	configData = require('./config'),
	{build} = require('@ramster/webpack-tools')

build(configData.webpackConfig).then(
	(res) => console.log('Build completed successfully with result:', res),
	(err) => console.error(err)
)
````
<br/>



## buildFromFile
This method takes a path to a file containing a webpack configuration object and executes webpack(config) for it, returning a promise.
<table>
	<tr>
		<td></td>
		<td>Name</td>
		<td>Type</td>
		<td>Description</td>
	</tr>
	<tr>
		<td>@param (required)</td>
		<td>configFilePath</td>
		<td>string</td>
		<td>The path to the file, containg the config to be passed on to Webpack for building the bundle.</td>
	</tr>
	<tr>
		<td>@param (optional)</td>
		<td>pluginsProfileName</td>
		<td>string</td>
		<td>The name of the plugins profile to be injected into the webpack config's plugins array.</td>
	</tr>
	<tr>
		<td>@returns</td>
		<td></td>
		<td>Promise</td>
		<td>Resolves with true (boolean) or rejects with the error thrown.</td>
	</tr>
</table>

The file should be in the format
````typescript
{
	profileWebpackPlugins?: { [profileName: string]: Webpack.Plugin[] },
	webpackConfig: Webpack.Configuration
}
````

Example:

````typescript
// main.js
const
	{buildFromFile} = require('@ramster/webpack-tools'),
	path = require('path')

buildFromFile(path.join(__dirname, 'webpackConfig.js'), 'development').then(
	(res) => console.log('Build completed successfully with result:', res),
	(err) => console.error(err)
)
````
<br/>



## watch
This method takes a webpack configuration object and starts a webpack devserver for it.
<br/>
<table>
	<tr>
		<td></td>
		<td>Name</td>
		<td>Type</td>
		<td>Description</td>
	</tr>
	<tr>
		<td>@param (required)</td>
		<td>webpackConfig</td>
		<td><a href='https://webpack.js.org/configuration/' target='_blank'>Webpack.Configuration</a></td>
		<td>The config to be passed on to Webpack for building the bundle.</td>
	</tr>
	<tr>
		<td>@param (required)</td>
		<td>devserverConfig</td>
		<td>{ hostName: string, port: number }</td>
		<td>The HTTP config for the webpack devserver.</td>
	</tr>
	<tr>
		<td>@returns</td>
		<td></td>
		<td>Promise</td>
		<td>Resolves with true (boolean) when the devserver build has <b>started</b> successufully (not on build completion) or rejects with the error thrown.</td>
	</tr>
</table>

Example:
````javascript
// main.js
const
	configData = require('./config'),
	{watch} = require('@ramster/webpack-tools')

watch(configData.webpackConfig, configData.devserverConfig).then(
	(res) => console.log('Build completed successfully with result:', res),
	(err) => console.error(err)
)
````
<br/>



## watchFromFile
This method takes a path to a file containing a webpack configuration object and starts a webpack devserver for it.
<table>
	<tr>
		<td></td>
		<td>Name</td>
		<td>Type</td>
		<td>Description</td>
	</tr>
	<tr>
		<td>@param (required)</td>
		<td>configFilePath</td>
		<td>string</td>
		<td>The path to the file, containg the config to be passed on to Webpack for building the bundle.</td>
	</tr>
	<tr>
		<td>@param (optional)</td>
		<td>pluginsProfileName</td>
		<td>string</td>
		<td>The name of the plugins profile to be injected into the webpack config's plugins array.</td>
	</tr>
	<tr>
		<td>@param (required)</td>
		<td>devserverConfig</td>
		<td>{ hostName: string, port: number }</td>
		<td>The HTTP config for the webpack devserver.</td>
	</tr>
	<tr>
		<td>@returns</td>
		<td></td>
		<td>Promise</td>
		<td>Resolves with true (boolean) when the devserver build has <b>started</b> successufully (not on build completion) or rejects with the error thrown.</td>
	</tr>
</table>

The file should be in the format
````typescript
{
	devserverConfig: { hostName: string, port: number },
	profileWebpackPlugins?: { [profileName: string]: Webpack.Plugin[] },
	webpackConfig: Webpack.Configuration
}
````

Example:

````typescript
// main.js
const
	{buildFromFile} = require('@ramster/webpack-tools'),
	path = require('path')

buildFromFile(path.join(__dirname, 'webpackConfig.js'), 'development').then(
	(res) => console.log('Build completed successfully with result:', res),
	(err) => console.error(err)
)
````
<br/>


## injectPluginsInConfig
Takes a webpack config and injects plugins into its "plugins" array. If the object doesn't have a "plugins" array, it will be created automatically.
<br/>
<table>
	<tr>
		<td></td>
		<td>Name</td>
		<td>Type</td>
		<td>Description</td>
	</tr>
	<tr>
		<td>@param (required)</td>
		<td>config</td>
		<td><a href='https://webpack.js.org/configuration/' target='_blank'>Webpack.Configuration</a></td>
		<td>The webpack config to inject the plugins in.</td>
	</tr>
	<tr>
		<td>@param (required)</td>
		<td>config</td>
		<td>{ [profileName: string]: Webpack.Plugin[] }</td>
		<td>The object containing the config-profile-specific plugin arrays.</td>
	</tr>
	<tr>
		<td>@param (required)</td>
		<td>configProfileName</td>
		<td>string</td>
		<td>The name of the config profile to inject the plugins for.</td>
	</tr>
	<tr>
		<td>@returns</td>
		<td></td>
		<td>Promise</td>
		<td>Resolves with true (boolean) when the bundle build is finished or rejects with the error thrown.</td>
	</tr>
</table>

Example:
````javascript
// main.js
const
	configData = require('./config'),
	{build, injectPluginsInConfig} = require('@ramster/webpack-tools')

configData.webpackConfig = injectPluginsInConfig(configData.webpackConfig, configData.profileWebpackPlugins, 'development')
build(configData.webpackConfig).then(
	(res) => console.log('Build completed successfully with result:', res),
	(err) => console.error(err)
)
````
<br/><br/>


#### exampleConfigFile
````typescript
// config.js
const
	BellOnBundlerErrorPlugin = require('bell-on-bundler-error-plugin'),
	path = require('path'),
	ProgressBarPlugin = require('progress-bar-webpack-plugin'),
	webpack = require('webpack')

module.exports = {
	devserverConfig: { hostName: '127.0.0.1', port: 9999 },
	profileWebpackPlugins: {
		development: [
			new BellOnBundlerErrorPlugin()
		]
	},
	webpackConfig: {
		devtool: 'source-map',
		entry: [
			path.join(__dirname, 'src/index.ts')
		],
		output: {
			path: path.join(__dirname, 'dist'),
			filename: '[name].js',
			chunkFilename: '[id].chunk.js',
			publicPath: '/dist/'
		},
		resolve: {
			extensions: ['.ts', '.js'],
			modules: ['node_modules']
		},
		module: {
			rules: [
				{
					test: /\.ts$/,
					include: path.join(__dirname, 'src'),
					exclude: [],
					use: ['awesome-typescript-loader']
				}
			]
		},
		stats: 'verbose',
		plugins: [
			new ProgressBarPlugin({
				format: '  build [:bar] (:percent) - (:elapsed seconds)',
				clear: false,
				complete: '#',
				summary: 'true'
			})
		]
	}
}
````
<br/><br/>




# CLI
The CLI allows you to use the buildFromFile and watchFromFile methods using from the command line. Running `ramster-webpack --help` will display the full usage information that you can see below:
<br/><br/>
Usage: ramster-webpack [options]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ramster-webpack -c config/webpack.js -p production<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ramster-webpack --configFilePath=config/webpack.js --pluginProfileName=production<br/>
<br/>
Options:<br/>
&nbsp;&nbsp;-b, --build&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signals the script to build the bundles for the provided config files and exit<br/>
&nbsp;&nbsp;-w, --watch&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signals the script to build and watch the bundles for the provided config files by running a devserver<br/>
&nbsp;&nbsp;-c, --configFilePath&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;required; specifies the config file to use for the run; if provided multiple times, multiple files will be built<br/>
&nbsp;&nbsp;-p, --pluginProfileName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;optional; specifies the plugins profile for the config file to use for the run; if provided multiple times, each one will be matched to a single --configFilePath in the order provided<br/>
&nbsp;&nbsp;-h, --help&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display this menu<br/>
<br/><br/>




<br/><br/>


Security issues
==
Please report any security issues privately at r_rumenov@lemmsoft.com.