Browserify
Der Wechsel zu dieser Architektur hat Vor- und Nachteile. Bitte fügen Sie Ihre Gedanken hinzu.
Hinweis: Dies erfordert nicht, dass Three.js-Konsumenten browserify verwenden.
Ein Vorteil ist, dass dies eine modulare Architektur für die Weiterentwicklung von three.js erzwingen würde.
Der übliche Stil in node/browserify lässt jede Datei ihre Abhängigkeiten oben deklarieren und betrachtet globale Variablen als Anti-Muster.
Hier ist ein Beispiel-Schnipsel:
// src/geometry/BoxGeometry.js
var Geometry = require('./Geometry.js');
var Vector3 = require('../core/Vector3.js');
module.exports = BoxGeometry;
function BoxGeometry() {
// ...
}
BoxGeometry.prototype = Geometry.prototype;
Ein weiterer Vorteil ist, dass Verbraucher von three.js
, die browserify verwenden, in der Lage sind, die gewünschten Teile auszuwählen. Sie könnten einfach Scene
, BoxGeometry
, PerspectiveCamera
und WebGLRenderer
importieren und die Abhängigkeiten für all diese automatisch abrufen ( Object3D
etc ), und haben ein kleines Bündel von Javascript, das nur die gewünschten Funktionen unterstützt.
Dies könnte auf eine Weise erfolgen, die keine grundlegenden Änderungen auferlegt. Auf der obersten Ebene würden wir alle Klassen exportieren, die wir als Teil des Standardpakets betrachten
// src/three.js
var THREE = { rev: 101 }
module.exports = THREE
THREE.Geometry = require('./geometry/Geometry.js')
THREE.BoxGeometry = require('./geometry/BoxGeometry.js')
// ...
Hinweis: Ich benötige die Abhängigkeiten oben in diesem Beispiel nicht genau, da diese Datei fast ausschließlich aus require-Anweisungen besteht.
Schließlich würden wir das in eine universelle Moduldefinition einschließen, die erkennt, ob ein Modulsystem (Node/Browserify, AMD) verwendet wird, und wenn ja, exportiert oder anderweitig an das globale Objekt anhängt ( window
).
Lassen Sie uns überprüfen:
three.js
Verbrauchern, die browserify verwenden, die Funktionalität auszuwählenDies würde einen Austausch des Build-Systems erfordern, aber das neue wäre ziemlich einfach.
Einige weitere Vorteile:
@shi-314 Ich glaube, ich bin ein wenig verwirrt, ich habe das Gefühl, dass You can structure your code
und You can build for production
Dinge sind, die Sie ohne die architektonische Verschiebung tun können? Sprechen Sie über Three.js-Quelle oder Dinge, die mit Three.js erstellt wurden?
Eine Methode, die Three.js verwendet, die die Verwendung in Commonjs-Umgebungen schwierig macht, ist die Verwendung von instanceof
: https://github.com/mrdoob/three.js/blob/master/src/core/Geometry .js#L82
Dies liegt daran, dass Sie in einer Anwendung oft unterschiedliche Versionen derselben Bibliothek in Ihrem Quellbaum haben, sodass das Überprüfen von instanceof zwischen verschiedenen Versionen derselben Bibliothek nicht funktioniert. Als Vorbereitung für einen Wechsel zu einem Commonjs-Modulsystem wäre es gut, diese Instanzüberprüfungen durch die Funktionsüberprüfung hinter einer Schnittstelle im Stil von Geometry.isGeometry(geom)
zu ersetzen.
@kumavis Ich spreche von Dingen, die in Three.js gebaut wurden. Nehmen wir an, Sie möchten Ihr eigenes Material mit Ihren Shadern usw. erstellen. Im Moment müssen Sie das globale THREE-Objekt erweitern, um mit dem Rest des Three.js-Codes konsistent zu bleiben:
THREE.MeshMyCoolMaterial = function (...) { ... }
Aber wenn wir Browserify hätten, als Sie könnten:
var MeshLambertMaterial = require('./../MeshLambertMaterial');
var MeshMyCoolMaterial = function (...) {...}
So bleibt Ihr Namespace konsistent und Sie müssen nicht THREE.MeshLambertMaterial
und MeshMyCoolMaterial
in Ihrem Code verwenden.
Und mit You can build for production
meinte ich im Grunde dasselbe, was du erwähnt hast: allows three.js consumers using browserify to pick and choose functionality
.
@shi-314 danke, das ist klarer. Das wirkt sich auf meine vorgeschlagene allgemeine Lösung zur Deserialisierung von verbraucherdefinierten Klassen aus:
// given that `data` is a hash of a serialized object
var ObjectClass = THREE[ data.type ]
new ObjectClass.fromJSON( data )
Dies ist von meinem vorgeschlagenen Serialisierungs- / Deserialisierungs-Refactor
https://github.com/mrdoob/three.js/pull/4621
Die Leistung sollte durch eine solche Änderung nicht beeinträchtigt werden.
Das ist eine ziemlich große Veränderung, aber ich bin auch dafür.
Einige andere große Vorteile:
standalone
browserify verwenden, um einen UMD-Build für Sie zu generieren. Sie müssen nicht manuell an UMD-Wrappern herumbasteln.threejs-vecmath
ohne uns Sorgen machen zu müssen, dass jeder Code kaputt geht. Und auf der anderen Seite, wenn wir einen Patch oder eine Nebenversion in einem bestimmten Modul erstellen, können die Leute, die diese Module konsumieren, die Änderungen automatisch erhalten.npm install threejs-shader-bloom
).require()
die unsere App tatsächlich verwendet.An @mrdoob und die anderen Autoren; Wenn Sie nicht viel Erfahrung mit NPM/Browserify haben, würde ich vorschlagen, ein paar kleine Projekte damit zu machen und ein Gefühl für seine "Philosophie" zu bekommen. Es unterscheidet sich stark von der ThreeJS-Architektur; eher als große Frameworks ermutigt es viele kleine Dinge .
Ein weiterer Vorteil dieses Ansatzes besteht darin, dass es ein Ökosystem von Open-Source-Drittanbieter-Three.JS-Modulen geben kann, insbesondere Shader, Geometrien, Modelllader usw., die über NPM oder Github/Component veröffentlicht werden und auf die die Leute dann einfach verweisen und verwenden können. Im Moment wird Sachen geteilt, indem eine Demo gehostet wird, auf der die Leute dann "Quelle anzeigen" können. Three.JS verdient Besseres!
Ich denke, eines der Probleme, die ich mit Three.JS habe, ist, wie schnell Code mit der aktuellen Version von Three.JS inkompatibel wird. Ein weiterer Vorteil des Umstiegs auf so etwas ist die Möglichkeit, bestimmte Versionen von _bits_ von Three.JS angeben zu können, was sehr mächtig und praktisch wäre.
+1
+1 für eine CommonJS/browserify-Architektur würde den Kern leichter machen und Erweiterungen würden passen, selbst wenn sie von Drittanbietern kommen
Die Fragmentierung von Three.js in kleine Module ist ebenfalls mit hohen Kosten verbunden. Das aktuelle System erlaubt recht einfache Addons von Drittanbietern (wie zB die THREEx Module von Jetienne). Es gibt viel über die Einfachheit des aktuellen Setups zu sagen, solange die JS-Modulsysteme nur Wrapper für Build-Systeme sind.
Eine andere Möglichkeit, die Build-Größe zu minimieren, ist ClojureScript. Sie folgen einigen Konventionen, die es dem Closure-Compiler von Google ermöglichen, das gesamte Programm zu analysieren und toten Code zu beseitigen.
+1 für die nicht geschätzte und oft übersehene Eleganz der Einfachheit
+1
Die Fragmentierung von Three.js in kleine Module ist ebenfalls mit hohen Kosten verbunden. Das aktuelle System erlaubt recht einfache Addons von Drittanbietern (wie zB die THREEx Module von Jetienne).
Die Idee hier ist, dass ein UMD-Build immer noch für Nicht-Node-Umgebungen bereitgestellt wird. Plugins wie THREEx würden für diejenigen, die von ThreeJS abhängig sind, mit einfachen <script>
Tags genauso funktionieren.
Die knifflige Sache wird sein: Wie können wir ein bestimmtes Plugin require()
wenn wir uns in einer CommonJS-Umgebung befinden? Vielleicht könnte browserify-shim helfen.
Es gibt viel über die Einfachheit des aktuellen Setups zu sagen, solange die JS-Modulsysteme nur Wrapper für Build-Systeme sind.
Das aktuelle Plugin-/Erweiterungssystem von ThreeJS ist ziemlich schlecht zu handhaben und alles andere als "einfach" oder einfach. Die meisten ThreeJS-Projekte neigen dazu, irgendeine Form von Plugin oder Erweiterung zu verwenden, wie EffectComposer oder FirstPersonControls oder einen Model Loader oder eine der vielen anderen JS-Dateien, die im Ordner examples
herumliegen. Im Moment die einzige Möglichkeit, sich auf diese Plugins zu verlassen:
vendor
Ordner einStellen Sie sich nun vor, Sie könnten mit browserify so etwas tun:
var FirstPersonControls = require('threejs-controls').FirstPersonControls;
//more granular, only requiring necessary files
var FirstPersonControls = require('threejs-controls/lib/FirstPersonControls');
Diese Plugins werden require('threejs')
und alles andere, was sie benötigen (wie GLSL-Schnipsel oder Texttriangulation ). Die Abhängigkeits-/Versionsverwaltung ist für den Benutzer vollständig verborgen, und es besteht keine Notwendigkeit für manuell verwaltete Grunt-/Schluck-Concat-Aufgaben.
Die knifflige Sache wird sein: Wie benötigen wir () ein bestimmtes Plugin, wenn wir uns in einer CommonJS-Umgebung befinden?
Ich verwende CommonJS seit einiger Zeit für THREE.js-Projekte. Es ist ein bisschen ein manueller Prozess, Teile des Codes anderer Leute in Module zu konvertieren, und ich glaube nicht, dass es eine einfache Möglichkeit geben wird, dies für Legacy-Code zu vermeiden, der nicht von den Autoren oder Mitwirkenden konvertiert wird.
Wichtig ist, dass es ein Modul gibt, das das gesamte 'Standard'-DREI-Objekt exportiert, das dann von jedem angefordert werden kann, der es erweitern möchte.
var THREE = require('three');
THREE.EffectComposer = // ... etc, remembering to include copyright notices :)
Dies hat für mich ziemlich gut funktioniert, insbesondere da das Projekt wächst und ich beginne, meine eigenen Shader und Geometrien in ihre eigenen Module usw.
Solange es ein 'threejs-full' oder 'threejs-classic' npm-Paket gibt, ist dies eine ziemlich praktikable Art, mit altem Three.js-Zeug in einer CommonJS-Umgebung zu arbeiten, aber ich vermute, dies ist eine ziemliche Nische!
+1
Ich glaube, sobald fragmentierte Threejs-Module in npm verfügbar sind, Plugin
Entwickler werden es lieben, zu CommonJS env zu migrieren.
Am 5. Juni 2014 um 21:19 schrieb "Charlotte Gore" [email protected] :
Die knifflige Sache wird sein: Wie benötigen wir () ein bestimmtes Plugin, wenn wir
befinden sich in einer CommonJS-Umgebung?Ich verwende CommonJS seit einiger Zeit für THREE.js-Projekte. Es ist ein bisschen
eines manuellen Prozesses, der Teile des Codes anderer Leute in Module umwandelt
und ich glaube nicht, dass es eine einfache Möglichkeit geben wird, dies für Legacy-Code zu vermeiden
die nicht von den Autoren oder Mitwirkenden konvertiert wird.Wichtig ist, dass es ein Modul gibt, das den gesamten 'Standard' exportiert
DREI Objekte, die dann von allem benötigt werden können, was sich erweitern möchte
es.var DREI = erfordern('drei');
THREE.EffectComposer = // ... usw. Denken Sie daran, Urheberrechtshinweise aufzunehmen :)Das hat bei mir ziemlich gut funktioniert, zumal das Projekt wächst und ich
fange an, meine eigenen Shader und Geometrien in ihre eigenen Module usw.Solange es dann ein 'threejs-full' oder 'threejs-classic' npm-Paket gibt
Dies wird eine ziemlich praktikable Art, mit alten Three.js-Sachen in a . zu arbeiten
CommonJS-Umgebung, aber ich vermute, das ist eine ziemliche Nische!—
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/mrdoob/three.js/issues/4776#issuecomment -45236911.
Es könnte auch die Shader modular machen, zB mit glslify . Selbst Dinge wie die Erstellung einer Express-Middleware, die Shader nach Bedarf generiert, werden dann einfacher.
Vor einigen Monaten habe ich frame.js in require.js verschoben und endlich verstanden, wie dieses AMD-Zeug funktioniert.
Ich muss aber noch lernen, wie man das "kompiliert". Was ist das Tool/Workflow zum Generieren eines three.min.js
aus einer Liste von Modulen?
Ich bevorzuge gulp.js als Build-System mit dem gulp-browserify- Plugin. Es ist wirklich einfach zu verstehen und der Code sieht meiner Meinung nach sauberer aus als grunzen. Schau dir das an: http://travismaynard.com/writing/no-need-to-grunt-take-a-gulp-of-fresh-air :wink:
einige Gedanken: (basierend auf meiner begrenzten Erfahrung mit node, npm, browserify natürlich)
Nach der Diskussion in diesem Thread bin ich mir jedoch nicht sicher, ob alle das gleiche Verständnis von browserify hatten (browserify, commonjs, requirejs, amd, umd sind etwas verwandt, obwohl sie möglicherweise nicht dasselbe sind).
Nun, wenn Sie meiner Gedankenkette ein wenig folgen dürfen.
Hier kommt Browserify ins Spiel. Nun, technisch kann man requireJS im Browser verwenden. Aber Sie möchten js-Dateien zusammenfassen, ohne zu viele Netzwerkaufrufe zu tätigen (im Gegensatz zu Dateisystem-Require()s, die schnell sind). Dort macht Browserify einige coole Sachen wie statische Analysen, um zu sehen, welche Module importiert werden müssen, und erstellt Builds, die für Ihre Anwendung optimiert sind. (Es gibt natürlich Einschränkungen, es kann wahrscheinlich nicht parsen require('bla' + Variable)) Es kann sogar Teile austauschen, die eine Emulationsschicht für node.js-abhängiges Zeug erfordern. Ja, es generiert einen js-Build, den ich jetzt in meinen Browser einbinden kann.
Hier sind einige der Dinge, die browserify tun kann https://github.com/substack/node-browserify#usage
Klingt so, als wäre bisher alles großartig ... aber es gibt ein paar Punkte, die ich in Betracht ziehen sollte, wenn wir zu einer "Architektur zum Durchsuchen" wechseln.
Wenn wir also diese Vielfalt und das bequeme Laden von Modulen (hauptsächlich auf dem npm-Ökosystem) zusammen mit benutzerdefinierten Builds als großartige Sache ansehen, dann lohnt es sich vielleicht, einen Paradigmenwechsel vorzunehmen, Code zu refaktorisieren und unser aktuelles Build-System zu ändern.
@mrdoob einige Tools rund um browserify sind hier aufgelistet: https://github.com/substack/node-browserify/wiki/browserify-tools.
In Bezug auf three.min.js
würden Sie den minimierten Code in Ihrem Projekt nicht verwenden. Alles, was Sie tun, ist var three = require('three')
in Ihrem project.js
und dann browserify project.js > bundle.js && uglifyjs bundle.js > bundle.min.js
auszuführen. Hinweis: Sie können weiterhin minifizierten Code für <script src="min.js">
versenden.
Ich verpacke derzeit Three.js mit
if ('undefined' === typeof(window))
var window = global && global.window ? global.window : this
var self = window
und
module.exports = THREE
dann wickle ich Erweiterungen mit ein
module.exports = function(THREE) { /* extension-code here */ }
also kann ich es so verlangen:
var three = require('./wrapped-three.js')
require('./three-extension')(three)
das ist also nicht optimal, aber ich persönlich kann damit leben und denke, dass es nicht so schlimm ist - obwohl @kumavis- Vorschlag ein _riesiger_ Vorteil wäre.
aber vielleicht wäre es sinnvoll, drei zu teilen und alle Dinge in separate Module zu legen, nur um zu sehen, wie es funktionieren würde.
Besuchen Sie auch http://modules.gl/, das stark auf browserify basiert (obwohl Sie jedes Modul ohne browserify alleine verwenden können).
@mrdoob @shi-314 gulp-browserify wurde auf die schwarze Liste gesetzt, um browserify nur direkt zu verwenden (dh über Vinyl-Source-Stream).
Tools wie Grunzen/Schlucken/etc sind ständig im Fluss und Sie werden viele unterschiedliche Meinungen finden. Am Ende spielt es keine Rolle, was Sie wählen oder ob Sie es einfach mit einem benutzerdefinierten Skript tun. Die wichtigeren Fragen sind: Wie werden Benutzer ThreeJS nutzen und wie viel Abwärtskompatibilität möchten Sie aufrechterhalten?
Nach einigem Nachdenken denke ich, dass es _wirklich_ schwierig sein wird, alles zu modularisieren, ohne das Framework und seine Architektur vollständig umzugestalten. Hier sind einige Probleme:
../../../math/Vector2
usw.three-scene
von three-lights
usw. entkoppelt. Dann können Sie jedes Paket separat versionieren. Diese Art der Fragmentierung scheint für ein Framework von der Größe ThreeJS unrealistisch und wäre sehr mühsam beizubehalten.require('three/src/math/Vector2')
Mein Vorschlag? Wir betrachten zwei Dinge, die vorankommen:
Ich würde gerne alles modularisiert sehen, aber ich bin mir eines Ansatzes nicht sicher, der für ThreeJS realistisch ist. Vielleicht sollte jemand einige Experimente in einer Gabel machen, um zu sehen, wie machbar die Dinge sind.
Danke für die Erklärungen Jungs!
Was ich befürchte, ist, die Dinge für Leute zu komplizieren, die gerade erst anfangen. Sie zu zwingen, dieses Browserify/Module-Zeug zu lernen, ist möglicherweise keine gute Idee ...
Muss @mrdoob hier zustimmen. Ich und viele Kollegen sind keine Webprogrammierer (eher VFX/Animations-TDs). WebGL und Three in die Hand zu nehmen, war sicherlich genug Arbeit, wie auch zu unserer aktuellen Arbeitsbelastung (und in einigen Fällen mussten einige von uns js sofort lernen). Vieles von dem, was ich in diesem Thread gelesen habe, lässt mich manchmal schaudern, wenn ich daran denke, wie viel mehr Arbeit zu meiner Platte hinzugefügt würde, wenn Three in diese Struktur umziehen würde. Ich könnte mich irren, aber so liest es sich für mich.
Mit einem vorkompilierten UMD-Build ( browserify --umd
) im Repository ändert sich der Workflow für bestehende Entwickler nicht.
@mrdoob Die Idee eines Abhängigkeitsmanagementsystems ist Einfachheit. Das Lesen von Dutzenden von Beiträgen zu Optionen und Build-Systemen mag überwältigend sein, aber letztendlich ist das aktuelle System nicht nachhaltig. Jedes Mal, wenn eine Datei von einer anderen abhängt, ist dies eine Jagd- und- Suche, die jeder neue Entwickler durchführen muss, um eine Referenz zu finden. Bei browserify ist die Abhängigkeit explizit und es gibt einen Pfad zur Datei.
@repsac Ein Abhängigkeitssystem sollte Three für Benutzer anderer Sprachen zugänglicher machen, da es den globalen Geltungsbereich vermeidet, Albträume der Ladereihenfolge vermeidet und einem ähnlichen Paradigma wie bei anderen gängigen Sprachen folgt. var foo = require('./foo');
ist (lose) verwandt mit using foo;
von C# oder import foo;
Java
Ich würde gerne alles modularisiert sehen, aber ich bin mir eines Ansatzes nicht sicher, der für ThreeJS realistisch ist. Vielleicht sollte jemand in einer Gabel experimentieren, um zu sehen, wie machbar die Dinge sind
Ich denke, das ist wirklich der richtige Weg. Erledigen Sie die Arbeit, zeigen Sie, wie es funktioniert.
Und die API zu verbrauchen wäre ziemlich
ugly: require('three/src/math/Vector2')
Als Experiment habe ich gerade die 'Erste Schritte' von den Three docs auf diesen neuen modularen Ansatz umgestellt. Ich kann mir vorstellen, dass es viele Referenzen gibt, es sei denn, die Leute sind ziemlich streng, ihren Code in winzige Module aufzuteilen.
Der Hauptvorteil dabei wäre, dass die resultierende Build-Größe nur einen winzigen Bruchteil der Größe des vollständigen Three.js ausmachen würde, da Sie nur die Dinge einschließen würden, auf die hier speziell verwiesen wird, und dann die Dinge, von denen diese Dinge abhängen.
Ich denke, es könnte sich in der Praxis als etwas zu schrecklich erweisen, auf alle benötigten Abhängigkeiten zu verweisen (und sie alle einzeln zu installieren).
Wenn Sie explizit auf mobile Geräte abzielen, wäre dieser hochgradig granulare Ansatz perfekt, aber in Wirklichkeit benötigen wir Pakete, die die gesamten DREI APIs exportieren, die wie gewohnt funktionieren, und dann kleinere Pakete, die die gesamte Bonusgeometrie kapseln, alle Renderer, die ganze Mathematik, alle Materialien usw., dann bis auf die einzelne Modulebene, damit die Entwickler selbst entscheiden können.
Und ja, das Programmieren für das Web ist mühsam.
Wie auch immer, weiter mit dem Experiment...
Installieren Sie unsere Abhängigkeiten..
npm install three-scene three-perspective-camera three-webgl-renderer three-cube-geometry three-mesh-basic-material three-mesh three-raf
Schreiben Sie unseren Code...
// 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();
dann baue unsere Datei
browserify entry.js -o scripts/hello-world.js
dann füge es in unsere Seite ein
<script src="/scripts/hello-world.js" type="text/javascript"></script>
Ich denke, es könnte sich in der Praxis als etwas zu schrecklich erweisen, auf alle benötigten Abhängigkeiten zu verweisen (und sie alle einzeln zu installieren).
Der Endbenutzer muss in seinem Projekt nicht unbedingt browserify verwenden, damit Three browserify zur Verwaltung seiner Codebasis verwendet. Drei können als globales THREE
wie es jetzt ist ... die Build-Datei einschließen und damit ausführen.
@repsac @mrdoob die Änderungen wären abwärtskompatibel, sodass aktuelle Benutzer nichts ändern müssen, wenn sie dies nicht möchten. Diese Vorschläge sollen die langfristige Wartbarkeit und Langlebigkeit der weitläufigen und monolithischen Codebasis von ThreeJS verbessern. Dinge wie Abhängigkeits- und Versionsverwaltung mögen für Uneingeweihte nach Kopfschmerzen klingen, aber sie sind großartig für diejenigen, die Tools, Frameworks, Plugins und große Websites zusätzlich zu ThreeJS entwickeln.
dh der Endbenutzercode kann immer noch gleich aussehen und die examples
müssen überhaupt nicht geändert werden:
<script src="three.min.js"></script>
<script>
var renderer = new THREE.WebGLRenderer();
</script>
Für ambitionierte Entwickler, die nach einem modularen Build suchen, _oder_ für diejenigen, die langfristige Lösungen auf ThreeJS entwickeln möchten (dh die Versions-/Abhängigkeitsverwaltung nutzen), könnte es eher so aussehen:
npm install three-vecmath --save
Dann im Code:
var Vector2 = require('three-vecmath').Vector2;
//.. do something with Vector2
Darüber hinaus ermöglicht dies den Benutzern, Dinge wie die Vektormathematik von ThreeJS, Farbkonvertierungen, Triangulation usw. außerhalb des Anwendungsbereichs von ThreeJS zu verwenden.
Auch wenn ich denke, dass das Durcheinander von require() eine schlechte Idee und ein schlechter Kompromiss ist, wäre es eine noch schlimmere Idee, Benutzer zwei verschiedenen Arten von Three.js-Code auszusetzen und den Benutzern zu sagen, dass einer der ausgefallene Modulsystem-Geschmack und der andere der ist einfachere (aber zweitklassige) Modulsystem-Geschmack.
@erno Ich denke, Sie haben den Punkt übersehen, three.js
würde intern durch eine Modulstruktur organisiert, aber das wird verwendet, um eine Build-Datei zu erstellen, die sich nicht vom aktuellen Setup unterscheidet.
Der Hauptgewinn besteht darin, die Erfahrung bei der Entwicklung und Wartung von three.js
verbessern.
@kumavis - nein @erno hat das nicht wirklich übersehen, aber ich habe verstanden(*), dass er darauf three.js
manchmal über require verwendet wird und manchmal nicht. Zum Beispiel schaut sich jemand sowohl die drei Quellen als auch einige Beispiele von Drittanbietern an und stößt auf Unterschiede in der Art und Weise, wie alles ist und funktioniert.
(*) Wir haben heute im IRC darüber gesprochen.
Ich denke, das ist eine Art gültiger Punkt, bin mir aber nicht sicher, ob / wie es am Ende funktioniert - ob es wirklich ein Problem mit der Modul- und Build-Ding-Verwendung ist. Scheint aber sicherlich eine Überlegung wert zu sein und insgesamt hat mir gut geschienen, dass die Gesamtangelegenheit hier sorgfältig bedacht wurde, danke für die bisherigen Infos und Ansichten meinerseits.
@antont Ich sehe. Die Leute haben hier eine Vielzahl von verschiedenen Ansätzen vorgeschlagen, ich ging davon aus, dass wir hauptsächlich Dokumentation für die Verwendung auf höchster Ebene bereitstellen würden (alles von THREE
abziehen), aber andere könnten Beispiele erstellen, die diesem nicht folgen würden, und es kann sein zu einiger Verwirrung führen. Und das ist ein berechtigtes Anliegen.
Ich glaube, die Sprache hat mich etwas verwirrt.
und das andere ist das einfachere (aber zweitklassige) Modulsystem-Geschmack.
Dies bezieht sich nur auf die Build-Datei, ja?
Nach meinem Verständnis ja. Ich kann mir nicht vorstellen, was anderes, aber es kann etwas fehlen.
antont, kumavis: In den Vorschlägen hier ging es darum, den Code im Stil von require() auch Endbenutzern zur Verfügung zu stellen, siehe zB. Der neueste Kommentar von mattdesl.
"Für ambitionierte Entwickler, die nach einem modularen Build suchen, oder für diejenigen, die langfristige Lösungen auf der Grundlage von ThreeJS entwickeln möchten (dh die Versions-/Abhängigkeitsverwaltung nutzen) [...]"
Eine Möglichkeit zu optimierten Builds besteht darin, ein Skript zu verwenden, das Ihre Abhängigkeiten automatisch ermittelt und die erforderlichen Module ausgibt.
Im Moment verzichtet Bower & browserify auf require, aber das sind nicht die einzigen Lösungen. Ich weiß nicht, ob es andere Open-Source-Projekte von der Stange gibt, die dies tun (vielleicht wie ng-Abhängigkeiten), aber ich habe solche Tools schon früher geschrieben, von denen ich denke, dass es andere Ansätze zur Lösung dieser Probleme geben würde.
Der Closure-Compiler von Google könnte ein solches Tool sein?
Könnte dies auf der Benutzerseite eine Hilfe sein?
http://marcinwieprzkowicz.github.io/three.js-builder/
das ist ziemlich interessant @erichlof :) ich frage mich, ob @marcinwieprzkowicz das von Hand generiert hat ... https://github.com/marcinwieprzkowicz/three.js-builder/blob/gh-pages/threejs-src/r66/modules.json
Eine Methode, die Three.js verwendet, die die Verwendung in Commonjs-Umgebungen schwierig macht, ist die Verwendung von instanceof: https://github.com/mrdoob/three.js/blob/master/src/core/Geometry.js#L82
Dies liegt daran, dass Sie in einer Anwendung oft unterschiedliche Versionen derselben Bibliothek in Ihrem Quellbaum haben, sodass das Überprüfen von instanceof zwischen verschiedenen Versionen derselben Bibliothek nicht funktioniert. Als Vorbereitung für einen Wechsel zu einem Commonjs-Modulsystem wäre es gut, diese Instanzüberprüfungen durch die Merkmalsprüfung hinter einer Schnittstelle im Stil von Geometry.isGeometry(geom) zu ersetzen.
in git/three.js/src:
grep -r instanceof . | wc -l
164
in git/three.js/examples:
grep -r instanceof . | wc -l
216
es gibt also insgesamt 380 Verwendungen von instanceof
in Three.js. Was wäre die beste Implementierung als Ersatz?
Ich habe kürzlich eine type
Eigenschaft hinzugefügt, die verwendet werden kann, um die meisten davon zu ersetzen.
Ich habe vor kurzem eine type-Eigenschaft hinzugefügt, die verwendet werden kann, um die meisten davon zu ersetzen.
nett! Werde eine PR vorbereiten.
Ein Beispiel dafür, wie dies in einer anderen beliebten und großen JS-Bibliothek gehandhabt wird, finden Sie unter https://github.com/facebook/react . Die Codebasis ist mit dem Node-Style-basierten Modulsystem (das browserify implementiert) strukturiert, aber für die Veröffentlichung mit Grunt gebaut. Diese Lösung ist flexibel für 3 Anwendungsfälle.
require
spezifische Abhängigkeiten deklarieren. Die Vorteile eines geeigneten Abhängigkeitsmanagements sind gut dokumentiert.Ich habe etwas recherchiert...
Gestern habe ich ein (eher dummes) Skript gehackt, das den Three.js-Quellcode so umwandelt, dass er CommonJS require()
Anweisungen verwendet, um Abhängigkeiten zwischen Dateien zu deklarieren. Nur um zu sehen, was passiert... Das:
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');
Wir würden einige große Umgestaltungen benötigen, vielleicht den WebGLRenderer (und dergleichen) in mehrere Module aufteilen (die Datei ist über 6000 Zeilen lang).
THREE.ShaderChunk
kompiliert und dann zur Laufzeit in THREE.ShaderLib
(Verknüpfung von Arrays von THREE.ShaderChunk
s), was nur mit browserify ziemlich knifflig ist. Ich nehme an, es würde eine browserify-Transformation erfordern, die das gleiche tut.React.js verwendet Commoner, um ihre Module zu suchen, ohne dass sie über den Dateipfad darauf verweisen müssen. Vielleicht könnten wir dasselbe tun und auch benutzerdefinierte Regeln definieren, die es uns ermöglichen, require
GLSL-Dateien in die JS-Syntax umzuwandeln.
@rasteiner Sie können sehr glücklich sein , um zu erfahren , https://github.com/stackgl/glslify , es kommt aus der wachsenden http://stack.gl Familie
Ich habe in den letzten Monaten einiges an Erfahrung mit Modulen und dem "Unixy"-Ansatz gemacht und denke jetzt, dass es zu wenig zu spät ist und das Refactoring von Threejs für Modularität oder npm-Module ein unrealistisches Ziel wäre.
Folgendes tue ich derzeit, um das Problem der Modularität/Wiederverwendbarkeit anzugehen:
Meine neuen Projekte neigen dazu, "drei" auf npm zu verwenden, nur um zum Laufen zu kommen. Es wäre ziemlich großartig, wenn ThreeJS den Build offiziell für npm veröffentlichen würde, indem Versions-Tags verwendet werden, die mit den Release-Nummern übereinstimmen.
PS: an diejenigen, die daran interessiert sind, wiederverwendbare/modulare Shader in ihren Workflow zu integrieren:
https://gist.github.com/mattdesl/b04c90306ee0d2a412ab
von meinem Iphone gesendet
Am 20. November 2014 um 7:42 Uhr schrieb aaron [email protected] :
@rasteiner Sie können sehr glücklich sein , um zu erfahren , https://github.com/stackgl/glslify , es kommt aus der wachsenden http://stack.gl Familie
—
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an.
Im Fall hilft es , andere , die vielleicht suchen , wie Three.js mit browserify zu verwenden, und stolpert auf diesem Thread, so , wie ich es gerade eingerichtet habe ich verwenden browserify-Shim .
Nach dem README-Abschnitt zu _"Sie werden manchmal a) globale Variablen über global verfügbar machen"_ habe ich ein separates Skript-Tag für Three.js eingefügt und es so konfiguriert, dass es die globale Variable THREE verfügbar macht.
Und dann musste ich nur noch herausfinden, wie man Extras wie ColladaLoader, OrbitControls usw. einfügt. Ich habe das so gemacht:
Von 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" }
};
Dann in meinem eigenen Skript 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 erfordert den Neuaufbau des gesamten Skripts, wenn Sie sogar Bytes ändern. Ich benutze browserify einmal, um ein Projekt zu packen, das THREE.js erfordert, dann dauert es mehr als zwei Sekunden, um ein Boundle zu bauen, und blockiert die Livereload jedes Mal, wenn ich eine Änderung vornehme. Das ist zu frustrierend.
Watchify wird normalerweise während der Entwicklung mit Livereload verwendet. Dieser baut das Bundle inkrementell auf.
Watchify funktioniert bei mir nicht. Wenn ich eine Datei ändere und speichere, liefern watchify und beefy's Livereload die ältere / zwischengespeicherte Version. Ich habe keine Ahnung, warum das passiert. Zum Glück funktioniert browserify bereits ziemlich gut.
@ChiChou Pass in --noparse=three
zum Browserify. Dadurch wird der Browserify-Bundle-Schritt von 1000 ms auf 500 ms auf meinem Computer reduziert, was für ein sofortiges Feedback-Feeling anständig genug ist.
@rasteiner Ich möchte Ihnen noch einmal für Ihre informelle Recherche zu den wechselseitigen Abhängigkeiten von Three.js danken. Während diese riesige Liste von Deps ein hässlich aussehender Code ist, ist diese Hässlichkeit tatsächlich vorhanden, nur unsichtbar. Die Stärke von Browserify besteht darin, dass wir unsere schmutzige Wäsche lüften und weniger verworrene Systeme verfolgen müssen.
Es gibt viele Stellen in Three.js, an denen wir ein Objekt aufnehmen, seinen Typ wahrnehmen und basierend auf diesem Typ verschiedene Aufgaben ausführen. In den meisten Fällen könnte dieser typabhängige Code in den Typ selbst verschoben werden, und wir müssten nicht alle möglichen Typen kennen, mit denen wir arbeiten.
Das Folgende ist ein gekürztes Beispiel von WebGLRenderer :
if ( texture instanceof THREE.DataTexture ) {
// ...
} else if ( texture instanceof THREE.CompressedTexture ) {
// ...
} else { // regular Texture (image, video, canvas)
// ...
}
sollte mehr von der form sein
texture.processTexImage( _gl, mipmaps, otherData )
Lassen Sie den Typ bestimmen, wie er sich selbst behandelt. Dies ermöglicht es dem Bibliotheksbenutzer auch, neuartige Texturtypen zu verwenden, an die wir nicht gedacht hatten. Diese Struktur soll Interdependenzen reduzieren.
Ich denke, der Wechsel zu einer browserbasierten Architektur ist definitiv der richtige Weg. Der UMD-Build erleichtert die Nutzung von THREE.js. Es wird uns auch ermöglichen, den WebGLRenderer in mehrere Dateien aufzuteilen, da er im Moment ziemlich monolithisch und beängstigend aussieht.
Ich habe einen Branch gestartet, in dem ich derzeit daran arbeite, ihn hierher zu verschieben: https://github.com/coballast/three.js/tree/browserify-build-system
Bitte sag mir was du denkst.
Hier sind die Änderungen von @coballast .
Es sieht so aus, als ob Sie mit Ihrer browserifyify.js
Datei den automatisierten Konvertierungsansatz verfolgen, was meiner Meinung nach der richtige Weg ist.
Eine Sache, über die wir alle noch nicht viel gesprochen haben, ist, wie man diese große, sich ständig ändernde Bibliothek am besten auf browserify umstellt. Sie können die Änderungen vornehmen und dann eine PR öffnen, die jedoch sofort veraltet ist. Das ist das überzeugende an dem automatisierten Ansatz.
Wenn wir können:
browserifyify.js
)...dann können wir daraus einen Umbau auf Knopfdruck machen, der auf absehbare Zeit noch funktioniert. Diese Einfachheit ermöglicht es, diese verträumte Vorstellung einer grundlegenden Architekturverschiebung zu einem so großen Projekt zu verwirklichen, wenn die ideologischen Argumente gewinnen.
@coballast zu diesem Zweck würde ich die Änderungen an src/
Hinweis: Nicht nur rückgängig machen, sondern diese Änderungen über einen neuen Branch oder einen Force-Push aus dem Branch-Verlauf entfernen
@coballast Ich frage mich, ob es sinnvoller wäre, wenn das Konvertierungsdienstprogramm keine Abzweigung von three.js
, sondern ein externes Dienstprogramm, das Sie auf das Entwicklungsverzeichnis von three.js
, und es konvertiert die Quelle -Dateien, fügt ein Build-Skript hinzu und führt die Tests aus.
@kumavis Ich bin damit einverstanden, das src-Verzeichnis in Ruhe zu lassen. Ich denke, das Dienstprogramm muss ein doppeltes Verzeichnis mit dem Commonjs-Code schreiben, und wir können den browserify-Build von dort aus testen und ausführen, um sicherzustellen, dass die Beispiele alle funktionieren, bevor wir versuchen, etwas Wichtigeres zu tun.
Es gibt hier auch eine interessante Gelegenheit, statische Analysen zu schreiben, die automatisch einen konsistenten Stil in der gesamten Codebasis überprüfen und erzwingen.
@coballast hört sich gut an.
Es gibt eine Fülle von Tools für das automatisierte Umschreiben von Code, zB escodegen . Wir müssen sicherstellen, dass Kommentare usw. gepflegt werden.
Möchten Sie ein Threejs-Conversion-Utility-Repo starten?
@coballast Abgesehen davon ist es wichtig, einen scharfen Fokus auf dieses Dienstprogramm zu
@kumavis Betrachten Sie es als erledigt. Ich möchte wirklich, dass dies geschieht. Dies ist nur eines von zwei Projekten, an denen ich gerade arbeite.
@kumavis @mrdoob Ein Teil der Diskussion hier scheint sich um die Idee zu
Ich bin gespannt, was die Ausgabe dieses Dienstprogramms ist ^^
@coballast verlinkt ein Repo, das wir verfolgen können, auch wenn es an dieser Stelle nur leer ist. Von dort aus können wir bauen.
https://github.com/coballast/threejs-browserify-conversion-utility
Der Code ist ein Durcheinander, wird bald aufgeräumt.
Auf geht's! :Rakete:
Ich habe das Dienstprogramm jetzt in einem Zustand, in dem es browserify src generiert und es ohne Probleme erstellen wird. Ich werde das Repo mit Anweisungen aktualisieren, wie Sie dies selbst tun können. An dieser Stelle funktionieren die Beispiele nicht. Es gibt mehrere Probleme, die behandelt werden müssen, um das zu beheben. Ich werde sie dem Repo hinzufügen, wenn jemand die Ärmel hochkrempeln und helfen möchte.
@coballast ja, bitte
Es sind ernsthafte Probleme aufgetreten. Siehe #6241
Hier ist meine Analyse, was passieren müsste, damit dies funktioniert: https://github.com/coballast/threejs-browserify-conversion-utility/issues/9#issuecomment -83147463
browserify ist aufgrund seines Designs zumindest transportredundant (konjestiv). Dies macht die Nutzungskosten inflatorisch (Datentarif irgendjemand?) und langsam.
Eine einfache Abhilfe besteht darin, das Dokument vom Bibliothekscode zu trennen, was zwei Client-Dateien und nicht eine zur Folge hätte. Dies ist gängige Praxis für clientseitige js.
Wenn browserify am Anfang fehlerhaft ist und selbst behoben werden muss, kann ich kaum einsehen, warum es überhaupt in Betracht gezogen werden sollte, etwas zu verbessern, geschweige denn so etwas wie Threejs.
@spaesani Weil die Daten für Threejs sowieso heruntergeladen werden müssen. Wenn wir Threejs in kleinere Module aufteilen und einem automatisierten Build-System überlassen, was es für eine einzelne App benötigt, wären die meisten Threejs-Apps tatsächlich leichter.
Wenn Sie aus irgendeinem Grund immer noch "Dokument vom Bibliothekscode" trennen möchten, können Sie dies immer noch tun und eine vorgefertigte Version verwenden, wie wir es jetzt tun. Sie können Ihre von Browserify erstellte App sogar in separate Module aufteilen, indem Sie die Flags
Browserify ist nur eine Möglichkeit, eine kampferprobte Moduldefinitions-API (CommonJS) im Browser zu verwenden. Es würde die Entwicklung von Threejs-Plugins erheblich vereinfachen und die Code-Klarheit und damit die Produktivität verbessern. Es würde uns die Integration in ein größeres Ökosystem (npm) ermöglichen, in dem der Code von Natur aus von mehr Leuten gepflegt wird, während die Integrität durch das Versionierungssystem erhalten bleibt (denken Sie an die stackgl- Familie), und es würde die Leute nicht einmal zu CommonJS zwingen, wenn sie es nicht wollen.
Natürlich gibt es Nachteile, aber das sind nicht die, die Sie erwähnt haben.
Three.js und Three.min.js können zwischengespeichert werden, um Transport (Daten) zu sparen, sei es durch einen Proxy, die gängige mobile Lösung oder einen Caching-Browser.
In dem Moment, in dem Sie den Threejs-Code mit dokumentspezifischem Code auswählen und aggregieren, ist das Caching nicht machbar.
Wenn browserify es erlaubt,
sp
On Mar 28, 2015 1:06 PM, Roman Steiner notifications@github.com wrote:@spaesani Because the data for threejs has to be downloaded anyway. If we split threejs into smaller modules and let an automated build system cherry pick what it needs for a single app, actually most threejs apps out there would be lighter.
If for some reason you still want to separate "document from library code", you could still do this and use a pre-built version like we do now. You could even split your browserify-built app into separate modules by using the --standalone flag.
Browserify is just a way to use a battle proven module definition API (CommonJS) on the browser. It would greatly simplify the development of threejs plugins and enhance code clarity and therefore productivity, it would allow us to integrate into a bigger ecosystem (npm) where the code is inherently maintained by more people while still maintaining integrity through the versioning system, and it wouldn't even force people into CommonJS if they don't want it.
Of course there are downsides, but they're not the ones you've mentioned.
—Reply to this email directly or view it on GitHub.
@spaesani Es (browsen) verbessert die Dinge für den Menschen. Mein eigenes psychisches Glück und Wohlbefinden sind wichtiger als die Leichtigkeit, mit der eine Maschine Dinge laden und ausführen kann.
Viele Probleme mit der Auslastung des Mobilfunknetzes werden durch Dinge wie http/2 etwas gemildert. Solche Probleme lassen sich am besten durch Modifizieren von Ebenen lösen, die sich weiter unten auf dem Abstraktionsstapel befinden. Leistungsprobleme sollten uns nicht davon abhalten, Best Practices für die Softwareentwicklung wie Modularität/Trennung von Bedenken usw. zu befolgen.
Ich habe dieses Problem gefunden, weil mein Team seit kurzem jspm verwendet. Wir können Threejs importieren (ich glaube, das liegt daran, dass die Hauptdatei durchsucht wurde). Ich wollte sehen, ob jemand Threejs zu es6-Modulen gemacht hat, hauptsächlich wegen der Build-Funktion von jspm (alle Abhängigkeiten in einer einzigen Datei bündeln, aber nur Abhängigkeiten erfassen, die verwendet werden).
Obwohl es großartig ist, dass mrdoob die Größe von Threejs unter 100kb hält, finde ich, dass die meisten meiner Projekte nicht viel von der Codebasis verwenden (ich habe das Gefühl, dass es am meisten ist, aber ich habe nicht versucht, das herauszufinden). CubeCamera, OrthographicCamera, CanvasRenderer, diverse Lights, Loader, Curves, Geometries, Helpers, etc. Außerdem finde ich, dass die meisten meiner Projekte einige der Beispielskripte enthalten.
Meine Hoffnung war, dass es möglich wäre, einen einzigen Speicherort für all diese Module zu haben (die normalerweise mit Threejs gebündelten sowie die in Beispielen) und einfach die zu importieren, die ich benötige in einer Datei, die viel kleiner als die ursprünglichen Threejs ist, obwohl sie viele Teile enthält, die ursprünglich nicht enthalten waren.
Ich wollte auch hinzufügen, dass, wenn Threejs mit browserify-Modulen erstellt würde, ein kleiner Overhead an Dateigröße (aber nicht vergleichbar mit den aktuellen 403 KB bei r70), aber auch die Verwendung der globalen THREE-Variablen aus dem Code entfernt würde Dadurch können Variablen wie THREE.Geometry durch Closure minimiert werden.
Ich habe einen schnellen Test durchgeführt, einen Find-Replace durchgeführt, um das DREI-Objekt loszuwerden (so dass alle seine Kinder den Namespace verschmutzt haben) und die gesamte Datei in ein IIFE verpackt, dann habe ich das Ganze durch Google-Schließung laufen lassen. Die resultierende Datei (nicht mit gzip gezippt) hatte eine Größe von 238 KB, gegenüber 777 KB.
Obwohl die Ergebnisse variieren werden, denke ich, dass es sich auf jeden Fall lohnt, sicherzustellen, dass dies geschehen kann.
danke fürs erzählen - viele gute punkte dabei und uns auch bekannt. Wir verwenden auch nie viele Renderer in einem Projekt, sondern machen eine Art Lib-Ding aus Beispielen.
Ich wusste nicht, dass es um das Minimieren geht - das ist ein ziemlich großer Unterschied.
und es6-Module schienen sicher vielversprechend zu sein -- es war auch gut zu hören, dass es auch einen Weg dorthin vom AMD/CommonJS/solchen Modulmuster und der lib-Verwendung gibt.
@colin Ich bin
hilft Ihrem psychologischen Glück.
Steht es in der Dokumentation?
browserify ist eine Träger-Cash-Cow...
Dienstag, 31. März 2015, 22:11 - 04:00 von Colin Ballast notifications@github.com :
@spaesani Es (browsen) verbessert die Dinge für den Menschen. Mein eigenes psychologisches Glück und Wohlbefinden sind wichtiger als die Leichtigkeit, mit der eine Maschine Dinge laden und ausführen kann.
Viele Probleme mit der Auslastung des Mobilfunknetzes werden durch Dinge wie http/2 etwas gemildert. Solche Probleme lassen sich am besten durch Modifizieren von Ebenen lösen, die sich weiter unten auf dem Abstraktionsstapel befinden. Leistungsprobleme sollten uns nicht davon abhalten, Best Practices für die Softwareentwicklung wie Modularität/Trennung von Bedenken usw. zu befolgen.
—
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an.
Wenn browserify Abhängigkeiten ohne eine require-Anweisung automatisch ermitteln würde... hey warte...
@spaesani Ich bevorzuge eigentlich die expliziten Abhängigkeiten - hilft Ihnen zu verstehen, wie der Code zusammenpasst.
browserify ist eine Träger-Cash-Cow...
@spaesani browserify Overhead ist
Status-Update:
Ich habe einen Zweig mit einigem browserifiziertem Code:
https://github.com/coballast/three.js/tree/browserify
Bitte bedenken Sie, dass dies noch in Arbeit ist. Dieser Code wurde automatisch generiert und wird daher für eine Weile ziemlich schrecklich aussehen. Ich versuche immer noch, einige Build-Probleme zu beheben. Siehe coballast/threejs-browserify-conversion-utility#10, wenn Sie denken, dass Sie das Problem beheben können. Es wurde eine Weile gebaut, aber jetzt nicht mehr.
@kumavis und ich haben daran gearbeitet, einige Laufzeitprobleme zu
Entschuldigung für die lange Antwort. TLDR: jspm/es6 läuft, hat aber etwas Seltsames: 1) Exportieren von Objekten vor deren Definition; 2) Exportieren von Objekten, die eine einzelne Klasse enthalten, anstatt nur eine einzelne Klasse zu exportieren; 3) IIFE unter Verwendung von zirkulären Abhängigkeiten; 4) Dateistruktur.
Ich habe mit Ihrem browserifizierten Zweig in jspm gespielt ( @spinchristopher oben ? zusammengewürfelt?
Obwohl es ausgeführt wird, gibt es nicht das richtige Ergebnis aus. (mit der einfachen Demo zu den ersten Schritten). Erstellt die Leinwand und füllt sie schwarz (es sei denn, ich setze die klare Farbe auf transparent), rendert den Würfel jedoch nicht wirklich. Ich erwarte jedoch nicht, dass es zu diesem Zeitpunkt funktioniert, da dies noch sehr früh im Prozess ist.
Ich bin auf 3 Hauptprobleme gestoßen:
Einer. Dies war der nervigste, und ich bin mir ehrlich gesagt nicht sicher, wie Sie mit diesem speziellen Fehler überhaupt etwas kompilieren können, da es überhaupt nicht funktionieren sollte. Viele der Dateien beginnen so (das ist in Ordnung, da Funktionsdefinitionen an die Zeit angepasst und im Wesentlichen vor der Zeile module.exports ausgeführt werden, obwohl sie zuerst angezeigt wird):
module.exports.Foo = Foo;
function Foo() {}
Das Problem tritt in den vielen Dateien auf, die so sind (die erste, die ich sah, war math/Math.js). Die Objektinitialisierung wird angehoben (daher liegt kein undefinierter Fehler vor), die Definition bleibt jedoch bestehen (der Export ist also undefiniert).
module.exports.Foo = Foo;
var Foo = {};
Die einzige Lösung, die ich hier gefunden habe, besteht darin, die Exportzeile ans Ende zu verschieben oder sie so umzuschreiben (bevorzugt):
var Foo = module.exports.Foo = {};
Zwei. Die exportierten Daten. Beim Umgang mit modularisierten Dateien ist der Standard, dass jede Datei ein einzelnes Objekt exportiert. Während die meisten Dateien so sind (obwohl einige mehr exportieren), exportieren sie nicht den einzelnen Konstruktor, sondern ein Objekt, das diesen Konstruktor enthält (dh: module.exports.Foo = Foo;
statt module.exports = Foo;
. Letzteres so funktionieren alle browserify-Beispiele). Wenn Sie die Anforderungen verwenden, müssen Sie daher eine Stufe tiefer gehen ( var Vector3 = require('../math/Vector3').Vector3;
). Abgesehen davon, dass dies unnötig ist, gibt es keine Möglichkeit, dies beim Importieren in es6 zu tun. ( import Vector3 from '../math/Vector3'; var vector = new Vector3.Vector3();
). Während es in es6 möglich ist, einen bestimmten Export zu greifen, gilt er bei der Verwendung von browserbasierten Modulen und hätte immer noch die gleiche Redundanz ( import { Vector3 } from '../math/Vector3';
). Es gibt ein paar Dateien, die einfach andere Objekte sammeln (das Offensichtliche ist Three.js), aber diese sollten auf ein Minimum beschränkt werden und sollten wirklich nur für den Build-Prozess verwendet werden, nicht um viele Dinge in der Produktion zu greifen .
Drei. Dies hat mit den zirkulären Abhängigkeiten zu tun. System.js (der von jspm verwendete Modullader) kann zirkuläre Abhängigkeiten problemlos verarbeiten, aber es gibt ein Problem. An vielen Stellen liest sich der Code etwa wie folgt. Das Problem ist, dass Vector3 zwar als Abhängigkeit übergeben wurde, aber zu diesem Zeitpunkt noch nicht vollständig geladen wurde (da Vector3 auch diese Datei enthält, kann jeder nicht aufgelöst werden, bis der andere aufgelöst wurde) und kann nicht erstellt werden. Ich habe eine sehr schlechte Lösung hinzugefügt (siehe unten), obwohl ich nicht sicher bin, wie dies besser behoben werden könnte. Es scheint, dass dies ein architektonisches Problem ist, für das es möglicherweise keine einfache Lösung gibt. Es passiert viele, viele Male. Es scheint eine Optimierung zu sein, um zu verhindern, dass bei jedem Aufruf der Funktion ein neuer Vector3 erstellt wird. Wenn es tatsächlich einen erheblichen Leistungseinbruch gibt, der nicht durch die Optimierung von Vector3 behoben werden kann, dann fügen Sie Vector3 vielleicht eine Funktion hinzu, um einen unbenutzten vector3 zurückzugeben, der später veröffentlicht wird?
Foo.prototype.bar = function() {
var vector = new Vector3();
return function() {
// some data which reuses vector repeatedly.
};
}();
Die Reparatur:
Foo.prototype.bar = function() {
var vector;
return function() {
if(!vector) vector = new Vector3();
// some data which reuses vector repeatedly.
};
}();
Schließlich wollte ich noch etwas zur Dateiorganisation hinzufügen. Dies ist offensichtlich etwas, das man in Angriff nehmen muss, nachdem das aktuelle Set richtig erstellt wurde, aber ich wollte es jetzt ansprechen. Während die aktuelle Dateistruktur funktioniert, sind Teile davon eher seltsam oder sogar umständlich. Die wichtigsten Gruppierungen (Kameras, Materialien, Geometrien usw.) scheinen es gut zu haben, obwohl ich einige Änderungen vornehmen würde, wie unten gezeigt. Ich würde auch die Globals in ThreeGlobals jeweils auf das Ding verschieben, für das sie ein Global sind. IE: FrontSide, BackSide, DoubleSide gehören alle zu Material (zusammen mit NoShading, FlatShading und SmoothShading. Tatsächlich scheinen es die meisten von ihnen zu tun...).
Meine primären Verwirrungen kamen mit Kern und Extras. core/Geometry.js sollte sich im Ordner geometries befinden, genau wie Material im Ordner materials. Aber es gibt keinen Geometrie-Ordner, sondern in Extras. Extras hat übrigens auch einen Kern und eine Geometrie, aber die Basisgeometrie ist nicht in diesem Ordner. Es gibt diese große Sammlung von Helfern, aber sollte nicht jeder Helfer bei der Sache sein, der er hilft? Build-Prozesse können einfach so konfiguriert werden, dass nur die gewünschten Dateien verwendet werden. Es gibt also keine Entschuldigung, die unwichtigen Dateien an anderer Stelle abzulegen.
Ich habe derzeit eine Zeile in meinem Code, die import BoxGeometry from 'threejs/extras/geometries/BoxGeometry';
und var geometry = new BoxGeometry.BoxGeometry( 1, 1, 1 );
liest. Bei der modularen Verwendung ist der Dateispeicherort genauso wichtig wie so etwas wie Funktionssignaturen.
Allgemeine Änderungen würde ich an der Dateistruktur vornehmen. Diese gelten an vielen Stellen, aber ich zeige nur ein Beispiel. (Zur Anmerkung, ich habe immer ein Modell bevorzugt, die Datei nach der einzelnen Klasse zu benennen, die sie exportiert, und die Datei in einem Ordner mit demselben Namen abzulegen. Alle direkten Nachkommen würden im Allgemeinen in diesen Ordner gehen, aber wieder in einen Ordner. mit dem gleichen Namen wie sie selbst. Wenn einem dieses Muster jedoch nicht gefällt, gilt die gleiche Struktur unten, nur diese zusätzliche Ebene herausnehmen.Außerdem kann jeder Dateilader leicht modifiziert werden [die Hooks werden normalerweise direkt bereitgestellt], um automatisieren Sie das Layering und vereinfachen Sie die require-Anweisungen].) (Ich bevorzuge auch alle Dateien in Kleinbuchstaben, bei Bedarf mit Unterstrichen.)
Three.js - This is _only_ used in the build process, so it should actually be with the build files, but run as if it is in this location.
geometry/geometry.js - Currently at core/Geometry.js
geometry/face3/face3.js - from core/Face3.js
geometry/box_geometry/box_geometry.js - Currently at extras/geometries/BoxGeometry.js
geometry/circle_geometry/circle_geometry.js - Similar to above.
geometry/utils/utils.js - from extras/GeometryUtils.js
camera/camera.js
camera/cube_camera/cube_camera.js
camera/perspective_camera/perspective_camera.js
camera/helper/helper.js - or camera/camera_helper/camera_helper.js
scene/scene.js
scene/fog/fog.js
scene/fog_exp2/fog_exp2.js
Ich würde Mathe wahrscheinlich auch in Utils umbenennen (jede Kategorie kann auch ein Utils haben, wie die obige Geometrie), damit es mehr als nur Mathematik enthalten kann (viele der Dinge aus dem Kern).
@HMUDesign @spinchristopher danke für die tolle Analyse ! Es ist am besten, diese Art von Problemen in Zukunft in das Coballast/threejs-browserify-conversion-utility-Repository aufzunehmen.
ok lass mich deinen Kommentar jetzt richtig lesen.
Ich habe den Link zu diesem Repo oben irgendwie übersehen. Ich werde meine Probleme gerne verschieben
morgen zu diesem Repo, dann nach Bedarf aufteilen (das ist mir zumindest aufgefallen
einiges davon ist schon da)
Am 9. April 2015 um 00:09 schrieb "kumavis" notifications@github.com :
@HMUDesign https://github.com/HMUDesign @spinchristopher
https://github.com/spinchristopher danke für die tolle Analyse! Am besten
um diese Art von Problemen in die
coballast/threejs-browserify-conversion-utility Repository in der Zukunft.ok lass mich deinen Kommentar jetzt richtig lesen.
—
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/mrdoob/three.js/issues/4776#issuecomment -91132413.
Ja, und das mache ich für eigene Bibliotheken vom Typ Util (*Util-Dateien sind die
Nur wenn ich keinen Standardexport habe, füge ich manchmal einen hinzu
expert zusätzlich zum Standard), diese Syntax funktioniert jedoch nur, wenn Sie
mehrere benannte Variablen exportieren. Der Loader für gängige js-Module behandelt
module.exports als Standardexport, der im nicht destrukturiert werden kann
importieren =(
Am 9. April 2015 um 00:12 schrieb "kumavis" notifications@github.com :
in es6 können Sie Eigenschaften aus den Exportobjekten importieren über
Destrukturierung.import { Vector3 } from '../math/Vector3';
Trotzdem stimme ich zu, dass ein Export pro Modul bevorzugt wird.
—
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/mrdoob/three.js/issues/4776#issuecomment -91132982.
@HMUDesign Nochmals vielen Dank für Ihre Energie und Analyse - hier gerne einsteigen und so weiter. https://github.com/coballast/threejs-browserify-conversion-utility/issues/17
+1 für Browserify.
Auch +1 zum Verschieben von Shadern in separate Dateien mit glslify.
Auch +1 für die Übernahme einiger ES6-Funktionen - wie Klassen und Module. Der neue Build-Stack wird es uns ermöglichen, bei Bedarf auf ES5 zurückzukompilieren. Siehe Beispiel:
import Object3D from '../core/Object3D';
import Geometry from '../core/Geometry';
import MeshBasicMaterial from '../materials/MeshBasicMaterial';
class Mesh extends Object3D {
constructor(
geometry = new Geometry(),
material = new MeshBasicMaterial({color: Math.random() * 0xffffff}
) {
super();
this.geometry = geometry;
this.material = material;
this.updateMorphTargets();
}
}
export default Mesh;
@lmcd Wo wir schon dabei sind, können wir es6-Module verwenden und babeljs verwenden, um alles zu kompilieren.
@coballast Ich wäre daran interessiert, deinen browserify
Zweig abzuzweigen und einige dieser verwirklichen
@lmcd Ich würde mich nicht darum
@coballast Ich habe mehr darüber nachgedacht, einen 5to6
Pass zu fahren: https://github.com/thomasloh/5to6
@lmcd oo schöner Fund
aber tbh, es scheint einfacher zu sein, drei.js von Grund auf neu zu schreiben: P
@lmcd Ich bin so froh, dass du das gefunden hast. Es war eines dieser Dinge, die ich aus reiner Notwendigkeit tun würde, aber es klang eindeutig nicht lustig.
@mrdoob was ist deine aktuelle
@anvaka Im Moment konzentriere ich mich auf das Refactoring von WebGLRenderer
. Mehr geistige Bandbreite habe ich nicht 😅
Ich bin kürzlich auf ein Projekt gestoßen, das es6-Module glücklich mit dem hier bereits erwähnten babel polyfill verwendet. Konnte mich jetzt nicht erinnern und noch nicht finden, was es war, sah mir jedenfalls gut aus.
Auch es6 scheint an der Standardfront nun fertig zu sein: "Endlich wurde ECMA-262 Edition 6 am 17. Juni 2015 offiziell genehmigt und als Standard veröffentlicht", sagt https://developer.mozilla.org/en-US/docs /Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla
Nur eine Anmerkung, dass die Situation in Bezug auf die Werkzeuge und die Stabilität der Modulspezifikation an dieser Front gut zu sein scheint.
Ich bin kürzlich auf ein Projekt gestoßen, das es6-Module glücklich mit dem hier bereits erwähnten babel polyfill verwendet. Konnte mich jetzt nicht erinnern und noch nicht finden, was es war, sah mir jedenfalls gut aus.
Es ist auch 47 KB zusätzliches js und liest und transpiliert Ihr enthaltenes Javascript in es5 im Browser, also nicht ideal für die Startzeit.
Es gibt nichts, was jeden, der Three.js verwendet, davon abhält, es6 in seinem eigenen Code zu verwenden; Die Verwendung in der Bibliothek würde jedoch generell zu Problemen mit der Browserkompatibilität und Leistung führen.
Ah - steht hier korrigiert, danke für die Info. Ich denke, browserify und solche, die im Build-Prozess funktionieren, sind jetzt noch besser.
Ah - steht hier korrigiert, danke für die Info. Ich denke, browserify und solche, die im Build-Prozess funktionieren, sind jetzt noch besser.
Eines der Hauptprobleme bei es6 ist, dass es mit es5 brechende Syntaxänderungen gibt; zum Beispiel ist der fette Pfeil => ungültig es5 und führt dazu, dass der Javascript-Parser fehlschlägt und versucht, den Code zu kompilieren. Hoffentlich findet jemand einen Weg, dies zu umgehen, aber sie haben es noch nicht.
Ich dachte eigentlich nur an das Modulsystem, die Importanweisung etc.
Es ist auch 47 KB zusätzliches js und liest und transpiliert Ihr enthaltenes Javascript in es5 im Browser, also nicht ideal für die Startzeit.
zum Beispiel der fette Pfeil => ist ungültig es5 und führt dazu, dass der Javascript-Parser fehlschlägt und versucht, den Code zu kompilieren
Der es6-Code kann während _build_ ohne Laufzeiteinbußen in es5 transpiliert werden. Es geht nur darum, der Build-Pipeline einen Babel-Schritt hinzuzufügen.
Zum Beispiel kann die Pfeilfunktion während des Builds ohne Polyfill oder Laufzeiteinbußen auf es5 transpiliert werden. Babel wird diesen es6-Schnipsel transpilieren
function MyObj() {
this.step = 1;
this.increment = function ( arr ) {
return arr.map( v => v + this.step );
}
}
in diese portable Version:
function MyObj() {
this.step = 1;
this.increment = function (arr) {
var _this = this;
return arr.map(function (v) {
return v + _this.step;
});
};
}
Andere Funktionen, wie es6-Klassen, erzeugen ein kleines Polyfill (Sie können in der babel-Repl http://babeljs.io/repl/ sehen).
@mrdoob verstanden. Würden Sie die Idee unterstützen, three.js in kleinere Module aufzuteilen, die auf der npm gehostet werden?
Das Hauptrepository von Three.js bleibt unverändert: Die Verbraucher müssen nichts bauen. Erfahrenere Benutzer könnten die erforderlichen Bits von Three.js auswählen.
Das klingt gut. Details kenne ich allerdings nicht.
Der es6-Code kann während des Builds ohne Laufzeiteinbußen in es5 transpiliert werden. Es geht nur darum, der Build-Pipeline einen Babel-Schritt hinzuzufügen.
Zum Beispiel kann die Pfeilfunktion während des Builds ohne Polyfill oder Laufzeiteinbußen auf es5 transpiliert werden. Babel wird diesen es6-Schnipsel transpilieren
Die ES6-Transpilierung ist immer noch mit erheblichen Laufzeiteinbußen verbunden: http://www.incaseofstairs.com/2015/06/es6-feature-performance/ speziell für eine Hochleistungsbibliothek.
module/npm/browserfy etc ist aber wahrscheinlich eine gute idee
+1 bei richtiger Modularisierung mit ES6-Modulen
+1 bei ordnungsgemäßer Modularisierung mit jedem vernünftigen Modulsystem (commonjs, amd, es6)
Ich denke, commonjs und amd sind die bevorzugten Optionen, da sie kein Transpilieren erfordern
Sie erfordern jedoch einen Build-Schritt, der dem
Schritt transpilieren.
Die Verwendung von ES6, abgesehen davon, dass es die nächste Version der Sprache ist, würde es ermöglichen, dass
Verwendung der nächsten Funktionen wie gewünscht, aber nicht den vorhandenen nativen Code brechen.
Ist es wirklich ratsam, die Codebasis in ein bereits vorhandenes System einzubinden?
nicht das neueste?
Am 20.07.2015 um 12:05 Uhr schrieb "kumavis" notifications@github.com :
+1 bei ordnungsgemäßer Modularisierung mit jedem vernünftigen Modulsystem (commonjs, amd,
es6)
Ich denke, commonjs und amd sind die bevorzugten Optionen, da sie es nicht tun?
transpilieren erforderlich machen—
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/mrdoob/three.js/issues/4776#issuecomment -122990605.
Sie erfordern jedoch einen Build-Schritt, der dem
Schritt transpilieren.
Bauen und Transpilieren sind hinsichtlich der Komplexität, die sie mit sich bringen, nicht gleichwertig.
Ist es wirklich ratsam, die Codebasis in ein bereits vorhandenes System einzubinden?
nicht das neueste?
commonjs ist einfach und funktioniert super. Ich bin nicht von der Vorstellung überzeugt, dass 'neueste' === 'besser'.
Die Verwendung von ES6 [...] würde die Nutzung der nächsten Funktionen wie gewünscht ermöglichen
das ist also eine Überlegung wert. Wollen wir es6-Funktionen? Wenn wir anfangen, es6 zu transpilieren, werden die Leute anfangen, es6 zu veröffentlichen. Wie @benaadams vorgeschlagen hat, gibt es nicht intuitive Leistungseinbußen bei der Verwendung von es6-Funktionen.
Außerdem müssen wir die Themen 'Modulsystem' und 'Es6-Features' nicht vermischen. Sie können es6 transpilieren und commonjs verwenden. und Sie können diese separat vorstellen.
+1 für browserify / commonjs - es ist einfach, mit browserify so zu kompilieren, dass die Leute die Bibliothek immer noch auf traditionelle Weise verwenden können, wenn sie möchten - dafür ist UMD da, AMD zulassen erfordert (wie require.js), CommonJS erfordert (wie node + browserify) und ein globales Fenster (für Skript-Tags), abhängig von der Umgebung, in der wir ausgeführt werden.
PIXI.js ist gerade mit browserify auf eine modulare Architektur umgestiegen und die Bibliothek wurde ganz ähnlich aufgebaut - alles hängt an einem globalen PIXI-Objekt. Ihr Setup ist sehr ähnlich wie @kumavis im zweiten Post beschrieben.
Weder browserify noch commonjs adressieren die spezifischen Anforderungen einer 3D-Engine, was nicht bedeutet, dass sie nicht verwendet werden können, aber sie sollten als Teil eines größeren Puzzles betrachtet werden:
Komponenten müssen Metainformationen über die Eigenschaften ihrer Instanzen exportieren, damit es einen Loader für beliebige Objekte und Datenverbindungen mit gemeinsam genutztem Speicher geben kann. Bei einer solchen Architektur wäre es nur eine Frage des gesunden Menschenverstands, bei der ersten Verwendung auch nicht kernigen Komponentencode zu laden. Brainstorming zu diesen Themen in #6464 und #6557.
+1
+1
Als Hybridlösung ist es auch möglich, die Anforderungen als Kommentare hinzuzufügen. Ich weiß, dass browserfy bereits in vielen Ökosystemen vorhanden ist, aber ich wollte dies hier als schnell zu implementierende Variante belassen :) weil du nichts ändern müsstest. Sie müssen nur zu jeder Datei einen Kommentar hinzufügen.
Als Entwickler können Sie ganz einfach Ihre eigenen min.js-Dateien mit den @requires
Informationen und dem gulp-Plugin erstellen.
Hallo zusammen, ich hatte vor kurzem ein ähnliches Bedürfnis, beliebige Ressourcen mit ihren eigenen Abhängigkeiten sauber und strukturiert zu laden, und ich habe die Lösung gefunden, require.js-Plugins für jeden Ressourcentyp zu schreiben. Auf diese Weise lasse ich die Require.js-Abhängigkeitsauflösung für das ordnungsgemäße Herunterladen und Zwischenspeichern der Ressourcen sorgen.... Gleichzeitig erstellt dieser Ansatz wiederverwendbare Ressourcen-Bündel, die ich in verschiedenen meiner Projekte verwenden kann.
Bei Interesse findet ihr das Projekt hier: https://github.com/wavesoft/three-bundles
(Ein Beispiel mit dieser Bibliothek wird in Kürze verfügbar sein)
Zukünftig plane ich, in diese Plugins eine Optimierungsphase aufzunehmen, damit der Optimierer von require.js die Ressourcen noch kompakter zusammenstellen kann.
Wenn man sich diese Konversation https://twitter.com/defunctzombie/status/682279526454329344 ansieht, sieht es nicht so aus, als ob es6-Module in naher Zukunft implementiert werden. Etwas zu beachten.
Ich habe einige Prototypen mit Commonjs-Modulen und browserify erstellt.
Mein endgültiges browserifiziertes Bundle enthält jede einzelne Datei des Ordners src
und führt zu einer Dateigröße von 962K
(im Vergleich zur ursprünglichen nicht durchsuchten Version 885K
).
Gezielter Build von cloth
Beispiel ist:
580K
(~44% kleiner)431K
(~8% kleiner)Hier ist die Aufschlüsselung der Paketgröße :
Ich denke, wir könnten die Größe des Bündels reduzieren durch:
instance of
-Prüfungen – sie erfordern explizite Verweise auf Module, auch wenn sie nicht verwendet werden. Ich sehe, dass einige der Klassen bereits type
- wir könnten dies in der gesamten Bibliothek verwenden.glslify
wurde ein paar Mal gebracht, und es könnte definitiv helfen. Idealerweise muss jede Komponente, die Shader benötigt, explizit von einem Shader abhängen.Sie können die Ergebnisse überprüfen und den Code überprüfen:
git clone --depth 1 --branch commonjs https://github.com/anvaka/three.js.git
cd three.js
npm i
# build backward compatible three.js library from commonjs modules.
# The output will be save into `build/three.min.js`. I'm using `.min.js` just
# to quickly verify examples. The actual file is not minified.
npm run build
# build cloth example
# the output is saved into ./examples/cjs/webgl_animation_cloth.bundle.js
npm run demo
Es sieht nicht so aus, als ob es6-Module in naher Zukunft implementiert werden. Etwas zu beachten.
Das stimmt, aber es ist auch wichtig zu wissen, dass die Unterstützung des CommonJS-Moduls _nie_ in Browsern implementiert wird, also haben Sie die Wahl zwischen
Bibliotheken wie D3 übernehmen ES6-Module, weil sie bereits alles können, was CommonJS-Module können (außer nativ in Node.js ausgeführt werden, was für eine Bibliothek wie Three.js nicht wirklich ein Problem darstellt) und zu kleineren Builds führen.
Ich habe unter https://github.com/rollup/three-jsnext etwas experimentiert, und obwohl es nicht produktionsbereit ist (ich muss etwas mehr Zeit mit der Portierung von Beispielen usw. verbringen), ist der UMD-Build, den er generiert, tatsächlich _kleiner_ als der aktuelle Build.
Ich würde dem Hinweis zu es6-Modulen im Vergleich zu anderen Systemen zustimmen. Ob oder
Sie sind kein es-Standard, sondern ein Gemeinschaftsstandard. Und obwohl sie
kann in node nicht "nativ" ausgeführt werden, es kann mit Babel-Hooks nativ aussehen.
Ich werde Ihrem Repo bald nachgehen.
Auch die Tatsache, dass es kleiner ist, war etwas, das ich früher erwähnt hatte
dieses Gespräch. Aus "THREE.Geometry" wird "Geometrie", die sein kann
zum Beispiel zu "a" verkleinert.
Außerdem besteht die Lösung für die Instanz von Prüfungen darin, sie alle zu entfernen
zusammen. Ein Modul sollte nicht anders betteln, je nachdem was
es wurde gegeben, aber eher auf die bereitgestellte Sache verschoben, um es zu tun, was es braucht
machen. Dann gibt es keine Instanz- oder Typprüfungen.
Am 1. Januar 2016, 20:23 Uhr, schrieb "Rich Harris" notifications@github.com :
Es sieht nicht so aus, als ob es6-Module in der Nähe implementiert werden
Zukunft. Etwas zu beachten.Das stimmt, aber es ist auch wichtig zu wissen, dass das CommonJS-Modul
Unterstützung wird _nie_ in Browsern implementiert, also haben Sie die Wahl zwischen
- weiter mit einer nicht-modularen Architektur und einem Ad-hoc-Build
System, das Three.js bisher gute Dienste geleistet hat, aber das Wachstum bremst
auf Dauer- mit CommonJS-Modulen, was einige Tricks um zyklische
Abhängigkeiten und führt zu einem größeren Build, oder- mit ES6-Modulen, die gut für eine Codebasis wie Three.js geeignet sind
die zyklische Abhängigkeiten aufweist und die zu den kleinsten und größten
minifizierbarer Aufbau möglich. Schließlich werden Browser sie nativ unterstützen,
und die Änderungen, die erforderlich sind, um unvorhergesehenen Macken im Lader Rechnung zu tragen
spec wird im Vergleich zum Aufwand höchstwahrscheinlich trivial sein
Upgrade von einer CommonJS-Codebasis.Bibliotheken wie D3 übernehmen ES6-Module, weil sie dies bereits können
alles, was CommonJS-Module können (außer nativ in Node.js laufen, was
ist nicht wirklich ein Problem für eine Bibliothek wie Three.js) und führt zu kleineren
baut.Ich habe ein bisschen experimentiert bei
https://github.com/rollup/three-jsnext , und während es nicht in Produktion ist
fertig (ich muss etwas mehr Zeit damit verbringen, Beispiele zu portieren usw!) der UMD-Build
es generiert ist tatsächlich _kleiner_ als der aktuelle Build.—
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/mrdoob/three.js/issues/4776#issuecomment -168363092.
Würde CommonJS immer noch zu einem größeren Build mit einer Codebasis führen, die keine zyklischen Abhängigkeiten aufweist?
@cecilemuller Ja – siehe https://github.com/nolanlawson/rollup-comparison. Bei CommonJS-Modulen zahlen Sie pro Modul Kosten (jedes Modul muss in eine Funktion verpackt werden und Importe, die im gesamten Bundle gemeinsam verwendet werden, neu deklarieren, sodass Sie für eine modularere Codebasis bestraft werden), Kosten pro Bundle (es muss eine Node.js-Umgebung simuliert werden) und andere Kosten wie nicht verkleinerbare Objekteigenschaftennamen, die in ES6-Modulen verkleinerbare Variablennamen wären. Mit ES6-Modulen können Sie buchstäblich ohne Overhead bündeln.
Obwohl das Transpilieren dann zu es5 einen gewissen Overhead verursachen würde. Derzeit,
Ich benutze Webpack mit Babel, das sehr wenig hinzufügt. Es gibt pro Modul Kosten
da es auch in s-Funktion eingeschlossen ist. Abhängigkeiten werden im Finale erklärt
Code durch Aufrufen einer require-like-Funktion mit einem ganzzahligen Index, so dass es
zu etwas wie "var a=f(5)" von dem, was ursprünglich "import" war, minimiert
Geometrie aus "./geometry";'
Die Verwendung von Generatoren fügt auch ein bisschen mehr hinzu, aber ich kann mir die Struktur von nicht vorstellen
der Code würde sich bald so stark ändern.
Am 2. Januar 2016 um 5:53 Uhr schrieb "Rich Harris" notifications@github.com :
@cecilemuller https://github.com/cecilemuller Ja – siehe
https://github.com/nolanlawson/rollup-comparison. Mit CommonJS-Modulen
Sie zahlen pro Modul Kosten (jedes Modul muss in eine Funktion verpackt werden,
und muss Importe, die im gesamten Bundle gemeinsam verwendet werden, neu deklarieren
Sie werden für eine modularere Codebasis bestraft), Kosten pro Bundle (es braucht
um eine Node.js-Umgebung zu simulieren) und andere Kosten wie z
Objekteigenschaftsnamen, die in ES6 miniifizierbare Variablennamen wären
Module. Mit ES6-Modulen können Sie buchstäblich ohne Overhead bündeln.—
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/mrdoob/three.js/issues/4776#issuecomment -168394376.
Obwohl das Transpilieren dann zu es5 einen Mehraufwand verursachen würde
Wenn Sie nur die Syntax import
und export
, um die Beziehung zwischen Modulen zu beschreiben, müssen Sie den Code selbst nicht mit Babel oder ähnlichem transpilieren. Erst wenn Sie andere ES6-Funktionen hinzufügen (wie Klassen und Blockbereichs- und Pfeilfunktionen usw.), wird eine Transpilierung erforderlich, sodass kein Overhead für die Verwendung von import
und export
. D3 und PouchDB sind zwei Beispiele für Bibliotheken, die import
und export
aber ansonsten Babel-lose ES5 sind, und drei-jsnext wird auf die gleiche Weise ausgeführt.
Ok, wir hatten alle die gleiche Idee. Es wäre toll, eine Geschichte wie Lodash zu haben.
Ich schlage vor, ein _three-foo_-Paket für jede Komponente _foo_ (zum Beispiel Three-Vector2) zu erstellen, die modularisiert werden kann, ohne den Code zu ändern, sodass sie ohne Auswirkungen in dieses Repository importiert werden kann.
Leute, die auf npm veröffentlichen, sollten gut spielen und mit @mrdoob zusammenarbeiten, da er der Schöpfer dieser großartigen Software ist. der Herausgeber sollte ihm die Kontrolle über den genommenen npm-Namespace geben.
Ich werde versuchen, das für die Pakete zu tun, die ich benötige. Mal sehen was passiert.
Es gibt nur eine große Community :)
Ich habe niemanden bemerkt, der vorschlug, die Bibliothek vollständig zu trennen, wie
lodash. Lodash ist eine Sammlung von Dienstprogrammen unter einem gemeinsamen Namen; du fährst
Nimm ein einzelnes Stück davon und benutze es. Threejs ist nicht; es ist ein umfassendes
Bibliothek, von denen das meiste ohne den Rest nutzlos ist. Es sind ein paar Teile
die getrennt werden können, wie die spezifischen Materialarten unsere spezifischen
Geometriegeneratoren, aber diese werden notwendigerweise sehr eng beieinander liegen
an den Kern gebunden und benötigt wahrscheinlich genaue Versionsübereinstimmungen. In Anbetracht ihrer
Größe, würde dies zu Wartungsproblemen ohne messbaren Gewinn führen.
Sollte Herr Doob einer solchen Spaltung zustimmen, glaube ich aber nicht
angemessen für jeden außer einem offiziellen Betreuer, der Threejs behauptet-*
Pakete.
Unabhängig davon halte ich es für sinnvoll, es modular zum Laufen zu bringen
Umwelt vor allem anderen. Es gab mehrere Projekte damit
Ziel, aber alle scheinen ins Stocken geraten zu sein.
Am 6. März 2016, 11:39 Uhr, schrieb "Gianluca Casati" notifications@github.com :
Ok, wir hatten alle die gleiche Idee. Es wäre toll eine Geschichte zu haben wie
lodash.Ich schlage vor, ein _three-foo_-Paket für jede Komponente _foo_ (für
Instanz Drei-Vektor2), die modularisiert werden kann, mit fast unveränderten
den Code, sodass er ohne Auswirkungen in dieses Repository importiert werden kann.Leute, die auf npm veröffentlichen, sollten gut spielen und mit @mrdoob zusammenarbeiten
https://github.com/mrdoob da er der Schöpfer dieses tollen Stücks ist
von Software, also wenn er wieder alle Pakete zentralisieren möchte wie in
_babel_, der Herausgeber sollte ihm die Kontrolle über den npm-Namensraum geben.Ich werde versuchen, das für die Pakete zu tun, die ich benötige. Mal sehen was passiert.
Es gibt nur eine große Community :)
—
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/mrdoob/three.js/issues/4776#issuecomment -192970867.
@mattdesl : Zum Beispiel verwendet Ihr Three-Shader-fxaa THREE.Vector2 und THREE.Texture, abgesehen von Three-Effectcomposer, den ich nicht überprüft habe, würde dies zu einem wirklich leichten Build mit dem oben vorgeschlagenen Modularitätsansatz führen.
@HMUDesign : Ich verstehe Ihre Zweifel, aber es scheint mir immer noch ein guter Ansatz zu sein. Ich möchte es versuchen, aber ich werde auf Ihren Rat hören, npm-Pakete von GitHub-URLs zu verwenden und sie nicht in der heiligen Registry zu veröffentlichen .
Ich habe es versucht, ausgehend von TrackballControls, die von Vector2, Vector3, Quaternion usw. abhängig sind.
Es gibt kreisförmige Abhängigkeiten (zum Beispiel hängt Matrix4 von Vector3 ab und umgekehrt). Dies ist nicht möglich, wenn die lib (dh threejs) monolithisch gestartet wurde.
Schade, dass das Modulmuster mit all seinen Vorteilen bei wichtigen Projekten wie diesem nicht ohne weiteres angewendet werden kann.
Ich versuche es auch mit anderen Projekten wie svg.js, vvvvjs, sogar x3dom, aber da die Autoren von dieser radikalen Entscheidung nicht ganz überzeugt sind, kann sie nicht durchgeführt werden.
Entschuldigung für den Spam, aber ich wollte es proaktiv versuchen: Ich habe übrigens mit dem Drei-Trackballcontrols- Repo angefangen.
@fibo ES6
Ich bin mir sicher, dass Sie dies gesehen haben: https://github.com/kamicane/three-commonjsify Er hat es in commonJS gelöst.
@drcmda echt interessant, werde ich mal ausprobieren
+1 für den Wechsel zu einer modularen Architektur.
+1
+1
@drcmda hat recht. ES6-Module verfügen über einen Initialisierungsschritt und einen Ausführungsschritt, der Zirkelverweise erlaubt. Sobald Sie jedoch zirkuläre Abhängigkeiten direkt aus dem Modulausführungskontext (im globalen Bereich eines Moduls) haben, werden beim ersten während der Laufzeit geladenen Abhängigkeiten undefinierte Werte angezeigt. Solange die Referenzen in unterschiedlichen Kontexten verwendet werden, in denen die Ausführungsreihenfolge zur Laufzeit wichtig ist, sind zirkuläre Abhängigkeiten kein Problem.
Ich schlage vor, auch Webpack anstelle von browserify in Betracht zu ziehen.
@gionkunz wir haben
Die Beta von Webpack 2 wurde gerade veröffentlicht (https://twitter.com/TheLarkInn/status/747955723003322368/photo/1), sodass es6-Module auch im Bundle von Tree Shaking profitieren könnten.
@mrdoob
Gab es in jüngerer Zeit eine offizielle Stellungnahme? Wie viele haben wir ES5 und Glue-Concats vor langer Zeit aufgegeben und es ist ziemlich schlimm, wie viel DREI in einem modernen Build-System aus der Reihe fällt. Wir verwenden vielleicht 10 % dessen, was es tun kann, aber es ist die größte Abhängigkeit, die wir liefern.
Dies ist für mich persönlich vielleicht _das_ beliebteste Projekt auf Github - ich hoffe aufrichtig, dass die Prioritäten überdacht werden.
Hmm, ich würde gerne mehr Details zur Browserunterstützung erfahren. Welche Browser tun und welche nicht. Welche Problemumgehungen und Leistungseinbußen gibt es für Browser, die dies nicht tun?
Tatsächlich wird die Browserunterstützung kein Thema (vielleicht sogar noch weniger als jetzt). Die Build-Systeme nehmen diesen ES6-Code und transpilieren ihn in es5 (manchmal nehmen sie weniger Platz ein, als der ursprüngliche ES5 hätte). Bestimmte Arten von transpilierten Dingen werden am Ende groß (hauptsächlich: Generatoren und asynchrone Funktionen), aber wenn Sie diese vermeiden, haben Sie diese Strafe nicht.
Wie @drcmda erwähnt, würde das Build-System immer noch eine monolithische Ausgabe erzeugen (und es wäre sehr einfach, genau anzupassen, was in dieser Ausgabe enthalten ist), aber die einzelnen Module könnten auch in unsere eigenen Projekte aufgenommen werden, also nur die Teile verwenden, die wir brauchen. Um den vollen Nutzen zu ziehen
dass Interdependenzen angepasst werden müssen, aber das kann im Laufe der Zeit passieren. Ich denke, die Hauptfunktionen, die wir wollen, sind die Modularisierung mit Import/Export. Aus Ihrer Sicht würde es die Verwendung von Klassen über Prototypen ermöglichen (sie verwenden immer noch Prototypen unter der Haube, also können Sie immer noch
bei Bedarf damit umgehen).
Es gibt einige Build-Systeme. Meine Stimme wäre Webpack (das Babel zum Transpilieren verwendet). Mit babel können Sie benutzerdefinierte Loader definieren, sodass das von Ihnen entwickelte Chunking-System für Shader mit einer #include-Erweiterung auf tatsächlichen glsl-Code reduziert werden könnte (ich mache meine Shader tatsächlich auf diese Weise und trage sie gerne in das Projekt ein). Dies bietet die gleichen Vorteile Ihres Systems (keine Codeduplizierung), ist aber sehr einfach zu bedienen.
Ich würde gerne Teil des Modularisierungsprojekts sein, aber ich weiß, dass dies ohne Ihre Unterstützung (und wahrscheinliche Hilfe) in keiner Weise erfolgreich sein wird. Viele von uns wissen, wie man die Bibliothek benutzt, aber keiner von uns weiß, wie sie intern so funktioniert wie Sie.
Bestimmte Arten von transpilierten Dingen werden am Ende groß (hauptsächlich: Generatoren und asynchrone Funktionen), aber wenn Sie diese vermeiden, haben Sie diese Strafe nicht.
Wie groß?
Sie haben auch nicht von Leistungseinbußen gesprochen. Ist das dann kein Thema?
Soweit ich sehen kann, werden ES6-Importe immer noch von keinem Browser unterstützt , daher wäre dieser Modul-Refactor hauptsächlich für Build-Systeme gedacht, oder?
Vergessen Sie nicht die Vorteile, die Sie durch die Verwendung von Tools wie rollupjs erhalten. Dies würde automatisch alle Exporte ausschließen, die ein Benutzer nicht verwendet. (Was bei JSPM Standard ist)
Das babel-polyfil-Paket, das nur benötigt wird, wenn Sie verwenden
Generatoren (die in diesem Projekt wahrscheinlich nicht einmal Sinn machen) oder asynchron
Funktionen (von denen ich nicht wirklich glaube, dass sie im Projekt viel ändern würden
entweder), fügt dem endgültigen Build etwa 50k hinzu. Aber auch dies ist optional.
Was die Leistung angeht, hängt es wirklich davon ab, welche Funktionen Sie haben
verwenden. Zum Beispiel sind Pfeilfunktionen aufgrund der
zugrunde liegende Bindung, Klassen sind etwas langsamer zu erstellen, obwohl die
Instanziierungszeit ist die gleiche. https://kpdecker.github.io/six-speed/
ES6-Importe/-Exporte werden von Browsern nicht unterstützt, aber da geht es
durch ein Build-System, das ist kein Thema. Der Produktoutput wäre
genau so verwendbar, wie es derzeit ist (sogar abwärtskompatibel), aber
würde die Integration in unsere Build-Systeme ermöglichen und die
interne Komponenten für uns wiederverwendbar.
Eine andere zu beachtende Sache ist die endgültige Build-Größe. Derzeit werden Dinge wie Geometrie,
Material, Mesh usw. sind Teil des Namensraums THREE. Wenn verkleinert,
Verweise auf THREE.Geometry, THREE.Material, THREE.Mesh etc bleiben im
Code. Mit einem modularen System würde jede dieser Dateien so etwas erhalten wie
var Geometry = require('./geometry');
dann Verweise auf die
Variable Geometry
später. Dann bei minifaciton, Geometry
und require
werden beide auf einzelne Zeichen umgestellt, das './geometry' wird durch a . ersetzt
Zahl, was zu einigen Einsparungen führt. Serviettenmathematik: die verkleinerte
build ist 511.794 Byte groß und enthält 2942 Verweise auf
THREE\.[A-Z][a-zA-Z]+
. All dies durch ein einziges Zeichen ersetzen
führt zu einer Reduzierung der Dateigröße um fast 10 % (auf 464.782). (Die gziped
Größen sind 117.278 bzw. 110.460, eine Reduzierung um 6%). Der Aufbau
könnte wahrscheinlich so eingestellt werden, dass dies noch weiter reduziert wird.
Rollup (wodurch ungenutzten Code aus einem endgültigen Build entfernt wurde) ist die Standardeinstellung
mit jspm, wird die Standardeinstellung mit webpack2 sein (und ich glaube, es kann verwendet werden)
mit Webpack). Wenn Dinge modular geschrieben sind, denke ich nicht, dass dies der Fall sein wird
aber hilfreich. Auf jeden Fall, solange der Code mit transpiliert werden kann
babel, es kann in jedem Build-System verwendet werden (der glsl-Loader, den ich erwähnt habe
vorher kann man auch mit webpack arbeiten).
Am Do, 7. Juli 2016 um 13:28 schrieb Mr.doob notifications@github.com :
Bestimmte Arten von transpilierten Dingen werden am Ende groß (hauptsächlich:
Generatoren und asynchrone Funktionen), aber wenn Sie diese vermeiden, haben Sie keine
diese Strafe.Wie groß?
—
Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/mrdoob/three.js/issues/4776#issuecomment -231197171,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe/AA71cqAqmgxsUjpvamnI_xyL2wpzeWrdks5qTWGBgaJpZM4B4aA7
.
Ich bin mir nicht sicher, ob dies schrecklich hilfreich ist, aber dies ist der Diskussionsthread für D3 zum gleichen Problem: https://github.com/d3/d3/issues/2220. D3 4.0 hat den ES6-Import/Export zum Verwalten von Modulen übernommen, ist aber immer noch in ES5 geschrieben (https://github.com/d3/d3/issues/2220#issuecomment-111655235).
Sehr interessant @jpweeks!
Also... mit diesem Import/Export-Ansatz... Wie würden Dinge wie object instanceof THREE.Mesh
aussehen?
@mrdoob
import/export
ist genau die Art und Weise, wie Module deklariert und benötigt werden. Es wird den in den Modulen definierten Code überhaupt nicht beeinflussen/ändern:
src/Objects/Mesh.js
// Mesh class, stays the same as today (except the export part)
var Mesh = function ( geometry, material ) {
// ...
}
export default Mesh
src/Three.js
// Library entry point, exports all files using som bundling tech
// In a "THREE" namespace for browsers
// As import three from 'three' in node
import Mesh from './objects/Mesh'
export {Mesh} // All three objects, such as Geometry, Material etc..
Application.js
// In node
import {Mesh} from 'three'
var mesh = new Mesh(geo, mat)
console.log(mesh instanceof Mesh) // true
Client.js
// In a browser
var mesh = new THREE.Mesh(geo, mat)
console.log(mesh instanceof THREE.Mesh) // true
Das ist super hilfreich @GGAlanSmithee! Vielen Dank!
Ich bin ein visueller Mensch, daher überzeugen mich Pseudocode-Beispiele mehr als große Textblöcke 😅
Richtig, es wird also ein bisschen Refactoring erfordern...
Weiß jemand, ob der Closure-Compiler dies unterstützen möchte?
Richtig, es wird also ein bisschen Refactoring erfordern...
Ich habe dich! Da dieser Thread in den letzten Tagen lebhaft geworden ist, habe ich ein bisschen mehr an three-jsnext gearbeitet . Es ist ein Projekt, das die vorhandene Three.js-Codebasis verwendet und sie automatisch in ES-Module umwandelt. Ich kämpfe nur mit ein paar kniffligen zyklischen Abhängigkeiten (insbesondere um KeyframeTrack
), sollte aber bald etwas zu teilen haben. Soweit ich das beurteilen kann, funktionieren alle Beispiele weiterhin und der minimierte Build ist kleiner als der aktuelle (mit Rollup zum Generieren einer UMD-Datei), also alles gute Nachrichten.
Ok, ich habe dafür eine Pull-Anfrage geöffnet: #9310
@mrdoob
Wir haben eine Bibliothek in Produktion, die mehr oder weniger wie DREI aufgebaut ist. Es funktioniert in Browsern und modularen Umgebungen. Die Codebasis ist ES6, aber Browser sind überhaupt nicht Ihr Anliegen.
Sie würden dies auf npm _as is_ liefern, alle Module enthalten + ein kompilierter globaler Namespace-Browser-Monolith (three.js). Wer einzelne Teile davon nutzen muss, nutzt Tools, um Bundles zu erstellen.
Betrachten Sie eine Struktur wie diese:
/src
classA.js
classB.js
classC.js
/index.js
/browser.js
index.js exportiert einfach alle Module und Funktionen in eine Datei neu:
export ClassA from './src/classA';
export ClassB from './src/classB';
export ClassC from './src/classC';
So kann der Endbenutzer die Lib npm installieren und einfach ohne weiteres verwenden:
// all exports from index.js will be under: mylib.ClassA, etc.
import * as mylib from 'libname':
// selected exports from index.js
import { ClassA, ClassC } from 'libname';
// or, specific modules
import ClassB from 'libname/src/classB'
browser.js wäre der einzige kompilierte Teil des Pakets. Normalerweise über Babel nach ES5 transpiliert und in einen Global-Namespace exportiert, damit es als Skript-Include verwendet werden kann. Rollup, Webpack usw. können dies problemlos erstellen.
@mrdoob es war eine wundervolle Fahrt 🚀
Hilfreichster Kommentar
Ich habe dich! Da dieser Thread in den letzten Tagen lebhaft geworden ist, habe ich ein bisschen mehr an three-jsnext gearbeitet . Es ist ein Projekt, das die vorhandene Three.js-Codebasis verwendet und sie automatisch in ES-Module umwandelt. Ich kämpfe nur mit ein paar kniffligen zyklischen Abhängigkeiten (insbesondere um
KeyframeTrack
), sollte aber bald etwas zu teilen haben. Soweit ich das beurteilen kann, funktionieren alle Beispiele weiterhin und der minimierte Build ist kleiner als der aktuelle (mit Rollup zum Generieren einer UMD-Datei), also alles gute Nachrichten.