Under The Hood

يصف هذا القسم التفاصيل الداخلية لـ webpack، ويمكن أن يكون مفيدًا لمطوري الإضافات.

التجميع هو دالة تأخذ بعض الملفات وتصدر ملفات أخرى.

لكن بين الإدخال والإخراج، توجد أيضًا وحدات ونقاط دخول و chunks و chunk groups وأجزاء وسيطة أخرى كثيرة.

الأجزاء الرئيسية

كل ملف مستخدم في مشروعك هو وحدة.

./index.js

import app from "./app.js";

./app.js

export default "the app";

من خلال استخدام الوحدات لبعضها، تشكّل هذه الوحدات مخططًا (ModuleGraph).

أثناء عملية التجميع، تُدمج الوحدات في chunks. وتُدمج chunks في chunk groups وتشكل مخططًا (ChunkGraph) مترابطًا عبر الوحدات. عندما تصف نقطة دخول، فأنت داخليًا تنشئ chunk group يحتوي chunk واحدًا.

./webpack.config.js

export default {
  entry: "./index.js",
};

يُنشأ chunk group واحد باسم main، وهو الاسم الافتراضي لنقطة الدخول. يحتوي هذا chunk group على وحدة ./index.js. وبينما يعالج parser الاستيرادات داخل ./index.js، تُضاف وحدات جديدة إلى هذا chunk.

مثال آخر:

./webpack.config.js

export default {
  entry: {
    home: "./home.js",
    about: "./about.js",
  },
};

يُنشأ chunk groupان باسمين home و about. لكل واحد منهما chunk يحتوي وحدة: ./home.js لـ home و ./about.js لـ about.

قد يوجد أكثر من chunk داخل chunk group واحد. على سبيل المثال، يقوم SplitChunksPlugin بتقسيم chunk إلى chunk واحد أو أكثر.

Chunks

تأتي chunks في شكلين:

  • initial: هو chunk الرئيسي لنقطة الدخول. يحتوي هذا chunk على كل الوحدات وتبعياتها التي تحددها لنقطة دخول.
  • non-initial: هو chunk يمكن تحميله كسولًا. قد يظهر عند استخدام dynamic import أو SplitChunksPlugin.

لكل chunk أصل مقابل. الأصول هي ملفات الإخراج الناتجة عن التجميع.

webpack.config.js

export default {
  entry: "./src/index.jsx",
};

./src/index.jsx

import { createRoot } from "react-dom/client";

import("./app.jsx").then((App) => {
  const root = createRoot(document.getElementById("root"));
  root.render(<App />);
});

يُنشأ chunk ابتدائي باسم main. يحتوي على:

  • ./src/index.jsx
  • react
  • react-dom

وكل تبعياتها، باستثناء ./app.jsx.

يُنشأ chunk غير ابتدائي لـ ./app.jsx لأن هذه الوحدة مستوردة ديناميكيًا.

الإخراج:

  • /dist/main.js: chunk من نوع initial
  • /dist/394.js: chunk من نوع non-initial

افتراضيًا، لا يوجد اسم لـ chunks من نوع non-initial، لذلك يُستخدم معرف فريد بدلًا من الاسم. عند استخدام dynamic import يمكننا تحديد اسم chunk صراحة باستخدام تعليق "سحري":

import(
  /* webpackChunkName: "app" */
  "./app.jsx"
).then((App) => {
  const root = createRoot(document.getElementById("root"));
  root.render(<App />);
});

الإخراج:

  • /dist/main.js: chunk من نوع initial
  • /dist/app.js: chunk من نوع non-initial

الإخراج

تتأثر أسماء ملفات الإخراج بحقلين في التكوين:

  • output.filename: لملفات chunks من نوع initial
  • output.chunkFilename: لملفات chunks من نوع non-initial
  • في بعض الحالات تُستخدم chunks كـ initial و non-initial. في هذه الحالات يُستخدم output.filename.

توجد عدة placeholders متاحة في هذه الحقول. الأكثر استخدامًا:

  • [id]: معرف chunk، مثل [id].js -> 485.js
  • [name]: اسم chunk، مثل [name].js -> app.js. إذا لم يكن للـ chunk اسم، فسيُستخدم معرفه.
  • [contenthash]: هاش md4 لمحتوى ملف الإخراج، مثل [contenthash].js -> 4ea6ff1de66c537eb9b2.js
Edit this page·
« Previous
Why webpack

1 Contributor

RlxChap2