استخدام أدوات حزم الوحدات مع Firebase

يمكن لحِزم وحدات JavaScript تنفيذ العديد من الإجراءات، ولكن من أهم ميزاتها هي إمكانية إضافة مكتبات خارجية واستخدامها في قاعدة الرموز البرمجية. تقرأ أدوات تجميع الوحدات مسارات الاستيراد في الرمز البرمجي وتُدمج (تُجمِّع) الرمز البرمجي الخاص بالتطبيق مع رمز المكتبة المستورَد.

اعتبارًا من الإصدار 9 والإصدارات الأحدث، تم تحسين واجهة برمجة التطبيقات المكوّنة من وحدات JavaScript في Firebase لتعمل مع ميزات تحسين حِزم الوحدات لتقليل مقدار رمز Firebase المضمّن في الإصدار النهائي.

import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged, getRedirectResult } from 'firebase/auth';

const firebaseApp = initializeApp({ /* config */ });
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => { /* check status */ });

/**
 * getRedirectResult is unused and should not be included in the code base.
 * In addition, there are many other functions within firebase/auth that are
 * not imported and therefore should not be included as well.
 */

تُعرف عملية إزالة الرموز غير المستخدَمة من المكتبة باسم "إزالة العناصر غير الضرورية". إنّ إزالة هذا الرمز المبرمَج يدوياً قد تستغرق وقتًا طويلاً وتؤدي إلى حدوث أخطاء، ولكن يمكن لأدوات تجميع الوحدات إزالة هذا الرمز المبرمَج تلقائيًا.

تتوفّر العديد من أدوات تجميع الوحدات العالية الجودة في منظومة JavaScript المتكاملة. يركز هذا الدليل على تغطية استخدام Firebase مع webpack و Rollup و esbuild.

البدء

يتطلّب هذا الدليل تثبيت npm في بيئة التطوير. يُستخدَم npm لتثبيت العناصر الاعتمادية (المكتبات) وإدارتها. لتثبيت npm، ثبِّت Node.js، الذي يتضمّن npm تلقائيًا.

يُجري معظم المطوّرين عملية الإعداد بشكل صحيح بعد تثبيت Node.js. ومع ذلك، هناك مشاكل شائعة يواجهها العديد من المطوّرين عند إعداد بيئتهم. إذا واجهت أي أخطاء، تأكَّد من توفُّر واجهة npm CLI في بيئتك ومن ضبط الأذونات المناسبة لكي تتمكّن من تثبيت الحِزم كمشرف باستخدام الأمر sudo.

ملف package.json وتثبيت Firebase

بعد تثبيت npm، ستحتاج إلى إنشاء ملف package.json في جذر مشروعك المحلي. يمكنك إنشاء هذا الملف باستخدام الأمر npm التالي:

npm init

سينقلك هذا الإجراء إلى معالج لتوفير المعلومات المطلوبة. بعد إنشاء الملف، سيظهر على النحو التالي:

{
  "name": "your-package-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {

  }
}

يُعدّ هذا الملف مسؤولاً عن العديد من الإجراءات المختلفة. هذا ملف مهم يجب التعرّف عليه إذا كنت تريد معرفة المزيد من المعلومات عن تجميع الوحدات و إنشاء رمز JavaScript بشكل عام. العنصر المهم في هذا الدليل هو ملف "dependencies". سيحتوي هذا العنصر على زوج مفتاح/قيمة للمكتبة التي ثبَّتها والإصدار الذي تستخدمه.

تتم إضافة التبعيات من خلال الأمر npm install أو npm i.

npm i firebase

عند تشغيل npm i firebase، ستُعدِّل عملية التثبيت package.json لإضافة Firebase كتبعية:

  "dependencies": {
    "firebase": "^9.0.0"
  },

المفتاح هو اسم المكتبة والقيمة هي الإصدار المطلوب استخدامه. قيمة version مرنة ويمكنها قبول نطاق من القيم. يُعرف ذلك باسم التسمية الدلالية أو semver. لمزيد من المعلومات عن semver، اطّلِع على دليل npm حول التسمية الدلالية للإصدارات.

مجلدَا المصدر والإنشاء

تتم قراءة الرمز الذي تكتبه ومعالجته بواسطة أداة تجميع وحدات، ثم يتم إخراجه كملف جديد أو مجموعة من الملفات. من المهم فصل هذين النوعين من الملفات. يُعرف الرمز الذي تقرأه أدوات تجميع الوحدات وتعالجه باسم الرمز "المصدر". وتُعرف الملفات التي تُنشئها باسم رمز الإنشاء أو "dist" (التوزيع).

من الإعدادات الشائعة في قواعد الرموز البرمجية تخزين رمز المصدر في مجلد باسم src والرمز المُنشئ في مجلد باسم dist.

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js

في مثال بنية الملف أعلاه، يُرجى العِلم أنّ index.js يستورد كلاً من animations.js وdatalist.js. عندما يعالج أداة تجميع الوحدات رمز المصدر، سينتج عن ذلك ملف bundle.js في المجلد dist. bundle.js هو عبارة عن مجموعة من الملفات في المجلد src وأي مكتبات يتم استيرادها أيضًا.

إذا كنت تستخدم أنظمة التحكّم في المصدر مثل Git، من الشائع تجاهل مجلد dist عند تخزين هذا الرمز في المستودع الرئيسي.

نقاط الدخول

تعتمد جميع حِزم الوحدات مفهوم نقطة الدخول. يمكنك اعتبار التطبيق شجرة للملفات. يستورد ملف واحد رمزًا من ملف آخر، وهكذا. وهذا يعني أنّ ملفًا واحدًا سيكون جذر الشجرة. يُعرف هذا الملف باسم نقطة الدخول.

لنراجع مثال بنية الملف السابق.

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js
// src/index.js
import { animate } from './animations';
import { createList } from './datalist';

// This is not real code, but for example purposes only
const theList = createList('users/123/tasks');
theList.addEventListener('loaded', event => {
  animate(theList);
});

يُعتبر ملف src/index.js نقطة الدخول لأنّه يبدأ عملية استيراد جميع الرموز البرمجية المطلوبة للتطبيق. ويستخدم مجمعو الحِزم ملف نقطة الدخول هذا لبدء عملية التجميع.

استخدام Firebase مع webpack

ما مِن إعدادات محدّدة مطلوبة لتطبيقات Firebase وWebpack. يتناول هذا القسم إعدادات عامة في webpack.

الخطوة الأولى هي تثبيت webpack من npm كعنصر تطوير تابع.

npm i webpack webpack-cli -D

أنشِئ ملفًا في جذر مشروعك على الجهاز باسم webpack.config.js وأضِف الرمز البرمجي التالي.

const path = require('path');

module.exports = {
  // The entry point file described above
  entry: './src/index.js',
  // The location of the build folder described above
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  devtool: 'eval-source-map',
};

بعد ذلك، تأكَّد من تثبيت Firebase كعنصر تابع.

npm i firebase

بعد ذلك، يمكنك إعداد Firebase في قاعدة الرموز البرمجية. يستورد الرمز البرمجي التالي Firebase ويُنشئه في ملف نقطة دخول، ويستخدم Firestore Lite لتحميل مستند "city".

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

الخطوة التالية هي إضافة نص npm لتشغيل عملية إنشاء webpack. افتح ملف package.json وأضِف زوج المفتاح/القيمة التالي إلى عنصر "scripts".

  "scripts": {
    "build": "webpack --mode=development"
  },

لتشغيل webpack وإنشاء مجلد الإنشاء، شغِّل الأمر التالي.

npm run build

أخيرًا، تحقّق من مجلد dist build. يجب أن يحتوي على ملف باسم bundle.js يحتوي على التطبيق المجمّع ورمز التبعيات.

لمزيد من المعلومات حول تحسين عملية إنشاء حِزم webpack للإصدار العلني، اطّلِع على المستندات الرسمية حول إعدادات الضبط "mode".

استخدام Firebase مع ميزة "تجميع التطبيقات"

ما مِن إعدادات محدّدة مطلوبة لتطبيقات Firebase وميزة "تجميع البيانات". يتناول هذا القسم إعدادات عامة للتقارير المجمّعة.

الخطوة الأولى هي تثبيت Rollup ومكوّن إضافي يُستخدَم لربط عمليات الاستيراد بالتبعيات المثبَّتة باستخدام npm.

npm i rollup @rollup/plugin-node-resolve -D

أنشِئ ملفًا في جذر مشروعك على الجهاز باسم rollup.config.js وأضِف الرمز التالي.

import { nodeResolve } from '@rollup/plugin-node-resolve';

export default {
  // the entry point file described above
  input: 'src/index.js',
  // the output for the build folder described above
  output: {
    file: 'dist/bundle.js',
    // Optional and for development only. This provides the ability to
    // map the built code back to the original source format when debugging.
    sourcemap: 'inline',
    // Configure Rollup to convert your module code to a scoped function
    // that "immediate invokes". See the Rollup documentation for more
    // information: https://rollupjs.org/guide/en/#outputformat
    format: 'iife'
  },
  // Add the plugin to map import paths to dependencies
  // installed with npm
  plugins: [nodeResolve()]
};

بعد ذلك، يمكنك إعداد Firebase في قاعدة الرموز البرمجية. يستورد الرمز البرمجي التالي Firebase ويُنشئه في ملف نقطة دخول، ويستخدم Firestore Lite لتحميل مستند "city".

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

الخطوة التالية هي إضافة نص npm لتشغيل عملية إنشاء الحزمة. افتح ملف package.json وأضِف زوج المفتاح/القيمة التالي إلى عنصر "scripts".

  "scripts": {
    "build": "rollup -c rollup.config.js"
  },

لتشغيل التجميع وإنشاء مجلد التصميم، شغِّل الأمر التالي.

npm run build

أخيرًا، تحقّق من مجلد dist build. يجب أن يحتوي على ملف باسم bundle.js يحتوي على التطبيق المجمّع ورمز التبعيات.

لمزيد من المعلومات حول تحسين إصدار Rollup للإصدار العلني، يمكنك الاطّلاع على المستندات الرسمية حول الإضافات لإصدارات العلنية.

استخدام Firebase مع esbuild

ما مِن إعدادات محدّدة مطلوبة لتطبيقات Firebase وesbuild. يتناول هذا القسم إعدادات esbuild العامة.

الخطوة الأولى هي تثبيت esbuild كأحد متطلّبات التطوير.

npm i esbuild -D

أنشِئ ملفًا في جذر مشروعك على الجهاز باسم esbuild.config.js وأضِف الرمز البرمجي التالي.

require('esbuild').build({
  // the entry point file described above
  entryPoints: ['src/index.js'],
  // the build folder location described above
  outfile: 'dist/bundle.js',
  bundle: true,
  // Replace with the browser versions you need to target
  target: ['chrome60', 'firefox60', 'safari11', 'edge20'],
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  sourcemap: 'inline',
}).catch(() => process.exit(1))

بعد ذلك، يمكنك إعداد Firebase في قاعدة الرموز البرمجية. يستورد الرمز البرمجي التالي Firebase ويُنشئه في ملف نقطة دخول، ويستخدم Firestore Lite لتحميل مستند "city".

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

الخطوة التالية هي إضافة نص npm لتشغيل esbuild. افتح ملف package.json وأضِف زوج المفتاح/القيمة التالي إلى عنصر "scripts".

  "scripts": {
    "build": "node ./esbuild.config.js"
  },

أخيرًا، تحقّق من مجلد dist build. يجب أن يحتوي على ملف باسم bundle.js يحتوي على التطبيق المجمّع ورمز التبعيات.

لمزيد من المعلومات حول تحسين esbuild للإصدار العلني، يُرجى الاطّلاع على مستندات المطوّرين الرسمية حول التصغير والتحسينات الأخرى.