Resolve

تتحكم هذه الخيارات في طريقة حل modules. يوفّر webpack إعدادات افتراضية مناسبة، ويمكنك تعديل سلوك resolver بالتفصيل عند الحاجة. راجع Module Resolution لفهم آلية عمل resolver بشكل أوضح.

resolve

object

خصّص طريقة حل modules. على سبيل المثال، عند استخدام import 'lodash' في ES2015، تحدد خيارات resolve الأماكن التي يبحث فيها webpack عن 'lodash' (راجع modules).

webpack.config.js

export default {
  // ...
  resolve: {
    // خيارات التخصيص
  },
};

resolve.alias

object

أنشئ أسماء مستعارة لتسهيل استيراد modules معيّنة عبر import أو require. على سبيل المثال، يمكنك إنشاء alias لمجموعة من مجلدات src/ كثيرة الاستخدام:

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

الآن، بدلاً من استخدام المسارات النسبية عند الاستيراد بهذه الطريقة:

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

يمكنك استخدام الاسم المستعار:

import Utility from "Utilities/utility";

يمكنك أيضًا إضافة علامة $ في نهاية مفتاح alias للدلالة على التطابق التام فقط:

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

ينتج عن ذلك السلوك التالي:

import Test1 from "xyz"; // تطابق تام، لذلك يتم حل path/to/file.js واستيراده
import Test2 from "xyz/file.js"; // ليس تطابقًا تامًا، لذلك تتم عملية resolve العادية

يمكنك أيضًا استخدام أحرف البدل (*) في تخصيص الاسم المستعار الخاص بك لإنشاء تعيينات أكثر مرونة:

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/*"), // يربط @something بالمسار path/to/something
    },
  },
};

يتيح لك هذا استخدام عمليات import مثل:

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خطأ
{ 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خطأ
{ 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خطأ
{ 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

يمكن أن يتم resolve لـ index.js إلى ملف آخر إذا كان ذلك معرّفًا في package.json.

قد يتابع webpack البحث من /abc/node_modules إلى /node_modules أيضًا.

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 يتجاهل module.

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

resolve.aliasFields

[string]: ['browser']

حدد حقلاً، مثل browser، ليتم تحليله وفقًا لـ هذه المواصفات.

webpack.config.js

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

resolve.byDependency

خصّص خيارات resolve حسب نوع طلب module.

  • النوع: [type: string]: ResolveOptions

  • مثال:

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

resolve.cache

boolean

يفعّل caching للطلبات التي تم حلها بنجاح، مما يسمح بإعادة استخدام إدخالات cache والتحقق منها.

webpack.config.js

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

resolve.cachePredicate

function(module) => boolean

دالة تقرر هل يجب تخزين الطلب في cache أم لا. يُمرر إليها object يحتوي على الخاصيتين path وrequest، ويجب أن ترجع boolean.

webpack.config.js

export default {
  // ...
  resolve: {
    cachePredicate: (module) =>
      // منطق إضافي
      true,
  },
};

resolve.cacheWithContext

boolean

إذا كان unsafe cache مفعّلًا، فسيتم تضمين request.context داخل مفتاح cache. يأخذ module enhanced-resolve هذا الخيار في الحسبان. يتم تجاهل context في resolve caching عند توفير plugins لـ resolve أو resolveLoader. يساعد هذا على تجنب تراجع performance.

resolve.conditionNames

string[]

أسماء الشروط في حقل exports، وهي التي تحدد entry points الخاصة بالـ package.

webpack.config.js

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

يطابق webpack شروط التصدير المدرجة داخل array الخاصة بـ resolve.conditionNames.

القيم الافتراضية

يضبط webpack القيمة الافتراضية لـ conditionNames ديناميكيًا حسب إعدادات mode وtarget:

تتضمن الشروط الأساسية دائمًا ما يلي:

  • "webpack": موجود دائمًا.
  • "production" أو "development": حسب قيمة mode الحالية. تُستخدم "production" عندما يكون الوضع "none" أو "production".

يتم إلحاق شروط إضافية بناءً على target:

قيمة targetالشرط
webworker"worker"
node"node"
web"browser"
electron"electron"
nwjs"nwjs"

على سبيل المثال، مع target: "web" (الافتراضي) وmode: "production"، يكون الإعداد الافتراضي conditionNames هو ["webpack", "production", "browser"].

شروط كل نوع dependency

يضبط webpack قيمة conditionNames عبر resolve.byDependency حسب طريقة استيراد module. الرمز "..." يرث الشروط الأساسية المذكورة أعلاه.

نوع dependencyconditionNamesالاستخدام
esm، wasm، loaderImport["import", "module-sync", "module", "..."]عمليات ESM import، وWebAssembly، وعمليات import من loaders
commonjs، amd، loader، unknown، undefined["require", "module-sync", "module", "..."]استدعاءات require() وAMD وأنواع dependency الأخرى
worker["worker", "import", "module-sync", "module", "..."]تعابير new Worker()
css-import["webpack", <mode>, "style"]تعليمات CSS @import

يُدرج 5.107.0+ الشرط "module-sync" ضمن الشروط الافتراضية للتوافق مع Node.js. هذا الشرط يعبّر عن حزم ESM التي يمكن تحميلها بشكل متزامن. الحزم التي تنشر تصديرًا باسم module-sync داخل package.json تُلتقط تلقائيًا بدون أي إعداد إضافي.

على سبيل المثال، عندما يستخدم ملف import في مشروع يحتوي على target: "web" وmode: "production"، فإن الشروط النهائية التي تم حلها هي ["import", "module-sync", "module", "webpack", "production", "browser"].

مطابقة الشروط

يعد ترتيب المفاتيح في الحقل exports مهمًا. أثناء مطابقة الشرط، تتمتع الإدخالات السابقة بأولوية أعلى وتكون لها الأسبقية على الإدخالات اللاحقة.

على سبيل المثال،

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

عمليات import:

  • سيتم resolve لـ 'foo' إلى 'foo/index-require.js'.
  • سيتم resolve لـ 'foo/bar' إلى 'foo/bar-node.js' لأن المفتاح "node" يأتي قبل "require" داخل object الخاص بالـ conditional exports.
  • سيتم resolve لـ 'foo/baz' إلى 'foo/baz-node.js'.

شروط مخصصة

إذا كنت تريد إضافة أسماء الحقول المخصصة الخاصة بك مع الاحتفاظ بالقيم الافتراضية webpack، فيمكنك استخدام "...":

webpack.config.js

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

أو إذا أردت إعطاء الأولوية للشروط الافتراضية أولًا، ثم إضافة شروطك المخصصة:

webpack.config.js

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

resolve.descriptionFiles

[string] = ['package.json']

ملفات JSON المستخدمة للأوصاف.

webpack.config.js

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

resolve.enforceExtension

boolean = false

إذا كانت القيمة true، فلن يسمح webpack بالاستيراد بدون الامتداد الكامل. لذلك يعمل import foo from "./foo"; أو require('./foo') افتراضيًا إذا كان ./foo يملك امتداد .js، لكن عند تفعيل هذا الخيار لن يعمل إلا import foo from "./foo.js" أو require('./foo.js').

webpack.config.js

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

resolve.exportsFields

[string] = ['exports']

الحقول الموجودة في package.json التي تُستخدم لحل طلبات module. راجع دليل package exports لمزيد من المعلومات.

webpack.config.js

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

resolve.extensionAlias

object

object يربط امتدادًا بامتدادات بديلة.

webpack.config.js

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

resolve.extensions

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

يحاول webpack resolve هذه الامتدادات بالترتيب. إذا كانت هناك ملفات متعددة لها الاسم نفسه لكن بامتدادات مختلفة، فسيختار webpack الملف صاحب الامتداد المذكور أولًا في array ويتخطى الباقي.

webpack.config.js

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

وهو ما يمكّن المستخدمين من ترك الامتداد عند الاستيراد:

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

لاحظ أن استخدام resolve.extensions كما في المثال أعلاه يلغي array الافتراضية، مما يعني أن webpack لن يحاول resolve modules باستخدام الامتدادات الافتراضية. يمكنك استخدام '...' لإبقاء الامتدادات الافتراضية:

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

resolve.fallback

object

يوجّه طلبات module إلى بدائل عند فشل resolve العادي.

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, // لا تضف polyfill لـ abc
      xyz: path.resolve(__dirname, "path/to/file.js"), // أضف polyfill لـ xyz
    },
  },
};

في webpack 5 لم يعد webpack يضيف polyfills تلقائيًا لـ Node.js core modules. إذا كنت تستخدم هذه modules في كود يعمل داخل browser أو بيئة مشابهة، فعليك تثبيت الحزم المتوافقة من npm وإضافتها بنفسك. هذه قائمة بالـ polyfills التي كان webpack يستخدمها قبل webpack 5:

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، يتعامل هذا الخيار مع الطلبات التي يكتبها المستخدم على أنها محددة بالكامل. هذا يعني أنه لا تُضاف امتدادات تلقائيًا، ولا يتم resolve للملفات الرئيسية داخل المجلدات. لاحظ أن هذا السلوك لا يؤثر على الطلبات القادمة من mainFields أو aliasFields أو aliases.

webpack.config.js

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

resolve.importsFields

[string]

الحقول في package.json التي تُستخدم لتوفير الطلبات الداخلية للـ package. الطلبات التي تبدأ بـ # تُعد داخلية.

webpack.config.js

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

resolve.mainFields

[string]

عند الاستيراد من npm package، مثل import * as D3 from 'd3'، يحدد هذا الخيار أي حقول من package.json يستخدمها webpack كنقطة دخول. تختلف القيم الافتراضية حسب target المحدد في إعداد webpack.

عند ضبط الخاصية target على webworker أو web أو تركها غير محددة:

webpack.config.js

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

لأي target آخر، بما في ذلك node:

webpack.config.js

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

على سبيل المثال، افترض وجود library اسمها upstream وملف package.json الخاص بها يحتوي على الحقول التالية:

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

عند كتابة import * as Upstream from 'upstream'، سيتم resolve للاستيراد إلى الملف الموجود في الخاصية browser. تحصل الخاصية browser على الأولوية لأنها أول عنصر في mainFields. وفي المقابل، سيحاول تطبيق Node.js المجمّع بواسطة webpack أن يستخدم الملف الموجود في الحقل module أولًا.

resolve.mainFiles

[string] = ['index']

اسم الملف الذي سيتم استخدامه أثناء حل الدلائل.

webpack.config.js

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

resolve.modules

[string] = ['node_modules']

أخبر webpack بأي مجلدات يبحث فيها عند resolve للـ modules.

يمكن استخدام كل من المسارات المطلقة والنسبية، لكن انتبه إلى أن سلوكهما سيكون مختلفًا بعض الشيء.

سيتم فحص المسار النسبي بشكل مشابه لكيفية فحص Node بحثًا عن node_modules، من خلال البحث في الدليل الحالي بالإضافة إلى أسلافه (أي ./node_modules، ../node_modules، وما إلى ذلك).

مع المسار المطلق، سيتم البحث فقط في الدليل المحدد.

webpack.config.js

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

إذا أردت إضافة مجلد بحث تكون له أولوية أعلى من 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]

قائمة resolve plugins إضافية يجب تطبيقها.

يمكن أن يكون كل عنصر واحدًا مما يلي:

  • plugin object يملك الدالة apply(resolver).
  • function plugin تُستدعى ويكون resolver هو قيمة this والـ argument الأول.

يتيح ذلك استخدام plugins مثل DirectoryNamedWebpackPlugin.

webpack.config.js

export default {
  // ...
  resolve: {
    plugins: [
      // plugin بأسلوب object
      {
        apply(resolver) {
          // منطق مخصص
        },
      },

      // plugin بأسلوب function
      function (resolver) {
        // `this` هو resolver أيضًا
      },
    ],
  },
};

resolve.preferAbsolute

boolean

5.13.0+

يفضّل المسارات المطلقة على resolve.roots أثناء resolve.

webpack.config.js

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

resolve.preferRelative

boolean

عند تفعيله، يفضّل webpack حل طلبات module كطلبات نسبية بدل استخدام modules من مجلدات node_modules.

webpack.config.js

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

src/index.js

// لنفترض أن `src/logo.svg` موجود
import logo1 from "logo.svg"; // يعمل هذا عندما يكون `preferRelative` مفعّلًا
import logo2 from "./logo.svg"; // وإلا فيجب استخدام مسار نسبي لحل logo.svg

// `preferRelative` مفعّل افتراضيًا في حالة `new URL()`
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

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

resolve.roots

[string]

قائمة المجلدات التي تُحل منها طلبات URL المرتبطة بجذر server، وهي الطلبات التي تبدأ بـ /. القيمة الافتراضية هي خيار context. في الأنظمة غير Windows، تُحل هذه الطلبات كمسار مطلق أولًا.

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

يحدد هل يتبع resolver الروابط الرمزية إلى المسار الحقيقي للملف.

عند تفعيله، تُحوّل الموارد المشار إليها عبر symlink إلى مسارها _الحقيقي، وليس إلى موقع symlink نفسه. لاحظ أن هذا قد يسبب فشل resolve للـ module عند استخدام أدوات تربط packages، مثل npm link.

webpack.config.js

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

resolve.unsafeCache

object boolean = true

يفعّل caching قويًا لكنه غير آمن للـ modules. تمرير true سيخزّن كل شيء في cache.

webpack.config.js

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

عند تمرير object، سيستخدمه webpack كـ cache.

على سبيل المثال، يمكنك تمرير كائن Proxy بدل object عادي:

webpack.config.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)) {
      // وإذا لم يكن موجودًا، احذف إدخال cache.
      delete cache[key];
      return undefined;
    }

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

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

resolve.useSyncFileSystemCalls

boolean

يستخدم استدعاءات نظام الملفات المتزامنة داخل resolver.

webpack.config.js

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

resolve.tsconfig

5.105.0+

boolean string object

إعداد TypeScript لتعيين المسارات. يغني هذا الخيار عن الحاجة إلى tsconfig-paths-webpack-plugin. يقرأ compilerOptions.baseUrl وcompilerOptions.paths من tsconfig.json ويطبق تلك الأسماء المستعارة أثناء resolve لعمليات import.

webpack.config.js

export default {
  // ...
  resolve: {
    tsconfig: true, // استخدم tsconfig.json الافتراضي
  },
};

الخيارات:

  • false - تعطيل path mapping الخاص بـ TypeScript
  • true - استخدم ملف tsconfig.json الافتراضي (يبحث عنه تلقائيًا)
  • string - المسار إلى ملف tsconfig.json (نسبي أو مطلق)

webpack.config.js

export default {
  // ...
  resolve: {
    tsconfig: "./tsconfig.app.json", // مسار مخصص
  },
};
  • object - object يحتوي على خياري configFile وreferences

webpack.config.js

export default {
  // ...
  resolve: {
    tsconfig: {
      configFile: "./tsconfig.json",
      references: "auto", // أو array من المسارات
    },
  },
};

خيارات object:

  • configFile (string): مسار إلى ملف tsconfig (نسبي أو مطلق)
  • references ("auto" | string[]): مراجع لملفات tsconfig الأخرى. "auto" يرث من إعداد TypeScript، أو يمكنك تمرير array من المسارات النسبية/المطلقة.

مثال tsconfig.json:

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

ثم في الكود الخاص بك:

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

ResolveLoader

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

هذه المجموعة من الخيارات تطابق خاصية resolve المذكورة أعلاه، لكنها تُستخدم فقط لـ resolve حزم loaders الخاصة بـ webpack.

webpack.config.js

export default {
  // ...
  resolveLoader: {
    modules: ["node_modules"],
    extensions: [".js", ".json"],
    mainFields: ["loader", "main"],
  },
};
·تعديل هذه الصفحة
السابق ›
Module
‹ التالي
Optimization

1 مساهم

RlxChap2