Просматривать
Переход к этой архитектуре имеет свои преимущества и недостатки. Пожалуйста, поделитесь своими мыслями.
Примечание: для этого не требуется, чтобы потребители three.js использовали browserify.
Одно из преимуществ состоит в том, что это потребует модульной архитектуры для продолжающейся разработки three.js.
В общем стиле в node / browserify каждый файл объявляет свои зависимости вверху, а глобальные переменные рассматриваются как анти-шаблон.
Вот пример фрагмента:
// src/geometry/BoxGeometry.js
var Geometry = require('./Geometry.js');
var Vector3 = require('../core/Vector3.js');
module.exports = BoxGeometry;
function BoxGeometry() {
// ...
}
BoxGeometry.prototype = Geometry.prototype;
Еще одно преимущество состоит в том, что потребители three.js
использующие browserify, смогут выбирать те части, которые им нужны. Они могли просто импортировать Scene
, BoxGeometry
, PerspectiveCamera
и WebGLRenderer
, получить зависимости для всех этих автоматически ( Object3D
т. Д.), и иметь небольшой пакет javascript, который поддерживает только тот набор функций, который им нужен.
Это можно было бы сделать так, чтобы не вносить критических изменений. На верхнем уровне мы экспортируем все классы, которые считаем частью стандартного пакета.
// src/three.js
var THREE = { rev: 101 }
module.exports = THREE
THREE.Geometry = require('./geometry/Geometry.js')
THREE.BoxGeometry = require('./geometry/BoxGeometry.js')
// ...
примечание: я не совсем нуждаюсь в зависимостях вверху в этом примере, потому что этот файл будет почти полностью содержать операторы require.
Наконец, мы бы обернули это в универсальное определение модуля, которое определяет, используется ли модульная система (node / browserify, AMD), и, если да, экспортирует ее или иным образом добавляет ее к глобальному объекту ( window
).
Давайте рассмотрим:
three.js
использующим browserify, выбирать функцииЭто потребует замены системы сборки, но новая будет довольно простой.
Некоторые другие преимущества:
@ shi-314 Думаю, я немного запутался, мне кажется, что You can structure your code
и You can build for production
- это то, что вы можете сделать без архитектурного сдвига? Вы говорите об исходном коде three.js или о вещах, построенных с использованием three.js?
Одна практика, которую использует three.js, которая усложняет использование в средах commonjs, - это использование instanceof
: https://github.com/mrdoob/three.js/blob/master/src/core/Geometry .js # L82
Это связано с тем, что в приложении вы часто получаете разные версии одной и той же библиотеки в исходном дереве, поэтому проверка instanceof не работает между разными версиями одной и той же библиотеки. Было бы хорошо подготовиться к переходу на модульную систему commonjs, чтобы заменить эти проверки instanceof проверкой функций за интерфейсом в стиле Geometry.isGeometry(geom)
.
@kumavis Я говорю о вещах, построенных на three.js. Допустим, вы хотите создать свой собственный материал с помощью своих шейдеров и т. Д. На данный момент вам нужно расширить глобальный объект THREE, чтобы он оставался согласованным с остальной частью кода three.js:
THREE.MeshMyCoolMaterial = function (...) { ... }
Но если бы у нас был Browserify, вы могли бы это сделать:
var MeshLambertMaterial = require('./../MeshLambertMaterial');
var MeshMyCoolMaterial = function (...) {...}
Таким образом, ваше пространство имен остается согласованным, и вам не нужно использовать в коде THREE.MeshLambertMaterial
и MeshMyCoolMaterial
.
И с You can build for production
я имел в виду то же самое, что вы упомянули: allows three.js consumers using browserify to pick and choose functionality
.
@ shi-314 спасибо, это более понятно. Это действительно влияет на предлагаемое мной общее решение десериализации классов, определяемых потребителем:
// given that `data` is a hash of a serialized object
var ObjectClass = THREE[ data.type ]
new ObjectClass.fromJSON( data )
Это из предложенного мной рефакторинга сериализации / десериализации
https://github.com/mrdoob/three.js/pull/4621
Подобные изменения не должны влиять на производительность.
Это довольно серьезное изменение, но я тоже за него.
Некоторые другие важные преимущества:
standalone
чтобы сгенерировать для вас UMD-сборку. Не нужно вручную возиться с обертками UMD.threejs-vecmath
не беспокоясь о том, что любой нарушит код. И, с другой стороны, если мы сделаем патч или второстепенный выпуск в конкретном модуле, люди, использующие эти модули, смогут получить изменения автоматически.npm install threejs-shader-bloom
)require()
модулей, которые фактически использует наше приложение.@Mrdoob и другим авторам; Если у вас нет большого опыта работы с NPM / Browserify, я бы посоветовал сделать с ним пару небольших проектов и прочувствовать его «философию». Она сильно отличается от архитектуры ThreeJS; вместо больших фреймворков он поощряет множество мелочей .
Еще одним преимуществом этого подхода является то, что может существовать экосистема модулей Three.JS с открытым исходным кодом, сторонних разработчиков, особенно шейдеров, геометрии, загрузчиков моделей и т. Д. Публикуемых через NPM или Github / Component, которые люди могут затем легко ссылаться и использовать. В настоящее время материалы распространяются посредством демонстрации, на которой люди затем «просматривают исходный код». Three.JS заслуживает лучшего!
Я думаю, что одна из моих проблем с Three.JS - это то, как быстро код становится несовместимым с текущей версией Three.JS. Еще одно преимущество перехода на что-то подобное - возможность указать конкретные версии _bits_ of Three.JS было бы очень мощным и удобным.
+1
+1 для архитектуры CommonJS / browserify, это сделает ядро более легким, и расширения будут подходить, даже если они поступают от сторонних производителей.
Фрагментация three.js на маленькие модули также требует больших затрат. Текущая система допускает довольно простые сторонние надстройки (например, модули THREEx от jetienne). О простоте текущей настройки можно много сказать, поскольку системы модулей JS являются просто оболочкой для систем сборки.
Другой способ минимизировать размер сборки - это то, что делает ClojureScript. Они следуют некоторым соглашениям, позволяющим компилятору Google Closure выполнять анализ всей программы и устранять мертвый код.
+1 за недооцененную и часто упускаемую из виду элегантность простоты
+1
Фрагментация three.js на маленькие модули также требует больших затрат. Текущая система допускает довольно простые сторонние надстройки (например, модули THREEx от jetienne).
Идея здесь в том, что сборка UMD по-прежнему будет предоставляться для сред, отличных от Node. Такие плагины, как THREEx, будут работать одинаково для тех, кто зависит от ThreeJS с простыми тегами <script>
.
Сложность будет заключаться в следующем: как нам require()
конкретный плагин, если мы находимся в среде CommonJS? Может быть, вам поможет browserify-shim.
О простоте текущей настройки можно много сказать, поскольку системы модулей JS являются просто оболочкой для систем сборки.
Текущая система плагинов / расширений ThreeJS довольно ужасна для работы и далека от «простой» или легкой. Большинство проектов ThreeJS, как правило, используют ту или иную форму плагина или расширения, например EffectComposer, или FirstPersonControls, или загрузчик модели, или один из многих других JS-файлов, плавающих в папке examples
. Прямо сейчас единственный способ зависеть от этих плагинов:
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 / gulp concat.
Сложность будет заключаться в следующем: как нам require () конкретный плагин, если мы находимся в среде CommonJS?
Я уже немного использую CommonJS для проектов THREE.js. Это немного ручной процесс, преобразование фрагментов чужого кода в модули, и я не думаю, что будет простой способ избежать этого для устаревшего кода, который не конвертируется авторами или участниками.
Важным моментом является наличие модуля, экспортирующего весь «стандартный» объект THREE, который затем может потребоваться всем, кто хочет его расширить.
var THREE = require('three');
THREE.EffectComposer = // ... etc, remembering to include copyright notices :)
У меня это сработало очень хорошо, особенно по мере того, как проект растет, и я начинаю добавлять свои собственные шейдеры и геометрию в их собственные модули и т. Д.
Пока существует пакет npm 'threejs-full' или 'threejs-classic', это становится довольно жизнеспособным способом работы со старыми материалами Three.js в среде CommonJS, но я подозреваю, что это довольно нишевый вариант!
+1
Я считаю, что когда-то фрагментированные модули threejs доступны в npm, плагине
разработчики будут рады перейти на CommonJS env.
5 июня 2014 г. в 21:19 «Шарлотта Гор» [email protected] написала:
Сложность будет заключаться в следующем: как нам использовать () конкретный плагин, если мы
находятся в среде CommonJS?Я уже немного использую CommonJS для проектов THREE.js. Это немного
ручного процесса, конвертируя куски чужого кода в модули
и я не думаю, что будет простой способ избежать этого для устаревшего кода
который не конвертируется авторами или участниками.Важным моментом является наличие модуля, экспортирующего весь «стандартный»
Объект THREE, который затем может потребоваться всем, что хочет расширить
Это.var THREE = require ('три');
THREE.EffectComposer = // ... и т.д., не забывая включать уведомления об авторских правах :)У меня это сработало очень хорошо, особенно когда проект растет, и я
начать добавлять мои собственные шейдеры и геометрию в их собственные модули и т. д.Если есть пакет npm 'threejs-full' или 'threejs-classic', тогда
это становится довольно жизнеспособным способом работы со старыми материалами Three.js в
Среда CommonJS, но я подозреваю, что это довольно нишевая!-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/mrdoob/three.js/issues/4776#issuecomment -45236911.
Он также может сделать шейдеры модульными, например, с помощью glslify . Тогда даже такие вещи, как создание промежуточного программного обеспечения Express, которое генерирует шейдеры по запросу, становится проще.
Несколько месяцев назад я переместил frame.js в require.js и наконец понял, как работает эта штука AMD.
Однако мне все еще нужно научиться "компилировать" это. Какой инструмент / рабочий процесс для создания three.min.js
из списка модулей?
Я предпочитаю gulp.js в качестве системы сборки с плагином -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
Похоже, что пока все отлично ... но есть несколько моментов, которые, как мне показалось, стоит учесть, когда мы переходим к "архитектурному просмотру"
Так что, если мы увидим это разнообразие и удобную загрузку модулей (в основном на основе экосистемы npm) вместе с настраиваемыми сборками, это здорово, тогда, возможно, стоит коротко изменить парадигму, провести рефакторинг кода и изменить нашу текущую систему сборки.
@mrdoob некоторые инструменты для просмотра перечислены здесь: https://github.com/substack/node-browserify/wiki/browserify-tools.
что касается three.min.js
, вы не будете использовать минифицированный код в своем проекте. все, что вы делаете, это var three = require('three')
в своем project.js
а затем запускаете browserify project.js > bundle.js && uglifyjs bundle.js > bundle.min.js
. примечание: вы по-прежнему можете отправить мини-код за <script src="min.js">
.
В настоящее время я упаковываю 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 было бы _ огромным_ преимуществом.
но, возможно, имеет смысл разделить три и поместить все в отдельные модули, чтобы посмотреть, как это сработает.
также проверьте http://modules.gl/, который в значительной степени основан на браузере (хотя вы можете использовать каждый модуль отдельно без просмотра).
@mrdoob @ shi-314 gulp-browserify был занесен в черный список в пользу простого использования browserify напрямую (то есть через Vin-source-stream).
Такие инструменты, как grunt / gulp / etc, постоянно меняются, и вы найдете множество разных мнений. В конце концов, не имеет значения, что вы выберете или просто сделаете это с помощью специального сценария. Более важные вопросы: как пользователи будут использовать ThreeJS и какую обратную совместимость вы хотите поддерживать?
Поразмыслив еще немного, я думаю, что будет действительно очень сложно разделить все на модули без полного рефакторинга фреймворка и его архитектуры. Вот некоторые проблемы:
../../../math/Vector2
и т. Д.three-scene
было бы отделено от three-lights
и т. Д. Затем вы можете редактировать каждый пакет отдельно. Такая фрагментация кажется нереальной для такого большого фреймворка, как ThreeJS, и его было бы сложно поддерживать.require('three/src/math/Vector2')
Мое предложение? В дальнейшем мы рассматриваем две вещи:
Мне бы хотелось, чтобы все было разделено на модули, но я не уверен в подходе, который реалистичен для ThreeJS. Может быть, кому-нибудь стоит поэкспериментировать с вилкой, чтобы увидеть, насколько это возможно.
Спасибо за объяснения, ребята!
Я боюсь усложнять вещи для людей, которые только начинают. Заставлять их изучать этот браузер / модули может быть не очень хорошей идеей ...
Придется согласиться с
С предварительно скомпилированной сборкой UMD ( browserify --umd
) в репозитории нет изменений в рабочем процессе для существующих разработчиков.
@mrdoob Идея системы управления зависимостями проста. Чтение десятков сообщений о вариантах и системах сборки может быть утомительным, но в конечном итоге текущая система не является устойчивой. Каждый раз, когда один файл зависит от другого, это охота и поиск, который должен выполнить любой новый разработчик, чтобы найти ссылку. С помощью browserify зависимость является явной и есть путь к файлу.
@repsac Система зависимостей должна сделать Three более доступными для пользователей других языков, поскольку она избегает глобальной области видимости, кошмаров порядка загрузки и следует парадигме, аналогичной другим популярным языкам. var foo = require('./foo');
(слабо) сродни using foo;
в C # или import foo;
Java
Мне бы хотелось, чтобы все было разделено на модули, но я не уверен в подходе, который реалистичен для ThreeJS. Может быть, кому-нибудь стоит поэкспериментировать с вилкой, чтобы увидеть, насколько это возможно.
Я думаю, что это действительно правильный путь. Сделайте работу, покажите, как она работает.
И использование API было бы довольно
ugly: require('three/src/math/Vector2')
В качестве эксперимента я просто преобразовал «начало работы» из трех документов в этот новый модульный подход. Я могу представить, что ссылок будет много, если только люди не будут достаточно строго разделять свой код на крошечные модули.
Основным преимуществом этого будет то, что размер результирующей сборки будет крошечной долей размера полного Three.js, потому что вы включите только те вещи, на которые здесь конкретно ссылаются, а затем то, от чего эти вещи зависят.
Я предполагаю, что ссылка на все необходимые зависимости (и установка их всех по отдельности) на практике может оказаться слишком ужасной.
Если вы явно нацеливаетесь на мобильные устройства, то этот высокодетализированный подход был бы идеальным, но на самом деле я подозреваю, что нам понадобятся пакеты, которые экспортируют все ТРИ 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>
Я предполагаю, что ссылка на все необходимые зависимости (и установка их всех по отдельности) на практике может оказаться слишком ужасной.
Конечному пользователю не обязательно использовать browserify в своем проекте, чтобы Three мог использовать browserify для управления своей кодовой базой. Три могут быть представлены как глобальный THREE
как сейчас ... включить файл сборки и запустить с ним.
@repsac @mrdoob изменения будут обратно совместимы, так что текущим пользователям не нужно ничего менять, если они не хотят. Эти предложения призваны улучшить долгосрочную ремонтопригодность и долговечность разросшейся и монолитной кодовой базы ThreeJS. Такие вещи, как зависимости и управление версиями, могут показаться головной болью для непосвященных, но они прекрасны для тех, кто разрабатывает инструменты, фреймворки, плагины и крупномасштабные веб-сайты на основе ThreeJS.
т.е. код конечного пользователя может по-прежнему выглядеть так же, и examples
вообще не нужно менять:
<script src="three.min.js"></script>
<script>
var renderer = new THREE.WebGLRenderer();
</script>
Для более амбициозных разработчиков, которые ищут модульную сборку, _или_ для тех, кто хочет разрабатывать долгосрочные решения на основе ThreeJS (то есть и использовать преимущества управления версиями / зависимостями), это может выглядеть примерно так:
npm install three-vecmath --save
Затем в коде:
var Vector2 = require('three-vecmath').Vector2;
//.. do something with Vector2
И, кроме того, это позволяет людям использовать такие вещи, как векторная математика ThreeJS, преобразование цветов, триангуляция и т. Д. За пределами ThreeJS.
Несмотря на то, что я думаю, что беспорядок с require () - плохая идея и плохой компромисс, было бы еще хуже, если бы пользователи увидели два разных типа кода three.js, сообщая пользователям, что один - это модная модульная система, а другой - более простая (но второсортная) модульная система.
@erno Я думаю, вы упустили суть, three.js
будет организовано внутренней структурой модуля, но это используется для создания файла сборки, не отличающегося от текущей настройки.
Основное преимущество - улучшение опыта разработки и поддержки three.js
.
@kumavis - нет @erno на самом деле этого не пропустил, но я понял (*), что он подчеркивает, что если three.js
иногда используется через require, а иногда нет, это может сбивать с толку. Например, кто-то смотрит как на три источника, так и на некоторые сторонние примеры, и обнаруживает различия в том, как все это есть и работает.
(*) мы говорили об этом сегодня на irc.
Я думаю, что это своего рода верная точка зрения, но я не уверен, получится ли / как это сработает в конце - действительно ли проблема с использованием модуля и сборки. Но, безусловно, кажется, стоит подумать, и в целом мне показалось хорошо, что этот вопрос был тщательно рассмотрен здесь, спасибо за информацию и мнения, так далекие с моей стороны.
@antont Понятно . Люди предлагали здесь множество различных подходов, я предполагал, что мы в основном предоставим документацию для использования на верхнем уровне (вытаскивая все из THREE
), но другие могут создавать примеры, которые не будут следовать этому, и это может привести к некоторой путанице. И это серьезная проблема.
Думаю, меня немного смутил язык.
и other - более простой (но второсортный) вариант модульной системы.
Это просто относится к файлу сборки, да?
В моем понимании да. Не могу представить, что еще, но может чего-то упустить.
antont, kumavis: В предложениях здесь говорилось о том, чтобы предоставить конечным пользователям также код в стиле require (), см. например. Последний комментарий mattdesl.
«Для более амбициозных разработчиков, которые ищут модульную сборку, или для тех, кто хочет разрабатывать долгосрочные решения на основе ThreeJS (т.е. и использовать преимущества управления версиями / зависимостями) [...]»
один из способов получить более оптимизированные сборки - это на самом деле иметь сценарий, который автоматически определяет ваши зависимости и производит необходимые модули.
прямо сейчас bower & browserify справляется с требованиями, но это не единственные решения. Я не знаю, есть ли другие готовые проекты с открытым исходным кодом, которые делают это (возможно, как ng-dependencies), но я писал такие инструменты раньше, и я думаю, что будут другие подходы к решению этих проблем.
Компилятор закрытия Google может быть таким инструментом?
Может ли это помочь со стороны пользователя?
http://marcinwieprzkowicz.github.io/three.js-builder/
это довольно интересно @erichlof :) Интересно, создал ли https://github.com/marcinwieprzkowicz/three.js-builder/blob/gh-pages/threejs-src/r66/modules.json
Одна практика, которую использует three.js, которая усложняет использование в средах commonjs, - это использование instanceof: https://github.com/mrdoob/three.js/blob/master/src/core/Geometry.js#L82
Это связано с тем, что в приложении вы часто получаете разные версии одной и той же библиотеки в исходном дереве, поэтому проверка 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
так что всего 380 использований instanceof
в three.js. Что было бы лучшей реализацией в качестве замены?
Недавно я добавил свойство type
которое можно использовать для замены большинства из них.
Недавно я добавил свойство типа, которое можно использовать для замены большинства из них.
отлично! Подготовим PR.
Пример того, как это делается в другой популярной и большой JS-библиотеке, можно найти на https://github.com/facebook/react . Кодовая база структурирована с использованием модульной системы на основе стиля узлов (которая реализует браузер), но построена для выпуска с использованием grunt. Это решение гибко для трех вариантов использования.
require
. Преимущества правильного управления зависимостями хорошо задокументированы.Я провел небольшое исследование ...
Вчера я собрал (довольно глупый) скрипт, который преобразует исходный код Three.js для использования операторов CommonJS require()
для объявления зависимостей между файлами. Просто чтобы посмотреть, что происходит ... Это:
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
s), что довольно сложно сделать, используя только просмотр. Я предполагаю, что для этого потребуется преобразование просмотра, которое делает то же самое.React.js использует commoner для поиска своих модулей, не обращаясь к ним по пути к файлу. Возможно, мы могли бы сделать то же самое, а также определить собственные правила, которые позволят нам преобразовать файлы require
GLSL в синтаксис JS.
@rasteiner, вы можете быть очень рады узнать о https://github.com/stackgl/glslify , это происходит от растущего семейства http://stack.gl
У меня был достаточный опыт работы с модулями и «unixy» подходом за последние пару месяцев, и сейчас я думаю, что слишком поздно, и рефакторинг threejs для модульности или модулей npm был бы нереальной целью.
Вот что я сейчас делаю, чтобы решить проблему модульности / возможности повторного использования:
Мои новые проекты, как правило, используют «тройку» в npm просто для того, чтобы начать работу. Было бы здорово, если бы ThreeJS официально опубликовал сборку в npm, используя теги версий, которые совпадают с номерами выпусков.
PS: для тех, кто заинтересован в использовании многоразовых / модульных шейдеров в своем рабочем процессе:
https://gist.github.com/mattdesl/b04c90306ee0d2a412ab
отправлено из моего Айфона
20 ноября 2014 г. в 7:42 aaron [email protected] написал:
@rasteiner, вы можете быть очень рады узнать о https://github.com/stackgl/glslify , это происходит от растущего семейства http://stack.gl
-
Ответьте на это письмо напрямую или просмотрите его на GitHub.
В случае, если это поможет другим, которые могут искать, как использовать Three.js с browserify, и наткнуться на эту тему, я только что настроил его сам - это использовать browserify-shim .
Следуя разделу 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 каждый раз, когда я вношу изменения. Это слишком расстраивает.
Обычно вы используете watchify во время разработки с livereload. Тот строит пакет постепенно.
watchify у меня не работает. Когда я изменяю файл и сохраняю его, livereload watchify и beefy обслуживает старую / кешированную версию. Понятия не имею, почему это происходит. К счастью, browserify уже работает довольно хорошо.
@ChiChou Передайте --noparse=three
для просмотра. Это увеличивает шаг пакета browserify с 1000 мс до 500 мс на моей машине, что достаточно прилично для мгновенного ощущения обратной связи.
@rasteiner Я хочу еще раз поблагодарить вас за ваше неформальное исследование взаимозависимостей three.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 )
Позвольте типу определять, как себя вести. Это также позволяет потребителю библиотеки использовать новые типы текстур, о которых мы не думали. Эта структура должна уменьшить взаимозависимость.
Я думаю, что переход на архитектуру просмотра с браузером - определенно правильный путь. Сборка UMD упростит использование THREE.js. Это также позволит нам разделить WebGLRenderer на несколько файлов, потому что сейчас он выглядит довольно монолитным и пугающим.
Я запустил ветку, над перемещением которой работаю в настоящее время: https://github.com/coballast/three.js/tree/browserify-build-system
Пожалуйста, дай мне знать, что ты думаешь.
Вот изменения @coballast .
Похоже, вы используете подход автоматического преобразования с вашим файлом browserifyify.js
, и я думаю, что это правильный путь.
Одна вещь, которую мы все еще не обсуждали, - это то, как лучше всего перевести эту большую, постоянно меняющуюся библиотеку на просмотр. Вы можете внести изменения, а затем открыть PR, но он сразу устареет. Вот что убедительно в автоматизированном подходе.
Если мы можем:
browserifyify.js
)... тогда мы можем превратить это в кнопочное преобразование, которое будет работать в обозримом будущем. Эта простота позволяет осуществить это мечтательное представление о фундаментальном архитектурном переходе к такому большому проекту, когда победят идеологические аргументы.
@coballast с этой целью, я бы удалил изменения в src / Three.js, если он работает точно так же.
Примечание: не просто вернуться, но и удалить эти изменения из истории ветки с помощью новой ветки или принудительного нажатия.
@coballast Интересно, было бы three.js
, а внешней утилитой, которую вы указываете на каталог разработки three.js
, и она преобразует исходный код файлы, добавляет сценарий сборки и запускает тесты.
@kumavis Я согласен оставить каталог src в покое. Я думаю, что нужно сделать так, чтобы утилита написала дублированный каталог с кодом commonjs, и мы можем протестировать и запустить сборку браузера оттуда, чтобы убедиться, что все примеры работают, прежде чем мы попытаемся сделать что-нибудь серьезное.
Здесь также есть интересная возможность написать некоторые элементы статического анализа, которые будут автоматически проверять и обеспечивать согласованный стиль во всей кодовой базе.
@coballast - великолепно звучит.
Существует множество инструментов для автоматического переписывания кода, например escodegen . Необходимо убедиться, что мы сохраняем комментарии и т. Д.
Хотите запустить репозиторий утилиты threejs-преобразования?
@coballast при этом важно поддерживать
@kumavis Считай, что это сделано. Я очень хочу, чтобы это произошло. Это только один из двух проектов, над которыми я работаю в данный момент.
@kumavis @mrdoob Некоторые из обсуждаемых здесь вопросов, похоже,
Мне будет любопытно посмотреть, что выдает эта утилита ^^
@coballast связывает репо, чтобы мы могли отслеживать его, даже если на данный момент он просто пуст. Мы можем строить оттуда.
https://github.com/coballast/threejs-browserify-conversion-utility
Код запутался, скоро уберу.
вот так! : ракета:
Теперь у меня есть утилита в состоянии, когда она генерирует browserify src и без проблем построит ее. Я обновлю репо с инструкциями, как это сделать самостоятельно. На данный момент примеры не работают. Чтобы это исправить, необходимо решить несколько проблем. Я добавлю их в репо, если кто-то захочет засучить рукава и выручить.
@coballast да, пожалуйста,
Возникли серьезные проблемы. См. № 6241
Вот мой анализ того, что должно произойти, чтобы это сработало: https://github.com/coballast/threejs-browserify-conversion-utility/issues/9#issuecomment -83147463
Browserify, по крайней мере, является избыточным (конъюнктурным) транспортом из-за его дизайна. Это делает его использование завышенным (у кого-нибудь тарифный план?) И медленным.
Простое решение этой проблемы - отделить документ от кода библиотеки, что повлечет за собой два клиентских файла, а не один. Это обычная практика для js на стороне клиента.
Если вначале browserify неисправен и сам требует исправления, я не понимаю, почему его вообще следует рассматривать для улучшения чего-либо, не говоря уже о том, чтобы что-то вроде threejs.
@spaesani Потому что данные для threejs все равно нужно загружать. Если мы разделим threejs на более мелкие модули и позволим автоматизированной системе сборки выбрать то, что ей нужно для одного приложения, на самом деле большинство трех приложений будет легче.
Если по какой-то причине вы все еще хотите отделить «документ от кода библиотеки», вы все равно можете сделать это и использовать предварительно созданную версию, как это делаем мы сейчас. Вы даже можете разделить приложение, созданное с помощью браузера, на отдельные модули, используя флаги
Browserify - это просто способ использовать проверенный в боях API определения модулей (CommonJS) в браузере. Это значительно упростило бы разработку плагинов threejs и повысило бы ясность кода и, следовательно, производительность, это позволило бы нам интегрироваться в более крупную экосистему (npm), где код по своей сути поддерживается большим количеством людей, при этом сохраняя целостность через систему управления версиями (подумайте о семейство stackgl ), и это даже не заставит людей перейти на CommonJS, если они этого не захотят.
Конечно, есть и недостатки, но они не те, о которых вы упомянули.
three.js и three.min.js можно кэшировать для экономии на транспорте (данных) через прокси, обычное мобильное решение или кеширующий браузер.
В тот момент, когда вы выбираете и объединяете код threejs с кодом документа, кеширование становится невозможным.
Если браузер позволяет
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 Это (просмотр) улучшает жизнь людей. Мое собственное психологическое счастье и благополучие важнее, чем то, насколько легко машина может загружать и выполнять вещи.
Многие проблемы с загрузкой мобильной сети можно решить с помощью таких вещей, как http / 2. Подобные проблемы лучше всего решать, изменяя уровни, расположенные ниже в стеке абстракции. Проблемы с производительностью не должны мешать нам следовать передовым методам разработки программного обеспечения, таким как модульность / разделение задач и т. Д.
Я обнаружил эту проблему, потому что моя команда недавно начала использовать jspm. Мы можем импортировать threejs (я считаю, что это потому, что основной файл был просмотрен). Я искал, сделал ли кто-нибудь threejs в модули es6, в первую очередь из-за функции сборки jspm (объединение всех зависимостей в один файл, но только захват используемых зависимостей).
Хотя это здорово, что mrdoob сохраняет размер threejs менее 100 КБ, я обнаружил, что большинство моих проектов не используют большую часть кодовой базы (мне кажется, что это больше всего, но я не пытался понять это). CubeCamera, OrthographicCamera, CanvasRenderer, различные источники света, загрузчики, кривые, геометрии, помощники и т. Д. Кроме того, я обнаружил, что большинство моих проектов включают несколько примеров скриптов.
Я надеялся, что можно будет иметь одно место для всех этих модулей (те, которые обычно связаны с threejs, а также те, что в примерах), и просто импортировать те, которые мне нужны, а затем, когда я объединяю проект, это приводит в файле, намного меньшем, чем исходный файл threejs, хотя он содержит много частей, которые изначально не были включены.
Я также хотел добавить, что если бы threejs были построены с использованием модулей просмотра, это добавило бы небольшие накладные расходы на размер файла (но несравнимые с текущими 403 КБ на r70), но также исключило бы использование глобальной переменной THREE из кода, тем самым позволяет минимизировать такие переменные, как THREE.Geometry, путем закрытия.
Я провел быстрый тест, выполнив поиск-замену, чтобы избавиться от объекта THREE (так что все его дочерние элементы загрязнили пространство имен) и обернул весь файл в IIFE, а затем запустил все это через закрытие Google. Полученный файл (без сжатия) был 238 КБ, по сравнению с 777 КБ.
Хотя результаты будут разными, я думаю, что определенно стоит убедиться, что это произойдет.
спасибо, что рассказал - много хороших моментов есть, да и нам знакомых тоже. мы также никогда не используем много средств визуализации в одном проекте, а делаем что-то вроде библиотеки из примеров.
не понимал этого насчет минимизации - это довольно большая разница.
и модули es6, безусловно, казались многообещающими - также было приятно услышать, что там есть путь от AMD / CommonJS / такого шаблона модуля и использования библиотеки.
@colin Не уверен, что я слежу за тобой в том, как просматривать
помогает вашему психологическому счастью.
Это в документации?
browserify - это дойная корова-перевозчик ...
Вторник, 31 марта 2015 г., 22:11 -04: 00 от Колина Балласта notifications@github.com :
@spaesani Это (просмотр) улучшает жизнь людей. Мое собственное психологическое счастье и благополучие важнее, чем то, насколько легко машина может загружать и выполнять вещи.
Многие проблемы с загрузкой мобильной сети можно решить с помощью таких вещей, как http / 2. Подобные проблемы лучше всего решать, изменяя уровни, расположенные ниже в стеке абстракции. Проблемы с производительностью не должны мешать нам следовать передовым методам разработки программного обеспечения, таким как модульность / разделение задач и т. Д.
-
Ответьте на это письмо напрямую или просмотрите его на GitHub.
Теперь, если browserify будет автоматически определять зависимости без инструкции require ... эй, подождите ...
@spaesani На самом деле я предпочитаю явные зависимости - помогает понять, как весь код сочетается друг с другом.
browserify - это дойная корова-перевозчик ...
@spaesani Browserify накладные расходы бесконечно
Обновление статуса:
У меня есть ветка с некоторым просмотренным кодом:
https://github.com/coballast/three.js/tree/browserify
Имейте в виду, что это очень большая работа. Этот код был сгенерирован автоматически и в результате какое-то время будет выглядеть ужасно. Я все еще пытаюсь исправить некоторые проблемы со сборкой. См. Coballast / threejs-browserify-conversion-utility # 10, если вы думаете, что сможете это исправить. Некоторое время он строился, но не сейчас.
@kumavis и я работаем над решением некоторых проблем во время выполнения (а также над улучшением архитектуры программного обеспечения). Кажется, я где-то упоминал об этом выше.
Извините за длинный ответ. TL; DR: jspm / es6 работает, но имеет некоторые странности: 1) Экспорт объектов перед их определением; 2) Экспорт объектов, содержащих один класс, а не только экспорт одного класса; 3) IIFE с использованием круговых зависимостей; 4) Файловая структура.
Я играл с вашей просматриваемой веткой в jspm ( @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;
. Последний так работают все примеры просмотра). Таким образом, при использовании требований вы должны ступить на уровень глубже ( 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) отлично справляется с циклическими зависимостями, но есть одна проблема. Во многих местах код читается примерно так. Проблема в том, что, хотя Vector3 был передан как зависимость, на данный момент он не был полностью загружен (поскольку Vector3 также включает этот файл, каждый из них не может разрешиться, пока не будет разрешен другой) и не может быть создан. Я добавил очень плохое исправление (показано ниже), хотя я не уверен, как это исправить лучше. Похоже, это архитектурная проблема, у которой может не быть простого решения. Это случается много-много раз. Похоже, это оптимизация для предотвращения создания нового Vector3 при каждом вызове функции. Если действительно наблюдается значительное снижение производительности, которое не может быть исправлено путем оптимизации Vector3, то, возможно, добавить функцию в Vector3 для возврата неиспользуемого вектора3, который будет выпущен позже?
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 должен находиться в папке geometries, как и Материал в папке материалов. Но папки с геометриями нет, она есть в экстр. Кстати, в extras тоже есть ядро и геометрия, но базовой геометрии нет в этой папке. Это большая коллекция помощников, но разве каждый помощник не должен заниматься тем, чем он помогает? Процессы сборки можно легко настроить так, чтобы они принимали только те файлы, которые вам нужны, поэтому нет оправдания размещению неважных файлов в другом месте.
В настоящее время у меня есть строка в моем коде, где написано import BoxGeometry from 'threejs/extras/geometries/BoxGeometry';
и var geometry = new BoxGeometry.BoxGeometry( 1, 1, 1 );
Привыкнув использовать new THREE.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.
хорошо, позвольте мне сейчас внимательно прочитать ваш комментарий.
Я как-то пропустил ссылку на это репо выше. Я с радостью перенесу свои проблемы
в это репо завтра, затем разделив по мере необходимости (я заметил, что по крайней мере
часть уже есть)
9 апреля 2015 г. в 0:09 "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
только раз у меня нет экспорта по умолчанию, хотя иногда я добавляю
эксперт в дополнение к стандартному), однако этот синтаксис работает только тогда, когда вы
экспортировать несколько именованных переменных. Загрузчик распространенных js-модулей лечит
modules.exports как экспорт по умолчанию, который нельзя деструктурировать в
import = (
9 апреля 2015 г., 00:12, "kumavis" notifications@github.com написал:
в es6 вы можете импортировать свойства из объектов экспорта через
деструктуризация.импортировать {Vector3} из '../math/Vector3';
Тем не менее, я согласен с тем, что предпочтительнее один экспорт на модуль.
-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/mrdoob/three.js/issues/4776#issuecomment -91132982.
@HMUDesign еще раз благодарим вас за вашу энергию и анализ - здесь мы составляем список https://github.com/coballast/threejs-browserify-conversion-utility/issues/17
+1 за просмотр.
Также +1 для перемещения шейдеров в отдельные файлы с помощью glslify.
Также +1 за использование некоторых функций ES6, таких как классы и модули. Новый стек сборки позволит нам при необходимости скомпилировать обратно до 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://github.com/thomasloh/5to6
@lmcd oo хорошая находка
но tbh, кажется, проще было бы переписать three.js с нуля: P
@lmcd Я так рада, что ты это нашел. Это была одна из тех вещей, которые я собирался сделать по чистой необходимости, но звучало явно не весело.
@mrdoob, что вы думаете по этому поводу на данный момент?
@anvaka На данный момент я сосредоточен на рефакторинге WebGLRenderer
. У меня не хватает умственных способностей 😅
Недавно я столкнулся с некоторым проектом, который успешно использовал модули es6 с полифилом babel, о котором уже упоминалось здесь. Не мог вспомнить и не найти, что это было, все равно мне понравилось.
Также, похоже, что es6 завершен в отношении стандартов: «Наконец, ECMA-262 Edition 6 официально одобрен и опубликован в качестве стандарта 17 июня 2015 года», - говорится в https://developer.mozilla.org/en-US/docs. / Web / JavaScript / New_in_JavaScript / ECMAScript_6_support_in_Mozilla
Замечу, что в отношении оснащения и стабильности спецификации модуля ситуация в этом плане кажется хорошей.
Недавно я столкнулся с некоторым проектом, который успешно использовал модули es6 с полифилом babel, о котором уже упоминалось здесь. Не мог вспомнить и не найти, что это было, все равно мне понравилось.
Это также 47 КБ дополнительных js и читает и переносит ваш включенный javascript в es5 в браузере, поэтому не очень подходит для времени запуска.
Ничто не мешает любому, кто использует three.js, использовать es6 в своем собственном коде; однако его использование в библиотеке может вызвать проблемы совместимости браузера и производительности по всем направлениям.
Ах - здесь стоит поправить, спасибо за информацию. Я думаю, что браузер Browserify и тому подобное, которые работают в процессе сборки, сейчас лучше.
Ах - здесь стоит поправить, спасибо за информацию. Я думаю, что браузер Browserify и тому подобное, которые работают в процессе сборки, сейчас лучше.
Одна из основных проблем с es6 - это критические изменения синтаксиса с es5; например, жирная стрелка => является недопустимым es5 и приведет к сбою парсера javascript и отказе от попытки скомпилировать код. Надеюсь, кто-то найдет способ обойти это, но пока этого не произошло.
На самом деле я думал только о модульной системе, операторе импорта и т. Д.
Это также 47 КБ дополнительных js и читает и переносит ваш включенный javascript в es5 в браузере, поэтому не очень подходит для времени запуска.
например, жирная стрелка => является недопустимым es5 и приведет к сбою парсера javascript и отказе от попытки скомпилировать код
Код es6 может быть перенесен в es5 во время _build_ без штрафных санкций во время выполнения. Это просто вопрос добавления этапа 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://www.incaseofstairs.com/2015/06/es6-feature-performance/, особенно для высокопроизводительной библиотеки.
модули / npm / browserfy и т. д., но, вероятно, это хорошая идея
+1 о правильной модуляции с использованием модулей ES6
+1 при правильной модуляции с использованием любой разумной модульной системы (commonjs, amd, es6)
Я думаю, что commonjs и amd являются предпочтительными вариантами b / c, которые не требуют транспилирования
Однако они требуют шага сборки, который эквивалентен
транспиловый шаг.
Использование ES6, помимо того, что это следующая версия языка, позволит
использовать следующие функции по желанию, но не нарушать существующий машинный код.
Действительно ли разумно преобразовать базу кода в систему, которая уже
не последний?
20 июля 2015 г. в 12:05 "kumavis" notifications@github.com написал:
+1 о правильной модуляции с использованием любой разумной модульной системы (commonjs, amd,
es6)
Я думаю, что commonjs и amd - предпочтительный выбор b / c, которого они не делают
требует транспиляции-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/mrdoob/three.js/issues/4776#issuecomment -122990605.
Однако они требуют шага сборки, который эквивалентен
транспиловый шаг.
Строительство и транспиляция не равнозначны с точки зрения сложности, которую они вносят.
Действительно ли разумно преобразовать базу кода в систему, которая уже
не последний?
commonjs прост и отлично работает. Я не убежден в том, что «последний» === «лучше».
Использование ES6 [...] позволит использовать следующие функции по желанию
так что это стоит рассмотреть. нам нужны функции es6? если мы начнем транспилировать es6, люди начнут пиарить es6. поскольку @benaadams предположил, что использование функций es6 не интуитивно влияет на производительность.
Более того, нам не нужно объединять вопросы «модульной системы» и «функций es6». вы можете транспилировать es6 и использовать commonjs. и вы можете представить их отдельно.
+1 для browserify / commonjs - его просто скомпилировать с помощью browserify таким образом, чтобы люди по-прежнему могли использовать библиотеку традиционным способом, если захотят - это то, для чего предназначен UMD, разрешить AMD (например, require.js), CommonJS требует (например, node + browserify) и глобального окна (для тегов скрипта) в зависимости от среды, в которой мы работаем.
PIXI.js только что перешел на модульную архитектуру с использованием browserify, и библиотека была настроена очень похожим образом - все привязано к глобальному объекту PIXI. Их настройка очень похожа на @kumavis, описанную во втором посте.
Ни browserify, ни commonjs не удовлетворяют специфическим потребностям 3D-движка, что не означает, что их нельзя использовать, но их следует рассматривать как часть большой головоломки:
Компоненты должны экспортировать метаинформацию о свойствах своих экземпляров, поэтому может быть загрузчик для произвольных объектов и подключений к данным в общей памяти. С такой архитектурой было бы просто вопросом здравого смысла также загружать код компонента вне ядра при первом использовании. Был проведен мозговой штурм по этим темам в # 6464 и # 6557.
+1
+1
В качестве гибридного решения также можно добавлять требования в виде комментариев. Я знаю, что browserfy уже есть во многих экосистемах, но я просто хотел оставить это здесь как вариант для быстрой реализации :), потому что вам не нужно ничего менять. Вам просто нужно добавить комментарий поверх каждого файла.
Как разработчик вы можете легко создавать свои собственные файлы min.js с помощью информации @requires
и плагина gulp.
Привет всем, недавно у меня возникла аналогичная потребность в загрузке произвольных ресурсов с их собственными зависимостями в чистом и структурированном виде, и я придумал решение написания плагинов require.js для каждого типа ресурса. Таким образом, я позволяю разрешению зависимостей require.js позаботиться о правильной загрузке и кэшировании ресурсов ... В то же время этот подход создает повторно используемые "пакеты" ресурсов, которые я могу использовать в различных моих проектах.
Если вам интересно, вы можете найти проект здесь: https://github.com/wavesoft/three-bundles
(Пример использования этой библиотеки будет скоро доступен)
В будущем я планирую включить в эти плагины этап оптимизации, чтобы позволить оптимизатору require.js компилировать ресурсы в еще более компактный формат.
Глядя на этот разговор https://twitter.com/defunctzombie/status/682279526454329344 , не похоже, что модули es6 будут реализованы в ближайшем будущем. Что нужно иметь в виду.
Я сделал несколько прототипов с модулями commonjs и просмотрел.
Мой последний просмотренный пакет включает в себя каждый отдельный файл из папки src
и дает размер файла 962K
(по сравнению с исходной версией без браузера 885K
).
Целевая сборка cloth
пример :
580K
(на 44% меньше)431K
(на ~ 8% меньше)Вот разбивка размера пакета: http://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 (за исключением запуска в Node.js, что на самом деле не является проблемой для такой библиотеки, как Three.js), и приводят к меньшим сборкам.
Я поэкспериментировал на https://github.com/rollup/three-jsnext , и, хотя он не готов к производству (мне нужно потратить немного больше времени на перенос примеров и т. Д.!), Созданная им сборка UMD на самом деле _smaller_ чем текущая сборка.
Я согласен с замечанием о модулях es6 по сравнению с другими системами. Будь или
не они являются стандартом es, они стандарт сообщества. И хотя они
не может работать "изначально" в узле, он может выглядеть "родным" с помощью хуков Babel.
Я скоро свяжусь с вашим репо.
Кроме того, тот факт, что он меньше, был тем, о чем я говорил ранее в
этот разговор. "ТРИ. Геометрия" становится "геометрией", которая может быть
например, уменьшенный до "a".
Кроме того, решение экземпляра проверок состоит в том, чтобы удалить их все.
вместе. Один модуль не следует начинать иметь по-разному в зависимости от того, что
он был дан, но скорее полагаясь на предоставленную вещь, чтобы сделать то, что ему нужно
делать. Тогда нет никаких проверок экземпляра или типа.
1 января 2016 г. в 20:23 «Рич Харрис» notifications@github.com написал:
не похоже, что модули es6 будут реализованы в ближайшем будущем
будущее. Что нужно иметь в виду.Это правда, но также важно понимать, что модуль CommonJS
поддержка будет _ никогда_ не будет реализована в браузерах, поэтому выбор стоит между
- продолжая с немодульной архитектурой и специальной сборкой
система, которая до сих пор хорошо служила Three.js, но тормозит рост
в долгосрочной перспективе- с использованием модулей CommonJS, что включает в себя некоторые хитрости вокруг циклических
зависимости и приводит к более крупной сборке, или- с использованием модулей ES6, которые хорошо подходят для кодовой базы, такой как Three.js
который имеет циклические зависимости и приводит к наименьшим и наибольшим
возможна мини-сборка. Со временем браузеры будут поддерживать их изначально,
и изменения, необходимые для учета любых непредвиденных особенностей загрузчика
спецификация, скорее всего, будет тривиальной по сравнению с усилиями, затраченными на
обновление из базы кода 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 Да - см. https://github.com/nolanlawson/rollup-comparison. С модулями CommonJS вы платите стоимость за модуль (каждый модуль должен быть обернут в функцию и должен повторно объявить импорт, который используется во всем пакете, поэтому вы будете наказаны за более модульную кодовую базу), стоимость каждого пакета (он должен имитировать среду Node.js) и другие затраты, такие как неуменьшаемые имена свойств объекта, которые будут мини-именами переменных в модулях ES6. Модули ES6 позволяют создавать пакеты практически с нулевыми накладными расходами.
Хотя при переносе на es5 возникнут некоторые накладные расходы. В настоящий момент,
Я использую webpack с babel, который добавляет очень мало. Цена за модуль
поскольку он также заключен в функцию s. Зависимости декларируются в финальном
код, вызывая функцию require с целочисленным индексом, поэтому он получает
уменьшено до чего-то вроде "var a = f (5)" из того, что было изначально 'import
Геометрия из "./geometry"; '
Использование генераторов также добавляет немного больше, но я не представляю себе структуру
код будет сильно меняться в ближайшее время.
2 января 2016 г. в 5:53 «Рич Харрис» 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
но в остальном являются ES5 без Babel, и three-jsnext выполняется таким же образом.
Хорошо, у нас у всех была одна и та же идея. Было бы здорово иметь такую историю, как lodash.
Я предлагаю создать пакет _three-foo_ для каждого компонента _foo_ (например, three-vector2), который может быть модульным, почти без изменений в коде, чтобы его можно было импортировать в это репо без каких-либо последствий.
Люди, которые публикуются на npm, должны хорошо играть и сотрудничать с @mrdoob, поскольку он является создателем этого замечательного программного обеспечения, поэтому, если он хочет снова централизовать все пакеты, как это сделал автор _babel_ (я имею в виду все основные пакеты в одной папке), издатель должен дать ему контроль над занятым пространством имен npm.
Я постараюсь сделать это для нужных мне пакетов. Давай посмотрим что происходит.
Есть только одно большое сообщество :)
Я не заметил, чтобы кто-нибудь предлагал полностью разделить библиотеку, например
lodash. Lodash - это набор утилит под общим названием; ты такси
возьмите один кусок и используйте его. Threejs - нет; это всеобъемлющий
библиотека, большая часть которой без остальных бесполезна. Есть несколько штук
которые можно разделить, например, на конкретные типы материалов, на наши конкретные
генераторы геометрии, но они обязательно будут очень близко
привязан к ядру, вероятно, требуются точные совпадения версий. Учитывая их
размер, это создало бы головную боль обслуживания без измеримого выигрыша.
Должен ли мистер Дуб одобрить такой раскол, однако, я не думаю, что это
подходит для всех, кроме официального сопровождающего, чтобы заявлять о threejs- *
пакеты.
Независимо от вышесказанного, я считаю разумным заставить его работать в модульном
окружающая среда прежде всего. Было несколько проектов с этим
гол, но все вроде запутались.
6 марта 2016 г., 11:39, «Джанлука Касати» notifications@github.com написал:
Хорошо, у нас у всех была одна и та же идея. Было бы здорово иметь историю вроде
lodash.Предлагаю создать пакет _three-foo_ для каждого компонента _foo_ (для
instance three-vector2), который можно разделить на модули, почти без изменения
код, поэтому его можно импортировать в это репо без каких-либо последствий.Люди, которые публикуются на npm, должны хорошо играть и сотрудничать с @mrdoob
https://github.com/mrdoob, так как он является создателем этого замечательного произведения
программного обеспечения, поэтому, если он захочет снова централизовать все пакеты, как в
_babel_, издатель должен дать ему контроль над занятым пространством имен npm.Я постараюсь сделать это для нужных мне пакетов. Давай посмотрим что происходит.
Есть только одно большое сообщество :)
-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/mrdoob/three.js/issues/4776#issuecomment -192970867.
@mattdesl : например, ваш three-shader-fxaa использует THREE.Vector2 и THREE.Texture, кроме трехэффектов, которые я не проверял, это приведет к действительно легкой сборке с использованием подхода модульности, предложенного выше.
@HMUDesign : Я понимаю ваши сомнения, но все же мне кажется, что это хороший подход. Я хочу попробовать, но прислушусь к вашему совету, используя пакеты npm из URL-адресов GitHub, а не публикуя их в священном реестре .
Я попробовал, начав с TrackballControls, который зависит от Vector2, Vector3, Quaternion и так далее.
Есть круговые зависимости (например, Matrix4 зависит от Vector3 и наоборот). Это невозможно сделать, если библиотека (например, threejs) была запущена в монолитном режиме.
Жалко, что шаблон модуля со всеми его преимуществами не может быть легко применен в таких важных проектах, как этот.
Я пробую также с другими проектами, такими как svg.js, vvvvjs, даже x3dom, но авторы не до конца убеждены в этом радикальном выборе, это невозможно.
Извините за спам, но я хотел попробовать проактивно: кстати, я начал с репозитория с
Шаблон @fibo ES6 Module не должен иметь проблем с зависимостями CIR afaik. Разве привязки не настраиваются перед выполнением модуля, как подъем в обычном JS?
Я уверен, что вы это видели: https://github.com/kamicane/three-commonjsify Он решил это совместно с JS.
@drcmda действительно интересно, я попробую
+1 за переход к модульной архитектуре.
+1
+1
@drcmda прав. В модулях ES6 есть этап инициализации и этап выполнения, которые допускают циклические ссылки. Однако, как только у вас возникнут циклические зависимости непосредственно из контекста выполнения модуля (в глобальной области модуля), тогда первый, загруженный во время выполнения, получит неопределенные значения для своих зависимостей. Пока ссылки используются в другом контексте, где важен порядок выполнения во время выполнения, циклические зависимости не являются проблемой.
Предлагаю также рассмотреть webpack вместо browserify.
@gionkunz у нас есть циклические ссылки на этапе инициализации bc шаблона, где есть закрытие для генерации временных переменных
Только что была выпущена бета-версия Webpack 2 (https://twitter.com/TheLarkInn/status/747955723003322368/photo/1), поэтому модули es6 также могут выиграть от дрожания дерева при объединении.
@mrdoob
Было ли официальное заявление совсем недавно? Как и многие, мы давно отказались от ES5 и glue-concats, и очень плохо, насколько THREE выпадают из строя в современной системе сборки. Мы используем, может быть, 10% того, что он может делать, но это самая большая зависимость, которую мы поставляем.
Это, наверное, самый любимый проект на Github лично для меня - я искренне надеюсь, что приоритеты будут пересмотрены.
Хм, хотелось бы узнать подробнее о поддержке браузером. Какие браузеры умеют, а какие нет. Для браузеров, которые этого не делают, каковы обходные пути и каковы потери производительности.
Собственно, поддержка браузером перестает быть проблемой (возможно, даже в меньшей степени, чем сейчас). Системы сборки берут этот код ES6 и переносят его в es5 (иногда занимая меньше места, чем было бы в исходном ES5). Определенные виды транслируемых вещей в конечном итоге оказываются большими (в первую очередь: генераторы и асинхронные функции), но если вы их избегаете, вы не получите этого штрафа.
Как упоминалось в @drcmda , система сборки по-прежнему будет производить монолитный вывод (и будет очень легко настроить именно то, что включено в этот вывод), но отдельные модули также могут быть включены в наши собственные проекты, таким образом, используя только те части, которые нам нужно. Чтобы в полной мере воспользоваться
что взаимозависимости необходимо скорректировать, но это может произойти со временем. Я думаю, что основные функции, которые нам нужны, - это сделать его модульным с импортом / экспортом. С вашей точки зрения, это позволит использовать классы вместо прототипов (они по-прежнему используют прототипы под капотом, так что вы все еще можете
возиться с ним по мере необходимости).
Есть несколько систем сборки. Я бы проголосовал за webpack (который использует babel для транспилирования). С помощью babel вы можете определять пользовательские загрузчики, поэтому разработанная вами система фрагментов для шейдеров может быть сокращена до фактического кода glsl с расширением #include (на самом деле я делаю свои шейдеры таким образом и был бы рад внести его в проект). Это дает те же преимущества, что и ваша система (без дублирования кода), но очень проста в использовании.
Я хотел бы принять участие в проекте модульности, но я знаю, что без вашей поддержки (и, вероятно, помощи) это ни в коем случае не увенчается успехом. Многие из нас знают, как использовать библиотеку, но никто из нас не знает, как она работает внутри, в такой степени, как вы.
Определенные виды транслируемых вещей в конечном итоге оказываются большими (в первую очередь: генераторы и асинхронные функции), но если вы их избегаете, вы не получите этого штрафа.
На сколько большой?
Кроме того, вы не говорили о штрафах за производительность. Разве это не проблема?
Насколько я понимаю, импорт ES6 по-прежнему не поддерживается ни одним браузером , поэтому этот рефакторинг модуля будет в основном для систем сборки, верно?
Не забывайте о преимуществах, которые вы получаете при использовании таких инструментов, как rollupjs, это автоматически исключит все экспортные данные, которые пользователь не использует. (Что по умолчанию с JSPM)
Пакет babel-polyfil, который необходим только в том случае, если вы используете
генераторы (которые, вероятно, даже не имеют смысла в этом проекте) или async
функции (которые, я не думаю, сильно изменится в проекте
либо), добавляет около 50 тыс. к окончательной сборке. Но опять же, это необязательно.
Что касается производительности, это действительно зависит от того, какие именно функции вы используете.
с использованием. Например, стрелочные функции немного медленнее из-за
базовая привязка, классы создаются немного медленнее, хотя
время создания экземпляра такое же. https://kpdecker.github.io/six-speed/
Импорт / экспорт ES6 не поддерживаются браузерами, но, поскольку он идет
через систему сборки, это не проблема. Выход продукта будет
можно использовать точно так же, как и в настоящее время (даже с обратной совместимостью), но
позволит интегрировать его в наши системы сборки и сделать
внутренние компоненты, которые можно использовать повторно.
Еще следует отметить окончательный размер сборки. В настоящее время такие вещи, как Геометрия,
Материал, сетка и т. Д. Являются частью пространства имен THREE. При минификации
ссылки на THREE.Geometry, THREE.Material, THREE.Mesh и т. д. остаются в
код. В модульной системе каждый из этих файлов получит что-то вроде
var Geometry = require('./geometry');
тогда ссылки на
переменная Geometry
позже. Затем при минифацитоне Geometry
и require
оба переводятся на отдельные символы, './geometry' заменяется на
номер, что дает небольшую экономию. Математика салфеток: минифицированные
build составляет 511 794 байта и содержит 2942 ссылки на
THREE\.[A-Z][a-zA-Z]+
. Замена всего этого одним символом
приводит к уменьшению размера файла почти на 10% (до 464 782). (Gziped
размеры 117 278 и 110 460 соответственно, сокращение на 6%). Сборка
можно было бы настроить, чтобы уменьшить это еще больше.
Накопительный пакет (который позволяет исключить неиспользуемый код из окончательной сборки) используется по умолчанию.
с jspm, будет по умолчанию с webpack2 (и я считаю, что его можно использовать
с веб-пакетом). Если все будет написано по модульному принципу, я не думаю, что это будет
хотя и полезно. В любом случае, если код можно передать с помощью
babel, его можно использовать в любой системе сборки (загрузчик glsl, о котором я упоминал
before также можно заставить работать с веб-пакетом).
7 июля 2016 г. в 13:28 г-н doob notifications@github.com написал:
Некоторые виды передаваемых вещей в конечном итоге оказываются большими (в первую очередь:
генераторы и асинхронные функции), но если вы их избегаете, у вас не будет
этот штраф.На сколько большой?
-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/mrdoob/three.js/issues/4776#issuecomment -231197171,
или отключить поток
https://github.com/notifications/unsubscribe/AA71cqAqmgxsUjpvamnI_xyL2wpzeWrdks5qTWGBgaJpZM4B4aA7
.
Не уверен, что это очень полезно, но это ветка обсуждения D3 по той же проблеме: https://github.com/d3/d3/issues/2220. D3 4.0 принял импорт / экспорт ES6 для управления модулями, но все еще написан на ES5 (https://github.com/d3/d3/issues/2220#issuecomment-111655235).
Очень интересно @jpweeks!
Итак ... с этим подходом к импорту / экспорту ... Как бы выглядело object instanceof THREE.Mesh
?
@mrdoob
import/export
- это просто способ, которым модули объявляются и требуются. Это не повлияет / не изменит код, определенный в модулях:
src / Объекты / 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! Спасибо!
Я визуальный человек, поэтому примеры псевдокода убеждают меня больше, чем большие куски текста 😅
Верно, потребуется немного рефакторинга ...
Кто-нибудь знает, планирует ли компилятор закрытия поддерживать это?
Верно, потребуется немного рефакторинга ...
Понял тебя! Поскольку за последние пару дней эта тема оживилась, я немного больше поработал над 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 просто повторно экспортирует все модули и функции в один файл:
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 будет единственной скомпилированной частью пакета. Обычно переносится в ES5 через Babel и экспортируется в глобальное пространство имен, чтобы его можно было использовать в качестве включения сценария. Rollup, Webpack и т. Д. Могут с легкостью создать это.
@mrdoob это была замечательная поездка 🚀
Самый полезный комментарий
Понял тебя! Поскольку за последние пару дней эта тема оживилась, я немного больше поработал над
KeyframeTrack
), но скоро должно быть чем поделиться. Насколько я могу судить, все примеры продолжают работать, а минифицированная сборка меньше текущей (с использованием Rollup для создания файла UMD), так что это хорошие новости.