知海

Resolve 配置

webpackjsorg-main配置参考

Resolve 配置

这些选项用于修改模块的解析方式。Webpack 提供了合理的默认值,但也可以对解析过程进行详细修改。请查看模块解析了解解析器工作原理的更多说明。

resolve

object

配置如何解析模块。例如,在 ES2015 中调用 import 'lodash' 时,resolve 选项可以改变 webpack 去寻找 'lodash' 的位置(参见 modules)。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    // configuration options
  },
};

resolve.alias

object

importrequire 创建别名,以便更轻松地导入特定模块。例如,为一些常用的 src/ 目录添加别名:

webpack.config.js

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/"),
    },
  },
};

现在,无需在导入时使用相对路径,如下所示:

js 复制代码
import Utility from "../../utilities/utility";

你可以使用别名:

js 复制代码
import Utility from "Utilities/utility";

还可以在给定对象的键名尾部添加 $ 来表示精确匹配:

webpack.config.js

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"),
    },
  },
};

这将产生如下结果:

js 复制代码
import Test1 from "xyz"; // 精确匹配,因此解析并导入 path/to/file.js
import Test2 from "xyz/file.js"; // 非精确匹配,执行正常解析

你还可以在别名配置中使用通配符(*)来创建更灵活的映射:

webpack.config.js

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/*"), // 将 @something 映射到 path/to/something
    },
  },
};

这允许你使用如下导入:

js 复制代码
import Component from "@components/Button";
import utils from "@utils/helpers";

下表说明了其他情况:

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.js error
{ xyz$: '/abc/path/to/file.js' } /abc/path/to/file.js /abc/node_modules/xyz/file.js
{ xyz: './dir/file.js' } /abc/dir/file.js error
{ 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.js error
{ 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

如果在 package.json 中定义了 index.js,它可能会解析到另一个文件。

/abc/node_modules 也可能在 /node_modules 中解析。

W> resolve.alias 优先于其他模块解析。

W> null-loader 在 webpack 5 中已弃用。请使用 alias: { xyz$: false } 或绝对路径 alias: {[path.resolve(__dirname, './path/to/module')]: false }

W> [string] 值自 webpack 5 开始支持。

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/utilities/"),
        path.resolve(__dirname, "src/templates/"),
      ],
    },
  },
};

resolve.alias 设置为 false 将告诉 webpack 忽略某个模块。

js 复制代码
export default {
  // ...
  resolve: {
    alias: {
      "ignored-module": false,
      "./ignored-module": false,
    },
  },
};

T> 要基于正则表达式忽略模块,可以使用 IgnorePlugin

resolve.aliasFields

[string]: ['browser']

指定一个字段(如 browser),并按照此规范进行解析。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    aliasFields: ["browser"],
  },
};

resolve.byDependency

根据模块请求的类型配置解析选项。

  • 类型:[type: string]: ResolveOptions

  • 示例:

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

resolve.cache

boolean

启用对成功解析请求的缓存,允许重新验证缓存条目。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    cache: true,
  },
};

resolve.cachePredicate

function(module) => boolean

一个函数,用于决定请求是否应被缓存。向函数传入一个具有 pathrequest 属性的对象。必须返回一个布尔值。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    cachePredicate: (module) =>
      // 附加逻辑
      true,
  },
};

resolve.cacheWithContext

boolean

如果启用了不安全缓存,则在缓存键中包含 request.context。此选项由 enhanced-resolve 模块考虑。当提供了 resolve 或 resolveLoader 插件时,解析缓存中的 context 会被忽略。这解决了性能回退问题。

resolve.conditionNames

string[]

用于 exports 字段的条件名称,该字段定义包的入口点。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    conditionNames: ["require", "node"],
  },
};

Webpack 将匹配 resolve.conditionNames 数组中列出的导出条件

默认值

默认的 conditionNames 会根据 modetarget 配置动态生成:

基础条件始终包括:

  • "webpack" — 始终存在。
  • "production""development" — 基于当前的 mode(当 mode 为 "none""production" 时使用 "production")。

根据 target 附加额外条件:

目标属性 条件
webworker "worker"
node "node"
web "browser"
electron "electron"
nwjs "nwjs"

例如,当 target: "web"(默认值)且 mode: "production" 时,基础 conditionNames 默认为 ["webpack", "production", "browser"]

按依赖类型区分的条件

Webpack 根据模块的导入方式,通过 resolve.byDependency 进一步调整 conditionNames"..." 令牌会继承上述基础条件。

依赖类型 conditionNames 用途
esmwasmloaderImport ["import", "module-sync", "module", "..."] ESM import 语句、WebAssembly、loader 导入
commonjsamdloaderunknownundefined ["require", "module-sync", "module", "..."] require() 调用、AMD 及其他依赖类型
worker ["worker", "import", "module-sync", "module", "..."] new Worker() 表达式
css-import ["webpack", <mode>, "style"] CSS @import 语句

"module-sync" 已包含在默认条件中,以与 Node.js 保持一致,Node.js 为可同步加载的 ESM 公开了 module-sync 社区条件。在其 package.json 中发布 module-sync 导出的包会被自动识别,无需额外配置。

例如,当项目中的文件在 target: "web"mode: "production" 下使用 import 时,最终解析的条件为 ["import", "module-sync", "module", "webpack", "production", "browser"]

T> resolveLoader 选项对 conditionNames 使用不同的默认值:["loader", "require", "node"]。参见 resolveLoader

条件匹配

exports 字段中键的顺序很重要。在条件匹配期间,较早的条目具有更高的优先级,并优先于较晚的条目。

例如,

package.json

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

js 复制代码
export default {
  // ...
  resolve: {
    conditionNames: ["require", "node"],
  },
};

导入

  • 'foo' 将解析为 'foo/index-require.js'
  • 'foo/bar' 将解析为 'foo/bar-node.js',因为在条件导出对象中 "node" 键位于 "require" 键之前。
  • 'foo/baz' 将解析为 'foo/baz-node.js'

自定义条件

如果你希望在保留默认 Webpack 值的同时添加自定义字段名,可以使用 "..."

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    conditionNames: ["my-custom-condition", "..."],
  },
};

或者,若要优先使用默认条件,然后再添加自定义条件:

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    conditionNames: ["...", "my-custom-condition"],
  },
};

resolve.descriptionFiles

[string] = ['package.json']

用于描述模块的 JSON 文件。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    descriptionFiles: ["package.json"],
  },
};

resolve.enforceExtension

boolean = false

如果为 true,则不允许使用无扩展名的文件。因此,默认情况下,如果 ./foo 具有 .js 扩展名,import foo from "./foo";/require('./foo') 可以工作,但启用此选项后,只有 import foo from "./foo.js"/require('./foo.js') 才会工作。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    enforceExtension: false,
  },
};

resolve.exportsFields

[string] = ['exports']

package.json 中用于解析模块请求的字段。有关更多信息,请参阅包导出指南

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    exportsFields: ["exports", "myCompanyExports"],
  },
};

resolve.extensionAlias

object

将扩展名映射到扩展名别名的对象。

webpack.config.js

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

resolve.extensions

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

按顺序尝试解析这些扩展名。如果多个文件共享相同的名称但具有不同的扩展名,webpack 将解析数组中排在最前面的扩展名的文件,并跳过其余文件。

webpack.config.js

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

这使用户在导入时可以省略扩展名:

js 复制代码
import File from "../path/to/file";

请注意,像上面这样使用 resolve.extensions覆盖默认数组,这意味着 webpack 将不再尝试使用默认扩展名解析模块。但是,你可以使用 '...' 来访问默认扩展名:

js 复制代码
export default {
  // ...
  resolve: {
    extensions: [".ts", "..."],
  },
};

resolve.fallback

object

当正常解析失败时,重定向模块请求。

webpack.config.js

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, // 不包含 abc 的 polyfill
      xyz: path.resolve(__dirname, "path/to/file.js"), // 包含 xyz 的 polyfill
    },
  },
};

Webpack 5 不再自动为 Node.js 核心模块提供 polyfill,这意味着如果你在浏览器或类似环境中运行的代码中使用它们,则必须从 npm 安装兼容模块并自行包含它们。以下是 webpack 在 webpack 5 之前使用过的 polyfill 列表:

js 复制代码
import { createRequire } from "node:module";

const require = createRequire(import.meta.url);

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

当设置为 true 时,此选项将用户指定的请求视为完全指定。这意味着不会自动添加扩展名,也不会解析目录中的 mainFiles。需要注意的是,此行为不会影响通过 mainFieldsaliasFieldsaliases 发出的请求。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    fullySpecified: true,
  },
};

resolve.importsFields

[string]

来自 package.json 的字段,用于提供包的内部请求(以 # 开头的请求被视为内部请求)。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    importsFields: ["browser", "module", "main"],
  },
};

resolve.mainFields

[string]

从 npm 包导入(例如 import * as D3 from 'd3')时,此选项将决定检查其 package.json 中的哪些字段。默认值将根据 webpack 配置中指定的 target 而有所不同。

target 属性设置为 webworkerweb 或未指定时:

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    mainFields: ["browser", "module", "main"],
  },
};

对于任何其他目标(包括 node):

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    mainFields: ["module", "main"],
  },
};

例如,考虑一个名为 upstream 的任意库,其 package.json 包含以下字段:

json 复制代码
{
  "browser": "build/upstream.js",
  "module": "index"
}

当我们执行 import * as Upstream from 'upstream' 时,实际上会解析到 browser 属性中的文件。browser 属性优先,因为它是 mainFields 中的第一项。同时,由 webpack 打包的 Node.js 应用程序将首先尝试使用 module 字段中的文件进行解析。

resolve.mainFiles

[string] = ['index']

解析目录时使用的文件名。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    mainFiles: ["index"],
  },
};

resolve.modules

[string] = ['node_modules']

告诉 webpack 解析模块时应搜索哪些目录。

绝对路径和相对路径都可以使用,但请注意它们的行为会略有不同。

相对路径的扫描方式与 Node 扫描 node_modules 的方式类似,会检查当前目录及其祖先目录(例如 ./node_modules../node_modules 等)。

对于绝对路径,只会搜索给定的目录。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    modules: ["node_modules"],
  },
};

如果你想添加一个优先于 node_modules/ 的搜索目录:

webpack.config.js

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]

应应用的附加解析插件列表。

每个条目可以是:

  • 具有 apply(resolver) 方法的插件对象
  • 或者函数式插件,解析器将同时作为 this 和第一个参数调用该函数

它允许使用诸如 DirectoryNamedWebpackPlugin 之类的插件。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    plugins: [
      // 对象式插件
      {
        apply(resolver) {
          // 自定义逻辑
        },
      },

      // 函数式插件
      function (resolver) {
        // `this` 也是解析器
      },
    ],
  },
};

resolve.preferAbsolute

boolean

解析时优先使用绝对路径,而不是 resolve.roots

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    preferAbsolute: true,
  },
};

resolve.preferRelative

boolean

启用后,webpack 将更倾向于将模块请求解析为相对请求,而不是使用来自 node_modules 目录的模块。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    preferRelative: true,
  },
};

src/index.js

{/* eslint-disable */}

js 复制代码
// 假设 `src/logo.svg` 存在
import logo1 from "logo.svg"; // 当启用 `preferRelative` 时,这是可行的
import logo2 from "./logo.svg"; // 否则你只能使用相对路径来解析 logo.svg

// 对于 `new URL()` 的情况,`preferRelative` 默认启用
const b = new URL("module/path", import.meta.url);
const a = new URL("./module/path", import.meta.url);

resolve.restrictions

[string, RegExp]

解析限制列表,用于限制请求可以解析到的路径。

webpack.config.js

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

resolve.roots

[string]

服务器相对 URL(以 / 开头)的请求所解析的目录列表,默认值为 context 配置选项。在非 Windows 系统上,这些请求首先作为绝对路径解析。

webpack.config.js

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],
  },
};

boolean = true

是否将符号链接解析到其链接位置。

启用时,符号链接资源将解析到其_实际_路径,而不是其符号链接位置。请注意,使用符号链接包的工具(如 npm link)时,这可能导致模块解析失败。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    symlinks: true,
  },
};

resolve.unsafeCache

object boolean = true

启用激进但不安全的模块缓存。传递 true 将缓存所有内容。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    unsafeCache: true,
  },
};

当提供对象时,webpack 将把它用作缓存。

例如,你可以提供一个 Proxy 对象而不是普通对象:

webpack.config.js

js 复制代码
// 复制自讨论 https://github.com/webpack/webpack/discussions/18089
const realUnsafeCache = {};
const unsafeCacheHandler = {
  get(cache, key) {
    const cachedValue = cache[key];

    // 确保文件存在于磁盘上
    if (cachedValue && !fs.existsSync(cachedValue.path)) {
      // 如果不存在,则逐出该缓存条目。
      delete cache[key];
      return undefined;
    }

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

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

W> 对缓存路径的更改在极少数情况下可能导致失败。

resolve.useSyncFileSystemCalls

boolean

解析器使用同步文件系统调用。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    useSyncFileSystemCalls: true,
  },
};

resolve.tsconfig

boolean string object

用于路径映射的 TypeScript 配置。此选项替代了对 tsconfig-paths-webpack-plugin 的需求。它从 tsconfig.json 中读取 compilerOptions.baseUrlcompilerOptions.paths,并在解析导入时应用这些别名。

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    tsconfig: true, // 使用默认的 tsconfig.json
  },
};

选项:

  • false - 禁用 TypeScript 路径映射
  • true - 使用默认的 tsconfig.json 文件(自动搜索)
  • string - tsconfig.json 文件的路径(相对或绝对)

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    tsconfig: "./tsconfig.app.json", // 自定义路径
  },
};
  • object - 包含 configFilereferences 选项的对象

webpack.config.js

js 复制代码
export default {
  // ...
  resolve: {
    tsconfig: {
      configFile: "./tsconfig.json",
      references: "auto", // 或路径数组
    },
  },
};

对象选项:

  • configFilestring):tsconfig 文件的路径(相对或绝对)
  • references"auto" | string[]):对其他 tsconfig 文件的引用。"auto" 从 TypeScript 配置继承,或为相对/绝对路径数组

tsconfig.json 示例:

json 复制代码
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "components/*": ["src/components/*"]
    }
  }
}

然后在你的代码中:

ts 复制代码
import Button from "@/components/Button";
import Header from "components/Header";

T> 此选项在 resolveLoader 中也可用,配置选项相同。

resolveLoader

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

这组选项与上述 resolve 属性相同,但仅用于解析 webpack 的 loader 包。

webpack.config.js

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

T> 请注意,你可以在此处使用别名以及 resolve 中熟悉的其他功能。例如,{ txt: 'raw-loader' }txt!templates/demo.txt 填充为使用 raw-loader

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。