أدلة استكشاف الأخطاء وإصلاحها
تغطي هذه الصفحة أكثر الأخطاء شيوعًا التي تُواجه عند استخدام @aspose/3d في مشاريع TypeScript و Node.js، مع شرح السبب الجذري وإصلاحات مُتحقّق منها.
أخطاء حل الوحدة
Error: Cannot find module '@aspose/3d/formats/obj'
السبب الجذري: لا تدعم استراتيجية حل الوحدات في TypeScript تصديرات المسارات الفرعية بنمط Node.js (exports في package.json) إلا إذا تم ضبط moduleResolution على node أو node16.
إصلاح: اضبط moduleResolution إلى "node" في tsconfig.json الخاص بك:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true
}
}إذا كنت تستخدم TypeScript 5.x مع "module": "node16" أو "module": "nodenext"، استخدم "moduleResolution": "node16" للمطابقة.
SyntaxError: Cannot use import statement in a module
السبب الجذري: يتم تشغيل جافا سكريبت المترجم مع دلالات require() لكن المخرجات تحتوي على بنية ES module import؛ يحدث هذا عندما يتم ضبط module على es2020 أو esnext لكن بيئة تشغيل Node.js تتوقع CommonJS.
الإصلاح: استخدم "module": "commonjs" في tsconfig.json وشغّل ملفات .js المجمعة باستخدام node مباشرةً:
{
"compilerOptions": {
"module": "commonjs",
"outDir": "./dist"
}
}ثم قم بالترجمة والتشغيل:
npx tsc
node dist/main.jsError: Cannot find module '@aspose/3d'
السبب الجذري: الحزمة غير مثبتة، أو node_modules قديمة.
إصلاح:
npm install @aspose/3dتحقق من التثبيت:
node -e "const { Scene } = require('@aspose/3d'); console.log('OK', new Scene().constructor.name);"مشهد فارغ بعد التحميل
المشهد يتم تحميله لكن rootNode.childNodes فارغ
السبب الجذري (1): يضع تنسيق الملف كل الهندسة مباشرة على rootNode.entity بدلاً من أن تكون كعقد فرعية. هذا شائع في ملفات STL ذات شبكة واحدة.
التشخيص:
import { Scene, Mesh } from '@aspose/3d';
const scene = new Scene();
scene.open('model.stl');
// Check rootNode directly
if (scene.rootNode.entity) {
console.log(`Root entity: ${scene.rootNode.entity.constructor.name}`);
}
console.log(`Child count: ${scene.rootNode.childNodes.length}`);إصلاح: التجوال بدءًا من scene.rootNode نفسه، وليس فقط أبنائه:
function visit(node: any): void {
if (node.entity instanceof Mesh) {
const m = node.entity as Mesh;
console.log(`Mesh: ${m.controlPoints.length} vertices`);
}
for (const child of node.childNodes) {
visit(child);
}
}
visit(scene.rootNode);السبب الجذري (2): مسار الملف غير صحيح أو أن الملف صفر بايت. تحقق من أن الملف موجود وغير فارغ قبل استدعاء open().
import * as fs from 'fs';
const path = 'model.obj';
if (!fs.existsSync(path)) throw new Error(`File not found: ${path}`);
const stat = fs.statSync(path);
if (stat.size === 0) throw new Error(`File is empty: ${path}`);قائمة المواد فارغة بعد تحميل OBJ
السبب الجذري: تم تعطيل تحميل المواد بشكل افتراضي في ObjLoadOptions. تقوم المكتبة بتحميل الهندسة دون قراءة ملف الجانب .mtl.
إصلاح: تعيين enableMaterials = true:
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
const scene = new Scene();
const opts = new ObjLoadOptions();
opts.enableMaterials = true;
scene.open('model.obj', opts);تأكد أيضًا من أن ملف .mtl موجود في نفس الدليل الذي يوجد فيه ملف .obj، حيث تقوم المكتبة بحل المسار بالنسبة إلى مسار .obj.
أخطاء التنسيق وإدخال/إخراج
openFromBuffer يطرح خطأ تنسيق غير معروف
Root cause: محتوى الذاكرة المؤقتة ليس بتنسيق ثنائي يمكن التعرف عليه، أو الذاكرة المؤقتة تالفة (مقتطعة، ترميز خاطئ، أو base64 بدلاً من البايتات الخام).
التشخيص:
const buffer = fs.readFileSync('model.glb');
console.log('Buffer size:', buffer.length, 'bytes');
console.log('First 4 bytes (hex):', buffer.slice(0, 4).toString('hex'));
// GLB magic: 676c5446 ("glTF")
// STL binary starts with 80 bytes of header; no fixed magic
// OBJ is text: openFromBuffer may not detect format
الإصلاح: للتنسيقات القائمة على النص (OBJ, COLLADA)، مرّر فئة الخيارات المناسبة لتلميح التنسيق:
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
scene.openFromBuffer(buffer, new ObjLoadOptions());الإخراج GLB يفتح كـ JSON في عارضات 3D
السبب الجذري: GltfSaveOptions.binaryMode يُعيّن افتراضيًا إلى false، مما ينتج .gltf JSON output حتى عندما يكون اسم ملف الإخراج .glb.
الإصلاح: تعيين صراحةً binaryMode = true:
import { GltfSaveOptions } from '@aspose/3d/formats/gltf';
const opts = new GltfSaveOptions();
opts.binaryMode = true;
scene.save('output.glb', opts);إخراج STL لا يحتوي على بيانات اللون أو المادة في أداة التقطيع
السبب الجذري: تنسيق STL لا يدعم المواد أو اللون في مواصفاته القياسية. تستخدم أدوات القطع القادرة على اللون امتدادات مملوكة لا يدعمها @aspose/3d.
الإصلاح: صدّر إلى 3MF بدلاً من ذلك، والذي يدعم بيانات اللون والمواد الوصفية:
scene.save('output.3mf');أخطاء تجميع TypeScript
Property 'controlPoints' does not exist on type 'Entity'
السبب الجذري: Entity هي الفئة الأساسية؛ Mesh هو النوع المطبق مع خصائص الهندسة. تحتاج إلى حارس instanceof قبل الوصول إلى الأعضاء الخاصة بالشبكة.
إصلاح:
import { Mesh } from '@aspose/3d';
if (node.entity instanceof Mesh) {
const mesh = node.entity as Mesh;
console.log(mesh.controlPoints.length);
}Type 'null' is not assignable to type 'Node'
السبب الجذري: getChildNode() يرجع Node | null. يتطلب وضع الصرامة في TypeScript التعامل مع حالة null.
إصلاح:
const child = node.getChildNode('wheel');
if (!child) throw new Error('Node "wheel" not found');
// child is now Node, not null
Cannot find name 'GltfSaveOptions'
السبب الجذري: GltfSaveOptions موجود في وحدة المسار الفرعي @aspose/3d/formats/gltf، وليس في جذر الحزمة.
Fix: الاستيراد من المسار الفرعي:
import { GltfSaveOptions } from '@aspose/3d/formats/gltf';مشكلات الذاكرة والأداء
العملية تنفد من الذاكرة مع ملفات FBX الكبيرة
السبب الجذري: ملفات FBX الكبيرة جدًا (>200 MB) تخصّص كومة كبيرة. الذاكرة الافتراضية للكومة في Node.js هي ~1.5 GB على الأنظمة ذات 64‑بت ولكن قد لا تكون كافية لملفات متعددة المشاهد.
الإصلاح: زيادة حجم الذاكرة المؤقتة (heap) في Node.js:
node --max-old-space-size=8192 dist/convert.jsقم بمعالجة الملفات تسلسليًا بدلاً من موازية عندما تكون الذاكرة محدودة:
for (const file of files) {
const scene = new Scene();
scene.open(file);
scene.save(file.replace('.fbx', '.glb'));
// scene goes out of scope; GC can reclaim
}انظر أيضًا
- الأسئلة المتكررة: إجابات سريعة على الأسئلة الشائعة
- تحميل النموذج: أنماط التحميل والخيارات
- التصيير والتصدير: خيارات التصدير وأنابيب التخزين المؤقت
- نظرة عامة على API: جميع الفئات والوحدات