مقدمة في العمل مع نظام الملفات في TypeScript
العمل مع نظام الملفات هو إحدى المهام الأساسية عند التطوير باستخدام TypeScript. بغض النظر عما إذا كنت تقوم بإنشاء تطبيق خادم، أو أداة لمعالجة البيانات، أو خادم ويب، فستحتاج بالتأكيد إلى قراءة وكتابة وإدارة الملفات والدلائل. في هذا الدليل، سنشرح أساسيات العمل مع وحدة fs (نظام الملفات) في TypeScript، وسنستعرض العمليات المتزامنة وغير المتزامنة، ونتعلم أيضًا كيفية معالجة الأخطاء.
TypeScript هي طبقة علوية مكتوبة بشدة فوق JavaScript، تضيف كتابة ثابتة. عند العمل مع نظام الملفات، سنستخدم وحدة Node.js القياسية fs، ولكن مع مزايا إضافية من TypeScript: الإكمال التلقائي، والتحقق من الأنواع، وقابلية قراءة محسنة للكود.
إعداد المشروع واستيراد الوحدات
قبل البدء، تأكد من تثبيت Node.js و TypeScript. قم بإنشاء مشروع جديد وقم بتثبيت الأنواع اللازمة:
mkdir fs-typescript-tutorialcd fs-typescript-tutorialnpm init -ynpm install typescript @types/node --save-devnpx tsc --initللعمل مع نظام الملفات، سنحتاج إلى وحدتين رئيسيتين:
- fs — لتنفيذ العمليات على الملفات (قراءة، كتابة، حذف، إلخ)
- path — للعمل بسهولة مع المسارات (الدمج، التسوية، الحصول على الامتداد)
سنقوم باستيرادها في ملف TypeScript الخاص بنا:
import * as fs from 'fs';import * as path from 'path';
// بديل — استيراد الوظائف المطلوبة فقط:import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';import { join, resolve } from 'path';لاحظ: نستخدم import * as fs لأن وحدة fs تصدر العديد من الوظائف. سيقوم TypeScript تلقائيًا بالتقاط الأنواع من الحزمة المثبتة @types/node.
قراءة وكتابة الملفات
لنبدأ بأبسط العمليات — قراءة وكتابة الملفات النصية. في Node.js، هناك طريقتان: متزامنة وغير متزامنة. بالنسبة للنصوص البرمجية البسيطة والأدوات المساعدة، غالبًا ما تُستخدم الطرق المتزامنة، بينما للخوادم عالية التحميل، تُستخدم الطرق غير المتزامنة لتجنب حظر حلقة الأحداث.
القراءة والكتابة المتزامنة
الطرق المتزامنة تمنع تنفيذ البرنامج حتى اكتمال العملية. إنها سهلة الاستخدام ومناسبة للسيناريوهات التي لا تكون فيها السرعة حرجة:
import { readFileSync, writeFileSync } from 'fs';import { join } from 'path';
const filePath = join(__dirname, 'data.txt');
// كتابة إلى ملف (ينشئ الملف إذا لم يكن موجودًا)writeFileSync(filePath, 'Hello, TypeScript!', 'utf-8');
// قراءة من ملفconst content: string = readFileSync(filePath, 'utf-8');console.log(content); // سيطبع: Hello, TypeScript!لاحظ كتابة النوع content: string — يضمن TypeScript أننا سنحصل على سلسلة نصية. إذا كان الملف غير موجود، سيتم طرح استثناء يجب معالجته عبر try/catch.
القراءة والكتابة غير المتزامنة
الطرق غير المتزامنة تقبل دالة رد اتصال أو تُرجع Promise (في الإصدارات الحديثة). يُوصى باستخدام إصدارات Promise مع async/await:
import { promises as fsPromises } from 'fs';import { join } from 'path';
const filePath = join(__dirname, 'async-data.txt');
async function handleFile(): Promise<void> { try { // كتابة غير متزامنة await fsPromises.writeFile(filePath, 'Async content', 'utf-8'); // قراءة غير متزامنة const data: string = await fsPromises.readFile(filePath, 'utf-8'); console.log(data); // Async content } catch (error) { console.error('خطأ في العمل مع الملف:', error); }}
handleFile();استخدام async/await يجعل الكود يبدو متزامنًا