Three.js: الانتقال إلى بنية معيارية

تم إنشاؤها على ٦ مايو ٢٠١٤  ·  153تعليقات  ·  مصدر: mrdoob/three.js

تصفح
الانتقال إلى هذه البنية له مزايا وعيوب. الرجاء إضافة أفكارك.

ملاحظة: هذا لا يتطلب من مستهلكين three.js استخدام browserify.

Suggestion

التعليق الأكثر فائدة

حسنًا ، لذلك سيتطلب الأمر القليل من إعادة البناء ...

حصلت عليك! منذ أن أصبح هذا الموضوع مفعمًا بالحيوية خلال اليومين الماضيين ، كنت أعمل أكثر قليلاً على three-jsnext . إنه مشروع يأخذ قاعدة الكود Three.js الحالية ويحولها إلى وحدات ES تلقائيًا. مجرد الجدل مع اثنين من التبعيات الدورية الصعبة (خاصة حول KeyframeTrack ) ، ولكن يجب أن يكون لديك شيء لمشاركته بشكل حقيقي قريبًا. بقدر ما أستطيع أن أقول ، تستمر جميع الأمثلة في العمل ، والبناء المصغر أصغر من الإصدار الحالي (باستخدام Rollup لإنشاء ملف UMD) ، لذا فهذه كلها أخبار جيدة.

ال 153 كومينتر

تتمثل إحدى الميزات في أن هذا من شأنه أن يفرض بنية معيارية للتطوير المستمر لـ three.js.

النمط الشائع في node / browserify يجعل كل ملف يعلن عن تبعياته في الأعلى ، ويعتبر المتغيرات العامة نمطًا مضادًا.

هنا مثال مقتطف:

// src/geometry/BoxGeometry.js
var Geometry = require('./Geometry.js');
var Vector3 = require('../core/Vector3.js');
module.exports = BoxGeometry;

function BoxGeometry() {
  // ...
}

BoxGeometry.prototype = Geometry.prototype;

ميزة أخرى هي أن مستهلكي three.js باستخدام browserify سيكونون قادرين على انتقاء واختيار الأجزاء التي يريدونها. يمكنهم فقط استيراد Scene ، BoxGeometry ، PerspectiveCamera ، و WebGLRenderer ، الحصول على التبعيات لكل هؤلاء تلقائيًا ( Object3D إلخ) ، ولديك حزمة صغيرة من جافا سكريبت تدعم مجموعة الميزات التي يريدونها فقط.

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

// src/three.js
var THREE = { rev: 101 }
module.exports = THREE

THREE.Geometry = require('./geometry/Geometry.js')
THREE.BoxGeometry = require('./geometry/BoxGeometry.js')
// ...

ملاحظة: أنا لا أطلب بالضبط التبعيات في الجزء العلوي في هذا المثال ، لأن هذا الملف سيتطلب بيانات بشكل حصري تقريبًا.

أخيرًا ، سنقوم بتغليف ذلك في تعريف الوحدة النمطية العالمية الذي يكتشف ما إذا كان نظام الوحدة النمطية (العقدة / المتصفح ، AMD) قيد الاستخدام ، وإذا كان الأمر كذلك ، نقوم بتصديره ، أو يتم إلحاقه بالعنصر العام ( window ).

دعنا نراجع:

  • يفرض أسلوب معياري جيد
  • يسمح للمستهلكين three.js باستخدام browserify لانتقاء واختيار الوظيفة
  • لا توجد تغييرات كسر

سيتطلب هذا استبدال نظام البناء ، لكن النظام الجديد سيكون واضحًا ومباشرًا.

بعض المزايا الأخرى:

  • يمكنك هيكلة التعليمات البرمجية الخاصة بك
  • يمكنك إنشاء / إعادة استخدام الوحدات النمطية دون تلويث مساحة الاسم العالمية
  • يمكنك البناء للإنتاج
  • يمكنك تصحيح الأخطاء بسهولة أكبر نظرًا لأن كل وحدة بها ملف خاص بها ، فلن تحتاج إلى البحث عن الوحدة المقابلة في ملف three.js كبير

@ shi-314 أعتقد أنني مرتبك قليلاً ، أشعر أن You can structure your code و You can build for production هي الأشياء التي يمكنك القيام بها بدون التحول المعماري؟ هل تتحدث عن مصدر three.js أو أشياء مبنية باستخدام three.js؟

إحدى الممارسات التي تستخدمها Three.js والتي تجعل من الصعب استخدامها في بيئات Commonjs هي استخدام instanceof : https://github.com/mrdoob/three.js/blob/master/src/core/Geometry .js # L82

هذا لأنه في أحد التطبيقات ، غالبًا ما ينتهي بك الأمر بإصدارات مختلفة من نفس المكتبة في شجرة المصدر الخاصة بك ، لذا فإن التحقق من المثيل لا يعمل بين الإصدارات المختلفة من نفس المكتبة. سيكون من الجيد التحضير للانتقال إلى نظام وحدة Commonjs لاستبدال تلك الشيكات بميزة التحقق من خلال واجهة نمط Geometry.isGeometry(geom) .

kumavis أنا أتحدث عن أشياء مبنية في three.js. لنفترض أنك تريد إنشاء مادة خاصة بك باستخدام أدوات التظليل الخاصة بك وما إلى ذلك. في الوقت الحالي ، تحتاج إلى توسيع عنصر الثلاثة العام للبقاء متسقًا مع باقي التعليمات البرمجية الثلاثة:

THREE.MeshMyCoolMaterial = function (...) { ... }

ولكن إذا كان لدينا Browserify مما يمكنك القيام به:

var MeshLambertMaterial = require('./../MeshLambertMaterial');
var MeshMyCoolMaterial = function (...) {...}

لذلك تظل مساحة الاسم الخاصة بك ثابتة ولا تحتاج إلى استخدام THREE.MeshLambertMaterial و MeshMyCoolMaterial في شفرتك.

ومع You can build for production كنت أعني نفس الشيء الذي ذكرته: allows three.js consumers using browserify to pick and choose functionality .

@ shi-314 شكرا لك ، هذا أكثر وضوحا. هذا يؤثر على الحل العام الذي أقترحه لإزالة التسلسل من الفئات التي يحددها المستهلك:

// given that `data` is a hash of a serialized object
var ObjectClass = THREE[ data.type ]
new ObjectClass.fromJSON( data )

هذا من إعادة بناء التسلسل / إلغاء التسلسل المقترح
https://github.com/mrdoob/three.js/pull/4621

لا ينبغي أن يتأثر الأداء بتغيير مثل هذا.

هذا تغيير كبير جدًا ولكني أؤيده أيضًا.

بعض المزايا الرئيسية الأخرى:

  • يمكنك استخدام خيار المتصفح standalone لإنشاء إصدار UMD من أجلك. لا حاجة للعبث يدويًا بأغلفة UMD.
  • يمكن بسهولة استهلاك الحزمة من قبل مستخدمي browserify / NPM
  • يصبح سحب التبعيات لـ threejs (مثل poly2tri ، سلسلة اللون ، إلخ) أسهل بكثير
  • يمكن سحب الوحدات التي "لا تنتمي حقًا" في مكتبة العرض (مثل مكتبات المتجهات / الرياضيات) كوحدات NPM منفصلة وإعادة استخدامها للعديد من أنواع المشاريع الأخرى. إحدى الفوائد الرئيسية لهذا هو أن الوحدات الفردية لها مستودع خاص بها للأخطاء / المشكلات ، والعلاقات العامة ، وما إلى ذلك (تنظيف مشكلات ThreeJS).
  • سوف NPM التعامل مع الإصدارات الدلالية لنا. على سبيل المثال ، يمكننا دفع تغيير فاصل في threejs-vecmath دون القلق بشأن كسر الكود لدى الجميع. وعلى الجانب الآخر ، إذا قمنا بإجراء تصحيح أو إصدار ثانوي في وحدة معينة ، فسيتمكن الأشخاص الذين يستهلكون هذه الوحدات من الحصول على التغييرات تلقائيًا.
  • يجعل "الإضافات" مثل EffectComposer ومختلف أدوات التظليل سهلة التجميع والاستهلاك (تخيل npm install threejs-shader-bloom )
  • عندما يتم سحب الوحدات النمطية ، سيبدأ حجم التوزيع النهائي في التقلص ويكون أكثر تخصيصًا للتطبيق. سيكون هناك في نهاية المطاف لا حاجة لمختلف "يبني أنواع" لأننا سوف فقط require() الوحدات التي لدينا التطبيق يستخدم في الواقع.

إلى mrdoob والمؤلفين الآخرين ؛ إذا لم تكن لديك خبرة كبيرة في NPM / Browserify ، فإنني أقترح إنشاء عدة مشاريع صغيرة معها والتعرف على "فلسفتها". إنها مختلفة تمامًا عن هندسة ThreeJS ؛ بدلاً من الأطر الكبيرة ، فهو يشجع على الكثير من الأشياء الصغيرة .

ميزة أخرى لهذا النهج هي أنه يمكن أن يكون هناك نظام بيئي مفتوح المصدر ، وطرف ثالث ، وحدات Three.JS ، خاصة التظليل ، والهندسة ، ومحمل النماذج وما إلى ذلك ، المنشورة من خلال NPM أو Github / Component والتي يمكن للأشخاص الرجوع إليها واستخدامها بسهولة. في الوقت الحالي ، تتم مشاركة الأشياء من خلال استضافة عرض توضيحي يقوم الأشخاص بعد ذلك "بعرض المصدر" عليه. Three.JS تستحق الأفضل!

أعتقد أن إحدى المشكلات التي أواجهها مع Three.JS هي مدى سرعة تعارض التعليمات البرمجية مع الإصدار الحالي من Three.JS. ميزة أخرى للتحول إلى شيء كهذا هي القدرة على تحديد إصدارات معينة من _bits_ من Three.JS ستكون قوية جدًا وسهلة الاستخدام.

+1

+1 لبنية CommonJS / browserify ، سيجعل النواة أكثر خفة وستكون الإضافات مناسبة حتى لو كانت تأتي من أطراف ثالثة

كما أن تجزئة three.js إلى وحدات صغيرة يتطلب الكثير من التكاليف أيضًا. يسمح النظام الحالي بوحدات إضافية بسيطة جدًا لطرف ثالث (شاهد على سبيل المثال ، وحدات THREEx من jetienne). هناك الكثير مما يمكن قوله حول بساطة الإعداد الحالي ، طالما أن أنظمة الوحدات النمطية JS هي مجرد أغلفة حول أنظمة الإنشاء.

طريقة أخرى لتقليل حجم التصميم هو ما يفعله ClojureScript. إنهم يتبعون بعض الاصطلاحات للسماح لمترجم Closure من Google بإجراء تحليل البرنامج بالكامل والتخلص من الشفرة الميتة.

+1 لأناقة البساطة التي لا تُقدَّر ، وغالبًا ما يتم التغاضي عنها

+1

كما أن تجزئة three.js إلى وحدات صغيرة يتطلب الكثير من التكاليف أيضًا. يسمح النظام الحالي بوحدات إضافية بسيطة جدًا لطرف ثالث (شاهد على سبيل المثال ، وحدات THREEx من jetienne).

الفكرة هنا هي أنه لا يزال من الممكن توفير بنية UMD للبيئات التي لا تحتوي على Node. ستعمل المكونات الإضافية مثل THREEx بنفس الطريقة لأولئك الذين يعتمدون على ThreeJS بعلامات <script> .

سيكون الشيء الصعب هو: كيف يمكننا require() مكونًا إضافيًا معينًا إذا كنا في بيئة CommonJS؟ ربما يمكن أن يساعدك browserify-shim.

هناك الكثير مما يمكن قوله حول بساطة الإعداد الحالي ، طالما أن أنظمة الوحدات النمطية JS هي مجرد أغلفة حول أنظمة الإنشاء.

يعد نظام الإضافات / الإضافات الحالي الخاص بـ ThreeJS أمرًا مروعًا جدًا للعمل معه ، وبعيدًا عن كونه "بسيطًا" أو سهلًا. تميل معظم مشاريع ThreeJS إلى استخدام شكل من أشكال الإضافات أو الإضافات ، مثل EffectComposer ، أو FirstPersonControls ، أو أداة تحميل النماذج ، أو أحد ملفات JS العديدة الأخرى الموجودة في المجلد examples . الطريقة الوحيدة الآن للاعتماد على هذه المكونات الإضافية:

  • قم بتنزيل الإصدار الحالي من ThreeJS
  • انسخ الملفات الضرورية والصقها في مجلد vendor
  • قم بتجميع مهام البلع / النخر لتسلسل وتقليل جميع المكونات الإضافية التي تحتاجها ؛ التأكد من تسلسلها بالترتيب الصحيح وإلا ستنكسر الأشياء. احتفظ بهذه القائمة يدويًا عند إضافة المزيد من المكونات الإضافية.
  • كرر الخطوتين 1 و 2 في كل مرة يتم فيها تحديث ThreeJS ؛ ثم اسحب شعرك عندما تدرك أن الكود الجديد غير متوافق مع الإصدارات السابقة

الآن ، تخيل ، باستخدام المتصفح ، يمكنك القيام بشيء مثل هذا:

var FirstPersonControls = require('threejs-controls').FirstPersonControls;

//more granular, only requiring necessary files
var FirstPersonControls = require('threejs-controls/lib/FirstPersonControls');

ستكون هذه المكونات الإضافية require('threejs') وأي شيء آخر قد يحتاجون إليه (مثل مقتطفات GLSL أو تثليث النص ). إدارة التبعية / الإصدار مخفية عن المستخدم ، وليست هناك حاجة إلى مهام grunt / gulp concat التي تتم صيانتها يدويًا.

سيكون الأمر الصعب: كيف نطلب () مكونًا إضافيًا معينًا إذا كنا في بيئة CommonJS؟

أستخدم CommonJS لمشاريع THREE.js لبعض الوقت الآن. إنها عملية يدوية إلى حد ما ، حيث يتم تحويل أجزاء من كود الأشخاص الآخرين إلى وحدات ولا أعتقد أنه ستكون هناك طريقة سهلة لتجنب ذلك بالنسبة للكود القديم الذي لم يتم تحويله من قبل المؤلفين أو المساهمين.

الشيء المهم هو أن هناك وحدة تقوم بتصدير الكائن "القياسي" بالكامل ، والذي يمكن أن يطلبه أي شيء يرغب في تمديده.

var THREE = require('three');

THREE.EffectComposer = // ... etc, remembering to include copyright notices :)

لقد نجح هذا الأمر جيدًا بالنسبة لي ، خاصةً مع نمو المشروع وبدأت في إضافة التظليل والأشكال الهندسية الخاصة بي إلى وحداتهم الخاصة وما إلى ذلك.

طالما أن هناك حزمة npm "threejs-full" أو "threejs-classic" ، تصبح هذه طريقة قابلة للتطبيق جدًا للعمل مع عناصر Three.js القديمة في بيئة CommonJS لكنني أظن أن هذا مناسب جدًا!

+1
أعتقد أنه بمجرد توفر وحدات threejs المجزأة في البرنامج المساعد npm
سيحب المطورون الانتقال إلى بيئة CommonJS.
في 5 حزيران (يونيو) 2014 ، الساعة 9:19 مساءً ، كتب "Charlotte Gore" [email protected] :

سيكون الأمر الصعب: كيف نطلب () مكونًا إضافيًا معينًا إذا كنا
في بيئة CommonJS؟

أستخدم CommonJS لمشاريع THREE.js لبعض الوقت الآن. انها قليلا
لعملية يدوية ، تحويل أجزاء من كود الآخرين إلى وحدات
ولا أعتقد أنه ستكون هناك طريقة سهلة لتجنب ذلك بالنسبة إلى التعليمات البرمجية القديمة
التي لم يتم تحويلها من قبل المؤلفين أو المساهمين.

الشيء المهم هو أن هناك وحدة تقوم بتصدير "المعيار" بالكامل
ثلاثة كائن ، والتي يمكن أن يطلبها أي شيء يرغب في التمديد
هو - هي.

var THREE = تتطلب ('ثلاثة') ؛
THREE.EffectComposer = // ... إلخ ، تذكر تضمين إشعارات حقوق النشر :)

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

طالما أن هناك حزمة npm "threejs-full" أو "threejs-classic"
تصبح هذه طريقة قابلة للتطبيق للعمل مع عناصر Three.js القديمة في ملف
بيئة CommonJS لكنني أظن أن هذا مكان مناسب جدًا!

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub
https://github.com/mrdoob/three.js/issues/4776#issuecomment -45236911.

يمكن أيضًا أن تجعل التظليل معياريًا أيضًا ، على سبيل المثال باستخدام glslify . حتى الأشياء مثل إنشاء برمجية وسيطة Express التي تنشئ تظليلًا عند الطلب تصبح أسهل بعد ذلك.

قبل بضعة أشهر ، قمت بنقل frame.js إلى required.js وفهمت أخيرًا كيف تعمل عناصر AMD هذه.

ما زلت بحاجة إلى تعلم كيفية "ترجمة" هذا. ما هي الأداة / سير العمل لتوليد three.min.js من قائمة الوحدات؟

أنا أفضل gulp.js كنظام بناء مع البرنامج المساعد gulp-browserify . من السهل حقًا فهم الرمز ويبدو أنظف من النخر في رأيي. تحقق من ذلك: http://travismaynard.com/writing/no-need-to-grunt-take-a-gulp-of-fresh-air : wink:

بعض الأفكار: (بناءً على خبرتي المحدودة مع node، npm، browserify بالطبع)

  1. أعتقد أن وحدات node.js رائعة (وهي npm والوحدات وتتطلب ())
  2. أعتقد أن browserify رائعة أيضًا

ومع ذلك ، بعد المناقشة حول هذا الموضوع ، لست متأكدًا مما إذا كان لدى الجميع نفس الفهم الخاص بـ browserify (browserify ، و commonjs ، و needjs ، و amd ، و umd مرتبطة إلى حد ما على الرغم من أنها قد لا تكون بالضرورة نفس الشيء).

الآن إذا كنت تستطيع اتباع سلسلة أفكاري قليلاً.

  1. JS رائع ، فهو يعمل بسرعة عبر المتصفحات.
  2. واو ، الآن JS يعمل على جانب الخادم أيضًا.
  3. هذا هو node.js ، إنه رائع ، لذلك دعونا نبرمج الأشياء في node.js
  4. لكني لا أرغب في كتابة / لا أستطيع كتابة كل شيء / العثور على شيء لأستخدمه.
  5. لا تقلق ، الآن قم بتشغيل وحدات تثبيت npm
  6. تتطلب الآن هذه الوحدات الرائعة حتى نتمكن من استخدامها.
  7. يعمل بشكل رائع!
  8. انتظر الآن ، لقد كتبنا للتو مجموعة كاملة من الأشياء في JS تعمل على node.js
  9. أليس من المفترض أن تكون js في المتصفحات؟ كيف نجعل هذه الشفرة تعمل هناك مرة أخرى؟

هناك حيث يأتي Browserify في الصورة. حسنًا ، من الناحية الفنية ، يمكن للمرء استخدام يتطلب JS في المتصفح. لكنك ترغب في تجميع ملفات js معًا دون إجراء عدد كبير جدًا من مكالمات الشبكة (على عكس نظام الملفات الذي يتطلب () الطلبات السريعة). هناك حيث يقوم Browserify ببعض الأشياء الرائعة مثل التحليل الثابت لمعرفة الوحدات التي يجب استيرادها وإنشاء بنية أكثر تحسينًا لتطبيقك. (هناك قيود بالطبع ، ربما لا تتطلب التحليل ("bla" + متغير)) يمكنها حتى تبديل الأجزاء التي تتطلب طبقة محاكاة للأشياء التابعة لـ node.js. نعم ، إنه ينشئ بنية js يمكنني الآن تضمينها في متصفحي.

فيما يلي بعض الأشياء التي يمكن أن يقوم بها المتصفح https://github.com/substack/node-browserify#usage

يبدو أن كل شيء رائع حتى الآن ... ولكن هناك بعض النقاط التي اعتقدت أنها تستحق الدراسة ، ننتقل إلى "بنية المتصفح"

  • يجب أن يكون هناك تحول في عقلية مطوري Three.js (يجب استخدام نظام الوحدة النمطية بالطبع)
  • يمكن بناء طبقة توافق بحيث يظل بإمكان مستخدمي Three.js استخدام three.js بالطريقة القديمة دون جني الفوائد النمطية
  • لتكون قادرًا على إنتاج تصميمات محسّنة ، سيحتاج مستخدمو three.js إلى الانتقال إلى النظام المطلوب
  • من المحتمل أن تتضمن عملية الإنشاء الجديدة سلسلة أدوات browserify (حاليًا يمكننا استخدام python أو node.js أو نسخ ولصق بسيط وما إلى ذلك) أو بعض أدوات تتطلب JS.
  • إذا كنا نريد أن تكون Three.js أكثر نمطية حقًا ، مع تعيين الإصدار لكل مكون ، مثل TrackballControls ، فسنحتاج إلى تقسيمها ، وقد يؤدي ذلك إلى التجزئة
  • قد يؤدي ذلك إلى التنوع أيضًا ، ولكن يبدو أن إحدى نقاط القوة في three.js حاليًا هي نقطة مركزية للعديد من الامتدادات

لذلك إذا رأينا هذا التنوع وتحميل الوحدة المريح (الركوب بشكل أساسي على النظام البيئي npm) جنبًا إلى جنب مع الإنشاءات المخصصة أمرًا رائعًا ، فقد يكون من المفيد إجراء تغيير في النموذج ورمز إعادة البناء وتغيير نظام البناء الحالي لدينا.

mrdoob يتم سرد بعض الأدوات حول browserify هنا: https://github.com/substack/node-browserify/wiki/browserify-tools.

بخصوص three.min.js ، فلن تستخدم الكود المصغر في مشروعك. كل ما تفعله هو var three = require('three') في project.js ثم تشغيل browserify project.js > bundle.js && uglifyjs bundle.js > bundle.min.js . ملاحظة: لا يزال بإمكانك شحن رمز مصغر لـ <script src="min.js"> .

أنا حاليًا ألتف بثلاثة ملفات

if ('undefined' === typeof(window))
  var window = global && global.window ? global.window : this
var self = window

و

module.exports = THREE

ثم ألتف التمديدات مع

module.exports = function(THREE) { /* extension-code here */ }

لذلك يمكنني أن أطلبه من هذا القبيل:

var three = require('./wrapped-three.js')
require('./three-extension')(three)

لذلك هذا ليس هو الأمثل ، لكنني شخصياً يمكنني التعايش معه وأعتقد أنه ليس سيئًا للغاية - على الرغم من أن اقتراح kumavis سيكون ميزة ضخمة.

ولكن ربما يكون من المنطقي أن نتفرع ثلاثة وأن نضع كل الأشياء في وحدات منفصلة فقط لنرى كيف ستنجح.

راجع أيضًا http://modules.gl/ الذي يعتمد بشكل كبير على browserify (على الرغم من أنه يمكنك استخدام كل وحدة بمفردها دون browserify).

mrdoob @ shi-314 تم إدراج gulp-browserify في القائمة السوداء لصالح مجرد استخدام browserify مباشرة (أي عبر تدفق مصدر الفينيل).

أدوات مثل grunt / gulp / إلخ في حالة تغير مستمر ، وستجد الكثير من الآراء المختلفة. في النهاية ، لا يهم ما تختاره ، أو ما إذا كنت تفعل ذلك فقط باستخدام برنامج نصي مخصص. الأسئلة الأكثر أهمية هي: كيف سيستهلك المستخدمون ThreeJS ، وما مقدار التوافق مع الإصدارات السابقة الذي تريد الحفاظ عليه؟

بعد المزيد من التفكير ، أعتقد أنه سيكون من الصعب حقًا جعل كل شيء نمطيًا بدون إعادة هيكلة إطار العمل وبنيته بالكامل. فيما يلي بعض المشاكل:

  • يجب تغيير جميع رموز مساحة الاسم إلى عمليات تصدير / طلب CommonJS. هذه مهمة ضخمة جدًا وسيكون هناك الكثير من القبيح ../../../math/Vector2 إلخ.
  • في عالم مثالي ، ستكون المكتبة مجزأة ، لذلك سيتم فصل three-scene عن three-lights إلخ. ثم يمكنك إصدار كل حزمة على حدة. يبدو هذا النوع من التجزئة غير واقعي بالنسبة لإطار كبير مثل ThreeJS ، وسيكون بمثابة ألم في المؤخرة للمحافظة عليه.
  • إذا لم نقم بتجزئة الإطار إلى مكونات صغيرة ، فسيكون الإصدار الدلالي كابوسًا. أي تغيير طفيف في أي مكان في إطار العمل سيحتاج إلى نسخة رئيسية نتوء لكل شيء. وسيكون استهلاك واجهة برمجة التطبيقات أمرًا سيئًا للغاية: require('three/src/math/Vector2')

اقتراحي؟ نحن نعتبر أمرين للمضي قدمًا:

  1. تبدأ صغيرة؛ استخرج بعض الميزات الأساسية والقابلة لإعادة الاستخدام مثل Vector / Quaternion ، وتحويلات الألوان ، والتثليث ، وما إلى ذلك. هذه الأشياء هي مرشحة جيدة لـ NPM لأنها مفيدة خارج نطاق ThreeJS. يمكن أن يكون لديهم أيضًا مجموعة الاختبار الخاصة بهم ، والإصدارات ، وتتبع المشكلات.
  2. عندما يلزم إضافة رمز جديد إلى ThreeJS ، مثل ميزة جديدة ، أو تبعية (مثل poly2tri / Tess2) ، ففكر في سحبه كوحدة منفصلة والاعتماد عليها عبر NPM.

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

شكرا على التفسيرات يا رفاق!

ما أخشاه هو تعقيد الأمور للأشخاص الذين بدأوا للتو. قد لا يكون إجبارهم على تعلم عناصر المتصفح / الوحدات النمطية هذه فكرة جيدة ...

يجب أن أتفق مع mrdoob هنا. أنا وكثير من الزملاء ليسوا مبرمجي ويب (بدلاً من VFX / الرسوم المتحركة TDs). لقد كان اختيار WebGL و Three عملاً كافياً بالتأكيد كما هو الحال في أعلى عبء العمل الحالي (وفي بعض الحالات كان على البعض منا تعلم js على الفور). الكثير مما قرأته في هذا الموضوع ، في بعض الأحيان ، يجعلني أرتجف عندما أفكر في مقدار العمل الإضافي الذي يمكن إضافته إلى لوحي إذا انتقل ثلاثة إلى هذا الهيكل. قد أكون مخطئا ولكن هذا بالتأكيد هو ما يقرأ لي.

مع إنشاء UMD مترجم مسبقًا ( browserify --umd ) في الريبو ، لا يوجد تغيير في سير العمل للمطورين الحاليين.

mrdoob فكرة نظام إدارة التبعية هي البساطة. قد تكون قراءة العشرات من المنشورات حول الخيارات وأنظمة الإنشاء أمرًا مربكًا ، لكن النظام الحالي في النهاية ليس مستدامًا. في أي وقت ، يعتمد ملف واحد على ملف آخر ، وهذا هو مطاردة - والبحث عن أي مطور جديد يجب أن يقوم به للعثور على مرجع. باستخدام browserify ، تكون التبعية صريحة وهناك مسار للملف.

repsac يجب أن يجعل نظام التبعية ثلاثًا أكثر سهولة في الوصول لمستخدمي اللغات الأخرى لأنه يتجنب النطاق العالمي وكوابيس ترتيب التحميل ويتبع نموذجًا مشابهًا للغات الشائعة الأخرى. var foo = require('./foo'); مشابه (بشكل فضفاض) لـ C # using foo; أو Java import foo;

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

أعتقد أن هذا هو الطريق الصحيح ، حقًا. أنجز العمل ، أظهر كيف يعمل.

وسيكون استهلاك واجهة برمجة التطبيقات أمرًا رائعًا ugly: require('three/src/math/Vector2')

كتجربة ، قمت للتو بتحويل "البدء" من المستندات الثلاثة إلى هذا النهج المعياري الجديد. يمكنني أن أتخيل وجود الكثير من المراجع ما لم يكن الناس صارمين جدًا بشأن تقسيم الكود إلى وحدات صغيرة.

تتمثل الميزة الرئيسية لفعل ذلك في أن حجم البنية الناتج سيكون جزءًا صغيرًا من حجم Three.js الكامل لأنك ستقوم فقط بتضمين الأشياء المشار إليها على وجه التحديد هنا ثم الأشياء التي تعتمد عليها تلك الأشياء.

أعتقد أن الرجوع إلى جميع التبعيات التي تحتاجها (وتثبيتها جميعًا بشكل فردي) قد يكون فظيعًا جدًا في الممارسة العملية.

إذا كنت تستهدف الأجهزة المحمولة بشكل صريح ، فسيكون هذا النهج شديد الدقة مثاليًا ولكن في الواقع أعتقد أننا سنحتاج إلى حزم تقوم بتصدير ثلاثة واجهات برمجة تطبيقات بالكامل والتي ستعمل كالمعتاد ، ثم الحزم الأصغر التي تغلف كل هندسة المكافآت ، وكلها العارضين ، كل الرياضيات ، كل المواد وما إلى ذلك ، ثم نزولاً إلى مستوى الوحدة الفردية بحيث يمكن للمطورين أن يقرروا بأنفسهم.

ونعم ، يعد الترميز للويب أمرًا مزعجًا.

على أي حال ، مع التجربة ...

تثبيت التبعيات لدينا ..

npm install three-scene three-perspective-camera three-webgl-renderer three-cube-geometry three-mesh-basic-material three-mesh three-raf

اكتب الكود الخاص بنا ...

// import our dependencies..
var Scene = require('three-scene'),
  Camera = require('three-perspective-camera'),
  Renderer = require('three-webgl-renderer'),
  CubeGeometry = require('three-cube-geometry'),
  MeshBasicMaterial = require('three-mesh-basic-material'),
  Mesh = require('three-mesh'),
  requestAnimationFrame = require('three-raf');

// set up our scene...
var scene = new Scene();
var camera = new Camera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new Renderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// create the cube...
var geometry = new CubeGeometry(1, 1, 1);
var material = new MeshBasicMaterial({color: 0x00ff00});
var cube = new Mesh(geometry, material);
scene.add(cube);
// position the camera...
camera.position.z = 5;
// animate the cube..
var render = function () {
  requestAnimationFrame(render);
  cube.rotation.x += 0.1;
  cube.rotation.y += 0.1;
  renderer.render(scene, camera);
};
// begin!
render();

ثم قم ببناء ملفنا

browserify entry.js -o scripts/hello-world.js

ثم قم بتضمينه في صفحتنا

<script src="/scripts/hello-world.js" type="text/javascript"></script>

أعتقد أن الرجوع إلى جميع التبعيات التي تحتاجها (وتثبيتها جميعًا بشكل فردي) قد يكون فظيعًا جدًا في الممارسة العملية.

لا يحتاج المستخدم النهائي بالضرورة إلى استخدام browserify في مشروعه حتى يتمكن Three من استخدام browserify لإدارة قاعدة الكود الخاصة به. يمكن كشف ثلاثة مثل THREE كما هو الآن ... قم بتضمين ملف البناء وتشغيله.

repsacmrdoob التغييرات ستكون المتوافقة مع السابقة، بحيث يمكن للمستخدمين الحالي لا تحتاج إلى تغيير أي شيء إذا لم ترغب في ذلك. تهدف هذه الاقتراحات إلى تحسين قابلية الصيانة طويلة المدى وطول العمر لقاعدة الشفرة المترامية الأطراف والمتجانسة الخاصة بـ ThreeJS. قد تبدو أشياء مثل التبعية وإدارة الإصدار بمثابة صداع للمبتدئين ، لكنها رائعة لأولئك الذين يطورون الأدوات والأطر والمكونات الإضافية ومواقع الويب واسعة النطاق أعلى ThreeJS.

على سبيل المثال ، يمكن أن يظل رمز المستخدم النهائي كما هو ، ولا يلزم تغيير examples على الإطلاق:

<script src="three.min.js"></script>

<script>
var renderer = new THREE.WebGLRenderer();
</script>

بالنسبة للمطورين الأكثر طموحًا الذين يبحثون عن بنية معيارية ، _أو_ لأولئك الذين يتطلعون إلى تطوير حلول طويلة الأجل على رأس ThreeJS (أي والاستفادة من إدارة الإصدار / التبعية) ، قد يبدو الأمر مثل هذا:
npm install three-vecmath --save

ثم في الكود:

var Vector2 = require('three-vecmath').Vector2;

//.. do something with Vector2

علاوة على ذلك ، يسمح هذا للأشخاص باستخدام أشياء مثل الرياضيات المتجهة لـ ThreeJS ، وتحويلات الألوان ، والتثليث ، وما إلى ذلك خارج نطاق ThreeJS.

على الرغم من أنني أعتقد أن الفوضى المطلوبة () هي فكرة سيئة ومقايضة سيئة ، إلا أنها ستكون فكرة أسوأ أن يتم تعريض المستخدمين لنوعين مختلفين من كود js. نكهة نظام وحدة أبسط (لكن من الدرجة الثانية).

erno أعتقد أنك فاتتك النقطة ، three.js سيتم تنظيمه بواسطة هيكل وحدة داخليًا ، لكن هذا يُستخدم لإنتاج ملف بناء لا يختلف عن الإعداد الحالي.

المكسب الأساسي هو تحسين تجربة تطوير three.js والحفاظ عليه.

kumavis - لم يفوتerno ذلك في الواقع ، لكنني فهمت (*) أنه يشير إلى أنه إذا تم استخدام three.js أحيانًا عبر طلب وأحيانًا لا يمكن أن يكون الأمر محيرًا. على سبيل المثال ، ينظر شخص ما إلى كل من المصدر الثالث ثم بعض أمثلة الجهات الخارجية ويواجه اختلافات في كيفية عمل كل شيء وعمله.

(*) تحدثنا عن هذا على موقع irc في وقت سابق اليوم.

أعتقد أن هذا نوع من النقاط الصحيحة ولكني لست متأكدًا مما إذا كان / كيف يعمل في النهاية - ما إذا كانت مشكلة في استخدامات الوحدة والبناء حقًا. ولكن يبدو بالتأكيد أنه يستحق التفكير ، وبدا عمومًا أنه من الجيد بالنسبة لي أن الأمر العام قد تم النظر فيه بعناية هنا ، شكرًا على المعلومات والآراء حتى الآن من جانبي.

antont أرى. اقترح الأشخاص مجموعة متنوعة من الأساليب المختلفة هنا ، كنت أفترض أننا سنوفر بشكل أساسي وثائق للاستخدام على المستوى الأعلى (سحب كل شيء من THREE ) ، لكن قد ينشئ الآخرون أمثلة لا تتبع هذا وقد يؤدي إلى بعض الالتباس. وهذا مصدر قلق صحيح.

أعتقد أنني كنت في حيرة من أمري بسبب اللغة.

والآخر هو نكهة نظام الوحدة النمطية الأبسط (لكن من الدرجة الثانية).

هذا يشير فقط إلى ملف البناء ، أليس كذلك؟

حسب فهمي ، نعم. لا أستطيع أن أتخيل ما هو غير ذلك ولكن يمكن أن يفوتك شيء رغم ذلك.

antont، kumavis: لقد تحدثت المقترحات هنا عن الكشف عن رمز النمط المطلوب () للمستخدمين النهائيين أيضًا ، انظر على سبيل المثال. أحدث تعليق لـ mattdesl.

"للمطورين الأكثر طموحًا الذين يبحثون عن بنية معيارية ، أو لأولئك الذين يتطلعون إلى تطوير حلول طويلة الأجل على رأس ThreeJS (أي والاستفادة من إدارة الإصدار / التبعية) [...]"

إحدى الطرق للحصول على تصميمات محسّنة هي في الواقع أن يكون لديك برنامج نصي يكتشف تبعياتك تلقائيًا وينتج الوحدات المطلوبة.

الآن bower & browserify لا يتطلب الأمر ، لكنهما ليسا الحلول الوحيدة. لا أعرف ما إذا كانت هناك مشاريع أخرى مفتوحة المصدر جاهزة تقوم بذلك (ربما مثل تبعيات المنظمات غير الحكومية) لكنني كتبت مثل هذه الأدوات قبل ذلك أعتقد أنه سيكون هناك طرق أخرى لحل هذه الآلام.

قد يكون مترجم إغلاق جوجل مثل هذه الأداة؟

من جانب المستخدم ، هل يمكن أن يكون هذا مفيدًا؟
http://marcinwieprzkowicz.github.io/three.js-builder/

هذا مثير للاهتمام erichlof :) أتساءل عما إذا كان marcinwieprzkowicz قد أنشأ هذا يدويًا ... https://github.com/marcinwieprzkowicz/three.js-builder/blob/gh-pages/threejs-src/r66/modules.json

إحدى الممارسات التي تستخدمها Three.js والتي تجعل من الصعب استخدامها في بيئات Commonjs هي استخدام مثال: https://github.com/mrdoob/three.js/blob/master/src/core/Geometry.js#L82

هذا لأنه في أحد التطبيقات ، غالبًا ما ينتهي بك الأمر بإصدارات مختلفة من نفس المكتبة في شجرة المصدر الخاصة بك ، لذا فإن التحقق من المثيل لا يعمل بين الإصدارات المختلفة من نفس المكتبة. سيكون من الجيد التحضير للانتقال إلى نظام وحدة Commonjs لاستبدال تلك الشيكات بفحص الميزات خلف واجهة نمط Geometry.isGeometry (geom).

في git / three.js / src:

grep -r instanceof . | wc -l 
164

في git / three.js / أمثلة:

grep -r instanceof . | wc -l 
216

لذلك يوجد إجمالي 380 استخدامًا instanceof في ثلاثة ملفات. ما هو أفضل تطبيق كبديل؟

لقد أضفت مؤخرًا خاصية type والتي يمكن استخدامها لاستبدال معظم هؤلاء.

لقد أضفت مؤخرًا خاصية النوع التي يمكن استخدامها لاستبدال معظم هؤلاء.

لطيف - جيد! سوف تعد العلاقات العامة.

للحصول على مثال حول كيفية التعامل مع ذلك في مكتبة JS كبيرة وشائعة أخرى ، ألق نظرة على https://github.com/facebook/react . تم تصميم قاعدة الكود باستخدام نظام الوحدة النمطية القائم على نمط العقدة (الذي يطبقه المتصفح) ولكنه مصمم للإصدار باستخدام grunt. هذا الحل مرن لـ 3 حالات استخدام.

  1. لا يزال بإمكان المستهلك الخالص لـ Three.js الذي يكتب Vanilla JS استخدام ملف الإنشاء كما هو الحال دائمًا. لا يوجد تغيير لحالة الاستخدام هذه.
  2. يمكن لمستخدمي Three.js الذين يستخدمون المتصفح أن يعلنوا أن Three.js تبعية في مشروع وأن تبعيات محددة فقط هي require . تم توثيق فوائد إدارة التبعية بشكل جيد.
  3. يجب أن تكون المساهمة في Three.js الآن أبسط حيث تم توثيق التبعيات بين المكونات بشكل صريح.

لقد أجريت بعض البحث ...

بالأمس قمت باختراق برنامج نصي (غبي نوعًا ما) يقوم بتحويل رمز المصدر Three.js لاستخدام عبارات CommonJS require() للإعلان عن التبعيات بين الملفات. فقط لنرى ما سيحدث ... هذا:

  1. ينتهي الأمر بالحصول على عبارات طلب سخيفة إلى حد ما مثل هذا (من WebGLRenderer):

var THREE = require('../Three.js'); require('../math/Color.js'); require('../math/Frustum.js'); require('../math/Matrix4.js'); require('../math/Vector3.js'); require('./webgl/WebGLExtensions.js'); require('./webgl/plugins/ShadowMapPlugin.js'); require('./webgl/plugins/SpritePlugin.js'); require('./webgl/plugins/LensFlarePlugin.js'); require('../core/BufferGeometry.js'); require('./WebGLRenderTargetCube.js'); require('../materials/MeshFaceMaterial.js'); require('../objects/Mesh.js'); require('../objects/PointCloud.js'); require('../objects/Line.js'); require('../cameras/Camera.js'); require('../objects/SkinnedMesh.js'); require('../scenes/Scene.js'); require('../objects/Group.js'); require('../lights/Light.js'); require('../objects/Sprite.js'); require('../objects/LensFlare.js'); require('../math/Matrix3.js'); require('../core/Geometry.js'); require('../extras/objects/ImmediateRenderObject.js'); require('../materials/MeshDepthMaterial.js'); require('../materials/MeshNormalMaterial.js'); require('../materials/MeshBasicMaterial.js'); require('../materials/MeshLambertMaterial.js'); require('../materials/MeshPhongMaterial.js'); require('../materials/LineBasicMaterial.js'); require('../materials/LineDashedMaterial.js'); require('../materials/PointCloudMaterial.js'); require('./shaders/ShaderLib.js'); require('./shaders/UniformsUtils.js'); require('../scenes/FogExp2.js'); require('./webgl/WebGLProgram.js'); require('../materials/ShaderMaterial.js'); require('../scenes/Fog.js'); require('../lights/SpotLight.js'); require('../lights/DirectionalLight.js'); require('../textures/CubeTexture.js'); require('../lights/AmbientLight.js'); require('../lights/PointLight.js'); require('../lights/HemisphereLight.js'); require('../math/Math.js'); require('../textures/DataTexture.js'); require('../textures/CompressedTexture.js');

سنحتاج إلى بعض عمليات إعادة البناء الرئيسية ، ربما تقسيم WebGLRenderer (وما شابه) إلى وحدات متعددة (يبلغ طول الملف أكثر من 6000 سطر).

  1. نحن بحاجة إلى إيجاد حل لقطع GLSL. يتم تجميع THREE.ShaderChunk في وقت التجميع ثم إلى THREE.ShaderLib في وقت التشغيل (الانضمام إلى مصفوفات أخرى THREE.ShaderChunk s) وهو أمر صعب إلى حد ما مع المتصفح فقط. أفترض أنه سيتطلب تحويلاً في المتصفح يقوم بالشيء نفسه.

يستخدم React.js لغة عامة للبحث عن الوحدات النمطية الخاصة بهم دون الحاجة إلى الرجوع إليها من خلال مسار الملف. ربما يمكننا فعل الشيء نفسه وتحديد القواعد المخصصة التي تتيح لنا ملفات GLSL require تحويلها إلى صيغة JS.

rasteiner ، قد تكون سعيدًا جدًا بمعرفة المزيد عن https://github.com/stackgl/glslify ، فهو يأتي من عائلة http://stack.gl المتنامية

لقد كانت لدي خبرة لا بأس بها مع الوحدات النمطية ونهج "unixy" في الشهرين الماضيين وأعتقد الآن أن الوقت قد فات ، وإعادة هيكلة threejs للوحدات النمطية أو npm سيكون هدفًا غير واقعي.

إليك ما أفعله حاليًا لمعالجة مشكلة النمطية / قابلية إعادة الاستخدام:

  • أضع بعض التظليل القابل لإعادة الاستخدام للطمس / fxaa / إلخ على NPM. انظر الى هذا:
    https://www.npmjs.org/package/three-shader-fxaa (الذي يستخدم محرك glsl-fxaa الحيادي)
  • يتم أيضًا نشر مكونات قابلة لإعادة الاستخدام مثل OrbitController و EffectComposer حسب الحاجة. على سبيل المثال:
    https://www.npmjs.org/package/three-orbit-controls
  • بدلاً من الاعتماد على "ثلاثة" ، تقوم هذه الوحدات بتصدير وظيفة تأخذ ثلاثة ، وتعيد فئة الأداة المساعدة. بهذه الطريقة يمكن استخدامه مع threejs العالمية ، أو commonjs.
  • الإصدار هو الألم. أحاول مواءمة إصداراتي الرئيسية مع أرقام إصدارات threejs. تقدم كل نسخة جديدة من threejs الكثير من التغييرات المفاجئة ، لذلك يجب التعامل معها بعناية.
  • يجب أن تعمل الوحدات التي تتعامل مع الرياضيات فقط على المصفوفات وتستخدم وحدات gl-vec3 و gl-mat4 وما إلى ذلك. وبهذه الطريقة تكون عامة ومفيدة خارج threejs. بعد ذلك ، سيتعين على مستخدمي threejs التعامل مع التفاف / فك التفاف على المصفوفات. انظر نظام verlet ، المسار المبسط ، إلخ.
  • إذا كنت بحاجة إلى ميزة webGL معيارية أو صغيرة جدًا ، فأنا أستخدم stackgl / glslify للمضي قدمًا. يمكن أن تعمل هذه أيضًا ضمن ThreeJS طالما أنك تعيد تعيين حالة GL. على سبيل المثال: https://www.npmjs.org/package/gl-sprite-text

تميل مشاريعي الجديدة إلى استخدام "ثلاثة" في npm فقط للتشغيل. سيكون من الرائع جدًا أن تقوم شركة ThreeJS بنشر البنية رسميًا إلى npm باستخدام علامات الإصدار التي تتوافق مع أرقام الإصدار.

ملاحظة: للمهتمين بجلب مظلات قابلة لإعادة الاستخدام / معيارية لسير عملهم:
https://gist.github.com/mattdesl/b04c90306ee0d2a412ab

مرسل من الايفون الخاص بي

في 20 تشرين الثاني (نوفمبر) 2014 ، الساعة 7:42 صباحًا ، كتب aaron [email protected] :

rasteiner ، قد تكون سعيدًا جدًا بمعرفة المزيد عن https://github.com/stackgl/glslify ، فهو يأتي من عائلة http://stack.gl المتنامية

-
قم بالرد على هذا البريد الإلكتروني مباشرة أو قم بعرضه على GitHub.

في حالة مساعدة الآخرين الذين قد يبحثون عن كيفية استخدام Three.js مع المتصفح ، وتعثروا في هذا الموضوع ، فإن الطريقة التي أعددتها بها بنفسي هي استخدام browserify-shim .

بعد قسم README في _ "سوف تقوم أحيانًا أ) بعرض المتغيرات العامة عبر global" _ ، قمت بتضمين علامة نصية منفصلة لـ Three.js وقمت بتكوينها لفضح المتغير العام الثلاثة.

وبعد ذلك ، كان الجزء الذي كان عليّ أن أتدرب عليه بنفسي هو كيفية تضمين إضافات مثل ColladaLoader و OrbitControls وما إلى ذلك.

من package.json:

    "browser": {
        "three": "bower_components/threejs/build/three.js"
    },
    "browserify-shim": "browserify-shim-config.js",
    "browserify": {
        "transform": [ "browserify-shim" ]
    }

browserify-shim-config.js:

    module.exports = {
        "three": { exports: "global:THREE" },
        "./vendor/threejs-extras/ColladaLoader.js": { depends: {"three": null}, exports: "global:THREE.ColladaLoader" },
        "./vendor/threejs-extras/OrbitControls.js": { depends: {"three": null}, exports: "global:THREE.OrbitControls" }
    };

ثم في البرنامج النصي الخاص بي ، main.js:

    require('../vendor/threejs-extras/ColladaLoader.js');
    require('../vendor/threejs-extras/OrbitControls.js');

    var loader = new THREE.ColladaLoader(),
        controls = new THREE.OrbitControls(camera);
...

يتطلب Browserify إعادة بناء البرنامج النصي بأكمله عند تعديله حتى بالبايت. أستخدم المستعرض مرة واحدة لحزم مشروع يتطلب THREE.js ، ثم يستغرق الأمر أكثر من ثانيتين لبناء حد وحظر حمل الكبد في كل مرة أقوم فيها بإجراء تغيير. هذا محبط للغاية.

عادة ما تستخدم المراقبة أثناء التطوير مع تحميل الكبد. هذا الشخص يبني الحزمة بشكل تدريجي.

watchify لا يعمل بالنسبة لي. عندما أقوم بتغيير ملف وحفظه ، راقب و beefy تحميل الكبد يقدم الإصدار الأقدم / المخبأ. ليس لدي فكرة لماذا يحدث هذا. لحسن الحظ ، يعمل المتصفح بشكل جيد بالفعل.

ChiChou Pass في --noparse=three للتصفح. يأخذ هذا خطوة حزمة المتصفح من 1000 مللي ثانية إلى 500 مللي ثانية على جهازي ، وهو أمر لائق بما يكفي لإحساس فوري بالتعليقات.

rasteiner ، أود أن أشكرك مرة أخرى على البحث غير الرسمي الذي أجريته في تبعيات three.js. في حين أن هذه القائمة الضخمة من الأقسام هي رمز قبيح المظهر ، فإن هذا القبح موجود بالفعل كما هو ، غير مرئي. تكمن قوة Browserify في أنها تتطلب منا تهوية ملابسنا المتسخة ومتابعة أنظمة أقل تشابكًا.

هناك الكثير من الأماكن في Three.js حيث نأخذ شيئًا ما ونفهم نوعه ونؤدي مهامًا مختلفة بناءً على هذا النوع. في معظم هذه الحالات ، يمكن نقل هذا الرمز المعتمد على النوع إلى النوع نفسه ، ولن نضطر إلى فهم جميع الأنواع الممكنة التي نعمل عليها.

فيما يلي مثال مختصر من WebGLRenderer :

if ( texture instanceof THREE.DataTexture ) {
  // ...
} else if ( texture instanceof THREE.CompressedTexture ) {
  // ...
} else { // regular Texture (image, video, canvas)
  // ...
}

يجب أن يكون أكثر من النموذج

texture.processTexImage( _gl, mipmaps, otherData )

دع النوع يحدد كيفية التعامل مع نفسه. يسمح هذا أيضًا لمستهلك المكتبة باستخدام أنواع نسيج جديدة لم نفكر فيها. يجب أن يقلل هذا الهيكل من الاعتماد المتبادل.

أعتقد أن الانتقال إلى بنية المتصفح هو بالتأكيد السبيل للذهاب. سيجعل بناء UMD استهلاك THREE.js أسهل. سيسمح لنا أيضًا بتقسيم WebGLRenderer إلى ملفات متعددة ، لأنه يبدو الآن متآلفًا ومخيفًا إلى حد ما.

لقد بدأت فرعًا حيث أعمل حاليًا على نقله هنا: https://github.com/coballast/three.js/tree/browserify-build-system

واسمحوا لي أن أعرف ما هو رأيك.

إليك تغييرات coballast .

يبدو أنك تتبع نهج التحويل الآلي مع ملفك browserifyify.js ، والذي أعتقد أنه الطريقة الصحيحة للذهاب.

الشيء الوحيد الذي لم نناقشه جميعًا كثيرًا حتى الآن هو أفضل طريقة لنقل هذه المكتبة الكبيرة المتغيرة باستمرار إلى المتصفح. يمكنك إجراء التغييرات ثم فتح بيان عام ، لكنه سيصبح قديمًا على الفور. هذا ما هو مقنع حول النهج الآلي.

اذا قدرنا:

  • قدم نصًا برمجيًا لتحويل src ثلاثي الأبعاد (مثل browserifyify.js )
  • قدم مستندًا يشرح كيفية عمل عملية التحويل
  • تقديم مستند يشرح كيفية عمل نظام البناء الجديد
  • إجراء الاختبارات بعد التحويل
  • عدم تضمين أي تغييرات في الملفات الموجودة والتي قد تؤدي إلى تعارض في الدمج

... ثم يمكننا تحويل هذا إلى تحويل بضغطة زر والذي سيستمر في العمل في المستقبل المنظور. تمكن هذه البساطة من تحقيق هذا المفهوم الحالم عن تحول معماري أساسي إلى مثل هذا المشروع الكبير عندما تفوز الحجج الأيديولوجية.

coballast لتحقيق هذه الغاية ، سأزيل التغييرات على src / Three.js إذا كانت تعمل بنفس الطريقة.

ملاحظة: ليس فقط العودة ، ولكن قم بإزالة هذه التغييرات من تاريخ الفرع عبر فرع جديد أو دفع القوة

coballast أتساءل عما إذا كان من المنطقي أكثر أن تكون أداة التحويل ليست three.js ، ولكن أداة خارجية تشير إلى three.js Development dir ، وتقوم بتحويل المصدر الملفات ، ويضيف نصًا برمجيًا للبناء ، ويدير الاختبارات.

kumavis أوافق على ترك دليل src بمفرده. أعتقد أن الشيء الذي يجب فعله هو جعل الأداة المساعدة تكتب دليلًا مكررًا برمز Commonjs ، ويمكننا اختبار وتشغيل إصدار المتصفح من هناك للتأكد من أن جميع الأمثلة تعمل قبل أن نحاول القيام بأي شيء رئيسي.

هناك أيضًا فرصة مثيرة للاهتمام هنا لكتابة بعض عناصر التحليل الثابت التي ستتحقق تلقائيًا وتفرض أسلوبًا متسقًا عبر قاعدة التعليمات البرمجية بأكملها.

coballast يبدو رائعًا.
هناك ثروة من الأدوات المتاحة لإعادة كتابة التعليمات البرمجية آليًا ، على سبيل المثال escodegen . بحاجة للتأكد من أننا نحافظ على التعليقات ، وما إلى ذلك.
تريد أن تبدأ الريبو threejs التحويل فائدة؟

coballast الذي قيل ، من

kumavis النظر في الأمر. انا حقا اريد ان يحدث هذا هذا واحد فقط من مشروعين أعمل عليهما في الوقت الحالي.

kumavismrdoob يبدو أن بعض المناقشات هنا تدور حول فكرة تقسيم ثلاث إلى وحدات منفصلة متعددة يمكن تثبيتها على الأرجح عبر npm ثم تجميعها باستخدام browserify. أنا لست ضد الفكرة تمامًا ، لكنني أعتقد أنه يجب أن تكون قضية منفصلة. الشيء الوحيد الذي أدافع عنه في هذه المرحلة هو استخدام browserify لإدارة قاعدة كود THREE داخليًا. قم بنقلها ، واجعلها تعمل بنفس الطريقة التي تعمل بها دائمًا للمستخدمين ، ثم قم بتقييم ما هو منطقي.

سأكون فضوليًا لمعرفة ما هو ناتج هذه الأداة المساعدة ^ ^

coballast قم بربط الريبو لنا لتتبعه ، حتى لو كان فارغًا فقط في هذه المرحلة. يمكننا البناء من هناك.

https://github.com/coballast/threejs-browserify-conversion-utility

الرمز في حالة من الفوضى ، سيتم تنظيفه قريبًا.

ها نحن ذا! :صاروخ:

لدي الآن الأداة المساعدة في حالة حيث تقوم بإنشاء المتصفح srcify وسوف نبنيها دون مشاكل. سوف أقوم بتحديث الريبو بتعليمات حول كيفية القيام بذلك بنفسك. في هذه المرحلة ، لا تعمل الأمثلة. هناك العديد من المشكلات التي يجب التعامل معها لإصلاح ذلك. سأضيفهم إلى الريبو إذا أراد أي شخص أن يشمر عن سواعده ويساعد.

coballast ، نعم ، يرجى تقديم المشكلات باسم TODOs ، وسأشارك أنا أو غيرنا قدر المستطاع.

ظهرت مشاكل خطيرة. انظر # 6241

إليك تحليلي لما يجب أن يحدث حتى يعمل هذا: https://github.com/coballast/threejs-browserify-conversion-utility/issues/9#issuecomment -83147463

browserify هو على الأقل زائدة عن الحاجة للنقل (احتفالي) بسبب تصميمه. هذا يجعلها تستخدم تكلفة تضخمية (خطة بيانات أي شخص؟) وبطيئة.

العلاج البسيط لذلك هو فصل المستند عن رمز المكتبة والذي قد يستلزم ملفين للعميل وليس ملفًا واحدًا. هذه ممارسة شائعة لشبيبة جانب العميل.

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

spaesani لأنه يجب تنزيل بيانات threejs على أي حال. إذا قمنا بتقسيم threejs إلى وحدات أصغر وسمحنا لنظام الإنشاء الآلي باختيار ما يحتاجه لتطبيق واحد ، فإن معظم تطبيقات threejs الموجودة ستكون أخف وزناً.

إذا كنت لا تزال تريد فصل "المستند عن رمز المكتبة" لسبب ما ، فلا يزال بإمكانك القيام بذلك واستخدام إصدار تم إنشاؤه مسبقًا كما نفعل الآن. يمكنك حتى تقسيم تطبيق browserify المدمج إلى وحدات منفصلة عن طريق استخدام علامتي --standalone و --exclude .

Browserify هو مجرد طريقة لاستخدام واجهة برمجة تطبيقات (CommonJS) لتعريف الوحدة التي أثبتت جدواها في المستعرض. سيؤدي ذلك إلى تبسيط تطوير المكونات الإضافية threejs إلى حد كبير وتعزيز وضوح الكود وبالتالي الإنتاجية ، وسيسمح لنا بالاندماج في نظام بيئي أكبر (npm) حيث يتم الحفاظ على الكود بطبيعته بواسطة المزيد من الأشخاص مع الحفاظ على النزاهة من خلال نظام الإصدار (فكر في الأمر) the stackgl family) ، ولن يجبر الأشخاص على الدخول إلى CommonJS إذا كانوا لا يريدون ذلك.

بالطبع هناك سلبيات ، لكنها ليست تلك التي ذكرتها.

يمكن تخزين three.js و three.min.js مؤقتًا للحفظ في النقل (البيانات) بواسطة وكيل أو حل الجوال الشائع أو متصفح التخزين المؤقت.
في اللحظة التي تختار فيها رمز threejs وتجميعه مع رمز خاص بالوثيقة ، لا يكون التخزين المؤقت ممكنًا.
إذا كان browserify يسمح لأحد