Resolve

These options change how modules are resolved. Webpack provides reasonable defaults, but it is possible to change the resolving in detail. Have a look at Module Resolution for more explanation of how the resolver works.

resolve

object

Configure how modules are resolved. For example, when calling import 'lodash' in ES2015, the resolve options can change where webpack goes to look for 'lodash' (see modules).

webpack.config.js

export default {
  // ...
  resolve: {
    // configuration options
  },
};

resolve.alias

object

Create aliases to import or require certain modules more easily. For example, to alias a bunch of commonly used src/ folders:

webpack.config.js

import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  // ...
  resolve: {
    alias: {
      Utilities: path.resolve(__dirname, "src/utilities/"),
      Templates: path.resolve(__dirname, "src/templates/"),
    },
  },
};

Now, instead of using relative paths when importing like so:

import Utility from "../../utilities/utility";

you can use the alias:

import Utility from "Utilities/utility";

A trailing $ can also be added to the given object's keys to signify an exact match:

webpack.config.js

import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  // ...
  resolve: {
    alias: {
      xyz$: path.resolve(__dirname, "path/to/file.js"),
    },
  },
};

which would yield these results:

import Test1 from "xyz"; // Exact match, so path/to/file.js is resolved and imported
import Test2 from "xyz/file.js"; // Not an exact match, normal resolution takes place

You can also use wildcards (*) in your alias configuration to create more flexible mappings:

webpack.config.js

import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  // ...
  resolve: {
    alias: {
      "@*": path.resolve(__dirname, "src/*"), // maps @something to path/to/something
    },
  },
};

This allows you to use imports like:

import Component from "@components/Button";
import utils from "@utils/helpers";

The following table explains other cases:

alias:import 'xyz'import 'xyz/file.js'
{}/abc/node_modules/xyz/index.js/abc/node_modules/xyz/file.js
{ xyz: '/abc/path/to/file.js' }/abc/path/to/file.jserror
{ xyz$: '/abc/path/to/file.js' }/abc/path/to/file.js/abc/node_modules/xyz/file.js
{ xyz: './dir/file.js' }/abc/dir/file.jserror
{ xyz$: './dir/file.js' }/abc/dir/file.js/abc/node_modules/xyz/file.js
{ xyz: '/some/dir' }/some/dir/index.js/some/dir/file.js
{ xyz$: '/some/dir' }/some/dir/index.js/abc/node_modules/xyz/file.js
{ xyz: './dir' }/abc/dir/index.js/abc/dir/file.js
{ xyz: 'modu' }/abc/node_modules/modu/index.js/abc/node_modules/modu/file.js
{ xyz$: 'modu' }/abc/node_modules/modu/index.js/abc/node_modules/xyz/file.js
{ xyz: 'modu/some/file.js' }/abc/node_modules/modu/some/file.jserror
{ xyz: 'modu/dir' }/abc/node_modules/modu/dir/index.js/abc/node_modules/modu/dir/file.js
{ xyz$: 'modu/dir' }/abc/node_modules/modu/dir/index.js/abc/node_modules/xyz/file.js

index.js may resolve to another file if defined in the package.json.

/abc/node_modules may resolve in /node_modules too.

import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  // ...
  resolve: {
    alias: {
      _: [
        path.resolve(__dirname, "src/utilities/"),
        path.resolve(__dirname, "src/templates/"),
      ],
    },
  },
};

Setting resolve.alias to false will tell webpack to ignore a module.

export default {
  // ...
  resolve: {
    alias: {
      "ignored-module": false,
      "./ignored-module": false,
    },
  },
};

resolve.aliasFields

[string]: ['browser']

Specify a field, such as browser, to be parsed according to this specification.

webpack.config.js

export default {
  // ...
  resolve: {
    aliasFields: ["browser"],
  },
};

resolve.byDependency

Configure resolve options by the type of module request.

  • Type: [type: string]: ResolveOptions

  • Example:

    export default {
      // ...
      resolve: {
        byDependency: {
          // ...
          esm: {
            mainFields: ["browser", "module"],
          },
          commonjs: {
            aliasFields: ["browser"],
          },
          url: {
            preferRelative: true,
          },
        },
      },
    };

resolve.cache

boolean

Enables caching of successfully resolved requests, allowing cache entries to be revalidated.

webpack.config.js

export default {
  // ...
  resolve: {
    cache: true,
  },
};

resolve.cachePredicate

function(module) => boolean

A function which decides whether a request should be cached or not. An object is passed to the function with path and request properties. It must return a boolean.

webpack.config.js

export default {
  // ...
  resolve: {
    cachePredicate: (module) =>
      // additional logic
      true,
  },
};

resolve.cacheWithContext

boolean

If unsafe cache is enabled, includes request.context in the cache key. This option is taken into account by the enhanced-resolve module. context in resolve caching is ignored when resolve or resolveLoader plugins are provided. This addresses a performance regression.

resolve.conditionNames

string[]

Condition names for exports field which defines entry points of a package.

webpack.config.js

export default {
  // ...
  resolve: {
    conditionNames: ["require", "node"],
  },
};

Webpack will match export conditions that are listed within the resolve.conditionNames array.

The key order in the exports field is significant. During condition matching, earlier entries have higher priority and take precedence over later entries.

For example,

package.json

{
  "name": "foo",
  "exports": {
    ".": {
      "import": "./index-import.js",
      "require": "./index-require.js",
      "node": "./index-node.js"
    },
    "./bar": {
      "node": "./bar-node.js",
      "require": "./bar-require.js"
    },
    "./baz": {
      "import": "./baz-import.js",
      "node": "./baz-node.js"
    }
  }
}

webpack.config.js

export default {
  // ...
  resolve: {
    conditionNames: ["require", "node"],
  },
};

importing

  • 'foo' will resolve to 'foo/index-require.js'
  • 'foo/bar' will resolve to 'foo/bar-node.js' as the "node" key comes before "require" key in the conditional exports object.
  • 'foo/baz' will resolve to 'foo/baz-node.js'

If you want to add your custom field names while still retaining the default Webpack values, you can use "...":

webpack.config.js

export default {
  // ...
  resolve: {
    conditionNames: ["my-custom-condition", "..."],
  },
};

Alternatively, to prioritize the default conditions first, then add your custom conditions:

webpack.config.js

export default {
  // ...
  resolve: {
    conditionNames: ["...", "my-custom-condition"],
  },
};

resolve.descriptionFiles

[string] = ['package.json']

The JSON files to use for descriptions.

webpack.config.js

export default {
  // ...
  resolve: {
    descriptionFiles: ["package.json"],
  },
};

resolve.enforceExtension

boolean = false

If true, it will not allow extension-less files. So by default require('./foo') works if ./foo has a .js extension, but with this enabled only require('./foo.js') will work.

webpack.config.js

export default {
  // ...
  resolve: {
    enforceExtension: false,
  },
};

resolve.exportsFields

[string] = ['exports']

Fields in package.json that are used for resolving module requests. See package-exports guideline for more information.

webpack.config.js

export default {
  // ...
  resolve: {
    exportsFields: ["exports", "myCompanyExports"],
  },
};

resolve.extensionAlias

object

An object which maps extension to extension aliases.

webpack.config.js

export default {
  // ...
  resolve: {
    extensionAlias: {
      ".js": [".ts", ".js"],
      ".mjs": [".mts", ".mjs"],
    },
  },
};

resolve.extensions

[string] = ['.js', '.json', '.wasm']

Attempt to resolve these extensions in order. If multiple files share the same name but have different extensions, webpack will resolve the one with the extension listed first in the array and skip the rest.

webpack.config.js

export default {
  // ...
  resolve: {
    extensions: [".js", ".json", ".wasm"],
  },
};

which is what enables users to leave off the extension when importing:

import File from "../path/to/file";

Note that using resolve.extensions like above will override the default array, meaning that webpack will no longer try to resolve modules using the default extensions. However you can use '...' to access the default extensions:

export default {
  // ...
  resolve: {
    extensions: [".ts", "..."],
  },
};

resolve.fallback

object

Redirect module requests when normal resolving fails.

webpack.config.js

import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  // ...
  resolve: {
    fallback: {
      abc: false, // do not include a polyfill for abc
      xyz: path.resolve(__dirname, "path/to/file.js"), // include a polyfill for xyz
    },
  },
};

Webpack 5 no longer polyfills Node.js core modules automatically which means if you use them in your code running in browsers or alike, you will have to install compatible modules from npm and include them yourself. Here is a list of polyfills webpack has used before webpack 5:

export default {
  // ...
  resolve: {
    fallback: {
      assert: require.resolve("assert"),
      buffer: require.resolve("buffer"),
      console: require.resolve("console-browserify"),
      constants: require.resolve("constants-browserify"),
      crypto: require.resolve("crypto-browserify"),
      domain: require.resolve("domain-browser"),
      events: require.resolve("events"),
      http: require.resolve("stream-http"),
      https: require.resolve("https-browserify"),
      os: require.resolve("os-browserify/browser"),
      path: require.resolve("path-browserify"),
      punycode: require.resolve("punycode"),
      process: require.resolve("process/browser"),
      querystring: require.resolve("querystring-es3"),
      stream: require.resolve("stream-browserify"),
      string_decoder: require.resolve("string_decoder"),
      sys: require.resolve("util"),
      timers: require.resolve("timers-browserify"),
      tty: require.resolve("tty-browserify"),
      url: require.resolve("url"),
      util: require.resolve("util"),
      vm: require.resolve("vm-browserify"),
      zlib: require.resolve("browserify-zlib"),
    },
  },
};

resolve.fullySpecified

boolean

When set to true, this option treats user-specified requests as fully specified. This means that no extensions are automatically added, and the mainFiles within directories are not resolved. It's important to note that this behavior does not affect requests made through mainFields, aliasFields, or aliases.

webpack.config.js

export default {
  // ...
  resolve: {
    fullySpecified: true,
  },
};

resolve.importsFields

[string]

Fields from package.json which are used to provide the internal requests of a package (requests starting with # are considered internal).

webpack.config.js

export default {
  // ...
  resolve: {
    importsFields: ["browser", "module", "main"],
  },
};

resolve.mainFields

[string]

When importing from an npm package, e.g. import * as D3 from 'd3', this option will determine which fields in its package.json are checked. The default values will vary based upon the target specified in your webpack configuration.

When the target property is set to webworker, web, or left unspecified:

webpack.config.js

export default {
  // ...
  resolve: {
    mainFields: ["browser", "module", "main"],
  },
};

For any other target (including node):

webpack.config.js

export default {
  // ...
  resolve: {
    mainFields: ["module", "main"],
  },
};

For example, consider an arbitrary library called upstream with a package.json that contains the following fields:

{
  "browser": "build/upstream.js",
  "module": "index"
}

When we import * as Upstream from 'upstream' this will actually resolve to the file in the browser property. The browser property takes precedence because it's the first item in mainFields. Meanwhile, a Node.js application bundled by webpack will first try to resolve using the file in the module field.

resolve.mainFiles

[string] = ['index']

The filename to be used while resolving directories.

webpack.config.js

export default {
  // ...
  resolve: {
    mainFiles: ["index"],
  },
};

resolve.modules

[string] = ['node_modules']

Tell webpack what directories should be searched when resolving modules.

Absolute and relative paths can both be used, but be aware that they will behave a bit differently.

A relative path will be scanned similarly to how Node scans for node_modules, by looking through the current directory as well as its ancestors (i.e. ./node_modules, ../node_modules, and on).

With an absolute path, it will only search in the given directory.

webpack.config.js

export default {
  // ...
  resolve: {
    modules: ["node_modules"],
  },
};

If you want to add a directory to search in that takes precedence over node_modules/:

webpack.config.js

import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export default {
  // ...
  resolve: {
    modules: [path.resolve(__dirname, "src"), "node_modules"],
  },
};

resolve.plugins

[Plugin | Function]

A list of additional resolve plugins which should be applied.

Each entry can be either:

  • A plugin object with an apply(resolver) method
  • Or a function plugin, which will be called with the resolver as both this and the first argument

It allows plugins such as DirectoryNamedWebpackPlugin.

webpack.config.js

export default {
  // ...
  resolve: {
    plugins: [
      // Object-style plugin
      {
        apply(resolver) {
          // custom logic
        },
      },

      // Function-style plugin
      function (resolver) {
        // `this` is also the resolver
      },
    ],
  },
};

resolve.preferAbsolute

boolean

5.13.0+

Prefer absolute paths to resolve.roots when resolving.

webpack.config.js

export default {
  // ...
  resolve: {
    preferAbsolute: true,
  },
};

resolve.preferRelative

boolean

When enabled, webpack would prefer to resolve module requests as relative requests instead of using modules from node_modules directories.

webpack.config.js

export default {
  // ...
  resolve: {
    preferRelative: true,
  },
};

src/index.js

// let's say `src/logo.svg` exists
import logo1 from "logo.svg"; // this is viable when `preferRelative` enabled
import logo2 from "./logo.svg"; // otherwise you can only use relative path to resolve logo.svg

// `preferRelative` is enabled by default for `new URL()` case
const b = new URL("module/path", import.meta.url);
const a = new URL("./module/path", import.meta.url);

resolve.restrictions

[string, RegExp]

A list of resolve restrictions to restrict the paths that a request can be resolved on.

webpack.config.js

export default {
  // ...
  resolve: {
    restrictions: [/\.(sass|scss|css)$/],
  },
};

resolve.roots

[string]

A list of directories where requests of server-relative URLs (starting with '/') are resolved, defaults to context configuration option. On non-Windows systems these requests are resolved as an absolute path first.

webpack.config.js

import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const fixtures = path.resolve(__dirname, "fixtures");

export default {
  // ...
  resolve: {
    roots: [__dirname, fixtures],
  },
};

resolve.symlinks

boolean = true

Whether to resolve symlinks to their symlinked location.

When enabled, symlinked resources are resolved to their real path, not their symlinked location. Note that this may cause module resolution to fail when using tools that symlink packages (like npm link).

webpack.config.js

export default {
  // ...
  resolve: {
    symlinks: true,
  },
};

resolve.unsafeCache

object boolean = true

Enable aggressive, but unsafe, caching of modules. Passing true will cache everything.

webpack.config.js

export default {
  // ...
  resolve: {
    unsafeCache: true,
  },
};

When an object is provided, webpack will use it as cache.

For example, you can supply a Proxy object instead of a regular one:

webpack.config.js

// copied from discussion here https://github.com/webpack/webpack/discussions/18089
const realUnsafeCache = {};
const unsafeCacheHandler = {
  get(cache, key) {
    const cachedValue = cache[key];

    // make sure the file exists on disk
    if (cachedValue && !fs.existsSync(cachedValue.path)) {
      // and if it doesn't, evict that cache entry.
      delete cache[key];
      return undefined;
    }

    return cachedValue;
  },
};
const theProxiedCache = new Proxy(realUnsafeCache, unsafeCacheHandler);

export default {
  // ...
  resolve: {
    unsafeCache: theProxiedCache,
  },
};

resolve.useSyncFileSystemCalls

boolean

Use synchronous filesystem calls for the resolver.

webpack.config.js

export default {
  // ...
  resolve: {
    useSyncFileSystemCalls: true,
  },
};

resolve.tsconfig

5.105.0+

boolean string object

TypeScript config for paths mapping. This option replaces the need for tsconfig-paths-webpack-plugin. It reads compilerOptions.baseUrl and compilerOptions.paths from tsconfig.json and applies those aliases when resolving imports.

webpack.config.js

export default {
  // ...
  resolve: {
    tsconfig: true, // Use default tsconfig.json
  },
};

Options:

  • false - Disable TypeScript path mapping
  • true - Use the default tsconfig.json file (searches for it automatically)
  • string - Path to a tsconfig.json file (relative or absolute)

webpack.config.js

export default {
  // ...
  resolve: {
    tsconfig: "./tsconfig.app.json", // Custom path
  },
};
  • object - Object with configFile and references options

webpack.config.js

export default {
  // ...
  resolve: {
    tsconfig: {
      configFile: "./tsconfig.json",
      references: "auto", // or array of paths
    },
  },
};

Object options:

  • configFile (string): A path to the tsconfig file (relative or absolute)
  • references ("auto" | string[]): References to other tsconfig files. "auto" inherits from TypeScript config, or an array of relative/absolute paths

Example tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "components/*": ["src/components/*"]
    }
  }
}

Then in your code:

import Button from "@/components/Button";
import Header from "components/Header";

resolveLoader

object { modules [string] = ['node_modules'], extensions [string] = ['.js', '.json'], mainFields [string] = ['loader', 'main']}

This set of options is identical to the resolve property set above, but is used only to resolve webpack's loader packages.

webpack.config.js

export default {
  // ...
  resolveLoader: {
    modules: ["node_modules"],
    extensions: [".js", ".json"],
    mainFields: ["loader", "main"],
  },
};

19 Contributors

sokraskipjackSpaceK33zpksjcesebastiandeutschtbroadleybyzyknumb86jgravoisEugeneHlushkoAghassimyshovanikethsahachenxsanjamesgeorge007snitin315sapenleiMazen050tusharthakur04