we

webpack-envy

An organizer for your Webpack configurations.

Showing:

Popularity

Downloads/wk

4

GitHub Stars

1

Maintenance

Last Commit

4yrs ago

Contributors

0

Package

Dependencies

4

License

MIT

Type Definitions

Tree-Shakeable

No?

Categories

Readme

Webpack Envy

An organizer for your Webpack configurations.

This is a simple utility that prevents your Webpack configurations from turning into a complex and confusing box of if statements. It organizes your settings by environment and delivers a full configuration object using webpack-merge.

This module is inspired by the ideas explained by Juho Vepsäläinen in his webpack book, more specifically in the Composing Configuration chapter.

Installation

# Using Yarn
$ yarn add webpack-envy --dev

# Using NPM
$ npm install webpack-envy --save-dev

What does it do for you?

If you're starting fresh, Webpack Envy CLI can create the following folder structure and wire it all up so you can focus on writing your configuration instead of organizing it.

$ ./node_modules/.bin/webpack-envy create
.
├── config                        # Holds project configuration files
│   ├── webpack.common.js         # Common configs shared across all environments
│   ├── webpack.development.js    # Development specific configs
│   ├── webpack.production.js     # Production specific configs
├── dist                          # Holds the built files for distribution
├── src                           # Holds the application source code
│   ├── index.js                  # Application entry point
├── webpack.config.js             # Entry point config file picked up by Webpack

Already have the project structured?

Using the CLI isn't mandatory. If you want/need to use a different folder structure, you can use the Webpack Envy lib to wire up your configurations manually and change it in whatever way you want.

In your webpack.config.js:

const WebpackEnvy = require('webpack-envy')

const envy = new WebpackEnvy({ /* options */ })

module.exports = envy.getConfig()

Options

KeyDescriptionDefault
pathDirectory where your config files will be placed. Relative to the root option.'./config'
filenameThe pattern for looking up config files into the configuration directory.'webpack.[env].js'
commonEnvIdA string to use as the identifier for configs shared across all environments'common'
rootDirectory where you run webpack. You can explicit set this if you're having trouble for whatever reason.process.cwd()
envA String with the environment id (name) or an Object. If not set, it will look at process.env.NODE_ENV and use that string. If that also isn't set, it will default to 'development'. You'll olny need this if you have some complex logic to determine your environment before calling Webpack Envy.process.env.NODE_ENV fallback to 'development'
verboseOutputs Webpack Envy information to the console when running webpackfalse

Example

If you have the following folder structure:

.
├── settings              # Holds project configuration files
│   ├── development.js    # Development specific configs
│   ├── production.js     # Production specific configs
│   ├── shared.js         # Common configs shared across all environments
├── webpack.config.js     # Entry point config file picked up by Webpack

Then your webpack.config.js will look like this:

const WebpackEnvy = require('webpack-envy')

const envy = new WebpackEnvy({
  path: './settings',
  filename: '[env].js',
  commonEnvId: 'shared'
})

module.exports = envy.getConfig()

How should I set the environment?

I recommend you to use the --env option of the webpack CLI in the scripts property of your package.json, passing --env environment for each command you specify. For example:

  "scripts": {
    "start": "webpack-dev-server --env development",
    "build": "webpack --env production -p",
    "stats": "webpack --env.id production --env.stats true -p"
  }

What is up with --env.id production --env.stats true?

This is a Webpack feature and it will parse this dot notation to an Object. This way you aren't limited to a simple String and will be able to pass custom params to your config, if needed.

In your config files, --env.id production --env.stats true will turn into:

  console.log(settings.env);

  // {
  //   id: 'production',
  //   stats: true
  // }

What if I need to set my environment programmatically?

You can determine your environment using the Webpack Envy env option. If you go this way, Webpack's CLI --env will be ignored. You can pass this a String or an Object.

If you go with an object, it must have an id property which will be used as the environment identifier. If id isn't present, Webpack Envy will look at process.env.NODE_ENV and if this also isn't set, it will default to 'development'.

If you pass a String, internally, Webpack Envy will use this string as the id property of the env object.

let environment = myComplexEnvironmentGetter(); // return 'production'

const envy = new WebpackEnvy({
  env: environment
})

// Then, you can access the string in your config files, for example:
if (settings.env.id === 'production') {
  // production specifics
}
let environment = myComplexEnvironmentGetter(); // return 'production'

const envy = new WebpackEnvy({
  env: {
    id: environment,
    customParam1: '1',
    customParam2: '2'
  }
})

// Then, you can access all properties in your config files like this:
console.log(settings.env.id); // production
console.log(settings.env.customParam1); // 1
console.log(settings.env.customParam2); // 2

Can I have additional environments?

Of course you can. All you have to do is:

Create an environment file under your config directory matching the environment id. For example:

.
├── config
│   ├── webpack.mynewenv.js

Pass the environment id to the initialization.

  "scripts": {
    "my:task": "webpack --env mynewenv"  
  }

Where should I put my Webpack configurations on this thing?

Each file in the configuration directory exports a function that receives the settings from Webpack Envy and returns an object with specific portions of a full Webpack configuration object. Webpack Envy then merges this objects together - according to the environment you're running - to produce the full Webpack configuration object. Here's an example:

./config/webpack.common.js

const path = require('path')
const Html = require('html-webpack-plugin')
const ExtractText = require('extract-text-webpack-plugin')

module.exports = function (settings) {
  return {
    entry: {
      'bundle': path.resolve(settings.root, 'src', 'index.js')
    },
    output: {
      path: path.resolve(settings.root, 'dist'),
      filename: '[name].[chunkhash].js'
    },
    module: { ... },
    plugins: [
      new Html({
        template: path.resolve(settings.root, 'src', 'index.html')
      }),
      new ExtractText('styles.[chunkhash].css')
    ]
  }
}    

./config/webpack.development.js

module.exports = function (settings) {
  return {
    devtool: 'cheap-module-eval-source-map',
    devServer: {
      proxy: {
        '/': {
          target: 'http://localhost:8081/'
        }
      },
      overlay: {
        errors: true,
        warnings: true
      }
    }
  }
}

./config/webpack.production.js

const CleanWebpackPlugin = require('clean-webpack-plugin')

module.exports = function (settings) {
  const config = {
    devtool: 'source-map',
    plugins: [
      new Clean(['./dist/*'], {
        root: settings.root
      })
    ]
  }

  if (settings.env.stats) {
    var BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

    config.plugins.push(
      new BundleAnalyzer({
        generateStatsFile: true
      })
    )
  }

  return config
}

Changelog

Be aware of breaking changes, bug fixes and more. Take a look at our changelog or the release notes.

License

This software is provided free of charge and without restriction under the MIT License

Rate & Review

Great Documentation0
Easy to Use0
Performant0
Highly Customizable0
Bleeding Edge0
Responsive Maintainers0
Poor Documentation0
Hard to Use0
Slow0
Buggy0
Abandoned0
Unwelcoming Community0
100
No reviews found
Be the first to rate

Alternatives

No alternatives found

Tutorials

No tutorials found
Add a tutorial