Browserify
このアーキテクチャへの移行には、長所と短所があります。 あなたの考えを追加してください。
注:これには、three.jsコンシューマーがbrowserifyを使用する必要はありません。
1つの利点は、これにより、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;
もう1つの利点は、browserifyを使用するthree.js
消費者が、必要なパーツを選択できることです。 Scene
、 BoxGeometry
、 PerspectiveCamera
、およびWebGLRenderer
インポートするだけで、これらすべての依存関係を自動的に取得できます( Object3D
など)。必要な機能セットだけをサポートするJavaScriptの小さなバンドルがあります。
これは、重大な変更を課さない方法で行うことができます。 トップレベルでは、標準パッケージの一部であると見なされるすべてのクラスをエクスポートします
// src/three.js
var THREE = { rev: 101 }
module.exports = THREE
THREE.Geometry = require('./geometry/Geometry.js')
THREE.BoxGeometry = require('./geometry/BoxGeometry.js')
// ...
注:このファイルはほぼ排他的にrequireステートメントであるため、この例の上部にある依存関係を正確に要求しているわけではありません。
最後に、モジュールシステム(ノード/ブラウザー化、AMD)が使用されているかどうかを検出し、使用されている場合はエクスポートするか、グローバルオブジェクト( window
)に追加するユニバーサルモジュール定義でラップします。
確認してみましょう:
three.js
消費者がbrowserifyを使用して機能を選択できるようにしますこれにはビルドシステムの交換が必要になりますが、新しいものは非常に簡単です。
その他の利点:
@ shi-314少し混乱していると思いますが、 You can structure your code
とYou can build for production
は、アーキテクチャを変更せずにできることですか? three.jsソースまたはthree.jsを使用して構築されたものについて話しているのですか?
commonjs環境での使用を難しくするthree.jsが使用する1つの方法は、 instanceof
です: https :
これは、アプリケーションでは、ソースツリーに同じライブラリの異なるバージョンが含まれることが多いため、instanceofのチェックは同じライブラリの異なるバージョン間では機能しないためです。 commonjsモジュールシステムへの移行の準備として、これらのinstanceofチェックをGeometry.isGeometry(geom)
スタイルのインターフェイスの背後にある機能チェックに置き換えるとよいでしょう。
@kumavis私は
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ラッパーを手動でいじくり回す必要はありません。threejs-vecmath
に重大な変更を加えることができます。 反対に、特定のモジュールでパッチまたはマイナーリリースを作成すると、それらのモジュールを使用するユーザーは自動的に変更を取得できるようになります。npm install threejs-shader-bloom
想像してください)。require()
するだけなので、最終的には異なる「ビルドタイプ」は必要ありません。@mrdoobと他の作者に; NPM / Browserifyの経験があまりない場合は、NPM / Browserifyを使用していくつかの小さなプロジェクトを作成し、その「哲学」を感じ取ってみることをお勧めします。 ThreeJSアーキテクチャとは大きく異なります。 大きなフレームワークではなく、多くの小さなことを奨励し
このアプローチのもう1つの利点は、オープンソースのサードパーティのThree.JSモジュール、特にシェーダー、ジオメトリ、モデルローダーなどのエコシステムが存在する可能性があることです。NPMまたはGithub / Componentを通じて公開され、人々は簡単に参照して使用できます。 現時点では、人々が「ソースを表示」するデモをホストすることで、コンテンツが共有されています。 Three.JSはもっと価値があります!
私がThree.JSで抱えている問題の1つは、コードが現在のバージョンのThree.JSとどれだけ早く互換性がなくなるかということだと思います。 このようなものに切り替えることのもう1つの利点は、Three.JSの_bits_の特定のバージョンを指定できることです。これは非常に強力で便利です。
+1
CommonJS / browserifyアーキテクチャの+1を使用すると、コアがより軽量になり、サードパーティ製であっても拡張機能が適合します。
three.jsを小さなモジュールに断片化することにも多くのコストがかかります。 現在のシステムでは、非常に単純なサードパーティのアドオン(例:jetienneのTHREExモジュール)を使用できます。 JSモジュールシステムがビルドシステムの単なるラッパーである限り、現在のセットアップの単純さについては多くのことが言われています。
ビルドサイズを最小化する別の方法は、ClojureScriptが行うことです。 これらは、GoogleのClosureコンパイラがプログラム全体の分析とデッドコードの除去を実行できるようにするためのいくつかの規則に従います。
シンプルさの評価されていない、そしてしばしば見過ごされている優雅さのための+1
+1
three.jsを小さなモジュールに断片化することにも多くのコストがかかります。 現在のシステムでは、非常に単純なサードパーティのアドオン(例:jetienneのTHREExモジュール)を使用できます。
ここでの考え方は、UMDビルドが非ノード環境に引き続き提供されるということです。 THREExのようなプラグインは、単純な<script>
タグを持つThreeJSに依存するプラグインでも同じように機能します。
トリッキーなことは、CommonJS環境にいる場合、特定のプラグインをどのようにrequire()
するかということです。 たぶんbrowserify-shimが役立つかもしれません。
JSモジュールシステムがビルドシステムの単なるラッパーである限り、現在のセットアップの単純さについては多くのことが言われています。
ThreeJSの現在のプラグイン/拡張システムは、操作するのがかなりひどく、「単純」または簡単にはほど遠いです。 ほとんどのThreeJSプロジェクトは、EffectComposer、FirstPersonControls、モデルローダー、またはexamples
フォルダーに浮かんでいる他の多くのJSファイルの1つなど、何らかの形式のプラグインまたは拡張機能を使用する傾向があります。 現在、これらのプラグインに依存する唯一の方法は次のとおりです。
vendor
フォルダに貼り付けますさて、browserifyを使用すると、次のようなことができると想像してください。
var FirstPersonControls = require('threejs-controls').FirstPersonControls;
//more granular, only requiring necessary files
var FirstPersonControls = require('threejs-controls/lib/FirstPersonControls');
これらのプラグインはrequire('threejs')
と、それらが必要とする可能性のあるその他のもの( GLSLスニペットやテキストの三角測量など)になります。 依存関係/バージョン管理はすべてユーザーに隠されており、手動で保守するgrunt / gulpconcatタスクは必要ありません。
トリッキーなことは、CommonJS環境にいる場合、特定のプラグインをどのようにrequire()するかということです。
CommonJS forTHREE.jsプロジェクトを少し使用しています。 これは少し手動のプロセスであり、他の人のコードのチャンクをモジュールに変換します。作成者や寄稿者によって変換されていないレガシーコードの場合、それを回避する簡単な方法はないと思います。
重要な点は、「標準」のTHREEオブジェクト全体をエクスポートするモジュールがあることです。これは、拡張したいすべてのオブジェクトで必要になる可能性があります。
var THREE = require('three');
THREE.EffectComposer = // ... etc, remembering to include copyright notices :)
これは私にとって非常にうまく機能しました。特にプロジェクトが成長し、独自のシェーダーとジオメトリを独自のモジュールなどに追加し始めたときです。
'threejs-full'または 'threejs-classic' npmパッケージがある限り、これはCommonJS環境で古いThree.jsのものを操作するためのかなり実行可能な方法になりますが、これはかなりニッチだと思います!
+1
断片化されたthreejsモジュールがnpm、プラグインで利用可能になったら、私は信じています
開発者はCommonJSenvに移行するのが大好きです。
2014年6月5日午後9時19分、「CharlotteGore」 [email protected]は次のように書いています。
トリッキーなことは、特定のプラグインをどのようにrequire()するかということです。
CommonJS環境にありますか?CommonJS forTHREE.jsプロジェクトを少し使用しています。 少しです
他の人のコードのチャンクをモジュールに変換する手動プロセスの
レガシーコードではそれを回避する簡単な方法はないと思います
それは作者や寄稿者によって変換されていません。重要な点は、「標準」全体をエクスポートするモジュールがあるということです。
3つのオブジェクト。これは、拡張したいものすべてが必要とする可能性があります。
それ。var THREE = require( 'three');
THREE.EffectComposer = // ...など、著作権表示を含めることを忘れないでください:)これは、特にプロジェクトが成長し、私が成長するにつれて、私にとってはかなりうまくいきました
独自のシェーダーとジオメトリを独自のモジュールなどに追加し始めます。'threejs-full'または 'threejs-classic'npmパッケージがある限り
これは、古いThree.jsのものを操作するためのかなり実行可能な方法になります
CommonJS環境ですが、これはかなりニッチだと思います。—
このメールに直接返信するか、GitHubで表示してください
https://github.com/mrdoob/three.js/issues/4776#issuecomment-45236911 。
また、たとえばglslifyを使用して、シェーダーをモジュール化することもできます。 そうすれば、オンデマンドでシェーダーを生成するExpressミドルウェアを作成するようなことでも簡単になります。
数ヶ月前、 frame.jsをrequire.jsに移動し、このAMDのものがどのように機能するかをようやく理解しました。
しかし、これを「コンパイル」する方法を学ぶ必要があります。 モジュールのリストからthree.min.js
を生成するためのツール/ワークフローは何ですか?
私はgulp -browserifyプラグインを使用したビルドシステムとしてhttp ://travismaynard.com/writing/no-need-to-grunt-take-a-gulp-of-fresh-air:wink:
いくつかの考え:(もちろん、node、npm、browserifyに関する私の限られた経験に基づく)
とは言うものの、このスレッドでの議論に続いて、誰もがbrowserifyについて同じ理解を持っているかどうかはわかりません(browserify、commonjs、requirejs、amd、umdは、同じものである必要はないかもしれませんが、いくらか関連しています)。
さて、私の考えの連鎖を少したどっていただければと思います。
Browserifyが登場するのはここです。 技術的には、ブラウザでrequireJSを使用できます。 ただし、ネットワーク呼び出しをあまり行わずにjsファイルをバンドルしたい(高速なファイルシステムrequire()とは異なります)。 Browserifyが静的分析などの優れた機能を実行して、インポートする必要のあるモジュールを確認し、アプリケーションに最適化されたビルドを作成する場所があります。 (もちろん制限があります。おそらくrequire( 'bla' + variable)を解析できません)node.jsに依存するもののためにエミュレーションレイヤーを必要とする部分を交換することさえできます。 ええ、それは私が今私のブラウザに含めることができるjsビルドを生成します。
これがbrowserifyができることのいくつかですhttps://github.com/substack/node-browserify#usage
これまでのところすべてが素晴らしいように聞こえます...しかし、「browserifyarchitecture」に移行することを検討する価値があると私が考えたいくつかのポイントがあります
したがって、この多様性と便利なモジュールの読み込み(主にnpmエコシステムに乗っている)とカスタマイズされたビルドが素晴らしいものであることがわかった場合は、パラダイムを変更し、コードをリファクタリングし、現在のビルドシステムを変更することをお勧めします。
@mrdoob browserifyに関するいくつかのツールがここにリストされています: https :
three.min.js
に関しては、プロジェクトで縮小されたコードを使用しません。 あなたがすべてであるvar three = require('three')
あなたにproject.js
、次に実行browserify project.js > bundle.js && uglifyjs bundle.js > bundle.min.js
。 注:縮小したコードは<script src="min.js">
発送できます。
私は現在three.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の提案は_巨大な_利点ですが。
しかし、3つをフォークして、すべてを別々のモジュールに入れて、それがどのように機能するかを確認するのは理にかなっているかもしれません。
また、browserifyに大きく基づいているhttp://modules.gl/もチェックアウトして
@mrdoob @ shi-314 gulp-browserifyは、browserifyを直接(つまり、Vinyl-source-stream経由で)使用することを優先してブラックリストに登録されました。
grunt / gulp / etcのようなツールは常に流動的であり、さまざまな意見がたくさんあります。 結局、どちらを選択するか、またはカスタムスクリプトを使用するかどうかは関係ありません。 より重要な質問は、ユーザーがThreeJSをどのように消費するか、そしてどの程度の下位互換性を維持したいかということです。
もう少し考えてみると、フレームワークとそのアーキテクチャを完全にリファクタリングせずにすべてをモジュール化するのは_本当に_難しいと思います。 ここにいくつかの問題があります:
../../../math/Vector2
などがたくさんあります。three-scene
はthree-lights
などから切り離されます。その後、各パッケージを個別にバージョン管理できます。 この種の断片化は、ThreeJSのような大きなフレームワークでは非現実的であり、維持するのが面倒です。require('three/src/math/Vector2')
私のおすすめ? 私たちは前進する2つのことを考えます:
すべてがモジュール化されているのを見たいのですが、ThreeJSにとって現実的なアプローチがわかりません。 たぶん誰かがフォークでいくつかの実験をして、どれほど実行可能かを確認する必要があります。
説明してくれてありがとう!
私が恐れているのは、始めたばかりの人々にとって物事を複雑にしていることです。 彼らにこのbrowserify / modulesのものを学ぶように強制することは良い考えではないかもしれません...
ここで@mrdoobに同意する
リポジトリにプリコンパイルされたUMD( browserify --umd
)が組み込まれているため、既存の開発者のワークフローに変更はありません。
@mrdoob依存関係管理システムの考え方は単純です。 オプションとビルドシステムに関する数十の投稿を読むのは大変かもしれませんが、最終的には現在のシステムは持続可能ではありません。 あるファイルが別のファイルに依存しているときはいつでも、それは参照を見つけるために新しい開発者が実行しなければならないハントアンドサーチです。 browserifyを使用すると、依存関係が明示的になり、ファイルへのパスがあります。
@repsac依存関係システムは、グローバルスコープを回避し、順序の悪夢をため、他の言語のユーザーがThreeにアクセスしやすくする必要があります。 var foo = require('./foo');
は、(大まかに)C#のusing foo;
またはJavaのimport foo;
似ています。
すべてがモジュール化されているのを見たいのですが、ThreeJSにとって現実的なアプローチがわかりません。 たぶん誰かがフォークで実験して、物事がどれほど実行可能かを確認する必要があります
本当にこれが道だと思います。 仕事を終わらせ、それがどのように機能するかを示してください。
そして、APIの消費はかなり
ugly: require('three/src/math/Vector2')
実験として、「はじめに」を3つのドキュメントからこの新しいモジュラーアプローチに変換しました。 コードを小さなモジュールに分割することにかなり厳格でない限り、多くの参照があることを想像できます。
これを行う主な利点は、ここで具体的に参照されているものと、それらが依存しているものだけを含めるため、結果のビルドサイズが完全なThree.jsのサイズのごく一部になることです。
必要なすべての依存関係を参照する(そしてそれらをすべて個別にインストールする)ことは、実際には少しひどいことになるかもしれません。
モバイルデバイスを明示的にターゲットにしている場合、この非常にきめ細かいアプローチは完璧ですが、実際には、通常どおりに機能する3つのAPI全体をエクスポートするパッケージが必要であり、次にすべてのボーナスジオメトリをカプセル化する小さなパッケージが必要になると思います。レンダラー、すべての数学、すべてのマテリアルなど、次に個々のモジュールレベルまで下げて、開発者が自分で決定できるようにします。
そして、はい、ウェブのコーディングは苦痛です。
とにかく、実験を続けて...
依存関係をインストールします。
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>
必要なすべての依存関係を参照する(そしてそれらをすべて個別にインストールする)ことは、実際には少しひどいことになるかもしれません。
Threeがbrowserifyを使用してコードベースを管理するために、エンドユーザーは必ずしもプロジェクトでbrowserifyを使用する必要はありません。 3つは現在のようにグローバルTHREE
として公開できます...ビルドファイルを含めて実行します。
@repsac @mrdoob変更には下位互換性があるため、現在のユーザーは必要がなければ何も変更する必要はありません。 これらの提案は、ThreeJSの広大でモノリシックなコードベースの長期的な保守性と寿命を改善することです。 依存関係やバージョン管理のようなものは、初心者にとっては頭痛の種のように聞こえるかもしれませんが、ThreeJSに加えてツール、フレームワーク、プラグイン、および大規模なWebサイトを開発する人にとっては素晴らしいものです。
つまり、エンドユーザーコードは同じように見える可能性があり、 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の範囲外で使用できるようになります。
require()の混乱は悪い考えであり、悪いトレードオフだと思いますが、ユーザーに2つの異なる種類のthree.jsコードを公開し、1つはファンシーモジュールシステムフレーバーで、もう1つはよりシンプルな(しかしセカンドクラスの)モジュールシステムフレーバー。
@erno要点を見逃したと思いますが、 three.js
は内部的にモジュール構造によって編成されますが、これは現在のセットアップと同じビルドファイルを生成するために使用されます。
主な利点は、 three.js
の開発と保守のエクスペリエンスを向上させることです。
@ kumavis-いいえ@ernoは実際にはそれを見逃していませんthree.js
がrequireを介して使用される場合と、そうでない場合は混乱する可能性があることを彼が指摘していることを理解しました(*)。 たとえば、誰かが3つのソースといくつかのサードパーティの例の両方を見て、すべてがどのように機能するかという違いに遭遇します。
(*)これについては、今日の初めにircで話しました。
それは一種の有効なポイントだと思いますが、最終的にどのように機能するか、モジュールとビルドの使用法に問題があるかどうかはわかりません。 しかし、確かに考える価値があるように思われ、全体的な問題がここで慎重に検討されていることは私には良さそうです。これまでの私の部分からの情報と見解に感謝します。
@antontなるほど。 人々はここでさまざまな異なるアプローチを提案しました。私は主にトップレベルの使用法( THREE
からすべてを引き出す)のドキュメントを提供すると想定していましたが、他の人はこれに従わない例を作成する可能性があります。混乱を招きます。 そして、それは有効な懸念事項です。
言語に少し戸惑っていたと思います。
もう1つは、より単純な(ただし、2番目のクラスの)モジュールシステムフレーバーです。
これはビルドファイルを参照しているだけですよね?
私の理解では、そうです。 他に何を想像することはできませんが、何かが欠けている可能性があります。
antont、kumavis:ここでの提案は、require()スタイルのコードをエンドユーザーにも公開することについて話しました。たとえば、を参照してください。 mattdeslの最新のコメント。
「モジュラービルドを探している、またはThreeJS上で長期的なソリューションを開発しようとしている(つまり、バージョン/依存関係管理を利用する)意欲的な開発者向け[...]」
より最適化されたビルドを作成する1つの方法は、実際には、依存関係を自動的に把握し、必要なモジュールを解約するスクリプトを作成することです。
現在、bower&browserifyはrequireを使用していませんが、解決策はこれだけではありません。 それを行う既製のオープンソースプロジェクトが他にあるかどうかはわかりませんが(おそらくng-dependenciesのように)、その前にそのようなツールを作成したことがあり、これらの問題を解決する他のアプローチがあると思います。
グーグルのクロージャーコンパイラはそのようなツールかもしれませんか?
ユーザー側では、これは何らかの助けになるでしょうか?
http://marcinwieprzkowicz.github.io/three.js-builder/
それはかなり興味深い@erichlof :) @ marcinwieprzkowiczがこれを手作業で生成したのだろうか... https://github.com/marcinwieprzkowicz/three.js-builder/blob/gh-pages/threejs-src/r66/modules.json
commonjs環境での使用を難しくするthree.jsが使用する1つのプラクティスは、instanceofの使用です: https :
これは、アプリケーションでは、ソースツリーに同じライブラリの異なるバージョンが含まれることが多いため、instanceofのチェックは同じライブラリの異なるバージョン間では機能しないためです。 commonjsモジュールシステムへの移行の準備として、これらのinstanceofチェックをGeometry.isGeometry(geom)スタイルのインターフェイスの背後にある機能チェックに置き換えるとよいでしょう。
git / three.js / src内:
grep -r instanceof . | wc -l
164
git / three.js / examples:
grep -r instanceof . | wc -l
216
したがって、three.jsでは合計380回のinstanceof
があります。 代替として最適な実装は何でしょうか?
最近、それらのほとんどを置き換えるために使用できるtype
プロパティを追加しました。
最近、それらのほとんどを置き換えるために使用できるtypeプロパティを追加しました。
良い! PRをご用意いたします。
これが別の人気のある大規模なJSライブラリでどのように処理されるかの例については、 https://github.com/facebook/reactを参照して
require
固有の依存関係のみを宣言できます。 適切な依存関係管理の利点は十分に文書化されています。私はいくつかの研究をしました...
昨日、ファイル間の依存関係を宣言するためにCommonJS require()
ステートメントを使用するようにThree.jsソースコードを変換する(かなりばかげた)スクリプトを一緒にハッキングしまし
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(など)を複数のモジュールに分割するなど、いくつかの主要なリファクタリングが必要になります(atmファイルの長さは6000行を超えます)。
THREE.ShaderChunk
にコンパイルされ、実行時にTHREE.ShaderLib
THREE.ShaderChunk
にコンパイルされます( THREE.ShaderChunk
の配列を結合します)。これは、browserifyだけで行うのはかなり難しいです。 同じことをするbrowserify変換が必要になると思います。React.jsは、 commonerを使用して、ファイルパスでモジュールを参照せずにモジュールを検索します。 たぶん、同じことをして、 require
GLSLファイルをJS構文に変換できるカスタムルールを定義することもできます。
@rasteiner https://github.com/stackgl/glslifyについて学ぶのはとてもうれしいかもしれません、それは成長しているhttp://stack.glファミリーから来ています
私は過去数か月でモジュールと「unixy」アプローチについてかなりの経験を積んでいますが、今では遅すぎると思います。モジュール性またはnpmモジュール用にthreejsをリファクタリングすることは非現実的な目標です。
モジュール性/再利用性の問題に取り組むために私が現在行っていることは次のとおりです。
私の新しいプロジェクトは、立ち上げて実行するためだけにnpmで「3」を使用する傾向があります。 ThreeJSがリリース番号と一致するバージョンタグを使用してビルドをnpmに公式に公開した場合、それはかなり素晴らしいことです。
PS:ワークフローに再利用可能/モジュラーシェーダーを導入することに関心のある方へ:
https://gist.github.com/mattdesl/b04c90306ee0d2a412ab
私のiPhoneから送信された
2014年11月20日には、7:42で、アーロン[email protected]は書きました:
@rasteiner https://github.com/stackgl/glslifyについて学ぶのはとてもうれしいかもしれません、それは成長しているhttp://stack.glファミリーから来ています
—
このメールに直接返信するか、GitHubで表示してください。
これがbrowserifyでThree.jsを使用する方法を探していて、このスレッドにつまずく可能性がある他の人を助ける場合、私が自分で設定した方法は、 browserify-shimを使用することです。
_「時々a)グローバルを介してグローバル変数を公開する」_のREADMEセクションに続いて、Three.js用の個別のスクリプトタグを含め、グローバルTHREE変数を公開するように構成しました。
そして、私が自分で解決しなければならなかったのは、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では、バイトを変更する場合でも、スクリプト全体を再構築する必要があります。 私はかつてbrowserifyを使用してTHREE.jsを必要とするプロジェクトをパックしましたが、変更を加えるたびにバウンドルを構築してlivereloadをブロックするのに2秒以上かかります。 それはあまりにもイライラします。
通常、 livereloadを使用した開発中に
watchifyは私には機能しません。 ファイルを変更して保存すると、watchifyとbeefyのlivereloadが古い/キャッシュされたバージョンを提供します。 なぜこれが起こるのか私にはわかりません。 ありがたいことに、browserifyはすでにかなりうまく機能しています。
@ChiChouは--noparse=three
を渡してbrowserifyします。 これにより、browserifyバンドルのステップが私のマシンで1000ミリ秒から500ミリ秒になります。これは、即座にフィードバックを感じるのに十分な程度です。
@ rasteinerthree.jsの相互依存関係についての非公式な調査に改めて感謝します。 その膨大なdepsのリストは見苦しいコードですが、実際にはその醜さはそのまま存在し、目に見えません。 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 )
タイプにそれ自体の処理方法を決定させます。 これにより、ライブラリの利用者は、私たちが考えもしなかった新しいテクスチャタイプを使用することもできます。 この構造は相互依存性を減らすはずです。
browserifyアーキテクチャへの移行は間違いなく進むべき道だと思います。 UMDビルドにより、THREE.jsの使用が容易になります。 また、WebGLRendererを複数のファイルに分割することもできます。これは、現在、かなりモノリシックで恐ろしいように見えるためです。
私は現在ここに移動することに取り組んでいるブランチを開始しました: https :
ご意見をお聞かせください。
これが@coballastの変更点です。
browserifyify.js
ファイルで自動変換アプローチを採用しているようです。これが正しい方法だと思います。
私たち全員がまだあまり議論していないことの1つは、この大きくて絶えず変化するライブラリをbrowserifyに移行する最善の方法です。 変更を加えてからPRを開くことはできますが、すぐに古くなります。 それが自動化されたアプローチの魅力です。
できれば:
browserifyify.js
)...次に、これをプッシュボタン変換に変換できます。これは、予見可能な将来にわたって機能します。 その単純さは、イデオロギーの議論が勝ったときに、そのような大規模なプロジェクトへの基本的なアーキテクチャのシフトのこの夢のような概念を達成することを可能にします。
そのために/Three.jsへの変更を削除します。
注:元に戻すだけでなく、新しいブランチまたは強制プッシュを使用して、ブランチの履歴からこれらの変更を削除します
@coballast変換ユーティリティがthree.js
フォークではなく、 three.js
開発ディレクトリを指す外部ユーティリティであり、ソースを変換する方が理にかなっているのではないかと思います。ファイルを作成し、ビルドスクリプトを追加して、テストを実行します。
@kumavissrcディレクトリをそのままにして
コードベース全体で一貫したスタイルを自動的にチェックして適用する静的分析を作成する興味深い機会もここにあります。
@coballastは素晴らしいです
escodegenなど、自動コード書き換え用のツールは豊富にあります。 コメントなどを維持していることを確認する必要があります。
threejs-conversion-utilityリポジトリを開始したいですか?
と言った@coballastは、このユーティリティの鋭い焦点を維持することが重要です
@kumavis完了したと考えてください。 私は本当にこれを実現したいと思っています。 これは私が現在取り組んでいる2つのプロジェクトのうちの1つにすぎません。
@kumavis @mrdoobここでの議論のいくつかは、おそらくnpmを介してインストールし、browserifyでコンパイルできる複数の個別のモジュールに3つを分割するという考えに関するもののようです。 私はその考えに完全に反対しているわけではありませんが、それは別の問題であるべきだと思います。 この時点で私が提唱しているのは、browserifyを使用してTHREEのコードベースを内部で管理することだけです。 それを移動して、ユーザーにとっていつもと同じように機能させてから、何が理にかなっているのかを評価します。
そのユーティリティの出力が何であるかを知りたいと思います^^
@coballastは、この時点で空の場合でも、追跡できるレポをリンクします。 そこから構築できます。
https://github.com/coballast/threejs-browserify-conversion-utility
コードはめちゃくちゃです、すぐにクリーンアップされます。
さあ行こう! :ロケット:
これで、browserify srcを生成し、問題なくビルドできる状態のユーティリティができました。 これを自分で行う方法の説明でリポジトリを更新します。 この時点では、例は機能しません。 それを修正するために対処する必要があるいくつかの問題があります。 誰かが袖をまくり上げて手伝いたい場合は、レポに追加します。
@coballastええ、TODOとして問題を提出してください。そうすれば、私や他の人ができる限り参加します。
深刻な問題が発生しています。 #6241を参照
これが機能するために何が起こる必要があるかについての私の分析は次のとおりです: https :
browserifyは、その設計により、少なくともトランスポートの冗長性(概念的)です。 これにより、使用コストが高くなり(データプランは誰か?)、遅くなります。
これに対する簡単な解決策は、1つではなく2つのクライアントファイルを必要とするライブラリコードからドキュメントを分離することです。 これは、クライアント側のjsの一般的な方法です。
最初にbrowserifyに欠陥があり、それ自体を修正する必要がある場合、threejsのようなものはもちろん、何かを改善することを検討する必要がある理由がほとんどわかりません。
@spaesaniとにかく、threejsのデータをダウンロードする必要があるためです。 threejsをより小さなモジュールに分割し、自動ビルドシステムに単一のアプリに必要なものを選択させると、実際には、そこにあるほとんどのthreejsアプリはより軽量になります。
何らかの理由で「ドキュメントをライブラリコードから」分離したい場合でも、これを実行して、現在のようにビルド済みバージョンを使用できます。 --standaloneフラグbrowserifyで構築されたアプリを個別のモジュールに分割することもできます。
Browserifyは、ブラウザーで実績のあるモジュール定義API(CommonJS)を使用する方法にすぎません。 これにより、threejsプラグインの開発が大幅に簡素化され、コードの明快さが向上し、生産性が向上します。これにより、バージョン管理システムを通じて整合性を維持しながら、コードが本質的により多くの人々によって維持される、より大きなエコシステム(npm)に統合できるようになります( stackglファミリー)、そして彼らがそれを望まないのであれば、それは人々をCommonJSに強制することさえしません。
もちろん欠点もありますが、それはあなたが言及したものではありません。
three.jsとthree.min.jsをキャッシュして、プロキシ、一般的なモバイルソリューション、またはキャッシングブラウザーによるトランスポート(データ)を節約できます。
threejsコードを選択してドキュメント固有のコードと集約した瞬間、キャッシュは実行できません。
browserifyで許可されている場合
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 It(browserify)は人間のために物事を改善します。 私自身の心理的な幸福と幸福は、マシンがどれだけ簡単にものをロードして実行できるかよりも重要です。
多くのモバイルネットワークの負荷の問題は、http / 2のようなものによっていくらか改善されるでしょう。 このような問題は、抽象化スタックの下位にあるレイヤーを変更することで最もよく解決されます。 パフォーマンスの問題により、モジュール性/関心の分離などのソフトウェアエンジニアリングのベストプラクティスに従うことが妨げられることはありません。
私のチームが最近jspmを使い始めたので、この問題を見つけました。 threejsをインポートすることができます(これはメインファイルがブラウザ化されているためだと思います)。 主にjspmのビルド機能(すべての依存関係を1つのファイルにバンドルしますが、使用されている依存関係のみを取得する)のために、誰かがthreejsをes6モジュールにしたかどうかを調べていました。
mrdoobがthreejsのサイズを100kb未満に保つのは素晴らしいことですが、私のプロジェクトのほとんどはコードベースをあまり使用していないことがわかりました(ほとんどのように感じますが、それを理解しようとはしていません)。 CubeCamera、OrthographicCamera、CanvasRenderer、さまざまなライト、ローダー、カーブ、ジオメトリ、ヘルパーなど。さらに、ほとんどのプロジェクトにいくつかのサンプルスクリプトが含まれていることがわかりました。
私の望みは、これらすべてのモジュール(通常はthreejsにバンドルされているモジュールと例のモジュール)を1つの場所に配置し、必要なモジュールをインポートするだけで、プロジェクトをバンドルすると結果が得られることです。元々含まれていなかった多くの部分が含まれているにもかかわらず、元のthreejsよりもはるかに小さいファイル内。
また、threejsがbrowserifyモジュールを使用して構築された場合、ファイルサイズのオーバーヘッドがわずかに追加されますが(ただし、r70の現在の403kbとは比較になりません)、コードからグローバルTHREE変数の使用が削除されることも追加したいと思いました。 THREE.Geometryのような変数をクロージャによって縮小できるようにします。
私は、3つのオブジェクトを取り除くためにfind-replaceを実行し(そのため、そのすべての子が名前空間を汚染した)、ファイル全体をIIFEでラップし、すべてをgoogleクロージャーで実行する簡単なテストを行いました。 結果のファイル(gzip圧縮されていない)は、777kbから238kbになりました。
結果はさまざまですが、これが発生する可能性があることを確認することは間違いなく価値があると思います。
教えてくれてありがとう-そこには多くの良い点があり、私たちにも馴染みがあります。 また、1つのプロジェクトで多くのレンダラーを使用することはありませんが、例から一種のlibを実行します。
縮小化については気づいていませんでした-それはかなり大きな違いです。
es6モジュールは確かに有望であるように思われました-AMD / CommonJS /そのようなモジュールパターンとlibの使用法からもそこにパスがあると聞いて良かったです。
@colinbrowserifyの方法についてフォローしているのかわからない
あなたの心理的な幸せを助けます。
それはドキュメントにありますか?
browserifyはキャリアキャッシュカウです...
2015年3月31日(火曜日) 、10:11 PM -04:コリン・バラストから00 notifications@github.com :
@spaesani It(browserify)は人間のために物事を改善します。 私自身の心理的な幸福は、マシンがどれだけ簡単にものをロードして実行できるかよりも重要です。
多くのモバイルネットワークの負荷の問題は、http / 2のようなものによっていくらか改善されるでしょう。 このような問題は、抽象化スタックの下位にあるレイヤーを変更することで最もよく解決されます。 パフォーマンスの問題により、モジュール性/関心の分離などのソフトウェアエンジニアリングのベストプラクティスに従うことが妨げられることはありません。
—
このメールに直接返信するか、GitHubで表示してください。
さて、browserifyがrequireステートメントなしで依存関係を自動的に決定する場合...ちょっと待ってください...
@spaesani私は実際には明示的な依存関係を好みます-コードがすべてどのように組み合わされているかを理解するのに役立ちます。
browserifyはキャリアキャッシュカウです...
@spaesanibrowserifyのオーバーヘッドは
ステータスアップデート:
私はいくつかのブラウザ化されたコードを備えたブランチを持っています:
https://github.com/coballast/three.js/tree/browserify
これは非常に進行中の作業であることを覚えておいてください。 このコードは自動生成されたものであり、結果としてしばらくの間かなりひどいものに見えるでしょう。 私はまだいくつかのビルドの問題を修正しようとしています。 修正できると思われる場合は、coballast / threejs-browserify-conversion-utility#10を参照してください。 しばらくの間構築されていましたが、現在は構築されていません。
@kumavisと私は、いくつかのランタイムの問題に対処することに取り組んでいます(そしてソフトウェアアーキテクチャも改善しています)。 私はそれをどこかで上で述べたと思います。
長い返信でごめんなさい。 TLDR:jspm / es6は実行されますが、いくつかの奇妙な点があります。1)オブジェクトを定義する前にオブジェクトをエクスポートする。 2)単一のクラスをエクスポートするだけでなく、単一のクラスを含むオブジェクトをエクスポートする。 3)循環依存関係を使用するIIFE。 4)ファイル構造。
私はjspmであなたのbrowserifiedブランチで遊んで(上記の@spinchristopherは私です)、いくつかのメモがありますが、最初に:そのフォークで問題を開くのは良いことではないので、このスレッドはそれらでいっぱいではなく、そうではありません一緒にごちゃ混ぜ?
実行しても、実際には正しい結果を出力しません。 (はじめに簡単なデモを使用)。 キャンバスを作成して黒で塗りつぶします(クリアカラーを透明に設定しない限り)が、実際には立方体をレンダリングしていません。 ただし、これはまだプロセスの非常に早い段階であるため、現時点では機能するとは思っていません。
私は3つの主要な問題に遭遇しました:
一つ。 これは最も厄介なものでしたが、まったく機能しないはずなので、この特定のエラーでコンパイルするためにどのように取得するのか正直にわかりません。 多くのファイルは次のように始まります(関数定義は時間に合わせて引き上げられ、最初に表示されても、基本的にmodule.exports行の前に実行されるためこれは問題ありません):
module.exports.Foo = Foo;
function Foo() {}
問題はこのような多くのファイルにあります(私が最初に見たのはmath / Math.jsでした)。 オブジェクトの初期化は引き上げられますが(これが未定義のエラーがない理由です)、定義はそのままです(したがって、エクスポートは未定義です)。
module.exports.Foo = Foo;
var Foo = {};
ここで見つけた唯一の修正は、エクスポート行を最後に移動するか、次のように書き直すことです(推奨)。
var Foo = module.exports.Foo = {};
二。 エクスポートされたデータ。 モジュール化されたファイルを扱う場合、標準では、各ファイルが単一のオブジェクトをエクスポートします。 ファイルのほとんどは(一部の輸出よりも)、それらが単一のコンストラクタをエクスポートしないこの方法ですが、彼らはそのコンストラクタを含むオブジェクトをエクスポートする(すなわち: module.exports.Foo = Foo;
ではなくmodule.exports = Foo;
後者。これは、すべてのbrowserifyの例が機能する方法です)。 したがって、requiresを使用する場合は、レベルをさらに深くする必要があります( var Vector3 = require('../math/Vector3').Vector3;
)。 不要であることに加えて、es6にインポートするときにこれを行う方法はありません。 ( import Vector3 from '../math/Vector3'; var vector = new Vector3.Vector3();
)。 es6で特定のエクスポートを取得する方法はありませんが、ブラウザー化されたモジュールを使用する場合は適用され、同じ冗長性( import { Vector3 } from '../math/Vector3';
)があります。 他のオブジェクトを単に収集するファイルがいくつかありますが(明らかにThree.jsです)、これらは最小限に抑える必要があり、実際にはビルドプロセスにのみ使用する必要があり、本番環境で多くのものを取得する方法としては使用しないでください。 。
三。 これは循環依存関係と関係があります。 System.js(jspmで使用されるモジュールローダー)は循環依存関係を問題なく処理できますが、1つの問題があります。 多くの場所で、コードは次のようなものを読み取ります。 問題は、Vector3が依存関係として渡されたにもかかわらず、現時点では完全にロードされておらず(Vector3にもこのファイルが含まれているため、それぞれが解決されるまで解決できない)、作成できないことです。 非常に悪い修正(以下に表示)を追加しましたが、これがどのように修正されるかはわかりません。 これはアーキテクチャ上の問題であり、簡単な解決策がないようです。 それは何度も起こります。 関数が呼び出されるたびに新しいVector3が作成されないようにするための最適化のようです。 Vector3を最適化しても修正できない重大なパフォーマンスの低下が実際にある場合は、Vector3に関数を追加して、後でリリースされる未使用のvector3を返すことができますか?
Foo.prototype.bar = function() {
var vector = new Vector3();
return function() {
// some data which reuses vector repeatedly.
};
}();
修正:
Foo.prototype.bar = function() {
var vector;
return function() {
if(!vector) vector = new Vector3();
// some data which reuses vector repeatedly.
};
}();
最後に、ファイルの編成について少し追加したいと思います。 これは明らかに、現在のセットが適切に構築された後に取り組むべきことですが、私は今それを取り上げたかったのです。 現在のファイル構造は機能しますが、その一部はかなり奇妙で、さらに厄介です。 主要なグループ(カメラ、素材、ジオメトリなど)はうまく機能しているようですが、以下に示すように、いくつか変更を加えます。 また、ThreeGlobalsのグローバルをそれぞれグローバルであるものに移動します。 IE:FrontSide、BackSide、DoubleSideはすべてMaterialに属しています(NoShading、FlatShading、SmoothShadingとともに。実際、それらのほとんどは...)。
私の主な混乱は、コアとエクストラにありました。 core / Geometry.jsは、Materialがmaterialsフォルダーにあるのと同じように、geometriesフォルダーにある必要があります。 しかし、geometriesフォルダーはなく、エクストラにあります。 ちなみに、エクストラにもコアとジオメトリがありますが、ベースジオメトリはこのフォルダにありません。 ヘルパーのこの大規模なコレクションがありますが、各ヘルパーはそれが助けているものと一緒にいるべきではありませんか? ビルドプロセスは、必要なファイルのみを取得するように簡単に構成できるため、重要でないファイルを別の場所に配置する言い訳はありません。
現在、コードにimport BoxGeometry from 'threejs/extras/geometries/BoxGeometry';
とvar geometry = new BoxGeometry.BoxGeometry( 1, 1, 1 );
という行があります。 `newTHREE.BoxGeometry()` ``の使用に慣れているため、ファイルを見つけるのにかなりの時間がかかりました。 モジュール式で使用する場合、ファイルの場所は関数の署名のようなものと同じくらい重要です。
ファイル構造に加える一般的な変更。 これらは多くの場所に当てはまりますが、ここでは例を示しています。 (注として、私は常に、エクスポートする単一のクラスにちなんでファイルに名前を付け、ファイルを同じ名前のフォルダーに配置するモデルを好みました。直接の子孫は通常、そのフォルダーに移動しますが、ここでもフォルダーに移動します。同じ名前ですが、このパターンが気に入らない場合は、以下の同じ構造が適用され、余分なレベルが削除されます。また、任意のファイルローダーを簡単に変更できます[実際には、フックは通常直接提供されます]。階層化を自動化し、requireステートメントを単純化します]。)(必要に応じて下線を付けた、すべて小文字のファイルも優先します。)
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
また、数学の名前をutilsに変更する可能性があります(各カテゴリには、上記のジオメトリのようにutilsも含まれる場合があります)。これにより、数学(コアからのものの多く)以上のものを保持できます。
@HMUDesign @spinchristopher素晴らしい分析に感謝します! 将来的には、これらの種類の問題をcoballast / threejs-browserify-conversion-utilityリポジトリに配置するのが最善です。
わかりました。コメントを正しく読みましょう。
上記のレポへのリンクをどういうわけか見逃しました。 私は自分の問題を喜んで動かします
明日そのレポに、必要に応じて分割します(少なくとも私はそれに気づきました
それのいくつかはすでにそこにあります)
2015年4月9日午前0時9分、「kumavis」 notifications@github.comは次のように書いています。
@HMUDesign https://github.com/HMUDesign @spinchristopher
https://github.com/spinchristopherすばらしい分析に感謝します! 一番
この種の問題を
将来的にはcoballast / threejs-browserify-conversion-utilityリポジトリ。わかりました。コメントを正しく読みましょう。
—
このメールに直接返信するか、GitHubで表示してください
https://github.com/mrdoob/three.js/issues/4776#issuecomment-91132413 。
はい、私は自分のutilタイプライブラリに対してそれを行います(* Utilファイルは
デフォルトのエクスポートがない場合のみですが、時々追加します
デフォルトに加えてエキスパート)、ただし、この構文は次の場合にのみ機能します
複数の名前付き変数をエクスポートします。 一般的なjsモジュールのローダーは扱います
modules.exportsをデフォルトのエクスポートとして使用します。これは、で分解することはできません。
インポート=(
2015年4月9日午前0時12分、「kumavis」 notifications@github.comは次のように書いています。
es6では、次の方法でエクスポートオブジェクトからプロパティをインポートできます。
破壊する。import {Vector3} from '../ math / Vector3';
そうは言っても、モジュールごとに1つのエクスポートが優先されることに同意します。
—
このメールに直接返信するか、GitHubで表示してください
https://github.com/mrdoob/three.js/issues/4776#issuecomment-91132982 。
@HMUDesignは、あなたのエネルギーと分析に改めて感謝します。ここでは、気軽に参加してください。 https://github.com/coballast/threejs-browserify-conversion-utility/issues/17
browserifyの場合は+1。
また、glslifyを使用してシェーダーを個別のファイルに移動する場合は+1。
また、クラスやモジュールなど、いくつかのES6機能を採用するための+1。 新しいビルドスタックにより、必要に応じてES5にコンパイルして戻すことができます。 例を参照してください。
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作業中は、es6モジュールを使用し、babeljsを使用してすべてをコンパイルできます。
@coballast browserify
ブランチから分岐して、このようなことのいくつかを実現することに興味があります
@lmcd私は気にしないだろう。 es5のものをes6に自動的に移動する自動ツールを開発します。 そこには膨大な量のes5コードがあり、それを手作業で移動するという労働要件は天文学的なものであるため、それは理にかなっています。
@coballast 5to6
パスの実行についてもっと考えていました: https :
@lmcd oo nice find
しかし、tbh、three.jsを最初から書き直す方が簡単なようです:P
@lmcdあなたがそれを見つけてくれてとてもうれしいです。 それは私がやむを得ずやろうとしていたことの一つでしたが、明らかに面白くなかったように聞こえました。
@mrdoobこの問題についてのあなたの現在の考えは何ですか?
@anvaka現在、私はWebGLRenderer
リファクタリングに焦点を合わせています。 私はこれ以上の精神的な帯域幅を持っていません😅
私は最近、ここでもすでに言及したbabelポリフィルでes6モジュールをうまく使用しているいくつかのプロジェクトに遭遇しました。 それが何であったかを今でも思い出せず、見つけることもできませんでしたが、とにかく私には良さそうに見えました。
また、es6は現在、標準の面で終了しているようです。「ついに、ECMA-262 Edition 6が正式に承認され、2015年6月17日に標準として公開されました」とhttps://developer.mozilla.org/en-US/docsは述べてい
モジュール仕様のツールと安定性に関しては、状況はその面で良好に見えることに注意してください。
私は最近、ここでもすでに言及したbabelポリフィルでes6モジュールをうまく使用しているいくつかのプロジェクトに遭遇しました。 それが何であったかを今でも思い出せず、見つけることもできませんでしたが、とにかく私には良さそうに見えました。
また、47kbの追加のjsであり、含まれているjavascriptを読み取ってブラウザーでes5に変換するため、起動時間には適していません。
three.jsを使用する人が自分のコードでes6を使用することを妨げるものは何もありません。 ただし、ライブラリで使用すると、ブラウザの互換性とパフォーマンスの問題が全面的に発生します。
ああ-情報をありがとう、ここで修正された立っています。 ビルドプロセスで機能するbrowserifyなどは今でも優れていると思います。
ああ-情報をありがとう、ここで修正された立っています。 ビルドプロセスで機能するbrowserifyなどは今でも優れていると思います。
es6の主な問題の1つは、es5で構文が大幅に変更されていることです。 たとえば、太い矢印=>は無効なes5であり、javascriptパーサーが失敗し、コードをコンパイルしようとしてベイルします。 うまくいけば、誰かがこれを回避する方法を思い付くでしょうが、彼らはまだしていません。
私は実際にモジュールシステムやインポートステートメントなどだけを考えていました。
また、47kbの追加のjsであり、含まれているjavascriptを読み取ってブラウザーでes5に変換するため、起動時間には適していません。
たとえば、太い矢印=>は無効なes5であり、javascriptパーサーが失敗し、コードをコンパイルしようとしてベイルします。
es6コードは、ランタイムペナルティなしで_build_中にes5にトランスパイルできます。 ビルドパイプラインにbabelステップを追加するだけです。
たとえば、矢印関数は、ポリフィルや実行時のペナルティなしで、ビルド中にes5にトランスパイルできます。 Babelはこのes6スニペットをトランスパイルします
function MyObj() {
this.step = 1;
this.increment = function ( arr ) {
return arr.map( v => v + this.step );
}
}
このポータブルバージョンに:
function MyObj() {
this.step = 1;
this.increment = function (arr) {
var _this = this;
return arr.map(function (v) {
return v + _this.step;
});
};
}
es6クラスのような他の機能は、小さなポリフィルを生成します(babel repl http://babeljs.io/repl/で確認できます)。
@mrdoobは理解しました。 three.jsをnpmでホストされている小さなモジュールに分割するというアイデアを支持しますか?
メインのthree.jsリポジトリは変更されません。コンシューマーは何も構築する必要がありません。 より経験豊富なユーザーは、three.jsの必要なビットを選択することができます。
いいですね。 詳細はわかりませんが。
es6コードは、ランタイムペナルティなしでビルド中にes5にトランスパイルできます。 ビルドパイプラインにbabelステップを追加するだけです。
たとえば、矢印関数は、ポリフィルや実行時のペナルティなしで、ビルド中にes5にトランスパイルできます。 Babelはこのes6スニペットをトランスパイルします
ES6トランスパイルには、実行時の重大なペナルティが伴います。http :
modules / npm / browserfyなどはおそらく良い考えです
ES6モジュールを使用した適切なモジュール化で+1
正常なモジュールシステム(commonjs、amd、es6)を使用した適切なモジュール化で+1
commonjsとamdは、トランスパイルを必要としないb / cの推奨される選択肢だと思います。
ただし、ビルドステップが必要です。これは、
トランスパイルステップ。
ES6を使用すると、言語の次のバージョンであることに加えて、
必要に応じて次の機能を使用しますが、既存のネイティブコードを壊さないでください。
コードベースをすでに存在するシステムに再変換することは本当に賢明ですか?
最新ではありませんか?
2015年7月20日12:05 PM、「kumavis」 notifications@github.comは次のように書いています。
正常なモジュールシステム(commonjs、amd、
es6)
commonjsとamdが推奨される選択肢だと思います。
トランスパイルが必要—
このメールに直接返信するか、GitHubで表示してください
https://github.com/mrdoob/three.js/issues/4776#issuecomment-122990605 。
ただし、ビルドステップが必要です。これは、
トランスパイルステップ。
構築とトランスパイルは、それらがもたらす複雑さの点で同等ではありません。
コードベースをすでに存在するシステムに再変換することは本当に賢明ですか?
最新ではありませんか?
commonjsはシンプルで、うまく機能します。 '最新' === 'より良い'という概念で販売されていません。
ES6 [...]を使用すると、必要に応じて次の機能を使用できるようになります
したがって、これは検討する価値があります。 es6機能が必要ですか? es6のトランスパイルを開始すると、人々はes6のPRを開始します。 @benaadamsが示唆しているように、es6機能の使用には直感的でないパフォーマンスへの影響があります。
さらに、「モジュールシステム」と「es6機能」の問題を混同する必要はありません。 es6をトランスパイルしてcommonjsを使用できます。 それらを個別に紹介することができます。
browserify / commonjsの+ 1-必要に応じて従来の方法でライブラリを使用できるようにbrowserifyでコンパイルするのは簡単です-これがUMDの目的であり、AMDが必要とするもの(require.jsなど)を許可します。 CommonJSには、実行している環境に応じて(node + browserifyなど)およびグローバルなウィンドウ(スクリプトタグ用)が必要です。
PIXI.jsは、browserifyを使用してモジュラーアーキテクチャに移行したばかりで、ライブラリは非常によく似た方法でセットアップされました。すべてがグローバルPIXIオブジェクトにアタッチされています。 それらのセットアップは、 @ kumavisが2番目の投稿で説明しているものと非常によく似ています。
browserifyもcommonjsも、3Dエンジンの特定のニーズに対応していません。これは、それらが使用できないことを意味するわけではありませんが、より大きなパズルの1つのピースと見なす必要があります。
コンポーネントは、インスタンスのプロパティに関するメタ情報をエクスポートする必要があるため、任意のオブジェクトと共有メモリデータ接続用のローダーが存在する可能性があります。 このようなアーキテクチャでは、最初の使用時にコア外のコンポーネントコードもロードするのが常識です。 #6464と#6557でこれらのトピックについてブレインストーミングを行っています。
+1
+1
ハイブリッドソリューションとして、要件をコメントとして追加することも可能です。 私はbrowserfyがすでに多くのエコシステムにあることを知っていますが、何も変更する必要がないので、これを実装するための高速なバリアントとしてここに残したかっただけです:)。 すべてのファイルの上にコメントを追加する必要があります。
開発者は、 @requires
情報とgulpプラグインを使用して独自のmin.jsファイルを簡単に作成できます。
こんにちは、私は最近、独自の依存関係を持つ任意のリソースをクリーンで構造化された方法でロードするという同様のニーズがあり、すべてのタイプのリソースに対してrequire.jsプラグインを作成するソリューションを思いつきました。 このようにして、require.jsの依存関係を解決して、リソースの適切なダウンロードとキャッシュを処理します。同時に、このアプローチにより、さまざまなプロジェクトで使用できる再利用可能なリソース「バンドル」が作成されます。
興味がある場合は、ここでプロジェクトを見つけることができます: https :
(このライブラリを使用した例はまもなく利用可能になります)
将来的には、require.jsオプティマイザーがリソースをさらにコンパクトな形式にコンパイルできるようにするために、これらのプラグインに最適化フェーズを含めることを計画しています。
この会話https://twitter.com/defunctzombie/status/682279526454329344を見ると、es6モジュールが近い将来実装される予定はないようです。 覚えておくべきこと。
commonjsモジュールとbrowserifyを使用していくつかのプロトタイプを作成しました。
私の最終的なブラウザ化されたバンドルには、 src
フォルダのすべてのファイルが含まれ、結果として962K
ファイルサイズになります(元のブラウザ化されていないバージョン885K
と比較して)。
cloth
例のターゲットビルドは次のとおりです。
580K
(〜44%小さい)431K
(〜8%小さい)バンドルサイズの内訳は次のとおりです: //output.jsbin.com/yogoxawozu。 レンダラーはバンドルの40%を取得し、その10%はシェーダーライブラリによって取得されます。
バンドルのサイズを次の方法で減らすことができると思います。
instance of
チェックの削除-モジュールが使用されていない場合でも、モジュールを明示的に参照する必要があります。 一部のクラスにはすでにtype
があります。これは、ライブラリ全体で使用できます。glslify
は数回持ち込まれましたが、間違いなく役に立ちます。 理想的には、シェーダーを必要とする各コンポーネントは、シェーダーに明示的に依存する必要があります。結果を確認し、コードを確認できます。
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
es6モジュールは近い将来実装される予定ではないようです。 覚えておくべきこと。
それは本当ですが、CommonJSモジュールのサポートはブラウザに実装されないことを理解することも重要です。そのため、どちらを選択するかを選択します。
D3のようなライブラリはES6モジュールを採用しています。これは、CommonJSモジュールが実行できるすべてのことをすでに実行できるため(Three.jsのようなライブラリでは実際には問題にならないNode.jsでネイティブに実行する場合を除く)、ビルドが小さくなります。
https://github.com/rollup/three-jsnextでいくつかの実験を行いましたが、本番環境では準備ができていませんが(例の移植などにもう少し時間をかける必要があります!)、生成されるUMDビルドは実際には_小さい_です。現在のビルドより。
es6モジュールと他のシステムに関する注記に同意します。 かどうか
それらはes標準ではなく、コミュニティ標準です。 そして彼らは
ノードで「ネイティブに」実行することはできません。Babelフックを使用してネイティブに見える可能性があります。
すぐにあなたのリポジトリをフォローアップします。
また、それが小さいという事実は、私が以前に育てたものでした
この会話。 「THREE.Geometry」は「geometry」になります。
たとえば、「a」に縮小されます。
また、チェックのインスタンスに対する解決策は、それらをすべて削除することです。
一緒。 1つのモジュールは、何に応じて異なる方法で物乞いをするべきではありません
それは与えられましたが、必要に応じて提供されたものを延期しました
やること。 その場合、インスタンスまたはタイプのチェックはありません。
2016年1月1日午後8時23分、「RichHarris」 notifications@github.comは次のように書いています。
es6モジュールが近くに実装されるようには見えません
将来。 覚えておくべきこと。それは本当ですが、CommonJSモジュールを認識することも重要です
サポートはブラウザに実装されることは決してないので、どちらかを選択します
- 非モジュラーアーキテクチャとアドホックビルドを継続
これまでThree.jsに役立ってきたが、成長のブレーキとして機能するシステム
長い目で見れば- CommonJSモジュールの使用。これには周期的なトリックが含まれます。
依存関係があり、ビルドが大きくなる、または- Three.jsのようなコードベースに適したES6モジュールを使用する
周期的な依存関係があり、結果として最小かつ最大になります
最小化可能なビルドが可能です。 最終的に、ブラウザはそれらをネイティブにサポートします。
ローダーの予期しない癖に対応するために必要な変更
スペックは、関与する努力と比較して、おそらく取るに足らないものになるでしょう
CommonJSコードベースからのアップグレード。D3のようなライブラリはES6モジュールを採用しています。
CommonJSモジュールが実行できるすべてのこと(Node.jsでネイティブに実行することを除く)
Three.jsのようなライブラリでは実際には問題ではなく、結果としてより小さくなります
ビルドします。私はでいくつかの実験をしました
https://github.com/rollup/three-jsnext 、そしてそれは本番ではありませんが
準備ができました(例の移植などにもう少し時間を費やす必要があります!)UMDビルド
生成されるのは、実際には現在のビルドよりも_小さい_です。—
このメールに直接返信するか、GitHubで表示してください
https://github.com/mrdoob/three.js/issues/4776#issuecomment-168363092 。
CommonJSは、周期的な依存関係を持たないコードベースを使用したより大きなビルドになりますか?
@cecilemullerはいください。 CommonJSモジュールを使用すると、モジュールごとのコスト(各モジュールは関数でラップする必要があり、バンドル全体で共有されるインポートを再宣言する必要があるため、よりモジュール化されたコードベースに対してペナルティが課せられます)、バンドルごとのコストを支払います(Node.js環境をシミュレートする必要があります)、およびES6モジュールで最小化可能な変数名となる最小化不可能なオブジェクトプロパティ名などの他のコスト。 ES6モジュールを使用すると、文字通りゼロのオーバーヘッドでバンドルできます。
es5へのトランスパイルにはいくらかのオーバーヘッドがありますが。 現在のところ、
私はほとんど追加しないbabel付きのwebpackを使用しています。 モジュールごとのコストがあります
また、s関数にラップされているためです。 依存関係は決勝で宣言されます
整数インデックスを使用してrequirelike関数を呼び出すことにより、コードを取得します。
元々インポートされていたものから「vara = f(5)」のようなものに縮小されました
"./geometry"からのジオメトリ; '
ジェネレーターを使用することももう少し追加しますが、私はの構造を想像していません
コードはすぐにそのように変更されるでしょう。
2016年1月2日午前5時53分、「RichHarris」 notifications@github.comは次のように書いています。
@cecilemuller https://github.com/cecilemullerはい–参照
https://github.com/nolanlawson/rollup-comparison。 CommonJSモジュールを使用
モジュールごとのコストを支払います(各モジュールは関数でラップする必要があります、
バンドル全体で共有されるインポートを再宣言する必要があるため、
よりモジュール化されたコードベースに対してペナルティが課せられます)、バンドルあたりのコスト(必要です
Node.js環境をシミュレートするため)、およびその他のコスト(最小化不可能など)
ES6で最小化可能な変数名となるオブジェクトプロパティ名
モジュール。 ES6モジュールを使用すると、文字通りゼロのオーバーヘッドでバンドルできます。—
このメールに直接返信するか、GitHubで表示してください
https://github.com/mrdoob/three.js/issues/4776#issuecomment-168394376 。
es5へのトランスパイルにはいくらかのオーバーヘッドがありますが
モジュール間の関係を記述するためにimport
とexport
構文のみを使用している場合は、コード自体をBabelなどでトランスパイルする必要はありません。 トランスパイルが必要になるのは、他のES6機能(クラス、ブロックスコープ、矢印関数など)の追加を開始したときだけなので、 import
とexport
を使用するオーバーヘッドはありません。 D3とPouchDBは、 import
とexport
を使用するライブラリの2つの例ですが、それ以外はBabelなしのES5であり、three-jsnextは同じ方法で実行されます。
わかりました、私たちは皆同じ考えを持っていました。 lodashのような話があれば素晴らしいと思います。
コードをほとんど変更せずにモジュール化できるすべてのコンポーネント_foo_(たとえば、three-vector2)に対して_three-foo_パッケージを作成することを提案します。これにより、影響を与えることなくこのリポジトリにインポートできます。
npmで公開する人は、 @ mrdoobがこのすばらしいソフトウェアの作成者であるため、うまくプレイしてコラボレーションする
必要なパッケージについては、そうしようと思います。 しばらく様子を見てみましょう。
大きなコミュニティは1つだけです:)
のようにライブラリを完全に分離することを提案している人は誰もいませんでした
lodash。 Lodashは、一般名のユーティリティのコレクションです。 あなたはタクシー
それの1つの部分をつかんで、それを使用してください。 Threejsはそうではありません。 それは包括的なです
ライブラリ、そのほとんどは残りなしでは役に立たない。 いくつかの部分があります
特定の材料タイプなど、分離することができます
ジオメトリジェネレータですが、それらは必然的に非常に密接になります
コアに関連付けられており、正確なバージョンの一致が必要になる可能性があります。 彼らを考慮して
サイズが大きいと、測定可能な利益がなく、メンテナンスの頭痛の種になります。
ドゥーブ氏がその性質の分割を承認する必要がありますが、私はそれを考えていません
公式メンテナ以外の誰もがthreejsを主張するのに適しています-*
パッケージ。
上記に関係なく、モジュラーで動作させるのが賢明だと思います
何よりも環境。 これにはいくつかのプロジェクトがありました
目標ですが、すべてが失敗したようです。
2016年3月6日午前11:39、「GianlucaCasati」 notifications@github.comは次のように書いています。
わかりました、私たちは皆同じ考えを持っていました。 次のような話があればいいのに
lodash。すべてのコンポーネント_foo_に対して_three-foo_パッケージを作成することを提案します(
インスタンス3-vector2)モジュール化でき、変更はほとんどありません
コードなので、影響を与えることなくこのリポジトリにインポートできます。npmで公開する人は上手にプレイし、@ mrdoobと協力する必要があります
https://github.com/mrdoob彼はこの素晴らしい作品の作成者なので、
ソフトウェアの、それで彼が再び一元化したいなら
_babel_、パブリッシャーは、取得したnpm名前空間を制御できるようにする必要があります。必要なパッケージについては、そうしようと思います。 しばらく様子を見てみましょう。
大きなコミュニティは1つだけです:)
—
このメールに直接返信するか、GitHubで表示してください
https://github.com/mrdoob/three.js/issues/4776#issuecomment-192970867 。
@mattdesl :たとえば、 three-shader-fxaaはTHREE.Vector2と3つのエフェクトコンポーザーは別として、上記で提案したモジュール性アプローチを使用した非常に軽いビルドになります。
@HMUDesign :あなたの疑問は理解できますが、それでも私には良いアプローチのようです。 試してみたいのですが、GitHub URLのnpmパッケージを使用して、聖なるレジストリに公開するのではなく、アドバイスを聞き
Vector2、Vector3、Quaternionなどに依存するTrackballControlsから始めて、試してみました。
円形のデップがあります(たとえば、Matrix4はVector3に依存し、その逆も同様です)。 lib(つまり、threejs)がモノリシックで開始された場合は実行できません。
このような重要なプロジェクトに、すべての利点を備えたモジュールパターンを簡単に適用できないのは残念です。
私はsvg.js、vvvvjs、さらにはx3domのような他のプロジェクトでも試してみましたが、著者はこの根本的な選択ができないことを完全には確信していません。
スパムで申し訳ありませんが、積極的に試してみたかったのです。ちなみに、私は3つのtrackballcontrolsリポジトリから始めました。
@fibo ES6モジュールパターンは、循環依存関係afaikに問題がないはずです。 プレーンJSでの巻き上げのように、モジュールが実行される前にバインディングが設定されていませんか?
https://github.com/kamicane/three-commonjsify彼はcommonJSでそれを解決しました。
@drcmdaは本当に面白いです、私はそれを試してみます
モジュラーアーキテクチャに移行する場合は+1。
+1
+1
@drcmdaは正しいです。 ES6モジュールには、循環参照を可能にする初期化ステップと実行ステップがあります。 ただし、(モジュールのグローバル領域で)モジュール実行コンテキストから直接循環依存関係が発生するとすぐに、実行時に最初にロードされた依存関係に、その依存関係の未定義の値が発生します。 実行時の実行順序が重要な異なるコンテキスト内で参照が使用されている限り、循環依存関係は問題ありません。
browserifyの代わりにwebpackも検討することをお勧めします。
@gionkunzパターンの初期化ステップbcに循環参照があり、スクラッチ変数を生成するためのクロージャがあります
Webpack 2のベータ版がリリースされたばかりなので(https://twitter.com/TheLarkInn/status/747955723003322368/photo/1)、es6モジュールもバンドル時にツリーシェイクの恩恵を受けることができます。
@mrdoob
最近公式声明がありましたか? 多くの人と同じように、私たちはずっと前にES5と接着剤を放棄しましたが、現代のビルドシステムで3つがどれだけラインから外れるかはかなり悪いです。 私たちはそれができることのおそらく10%を使用しますが、それでも私たちが出荷する最大の依存関係です。
これは、個人的にはGithubで最もお気に入りのプロジェクトかもしれません。優先順位が再検討されることを心から願っています。
うーん、ブラウザのサポートについてもっと詳しく知りたいのですが。 どのブラウザが実行し、どのブラウザが実行しないか。 そうでないブラウザの場合、回避策とパフォーマンスのペナルティは何ですか。
実際には、ブラウザーのサポートは問題になりません(おそらく、現在よりも問題は少なくなります)。 ビルドシステムは、そのES6コードを取得してes5にトランスパイルします(元のES5よりも少ないスペースを使用する場合があります)。 特定の種類のトランスパイルされたものは最終的に大きくなります(主に:ジェネレーターと非同期関数)が、それらを回避すれば、そのペナルティはありません。
@drcmdaが述べたように、ビルドシステムはモノリシック出力を生成します(そして、その出力に含まれるものを正確にカスタマイズするのは非常に簡単です)が、個々のモジュールを独自のプロジェクトに含めることもできるため、必要です。 最大限に活用するには
つまり、相互依存関係を調整する必要がありますが、それは時間の経過とともに発生する可能性があります。 私たちが望んでいる主な機能は、インポート/エクスポートでモジュール化することだと思います。 あなたの観点からは、それはプロトタイプよりもクラスの使用を可能にするでしょう(彼らはまだ内部でプロトタイプを使用しているので、あなたはまだ
必要に応じてそれを台無しにします)。
いくつかのビルドシステムがあります。 私の投票はwebpack(transpilingにbabelを使用)になります。 babelを使用すると、カスタムローダーを定義できるため、シェーダー用に開発したチャンクシステムを#include拡張子の付いた実際のglslコードに縮小できます(実際にはこの方法でシェーダーを実行し、プロジェクトに貢献できれば幸いです)。 これは、システムと同じ利点(コードの重複なし)を取得しますが、使用は非常に簡単です。
私はモジュール化プロジェクトに参加したいと思っていますが、あなたのサポート(そしておそらく支援)がなければ、これは決して成功しないことを私は知っています。 私たちの多くはライブラリの使用方法を知っていますが、あなたが行う範囲でライブラリが内部でどのように機能するかを知っている人は誰もいません。
特定の種類のトランスパイルされたものは最終的に大きくなります(主に:ジェネレーターと非同期関数)が、それらを回避すれば、そのペナルティはありません。
なんて大きい?
また、パフォーマンスの低下については話しませんでした。 それでは問題ではありませんか?
私が見る限り、 ES6インポートはまだどのブラウザで
rollupjsなどのツールを使用することで得られるメリットを忘れないでください。これにより、ユーザーが使用しないすべてのエクスポートが自動的に除外されます。 (これはJSPMのデフォルトです)
babel-polyfilパッケージ。これは、使用している場合にのみ必要です。
ジェネレーター(おそらくこのプロジェクトでは意味がありません)または非同期
関数(プロジェクトではあまり変わらないと思います)
いずれか)、最終ビルドに約50kを追加します。 ただし、これはオプションです。
パフォーマンスに関しては、それは本当にあなたがどの機能であるかに依存します
を使用します。 たとえば、矢印関数は、
基礎となるバインドでは、クラスの作成は少し遅くなりますが、
インスタンス化時間は同じです。 https://kpdecker.github.io/six-speed/
ES6のインポート/エクスポートはブラウザではサポートされていませんが、
ビルドシステムを介して、それは問題ではありません。 製品の出力は次のようになります
現在とまったく同じように使用できますが(下位互換性もあります)、
それを私たちのビルドシステムに統合することを可能にし、
私たちが再利用できる内部コンポーネント。
注意すべきもう1つのことは、最終的なビルドサイズです。 現在、ジオメトリのようなもの、
Material、MeshなどはTHREE名前空間の一部です。 縮小すると、
THREE.Geometry、THREE.Material、THREE.Meshなどへの参照は
コード。 モジュラーシステムでは、これらの各ファイルは次のようになります。
var Geometry = require('./geometry');
は、
後で変数Geometry
。 次に、ミニファシトンで、 Geometry
とrequire
両方とも単一の文字に切り替えられ、「。/geometry」はに置き換えられます
数、かなりの節約になります。 ナプキン数学:縮小化
ビルドは511,794バイトで、2942の参照が含まれています
THREE\.[A-Z][a-zA-Z]+
。 これらすべてを1つの文字に置き換える
その結果、ファイルサイズがほぼ10%削減されます(464,782まで)。 (gzipされた
サイズはそれぞれ117,278と110,460で、6%削減されます)。 ビルド
これをさらに減らすように調整できる可能性があります。
ロールアップ(最終ビルドから未使用のコードを削除)がデフォルトです
jspmでは、webpack2ではデフォルトになります(そして私はそれが使用できると信じています
webpack付き)。 物事がモジュール式に書かれている場合、これはそうなるとは思わない
しかし、役に立ちました。 いずれにせよ、コードがトランスパイルできる限り
babel、それはどんなビルドシステムでも使用できます(私が言及したglslローダー
以前はwebpackで動作させることもできます)。
13:28の木、2016年7月7日には、Mr.doob notifications@github.comは書きました:
特定の種類のトランスパイルされたものは最終的に大きくなります(主に:
ジェネレーターと非同期関数)が、それらを回避すると、
そのペナルティ。なんて大きい?
—
あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/mrdoob/three.js/issues/4776#issuecomment -231197171、
またはスレッドをミュートします
https://github.com/notifications/unsubscribe/AA71cqAqmgxsUjpvamnI_xyL2wpzeWrdks5qTWGBgaJpZM4B4aA7
。
これがひどく役立つかどうかはわかりませんが、これは同じ問題に関するD3のディスカッションスレッドです: https :
非常に興味深い@jpweeks!
それで...このインポート/エクスポートアプローチでは... object instanceof THREE.Mesh
ようなもの
@mrdoob
import/export
は、モジュールが宣言され、必要とされる方法です。 モジュール内で定義されているコードに影響を与えたり変更したりすることはありません。
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
それはとても役に立ちます@GGAlanSmithee! ありがとう!
私は視覚的な人間なので、擬似コードの例は、テキストの大きな塊以上のものを私に納得させます😅
そうです、少しリファクタリングが必要になります...
クロージャコンパイラがこれをサポートすることを計画しているかどうか誰かが知っていますか?
そうです、少しリファクタリングが必要になります...
見つけた! このスレッドがここ数日で活発になったので、私はthree-jsnextにもう少し取り組んできました。 これは、既存のThree.jsコードベースを取得し、それをESモジュールに自動的に変換するプロジェクトです。 いくつかのトリッキーな周期的依存関係(特にKeyframeTrack
前後)と格闘しているだけですが、すぐに共有できるものがあるはずです。 私の知る限り、すべての例は引き続き機能し、縮小されたビルドは現在のビルドよりも小さいため(Rollupを使用してUMDファイルを生成)、すべて朗報です。
わかりました、これのプルリクエストを開きました:#9310
@mrdoob
多かれ少なかれTHREEのように構成されたライブラリが本番環境にあります。 ブラウザやモジュラー環境で動作します。 コードベースはES6ですが、ブラウザーはまったく問題ではありません。
これは、npm _as is_で出荷され、すべてのモジュールが含まれ、コンパイルされたグローバル名前空間ブラウザーモノリス(three.js)が含まれます。 その一部を使用する必要がある人は誰でも、ツールを使用してバンドルを作成します。
次のような構造を考えてみましょう。
/src
classA.js
classB.js
classC.js
/index.js
/browser.js
index.jsは、すべてのモジュールと関数を1つのファイルに再エクスポートするだけです。
export ClassA from './src/classA';
export ClassB from './src/classB';
export ClassC from './src/classC';
したがって、エンドユーザーはライブラリをnpmでインストールし、それ以上の手間をかけずに使用できます。
// 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は、パッケージの唯一のコンパイル済み部分になります。 通常、Babelを介してES5にトランスパイルされ、グローバル名前空間にエクスポートされるため、スクリプトインクルードとして使用できます。 ロールアップ、Webpackなどで簡単に作成できます。
@mrdoobそれは素晴らしい乗り物でした🚀
最も参考になるコメント
見つけた! このスレッドがここ数日で活発になったので、私はthree-jsnextにもう少し取り組んできました。 これは、既存のThree.jsコードベースを取得し、それをESモジュールに自動的に変換するプロジェクトです。 いくつかのトリッキーな周期的依存関係(特に
KeyframeTrack
前後)と格闘しているだけですが、すぐに共有できるものがあるはずです。 私の知る限り、すべての例は引き続き機能し、縮小されたビルドは現在のビルドよりも小さいため(Rollupを使用してUMDファイルを生成)、すべて朗報です。