Configuration

Out of the box, webpack won't require you to use a configuration file. However, it will assume the entry point of your project is src/index.js and will output the result in dist/main.js minified and optimized for production.

Usually your projects will need to extend this functionality, for this you can create a webpack.config.js file in the root folder and webpack will automatically use it.

All the available configuration options are specified below.

New to webpack? Check out our guide to some of webpack's core concepts to get started!

Use different configuration file

If for some reason you want to use different configuration file depending on certain situations you can change this via command line by using the --config flag.

package.json

"scripts": {
  "build": "webpack --config prod.config.js"
}

Options

Click on the name of each option in the configuration code below to jump to the detailed documentation. Also note that the items with arrows can be expanded to show more examples and, in some cases, more advanced configuration.

Notice that throughout the configuration we use Node's built-in path module and prefix it with the __dirname global. This prevents file path issues between operating systems and allows relative paths to work as expected. See this section for more info on POSIX vs. Windows paths.

webpack.config.js

const path = require('path');

module.exports = {
  <mode "/configuration/mode">
    <default>
      mode: "production", // "production" | "development" | "none"
    </default>
    mode: "production", // enable many optimizations for production builds
    mode: "development", // enabled useful tools for development
    mode: "none", // no defaults
  </mode>
  // Chosen mode tells webpack to use its built-in optimizations accordingly.
  <entry "/configuration/entry-context/#entry">
    <default>
      entry: "./app/entry", // string | object | array
    </default>
    entry: ["./app/entry1", "./app/entry2"],
    entry: {
      a: "./app/entry-a",
      b: ["./app/entry-b1", "./app/entry-b2"]
    },
  </entry>
  // defaults to ./src
  // Here the application starts executing
  // and webpack starts bundling
  <link "/configuration/output">
    <default>
      output: {
    </default>
  </link>
    // options related to how webpack emits results
    path: path.resolve(__dirname, "dist"), // string
    // the target directory for all output files
    // must be an absolute path (use the Node.js path module)
    <filename "/configuration/output/#outputfilename">
      <default>
        filename: "bundle.js", // string
      </default>
      filename: "[name].js", // for multiple entry points
      filename: "[chunkhash].js", // for long term caching
    </filename>
    // the filename template for entry chunks
    <publicPath "/configuration/output/#outputpublicpath">
      <default>
        publicPath: "/assets/", // string
      </default>
      publicPath: "",
      publicPath: "https://cdn.example.com/",
    </publicPath>
    // the url to the output directory resolved relative to the HTML page
    library: "MyLibrary", // string,
    // the name of the exported library
    <libraryTarget "/configuration/output/#outputlibrarytarget">
      <default>
        libraryTarget: "umd", // universal module definition
      </default>
      libraryTarget: "umd2", // universal module definition
      libraryTarget: "commonjs2", // exported with module.exports
      libraryTarget: "commonjs", // exported as properties to exports
      libraryTarget: "amd", // defined with AMD defined method
      libraryTarget: "this", // property set on this
      libraryTarget: "var", // variable defined in root scope
      libraryTarget: "assign", // blind assignment
      libraryTarget: "window", // property set to window object
      libraryTarget: "global", // property set to global object
      libraryTarget: "jsonp", // jsonp wrapper
    </libraryTarget>
    // the type of the exported library
    <advancedOutput "#">
      <default>
        /* Advanced output configuration (click to show) */
      </default>
      pathinfo: true, // boolean
      // include useful path info about modules, exports, requests, etc. into the generated cod
      chunkFilename: "[id].js",
      chunkFilename: "[chunkhash].js", // for long term caching
      // the filename template for additional chunks
      jsonpFunction: "myWebpackJsonp", // string
      // name of the JSONP function used to load chunks
      sourceMapFilename: "[file].map", // string
      sourceMapFilename: "sourcemaps/[file].map", // string
      // the filename template of the source map location
      devtoolModuleFilenameTemplate: "webpack:///[resource-path]", // string
      // the name template for modules in a devtool
      devtoolFallbackModuleFilenameTemplate: "webpack:///[resource-path]?[hash]", // string
      // the name template for modules in a devtool (used for conflicts)
      umdNamedDefine: true, // boolean
      // use a named AMD module in UMD library
      crossOriginLoading: "use-credentials", // enum
      crossOriginLoading: "anonymous",
      crossOriginLoading: false,
      // specifies how cross origin request are issued by the runtime
    </advancedOutput>
    <expert "#">
      <default>
        /* Expert output configuration (on own risk) */
      </default>
      devtoolLineToLine: {
        test: /\\.jsx$/
      },
      // use a simple 1:1 mapped SourceMaps for these modules (faster)
      hotUpdateMainFilename: "[hash].hot-update.json", // string
      // filename template for HMR manifest
      hotUpdateChunkFilename: "[id].[hash].hot-update.js", // string
      // filename template for HMR chunks
      sourcePrefix: "\\t", // string
      // prefix module sources in bundle for better readablitity
    </expert>
  },
  module: {
    // configuration regarding modules
    rules: [
      // rules for modules (configure loaders, parser options, etc.)
      {
        test: /\\.jsx?$/,
        include: [
          path.resolve(__dirname, "app")
        ],
        exclude: [
          path.resolve(__dirname, "app/demo-files")
        ],
        // these are matching conditions, each accepting a regular expression or string
        // test and include have the same behavior, both must be matched
        // exclude must not be matched (takes preferrence over test and include)
        // Best practices:
        // - Use RegExp only in test and for filename matching
        // - Use arrays of absolute paths in include and exclude
        // - Try to avoid exclude and prefer include
        issuer: { test, include, exclude },
        // conditions for the issuer (the origin of the import)
        enforce: "pre",
        enforce: "post",
        // flags to apply these rules, even if they are overridden (advanced option)
        loader: "babel-loader",
        // the loader which should be applied, it'll be resolved relative to the context
        options: {
          presets: ["es2015"]
        },
        // options for the loader
      },
      {
        test: /\\.html$/,
        use: [
          // apply multiple loaders and options
          "htmllint-loader",
          {
            loader: "html-loader",
            options: {
              /* ... */
            }
          }
        ]
      },
      { oneOf: [ /* rules */ ] },
      // only use one of these nested rules
      { rules: [ /* rules */ ] },
      // use all of these nested rules (combine with conditions to be useful)
      { resource: { and: [ /* conditions */ ] } },
      // matches only if all conditions are matched
      { resource: { or: [ /* conditions */ ] } },
      { resource: [ /* conditions */ ] },
      // matches if any condition is matched (default for arrays)
      { resource: { not: /* condition */ } }
      // matches if the condition is not matched
    ],
    <advancedModule "#">
      <default>
        /* Advanced module configuration (click to show) */
      </default>
      noParse: [
        /special-library\\.js$/
      ],
      // do not parse this module
      unknownContextRequest: ".",
      unknownContextRecursive: true,
      unknownContextRegExp: /^\\.\\/.*$/,
      unknownContextCritical: true,
      exprContextRequest: ".",
      exprContextRegExp: /^\\.\\/.*$/,
      exprContextRecursive: true,
      exprContextCritical: true,
      wrappedContextRegExp: /.*/,
      wrappedContextRecursive: true,
      wrappedContextCritical: false,
      // specifies default behavior for dynamic requests
    </advancedModule>
  },
  resolve: {
    // options for resolving module requests
    // (does not apply to resolving to loaders)
    modules: [
      "node_modules",
      path.resolve(__dirname, "app")
    ],
    // directories where to look for modules
    extensions: [".js", ".json", ".jsx", ".css"],
    // extensions that are used
    alias: {
      // a list of module name aliases
      "module": "new-module",
      // alias "module" -> "new-module" and "module/path/file" -> "new-module/path/file"
      "only-module$": "new-module",
      // alias "only-module" -> "new-module", but not "only-module/path/file" -> "new-module/path/file"
      "module": path.resolve(__dirname, "app/third/module.js"),
      // alias "module" -> "./app/third/module.js" and "module/file" results in error
      // modules aliases are imported relative to the current context
    },
    <alias "/configuration/resolve/#resolvealias">
      <default>
        /* Alternative alias syntax (click to show) */
      </default>
      alias: [
        {
          name: "module",
          // the old request
          alias: "new-module",
          // the new request
          onlyModule: true
          // if true only "module" is aliased
          // if false "module/inner/path" is also aliased
        }
      ],
    </alias>
    <advancedResolve "#">
      <default>
        /* Advanced resolve configuration (click to show) */
      </default>
      symlinks: true,
      // follow symlinks to new location
      descriptionFiles: ["package.json"],
      // files that are read for package description
      mainFields: ["main"],
      // properties that are read from description file
      // when a folder is requested
      aliasFields: ["browser"],
      // properties that are read from description file
      // to alias requests in this package
      enforceExtension: false,
      // if true request must not include an extension
      // if false request may already include an extension
      moduleExtensions: ["-module"],
      enforceModuleExtension: false,
      // like extensions/enforceExtension but for module names instead of files
      unsafeCache: true,
      unsafeCache: {},
      // enables caching for resolved requests
      // this is unsafe as folder structure may change
      // but performance improvement is really big
      cachePredicate: (path, request) => true,
      // predicate function which selects requests for caching
      plugins: [
        // ...
      ]
      // additional plugins applied to the resolver
    </advancedResolve>
  },
  performance: {
    <hints "/configuration/performance/#performance-hints">
      <default>
        hints: "warning", // enum
      </default>
      hints: "error", // emit errors for perf hints
      hints: false, // turn off perf hints
    </hints>
    maxAssetSize: 200000, // int (in bytes),
    maxEntrypointSize: 400000, // int (in bytes)
    assetFilter: function(assetFilename) {
      // Function predicate that provides asset filenames
      return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
    }
  },
  <devtool "/configuration/devtool">
    <default>
      devtool: "source-map", // enum
    </default>
    devtool: "inline-source-map", // inlines SourceMap into original file
    devtool: "eval-source-map", // inlines SourceMap per module
    devtool: "hidden-source-map", // SourceMap without reference in original file
    devtool: "cheap-source-map", // cheap-variant of SourceMap without module mappings
    devtool: "cheap-module-source-map", // cheap-variant of SourceMap with module mappings
    devtool: "eval", // no SourceMap, but named modules. Fastest at the expense of detail.
  </devtool>
  // enhance debugging by adding meta info for the browser devtools
  // source-map most detailed at the expense of build speed.
  context: __dirname, // string (absolute path!)
  // the home directory for webpack
  // the entry and module.rules.loader option
  //   is resolved relative to this directory
  <target "/configuration/target">
    <default>
      target: "web", // enum
    </default>
    target: "webworker", // WebWorker
    target: "node", // Node.js via require
    target: "async-node", // Node.js via fs and vm
    target: "node-webkit", // nw.js
    target: "electron-main", // electron, main process
    target: "electron-renderer", // electron, renderer process
    target: (compiler) => { /* ... */ }, // custom
  </target>
  // the environment in which the bundle should run
  // changes chunk loading behavior and available modules
  <externals "/configuration/externals">
    <default>
      externals: ["react", /^@angular/],
    </default>
    externals: "react", // string (exact match)
    externals: /^[a-z\\-]+($|\\/)/, // Regex
    externals: { // object
      angular: "this angular", // this["angular"]
      react: { // UMD
        commonjs: "react",
        commonjs2: "react",
        amd: "react",
        root: "React"
      }
    },
    externals: ({request}) => { /* ... */ return "commonjs " + request }
  </externals>
  // Don't follow/bundle these modules, but request them at runtime from the environment
  <stats "/configuration/stats">
    <default>
      stats: "errors-only",
    </default>
    stats: { //object
      assets: true,
      colors: true,
      errors: true,
      errorDetails: true,
      hash: true,
      // ...
    },
  </stats>
  // lets you precisely control what bundle information gets displayed
  devServer: {
    proxy: { // proxy URLs to backend development server
      '/api': 'http://localhost:3000'
    },
    contentBase: path.join(__dirname, 'public'), // boolean | string | array, static file location
    compress: true, // enable gzip compression
    historyApiFallback: true, // true for index.html upon 404, object for multiple paths
    hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin
    https: false, // true for self-signed, object for cert authority
    noInfo: true, // only errors & warns on hot reload
    // ...
  },
  plugins: [
    // ...
  ],
  // list of additional plugins
  <advanced "#">
    <default>
      /* Advanced configuration (click to show) */
    </default>
    resolveLoader: { /* same as resolve */ }
    // separate resolve options for loaders
    parallelism: 1, // number
    // limit the number of parallel processed modules
    profile: true, // boolean
    // capture timing information
    bail: true, //boolean
    // fail out on the first error instead of tolerating it.
    cache: false, // boolean
    // disable/enable caching
    watch: true, // boolean
    // enables watching
    watchOptions: {
      aggregateTimeout: 1000, // in ms
      // aggregates multiple changes to a single rebuild
      poll: true,
      poll: 500, // intervall in ms
      // enables polling mode for watching
      // must be used on filesystems that doesn't notify on change
      // i. e. nfs shares
    },
    node: {
      // Polyfills and mocks to run Node.js-
      // environment code in non-Node environments.
      console: false, // boolean | "mock"
      global: true, // boolean | "mock"
      process: true, // boolean
      __filename: "mock", // boolean | "mock"
      __dirname: "mock", // boolean | "mock"
      Buffer: true, // boolean | "mock"
      setImmediate: true // boolean | "mock" | "empty"
    },
    recordsPath: path.resolve(__dirname, "build/records.json"),
    recordsInputPath: path.resolve(__dirname, "build/records.json"),
    recordsOutputPath: path.resolve(__dirname, "build/records.json"),
    // TODO
  </advanced>

webpack applies configuration defaults after plugins defaults are applied.

Want to rapidly generate webpack configuration file for your project requirements with few clicks away.

Generate Custom Webpack Configuration is an interactive portal you can play around by selecting custom webpack configuration options tailored for your frontend project. It automatically generates a minimal webpack configuration based on your selection of loaders/plugins, etc.

Or use webpack-cli's init command that will ask you a couple of questions before creating a configuration file.

npx webpack-cli init

You might be prompted to install @webpack-cli/init if it is not yet installed in the project or globally.

After running npx webpack-cli init you might get more packages installed to your project depending on the choices you've made during configuration generation.

npx webpack-cli init

β„Ή INFO For more information and a detailed description of each question, have a look at https://github.com/webpack/webpack-cli/blob/master/INIT.md
β„Ή INFO Alternatively, run `webpack(-cli) --help` for usage info.

? Will your application have multiple bundles? No
? Which module will be the first to enter the application? [default: ./src/index]
? Which folder will your generated bundles be in? [default: dist]:
? Will you be using ES2015? Yes
? Will you use one of the below CSS solutions? No

+ babel-plugin-syntax-dynamic-import@6.18.0
+ uglifyjs-webpack-plugin@2.0.1
+ webpack-cli@3.2.3
+ @babel/core@7.2.2
+ babel-loader@8.0.4
+ @babel/preset-env@7.1.0
+ webpack@4.29.3
added 124 packages from 39 contributors, updated 4 packages and audited 25221 packages in 7.463s
found 0 vulnerabilities


Congratulations! Your new webpack configuration file has been created!

createapp.dev - create a webpack configuration in your browser is an online tool for creating custom webpack configuration. It allows you to select various features that will be combined and added to resulting configuration file. Also, it generates an example project based on provided webpack configuration that you can review in your browser and download.