fannypack
Universal plug-and-play webpack configuration
The problem
At Policygenius, we have a number of different frontend apps that all use the same stack and build tools, however, there is very little commonality among them. In addition, when we build need frontend services, we would like to have certain components already built out so we can a) start coding sooner and b) maintain a set of standards across the team. Since we have decided that Webpack will be our primary bundle builder, it only follows that we should have a standard, reusable configuration for all of our applications.
This solution
fannypack
seeks to create a base-line Webpack configuration that would be able to work right out of the box for any frontend application. It can also allow for a certain set of options
to tweak a few more specific parts of the configuration, along with the ability to manually override if necessary. With fannypack
, we can maintain one set of dependencies and configuration that will be applied to a number of repositories.
Install
yarn add --dev policygenius-fannypack
Usage
Here is an example implementation in a webpack.config.js
file:
const fannypack = require('policygenius-fannypack');
const config = fannypack.baseConfig({
name: 'some-widget',
baseDirectoryPath: './src',
buildDirectoryPath: './build',
});
module.exports = config;
API
Configs
baseConfig
This provides a baseline configuration with everything needed to create a basic Webpack bundle.
devConfig
This adds live reloading and sourcemaps onto the baseConfig
. Runs Webpack in development mode.
prodConfig
This adds production optimizations for JavaScript and CSS onto the baseConfig
. Runs Webpack in production mode.
Runners
runWebpack
This provides a function that takes in a valid webpack configuration and uses the Webpack Node API to build assets.
Usage:
const { runWebpack } = require('policygenius-fannypack');
const validConfig = require('path/to/config');
runWebpack(validConfig);
You MUST use this runner to build production ready assets. If you try to build using the Webpack CLI and fannypack's prodConfig
, you will run into Module Concatenation issues, causing your bundle to be larger than necessary. It is also recommended to use this when building development assets that will not be served immediately. You do not, and should not, need to use this with webpack-dev-server
; use that CLI as is with the appropriate config.
Options
name
string
| defaults to: 'app'
This provides a name for the final bundled javascript along with namespacing for any built CSS files.
baseDirectoryPath
string
| defaults to: '__dirname/src'
This provides a path for which Webpack to resolve all imports and locate the default entry file (baseDirectoryPath + index.js). You must provide a valid path.
buildDirectoryPath
string
| defaults to: '__dirname/public/build'
This provides a path for which Webpack to output all built files. You must provide a valid path.
port
number
| defaults to: 8080
This provides the port number from which the dev server will serve content.
typescript
boolean
| defaults to: false
If you are using typescript, pass this property in as true
to enable appropriate loader and babel preset.
htmlPluginOptions
If you want to override the default HTMLWebpackPlugin, this option provides a seamless way for updating the configuration to fit your needs.
htmlPluginOptions.eject
boolean
| defaults to: false
Removes the HTMLWebpackPlugin completely if it is not needed for your build process.
htmlPluginOptions.config
object
| defaults to: { filename: 'index.html', template: '{baseDirectoryPath}/index.html'}
Configuration to override default HTMLWebpackPlugin. See plugin docs for valid configuration.
processEnvVariables
object
| defaults to: {}
Configuration for any process.env
variables you want to expose to your app at run time. Will be passed to the webpack.DefinePlugin
config.
cssDisabled
boolean
| defaults to: false
Disables all CSS loaders completely if they are not needed for your build process.
boolean
| defaults to: false
Disabled the ExtractTextPlugin loaders completely if they are not needed for your build process.
Override Webpack
Here is an example implementation of overriding default Webpack configurations:
const fannypack = require('policygenius-fannypack');
const config = fannypack.baseConfig({
name: 'some-widget',
baseDirectoryPath: './src',
buildDirectoryPath: './build',
processEnvVariables: {
'some-env-variable': JSON.stringify(proces.env['some-env-variable']),
}
});
module.exports = {
...config,
entry: 'some-new-file',
output: {
path: 'a-different-path',
},
plugins: [
...config.plugins,
new PluginToAdd(),
]
};
In short, you can override any of the Fannypack default configurations, partially or fully, by building a new object with the imported Fannypack configuration and adding on valid Webpack options. Please consult the Webpack documentation for a full list of configuration options.
Using CSS Modules
fannypack
comes set up with the necessary loader/configuration to use CSS Modules if desired. In order to make use of this configuration, your SCSS files must have the extension module.scss
. In addition, Fannypack assumes that you have a global SCSS file for all of your CSS Modules files that will provide helper methods, styles, etc. You MUST create a file with path ${options.baseDirectoryPath}/styles/assets/global_css_module.scss
for Fannypack to properly compile your SCSS files that you want to be modularized.
Hot Reloading
fannypack
comes built in with the correct babel plugins and options to allow for Hot Reloading in React. To complete the set up, use the following configuration in your top level component (the one you pass to ReactDOM.render
):
import React from 'react';
import { hot } from 'react-hot-loader';
class App extends React.Component {
}
export default module(hot)(App);
For this to work, ensure that you have downloaded the latest version of react-hot-loader
. For additional troubleshooting, please consult react-hot-loader
docs.
Dependencies
In order to have Fannypack work correctly in your project, you will need to install all of the necessary dependencies into your project, including Webpack, loaders and plugins. Fannypack uses Webpack 4, so ensure to have that version installed and all dependencies that work with that version.
Local Development
In Fannypack, run the following:
yarn clean && yarn build
yarn link
This will use Rollup to create the bundled javascript containing the 3 exportable configurations and runner. Then yarn will create a linked module.
In your applicaion, run:
yarn link policygenius-fannypack
This will link your app's version of fannypack to the local build.
If you make any updates to Fannypack while working, you will need to rerun the build command above.