Webpack Resolve(解析)

2023-05-15 17:50 更新

這些選項(xiàng)能設(shè)置模塊如何被解析。webpack 提供合理的默認(rèn)值,但是還是可能會(huì)修改一些解析的細(xì)節(jié)。關(guān)于 resolver 具體如何工作的更多解釋說(shuō)明,請(qǐng)查看模塊解析。

resolve

?object?

配置模塊如何解析。例如,當(dāng)在 ES2015 中調(diào)用 import 'lodash',resolve 選項(xiàng)能夠?qū)?webpack 查找 'lodash' 的方式去做修改(查看模塊)。

webpack.config.js

module.exports = {
  //...
  resolve: {
    // configuration options
  },
};

resolve.alias

?object?

創(chuàng)建 import 或 require 的別名,來(lái)確保模塊引入變得更簡(jiǎn)單。例如,一些位于 src/ 文件夾下的常用模塊:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  resolve: {
    alias: {
      Utilities: path.resolve(__dirname, 'src/utilities/'),
      Templates: path.resolve(__dirname, 'src/templates/'),
    },
  },
};

現(xiàn)在,替換“在導(dǎo)入時(shí)使用相對(duì)路徑”這種方式,就像這樣:

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

你可以這樣使用別名:

import Utility from 'Utilities/utility';

也可以在給定對(duì)象的鍵后的末尾添加 $,以表示精準(zhǔn)匹配:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  resolve: {
    alias: {
      xyz$: path.resolve(__dirname, 'path/to/file.js'),
    },
  },
};

這將產(chǎn)生以下結(jié)果:

import Test1 from 'xyz'; // 精確匹配,所以 path/to/file.js 被解析和導(dǎo)入
import Test2 from 'xyz/file.js'; // 非精確匹配,觸發(fā)普通解析

下面的表格展示了一些其他情況:

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? 可能會(huì)被解析為另一個(gè)文件。

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

module.exports = {
  //...
  resolve: {
    alias: {
      _: [
        path.resolve(__dirname, 'src/utilities/'),
        path.resolve(__dirname, 'src/templates/'),
      ],
    },
  },
};

將 ?resolve.alias? 設(shè)置為 false 將告知 webpack 忽略模塊。

module.exports = {
  //...
  resolve: {
    alias: {
      'ignored-module': false,
      './ignored-module': false,
    },
  },
};

resolve.aliasFields

[string]: ['browser']

指定一個(gè)字段,例如 browser,根據(jù) 此規(guī)范進(jìn)行解析。

webpack.config.js

module.exports = {
  //...
  resolve: {
    aliasFields: ['browser'],
  },
};

resolve.cacheWithContext

?boolean?

如果啟用了不安全緩存,請(qǐng)?jiān)诰彺骀I(cache key)中引入 request.context。這個(gè)選項(xiàng)被 enhanced-resolve 模塊考慮在內(nèi)。從 webpack 3.1.0 開(kāi)始,在配置了 resolve 或 resolveLoader 插件時(shí),解析緩存(resolve caching)中的上下文(context)會(huì)被忽略。這解決了性能衰退的問(wèn)題。

resolve.conditionNames

?string[]?

exports 配置項(xiàng) (定義一個(gè)庫(kù)的入口)的 conditionName。

webpack.config.js

module.exports = {
  //...
  resolve: {
    conditionNames: ['require', 'node'],
  },
};

Webpack 將會(huì)匹配列在 resolve.conditionNames 數(shù)組中的 export conditions。

exports 字段中的鍵順序很重要。在條件匹配期間,較早的入口具有更高的優(yōu)先級(jí)并優(yōu)先于后面的入口。

例如,

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

module.exports = {
  //...
  resolve: {
    conditionNames: ['require', 'node'],
  },
};

importing

  • 'foo' 將解析為 'foo/index-require.js'
  • 'foo/bar'將解析為 'foo/bar-node.js',因?yàn)樵跅l件導(dǎo)出對(duì)象中, "node" 字段在 "require" 之前。
  • 'foo/baz' 將解析為 'foo/baz-node.js'

resolve.descriptionFiles

?[string] = ['package.json']?

用于描述的 JSON 文件。

webpack.config.js

module.exports = {
  //...
  resolve: {
    descriptionFiles: ['package.json'],
  },
};

resolve.enforceExtension

?boolean = false?

如果是 true,將不允許無(wú)擴(kuò)展名文件。默認(rèn)如果 ./foo 有 .js 擴(kuò)展,require('./foo') 可以正常運(yùn)行。但如果啟用此選項(xiàng),只有 require('./foo.js') 能夠正常工作。

webpack.config.js

module.exports = {
  //...
  resolve: {
    enforceExtension: false,
  },
};

resolve.extensionAlias

object

一個(gè)將拓展名與拓展名別名映射的對(duì)象。

webpack.config.js

module.exports = {
  //...
  resolve: {
    extensionAlias: {
      '.js': ['.ts', '.js'],
      '.mjs': ['.mts', '.mjs'],
    },
  },
};

resolve.extensions

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

嘗試按順序解析這些后綴名。如果有多個(gè)文件有相同的名字,但后綴名不同,webpack 會(huì)解析列在數(shù)組首位的后綴的文件 并跳過(guò)其余的后綴。

webpack.config.js

module.exports = {
  //...
  resolve: {
    extensions: ['.js', '.json', '.wasm'],
  },
};

能夠使用戶(hù)在引入模塊時(shí)不帶擴(kuò)展:

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

請(qǐng)注意,以上這樣使用 resolve.extensions 會(huì) 覆蓋默認(rèn)數(shù)組,這就意味著 webpack 將不再?lài)L試使用默認(rèn)擴(kuò)展來(lái)解析模塊。然而你可以使用 '...' 訪問(wèn)默認(rèn)拓展名:

module.exports = {
  //...
  resolve: {
    extensions: ['.ts', '...'],
  },
};

resolve.fallback

?object?

當(dāng)正常解析失敗時(shí),重定向模塊請(qǐng)求。

webpack.config.js

module.exports = {
  //...
  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 不再自動(dòng) polyfill Node.js 的核心模塊,這意味著如果你在瀏覽器或類(lèi)似的環(huán)境中運(yùn)行的代碼中使用它們,你必須從 NPM 中安裝兼容的模塊,并自己包含它們。以下是 webpack 在 webpack 5 之前使用過(guò)的 polyfill 包列表:

module.exports = {
  //...
  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.mainFields

?[string]?

當(dāng)從 npm 包中導(dǎo)入模塊時(shí)(例如,import * as D3 from 'd3'),此選項(xiàng)將決定在 package.json 中使用哪個(gè)字段導(dǎo)入模塊。根據(jù) webpack 配置中指定的 target 不同,默認(rèn)值也會(huì)有所不同。

當(dāng) target 屬性設(shè)置為 webworker, web 或者沒(méi)有指定:

webpack.config.js

module.exports = {
  //...
  resolve: {
    mainFields: ['browser', 'module', 'main'],
  },
};

對(duì)于其他任意的 target(包括 node),默認(rèn)值為:

webpack.config.js

module.exports = {
  //...
  resolve: {
    mainFields: ['module', 'main'],
  },
};

例如,考慮任意一個(gè)名為 upstream 的類(lèi)庫(kù) package.json 包含以下字段:

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

在我們 import * as Upstream from 'upstream' 時(shí),這實(shí)際上會(huì)從 browser 屬性解析文件。在這里 browser 屬性是最優(yōu)先選擇的,因?yàn)樗?nbsp;mainFields 的第一項(xiàng)。同時(shí),由 webpack 打包的 Node.js 應(yīng)用程序首先會(huì)嘗試從 module 字段中解析文件。

resolve.mainFiles

?[string] = ['index']?

解析目錄時(shí)要使用的文件名。

webpack.config.js

module.exports = {
  //...
  resolve: {
    mainFiles: ['index'],
  },
};

resolve.exportsFields

?[string] = ['exports']?

在 package.json 中用于解析模塊請(qǐng)求的字段。欲了解更多信息,請(qǐng)查閱 package-exports guideline 文檔。

webpack.config.js

module.exports = {
  //...
  resolve: {
    exportsFields: ['exports', 'myCompanyExports'],
  },
};

resolve.modules

?[string] = ['node_modules']?

告訴 webpack 解析模塊時(shí)應(yīng)該搜索的目錄。

絕對(duì)路徑和相對(duì)路徑都能使用,但是要知道它們之間有一點(diǎn)差異。

通過(guò)查看當(dāng)前目錄以及祖先路徑(即 ./node_modules, ../node_modules 等等), 相對(duì)路徑將類(lèi)似于 Node 查找 'node_modules' 的方式進(jìn)行查找。

使用絕對(duì)路徑,將只在給定目錄中搜索。

webpack.config.js

module.exports = {
  //...
  resolve: {
    modules: ['node_modules'],
  },
};

如果你想要添加一個(gè)目錄到模塊搜索目錄,此目錄優(yōu)先于 node_modules/ 搜索:

webpack.config.js

const path = require('path');

module.exports = {
  //...
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
  },
};

resolve.unsafeCache

?RegExp [RegExp] boolean: true?

啟用,會(huì)主動(dòng)緩存模塊,但并 不安全。傳遞 true 將緩存一切。

webpack.config.js

module.exports = {
  //...
  resolve: {
    unsafeCache: true,
  },
};

正則表達(dá)式,或正則表達(dá)式數(shù)組,可以用于匹配文件路徑或只緩存某些模塊。 例如,只緩存 utilities 模塊:

webpack.config.js

module.exports = {
  //...
  resolve: {
    unsafeCache: /src\/utilities/,
  },
};

resolve.useSyncFileSystemCalls

?boolean?

對(duì) resolver 使用同步文件系統(tǒng)調(diào)用。

webpack.config.js

module.exports = {
  //...
  resolve: {
    useSyncFileSystemCalls: true,
  },
};

resolve.plugins

?[Plugin]?

應(yīng)該使用的額外的解析插件列表。 它允許插件,如 DirectoryNamedWebpackPlugin。

webpack.config.js

module.exports = {
  //...
  resolve: {
    plugins: [new DirectoryNamedWebpackPlugin()],
  },
};

resolve.preferRelative

?boolean?

當(dāng)啟用此選項(xiàng)時(shí),webpack 更傾向于將模塊請(qǐng)求解析為相對(duì)請(qǐng)求,而不使用來(lái)自 node_modules 目錄下的模塊。

webpack.config.js

module.exports = {
  //...
  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.preferAbsolute

?boolean?

?5.13.0+?

解析時(shí),首選的絕對(duì)路徑為 resolve.roots。

webpack.config.js

module.exports = {
  //...
  resolve: {
    preferAbsolute: true,
  },
};

resolve.symlinks

?boolean = true?

是否將符號(hào)鏈接(symlink)解析到它們的符號(hào)鏈接位置(symlink location)。

啟用時(shí),符號(hào)鏈接(symlink)的資源,將解析為其 真實(shí) 路徑,而不是其符號(hào)鏈接(symlink)的位置。注意,當(dāng)使用創(chuàng)建符號(hào)鏈接包的工具(如 npm link)時(shí),這種方式可能會(huì)導(dǎo)致模塊解析失敗。

webpack.config.js

module.exports = {
  //...
  resolve: {
    symlinks: true,
  },
};

resolve.cachePredicate

?function(module) => boolean?

決定請(qǐng)求是否應(yīng)該被緩存的函數(shù)。函數(shù)傳入一個(gè)帶有 path 和 request 屬性的對(duì)象。 必須返回一個(gè) boolean 值。

webpack.config.js

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

resolve.restrictions

?[string, RegExp]?

解析限制列表,用于限制可以解析請(qǐng)求的路徑。

webpack.config.js

module.exports = {
  //...
  resolve: {
    restrictions: [/\.(sass|scss|css)$/],
  },
};

resolve.roots

?[string]?

一個(gè)目錄列表,用于解析以斜杠('/')開(kāi)頭的服務(wù)器相對(duì)URL的請(qǐng)求,默認(rèn)為上下文配置選項(xiàng)。在非Windows系統(tǒng)上,這些請(qǐng)求首先被解析為絕對(duì)路徑。

webpack.config.js

const fixtures = path.resolve(__dirname, 'fixtures');
module.exports = {
  //...
  resolve: {
    roots: [__dirname, fixtures],
  },
};

resolve.importsFields

?[string]?

用于提供包內(nèi)部請(qǐng)求的 package.json 中的字段(以 # 開(kāi)頭的請(qǐng)求被視為內(nèi)部請(qǐng)求)。

webpack.config.js

module.exports = {
  //...
  resolve: {
    importsFields: ['browser', 'module', 'main'],
  },
};

resolve.byDependency

通過(guò) module 請(qǐng)求類(lèi)型來(lái)配置 resolve 選項(xiàng)。

  • Type: ?[type: string]?: ResolveOptions
  • Example:module.exports = ?{ // ... resolve: { byDependency: { // ... esm: { mainFields: ['browser', 'module'], }?, ?commonjs: { aliasFields: ['browser'], }, url: { preferRelative: true, }, }, }, };?

resolveLoader

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

這組選項(xiàng)與上面的 resolve 對(duì)象的屬性集合相同, 但僅用于解析 webpack 的 loader 包。

webpack.config.js

module.exports = {
  //...
  resolveLoader: {
    modules: ['node_modules'],
    extensions: ['.js', '.json'],
    mainFields: ['loader', 'main'],
  },
};


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)