Skip to content

urban/webpack-config

Repository files navigation

webpack-config

js-standard-style

This is an opinionated webpack configuration with smart defaults. It can help speed up the initial project setup time so you can focus on developing what's unique about your project.

Table of Contents

Install

This project is published as a scoped package. Use the following to install and save it as a dependency.

npm i --save @urban/webpack-config

Peer Dependencies

webpack-config specifies many of its dependencies as peerDependencies in order to give the consumer of this package flexibility to decide which version to use. For instance, you might want to use React 0.13.x instead of version React 0.14.x.

In npm version 3.x.x, peerDependencies are no longer installed by default. In order to install the latest versions of this packages peerDependencies, please run the following command.

npm i --save autoprefixer babel-loader css-loader extract-text-webpack-plugin file-loader json-loader postcss-loader style-loader url-loader webpack

Tools Used

webpack is a module bundler. It takes JavaScript modules with dependencies (i.e. other JavaScript files, CSS, images, ...) and generates static assets representing those modules for the browser. It's similar to Browserify but has a configuration based API.

  • Loaders

    • babel - Transpiles ES2015 and ES2016 code into vanilla ES5 using Babel.
    • css - Loads css file with resolved imports and returns css code (enables CSS Moduels).
    • postcss - A fast CSS parser written in JavaScript.
    • file - Emits the file into the output folder and returns the (relative) url.
    • json - Loads file as JSON.
    • style - Add exports of a module as style to DOM (enabled in development).
    • url - The url loader works like the file loader, but can return a Data Url if the file is smaller than a limit.
  • Plugins

    • DedupePlugin - Reduces file size by removing duplicate files.
    • DefinePlulgin - Inlines variables (__DEV__ and __PRERELEASE__) into the code which allows a minification pass to remove dead-code.
    • ExtractTextPlugin - Moves required CSS into a separate CSS output file (enabled in production).
    • HotModuleReplacementPlugin - Enables Hot Module Replacement (enabled in development).
    • NoErrorsPlugin - Prevents the output when an error occurs.
    • OccurenceOrderPlugin - Assign the module and chunk ids by occurrence count making ids predictable and reduces the total file size.
    • UglifyJs - Minimize all JavaScript output of chunks (enabled in production).

Basic Usage

There are several different ways to invoke webpack from the command line.

  • webpack for building once for development
  • webpack -d to switch loaders to debug mode, include source maps and output path info
  • webpack -p for building once with minification and occurence order plugins
  • webpack --watch for continuous incremental build (can combine with -d or -p)

To use this module, create a webpack.config.babel.js file at the root of your project with the following content.

// webpack.config.babel.js

import getConfig = '@urban/webpack-config'

export default getConfig({
    context: __dirname,
    entry: './src/index.js',
    output: {
        path: './public/'
    }
})

Next, add the following to the npm run scripts within your package.json file.

"scripts": {
    "start": "webpack-dev-server -d",
    "build": "NODE_ENV=production webpack -p"
}

You can now run your project in development with hot module replacement by typing npm start in the terminal from the root directory. To view the results, open a browser to http://localhost:8080/webpack-dev-server/.

If you'd like to build the static assets for your project, type npm run build into the terminal to generate all files into the public directory. Then type open ./public/index.html to view in your default browser.

Feature flags

In order to help in developing new features, the __DEV__ and __PRERELEASE__ global variables are made available to your code.

if (__DEV__) {
  console.log('Debug info.')
}

if (__PRERELEASE__) {
  console.log('Prerelease info.')
}

You can modify their default values by passing environment flags at build time. For instance, by building with BUILD_DEV=1 BUILD_PRERELEASE=0 webpack from terminal, it will result in the following.

if (true) {
  console.log('Debug info.')
}

if (false) {
  console.log('Prerelease info.')
}

And with dead-code elimination through minification, it will result in the following.

console.log('Debug info.')

Configuration

There are two different ways the configuration can be modified.

First, by adding additional options to the configuration object passed into the getConfig method. The will then by automatically merged with the defaults and even overriding them where possible.

import getConfig = '@urban/webpack-config'

// by adding additional, initial webpack config options
const config = {
    context: __dirname,
    entry: './src/index.js',
    output: {
        path: './public/'
        // ...more output options (e.g. libraryTarget: 'umd')
    },
    // ...more output options (e.g. libraryTarget: 'umd')
    resolve: {
        modulesDirectories: ['src', 'node_modules']
    }
}

// then export to webpack
export default getConfig(config)

Second, by manually merging or overriding the output of the getConfig method.

import getConfig = '@urban/webpack-config'

// minimum initial webpack config options
const config = getConfig({
    context: __dirname,
    entry: './src/index.js',
    output: {
        path: './public/'
    }
})

// by manually mergin or overriding config options
export default {
    ...config
    output: {
        ...config.options
        // ...more output options (e.g. libraryTarget: 'umd')
    },
    // ...more options or overrides
    plugins: [
        ...config.plugins,
        // ...additional plugins
    ]
}

Babel Config

To change the default Babel settings, create a file at the root of your project called .babelrc that contains the options you'd like.

See babelrc for more information.

{
  "presets": ["es2015", "stage-0"],
}

Autoprefixer Config

To change the default Autoprefixer settings, create a file at the root of your project called browserslist that contains the options you'd like.

See Browserslist docs for queries, browser names, config format, and default value.

# Browsers that we support

> 1%
Last 2 versions
IE 8 # sorry

Examples

About Styles

Each JavaScript module should require all it's dependencies, including styles. This is the "webpack way".

To require your styles from a JavaScript file, add the following. Be sure to include the extension: .css in your path.

import './path/to/styles.css'

CSS Modules

By default CSS exports all classNames to the global selector scope. This means every selector has the potential of introducing unintended side effects by targeting unwanted elements or clashing with other selectors. However, with CSS Modules you can mitigate this issue and expose your CSS to JavaScript.

With the CSS Module syntax, the css-loader replaces the className with unique identifiers. For example, if you had a CSS file located at ./path/to/styles.css with the following.

.className { color: green; }
.subClass p { color: blue; }

It would be transformed into the following.

.path-to-styles__className___23_aKvs-b8bW2Vg3fwHozO { color: green; }
.path-to-styles__subClass___13LGdX8RMStbBE9w-t0gZ1 p { color: blue; }

The identifiers are then available to your JavaScript module and can accessed with the following.

import { className, subClass } from './path/to/styles.css'

To make debugging easier, local classNames use the [path][name]__[local]___[hash:base64:5] format. Also, when authoring CSS, camelcasing className is recommended because they are easier to use in the importing JavaScript module.

For more information on CSS Modules, please see Local scope, Composing CSS classes and Importing local class names.

Note: CSS Module syntax is enabled by default for all files with the .css extension.

Autoprefixer

Autoprefixer is a post-process CSS transpiler that lets you write CSS without having to worry about vendor prefixing rules.

Note: Autoprefixer is enabled by default for all files with the .css extension through cssnext.

Credits

Inspired by:

License

The MIT License (MIT). Copyright (c) Urban Faubion.

About

An opinionated webpack config.

Resources

License

Stars

Watchers

Forks

Packages

No packages published