Skip to content

Completely customizable webpack base configuration generator

License

Notifications You must be signed in to change notification settings

nodesource/webpack-base

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

N|S webpack base

Prettier ZenHub made with love

This package generates a base webpack configuration and requires the necessary tooling dependencies for React web and Electron applications. Consuming projects can customize the generated base configurations to meet the specific needs of any project.

βš™οΈ Setup

ℹ️ See the test-app for a complete example application setup

1. Install

npm i -D @ns-private/webpack-base

2. Add package.json commands

{
  "scripts": {
    "build": "NODE_ENV=production webpack --mode=production",
    "start": "NODE_ENV=development webpack-dev-server --mode=development"
  }
}

3. Add configuration files

Setup a .babelrc config file and a webpack.config.js config file in the project root.

πŸ“¦ Project defaults

webpack base works out of the box for projects with projects that use the default project structure:

project
β”œβ”€ / public
β”‚  └─  favicon.ico
β”œβ”€ / src
β”‚  └─ / api
β”‚  └─ / components
β”‚  └─ / dux
β”‚  └─ / lib
β”‚  └─ / media
β”‚  β”‚  └─ / icons
β”‚  └─ / styles
β”‚  β”‚  └─ / dev
β”‚  β”‚  └─ / prod
β”‚  β”œβ”€  index.html
β”‚  └─  index.js
β”œβ”€  .babelrc
β”œβ”€  .eslintrc.js
└─  webpack.config.js

Directories

  • public - The public folder can be used as an escape hatch for including assets that are not imported by the project. The contents are copied to the output directory during builds.
  • src/media/icons - The SVG symbol sprite loader will sprite any SVG icons imported from this directory.
  • src/styles - SASS files in this directory can be imported with a relative import from anywhere in the project. The dev and prod directories are passed as importPaths to node-sass according to the build env.
  • src/index.js - The application entry file.
  • api, components, dux and lib directories are not required, only suggested as a convenient setup.

πŸ“ Configuration API

The project webpack.config.js should call the webpack base package to generate the base configuration set. The base configurations can then be modified in any way to support specific project needs.

// webpack.config.js
const webpackBase = require('@ns-private/webpack-base')

module.exports = () => {
  const { configs } = webpackBase(/* options */)

  /*
   * Handle non-standard, advanced project customization by directly updating
   * the generated base configs.
   */
  // eg: configs.bail = false

  return configs
}

Options

The base configurations generated by the package can be customized per project by passing an options object:

// The top level overrides allow specifying the build env, dev server
// customizations and default path overrides
const options = {
  devServer,
  envVars
  paths,
  target,
}

Available path configs

const paths = {
  /**
   * Application public static files directory. This directory is copied to the
   * build without manipulation by the `CopyWebpackPlugin` and provides an
   * escape hatch to include assets in a build without importing them in the
   * application source.
   */
  appPublic, // ./public
  /**
   * Application source files directory. The directory is added to the webpack
   * `resolve.modules` config to allow using imports relative to the source
   * directory.
   */
  appSrc, // ./src
  /**
   * Project root directory that is used by webpack (eg to handle resolutions).
   * webpack base attempts to automatically set the project context, but it
   * can help fix resolution errors to specify it.
   */
  context, // ./
  /**
   * Directories/files that will be loaded && sprited using the
   * `SVGSymbolSprite` system.
   */
  iconSpritePaths, // [./src/media/icons]
  /**
   * Directories that will be loaded using the JS loader, is passed as the
   * loader `include` property.
   */
  jsLoaderPaths, // [./src]
  /**
   * Directory that build assets are emitted to.
   */
  outputPath, // ./dist
  /**
   * The prefix appended to every URL created by the runtime or loaders. This
   * enables serving an application with a CDN or server subdirectory.
   */
  publicPath, // '/'
  /**
   * Directories included in the SASS resolver. Resources in these directories
   * will be available using relative imports. Useful for importing shared SASS
   * resources inside component SASS definitions.
   */
  sassIncludePaths, // ['src/styles']
}

😍 Featureset

  • JS loader setup to transpile all source in the babelLoaderInclude with the babel-loader
  • Appropriate sourcemaps for dev vs prod builds
  • Handles adding scripts to index.html
  • Friendly errors
  • Dev server with hot reloading
  • Progress indicators
  • Production optimizations including uglify and module concatenation
  • Output directory cleaning
  • Injected PUBLIC_PATH for routing
  • DEVTOOL environment variable will override source maps

webpack Resolution

The build configures the following module resolutions for convenient shorthand imports of common project directories.

Module Usage
/src Allows relative imports from the src directory, useful for shared utilities
/src/styles Allows importing style variables directly from any SASS partial

Environment variable injection

The following environment variables are injected by the build:

Constant Usage
process.env.NODE_ENV Defaults to match NODE_ENV, used by Babili to strip code in prod builds
process.env.DEBUG Defaults to false, can be used for adding detailed logging in dev environment
process.env.PUBLIC_PATH Set to publicPath configuration, useful for importing media and configuring CDN paths

Additional environment variables can be passed in an envVars option and they will be injected into the build

webpackBase({
  envVars: { TRACKING_ID: 'x-123456' }
})

βš›οΈ Electron support

Electron renderer processes can be bundled by passing an target flag in options:

// webpack.config.js
const webpackBase = require('@ns-private/webpack-base')

module.exports = () => {
  return webpackBase({ target: 'electron-renderer' }).configs
}

By default webpack-base will look for project source files in /src/renderer instead of /src and builds are output to /src/build instead of /dist. This is for working with Electron build systems.

🐳 Docker support

When working within a Docker setup, the dev server port (default 3000) must be exposed and the host set to 0.0.0.0. Including a start command for Docker is recommended:

{
  "start:docker": "NODE_ENV=development webpack-dev-server --host=0.0.0.0 --mode=development"
}

πŸŽ› Loader and plugins access

The configured loaders and plugins can be accessed directly in the return value:

// webpack.config.js
const webpackBase = require('@ns-private/webpack-base')

module.exports = () => {
  const { loaders, plugins } = webpackBase(/* options */)
}

Returned loaders

jsLoader, sassLoader, svgSpriteLoader, svgComponentLoader, fileLoader, rawLoader

Returned plugins

progressBarPlugin, environmentPlugin, htmlPlugin, svgSymbolSpritePlugin, copyPlugin, hotModuleReplacementPlugin, friendlyErrorsPlugin

This can be useful for adding loaders to projects like Storybook.

πŸ‘·β€β™€οΈ Developing

Development and testing of the repository use a Docker workflow to ensure that the generated configs work with the packages required and the minimum version of Node supported. The /test-app directory includes a complete test application.

  1. Start the docker container: npm run container (The image/container will be created and started)
  2. Start the webpack server for Docker envs: npm run start:docker

βœ… Testing

Unit tests are run with Jest and use snapshots to validate the generated configs for development and production environments.

πŸ—Ί Roadmap

Interested in contributing? Start here 😍

  • Investigate usage of profile in builds
  • Investigate including Bundle Buddy plugin
  • Add a script to bin to setup necessary configs for a project (.babelrc, webpack.config.js)
  • Add example of each supported feature to test-app for quick validation that package is working with acceptance tests.
  • Add svg-symbol-sprite-loader loader, plugin and example
  • Add a custom contains-magic badge for awesomeness.
  • Setup acceptance tests with Cypress or Puppeteer
  • Add issue and pull request templates

πŸ‘ Contributing

All contributions are greatly appreciated πŸ‘πŸŽ‰. To contribute please:

Node version support

Node version running inside Atom's Electron instance is support target to ensure users of ESLint import plugin are able to parse these webpack configs.

About

Completely customizable webpack base configuration generator

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 83.1%
  • CSS 11.1%
  • Dockerfile 5.1%
  • HTML 0.7%