Three.js: Продолжить поддержку библиотек JS вместе с библиотеками ES6 JSM.

Созданный на 5 окт. 2020  ·  51Комментарии  ·  Источник: mrdoob/three.js

Ваш запрос функции связан с проблемой?

Я считаю, что поддержка модульного и классического импорта статических файлов является хорошей гигиеной библиотеки. Это делает библиотеку доступной для более широкой группы разработчиков и позволяет разработчикам использовать предпочитаемый ими стиль.

Лично я действительно стараюсь избегать использования модулей в целом, мне нравятся проекты, которые представляют собой статические файлы с классическими простыми JS-файлами. Может быть, я просто чудак, но я действительно ненавижу то, насколько фреймворки излишне абстрагируют вас от вещей и насколько они заново изобретают колеса или иным образом загоняют вас в черный ящик. Я знаю, что вы можете использовать модули без каких-либо фреймворков, однако включение модулей менее интуитивно понятно, чем включение традиционных JS, они часто подводили меня при попытке использовать их в настройке статического файла.

Использование модулей ES6 не идеально для каждого развертывания, хотя они, безусловно, являются желанным дополнением. Я учу многих новых программистов 3J, потому что мне нравится библиотека, и, по моему мнению, это отличный и приятный способ начать программировать. Гораздо проще научить людей основам ванильного CSS/JS/HTML, не пихая им в глотку весь стек node/npm + framework одновременно. Статические библиотеки проще в использовании/понимании и снижают входной барьер.

Стилистически я также предпочитаю перегружать THREE дополнительными функциями, а не добавлять новые именованные функции, которые свободно перемещаются. Хотя это явно предпочтение.

Опишите желаемое решение

Возможно, я смогу лучше ответить на этот вопрос после того, как получу немного больше информации о том, почему было принято решение перейти только на модули, но я попробую.

В документации говорится, что модули ES6 могут работать не во всех ситуациях, и для этих ситуаций предлагается использовать сборщик, такой как browserify/rollup/webpack/parcel и т. д....

Мое решение состояло бы в том, чтобы автоматический скрипт сборки ES6 проходил через модули в /examples/jsm для создания /examples/js немодульных версий. Таким образом, разработчикам больше не нужно беспокоиться о внесении изменений в двух местах, и они могут продолжать пользоваться немодульными версиями JS и стилем импорта глобальной переменной, если им нравится.

Это автоматическое создание немодульных файлов JS может быть выполнено как часть процесса сборки или может быть командой в package.json, которую кто-то может запустить вручную. Хотя я бы выбрал автоматическую генерацию.

Создание этой автоматизации или иное обслуживание немодульных версий JS этой библиотеки — это то, на что я могу пожертвовать своим временем. Если причиной перехода только на ES6 является не просто устранение необходимости вручную обновлять две параллельные версии одной и той же вещи, я хотел бы обсудить и другие решения для решения этих проблем.

Опишите альтернативы, которые вы рассматривали

Очевидным другим соображением было бы оставить все как есть и продолжать поддерживать версии JS и JSM всех библиотек. Хотя, учитывая объявление о том, что они устарели, я нахожу это несколько маловероятным. Но я был бы рад взять на себя ответственность за то, чтобы библиотеки JS постоянно обновлялись с их аналогами JSM вручную, если мы решим пойти по этому пути.

Дополнительный контекст

Большая любовь к этой библиотеке и всем, кто вносит свой вклад либо в коде, либо сообщая/обсуждая проблемы.

Suggestion

Самый полезный комментарий

Спасибо всем, что поделились плюсами и минусами. Всегда полезно поделиться ими, чтобы убедиться, что мы принимаем обоснованные решения.

Это то, на что я потратил несколько мозговых циклов в этом году, и я даже спросил поставщиков браузеров об их приоритетах, чтобы иметь возможность планировать заранее.

Я согласен с тем, что будущее за модулями ES6, но разработка с их помощью без карт импорта может вызвать огромные головные боли и полностью нарушить ваш рабочий процесс. Когда мы решили отказаться от поддержки examples/js , я надеялся, что импорт карт будет более популярным, но, похоже, в настоящее время это не является приоритетом для браузеров.

Из-за этого я решил приостановить устаревание папки examples/js до тех пор, пока браузеры не реализуют импорт карт. Я бы не хотел заставлять новичков узнавать о полифиллах или упаковщиках, чтобы визуализировать свой первый куб.

Я пришел к тому же выводу, что и @Bug-Reaper. Сегодня я собираюсь создать скрипт, который создает examples/js из examples/jsm файлов.

Все 51 Комментарий

Гораздо проще научить людей основам ванильного CSS/JS/HTML, не пихая им в глотку весь стек node/npm + framework одновременно. Статические библиотеки снижают входной барьер.

Просто чтобы прояснить примеры модулей js, которые поддерживаются в этом проекте, не требуют использования узла, npm или какой-либо другой среды сборки. Их можно использовать как статически обслуживаемые файлы, как и старый глобальный импорт. Им просто требуется синтаксис импорта es6 для использования, но он будет работать во всех современных браузерах.

Просто чтобы прояснить примеры модулей js, которые поддерживаются в этом проекте, не требуют использования узла, npm или какой-либо другой среды сборки. Их можно использовать как статически обслуживаемые файлы, как и старый глобальный импорт. Им просто требуется синтаксис импорта es6 для использования, но он будет работать во всех современных браузерах.

Спасибо за пояснение! Это действительно хороший момент!
Я верю:

<script type="module">

  import { OrbitControls } from 'https://unpkg.com/three@<VERSION>/examples/jsm/controls/OrbitControls.js';

  const controls = new OrbitControls();

</script>
````
is perhaps less intuitive and harder to understand for newcomers than: 

подождите секунду... у нас еще есть:

<script src="path/to/local/build/three.js"></script>

в отличие от:

<script type=module src="path/to/local/build/three.module.js"></script>

Первый — это статический скрипт, который можно использовать в соответствии со старым глобальным способом в чьем-то html... верно? Что вы больше не могли делать после перехода на ES6?

Если я правильно понимаю, план состоит в том, чтобы по-прежнему включать «/build/three.js» в дополнение к «/build/three.module.js».

да. Однако сомнительно, имеет ли этот подход смысл. Когда examples/js удаляется, остается всего несколько вариантов использования, где three.js и three.min.js по-прежнему полезны.

На самом деле было бы полезно удалить three.js и three.min.js , поскольку это позволило бы нам изменить точку входа main npm , см. #19575.

Если мы можем сделать это легко, я считаю, что имеет смысл продолжать поддерживать /examples/js, автоматически генерируя их с помощью скрипта сборщика ES6 как часть процесса сборки.

Идея состоит в том, чтобы перенести examples/jsm на более современные функции языка JavaScript, такие как классы. Поскольку examples/js по-прежнему должен работать со старым браузером, необходимо настроить новую сборку (примеры) с функциями транспиляции кода. Кроме того, мы по-прежнему будем хранить дублированную кодовую базу ( examples/js против examples/jsm ), что, на мой взгляд, является плохим подходом. Это усложняет обслуживание.

Я считаю, что пользователь должен позаботиться о преобразовании ES6 в ES5, если это необходимо. То же самое для минимизации кода или других задач, связанных со сборкой.

Я считаю, что вы правы. Если я правильно понимаю, план состоит в том, чтобы по-прежнему включать « /build/three.js » в дополнение к « /build/three.module.js ».

Истинный

Проблема с заполнителями из папки /examples заключается в том, что вам нужно использовать файлы из папки /examples/js при использовании папки /build/three.js и файлы из папки $#$ /examples/jsm $#$ при использовании папки /build/three.module.js , также известный как сохранение согласованности в методе загрузки.

Почему? Потому что при использовании импорта модуля основной объект THREE больше не является простым js-объектом THREE = {} , а вместо этого объект модуля внутреннего браузера, который запечатан (не расширяем), поэтому файлы из /examples/js , который пытается записать новое свойство в объект THREE , терпит неудачу.

Так что вы не можете смешивать import * as THREE from '/build/three.module.js и THREE.WhateverExample = function() ...

Один из возможных способов - изменить имя импортированной библиотеки на любое другое, кроме THREE , и заново создать простой глобальный объект js THREE для примеров, которые будут записаны в нем...

Обычно это проблема

традиционный JS включает

это загрязняет глобальное именование пространства, и поскольку вы не можете изменять имена в загруженном файле, вы можете получить такие ошибки...
С другой стороны, с модулями пользователь получает возможность именования во время импорта, и уже не автор библиотеки выбирает результирующее имя...

бывший:

<script>
// a script you can't modify already use the name THREE
var THREE = document.getElementById('div-nb-3')
</script>

<script type="module">
import * as foo from '/build/three.module.js'

THREE.appendChild( new foo.WebGLRenderer().domElement )
</script>

@ Mugen87 Ты прав на 100%. Если мы откажемся от /examples/js , мы можем также отказаться от three.js и three.min.js , поскольку они по существу несовместимы ни с одним из дополнительных модулей. Их вариант использования будет нишевым, и это почти гарантированно вызовет путаницу.

@devingfx Вы правы в том, что модули имеют преимущества и устраняют потенциальные конфликты глобальных имен. За годы использования у меня никогда не было конфликтов с глобальной переменной THREE, и я думаю, что это маловероятный сценарий, но ваша точка зрения технически верна.

что, на мой взгляд, плохой подход. Это усложняет обслуживание.

Я считаю, что пользователь должен позаботиться о преобразовании ES6 в ES5, если это необходимо. То же самое для минимизации кода или других задач, связанных со сборкой.

@ Mugen87 Mugen87 Неужели так уж ужасно поддерживать традиционное включение js, которое использует глобальную переменную в дополнение к модулю? Многие библиотеки поддерживают и то, и другое, и, насколько я могу судить, традиционная версия JS часто так же широко используется, как и аналоги модульной версии. У обоих есть преимущества/недостатки, и некоторые из них сводятся к предпочтениям. Разве не хорошо дать разработчикам возможность использовать библиотеку в немодульном контексте?

Я готов позаботиться о создании/тестировании необходимых функций транспиляции кода для автоматического создания three.min.js, three.js и /examples/js из three.module.js и /examples/jsm . После доработки рабочего процесса транспиляции может потребоваться минимальное обслуживание, но это != поддержание двух параллельных версий. По большей части код нужно было бы обновлять только в файлах модуля, и лишь изредка вам нужно было бы исправить некоторые ошибки транспиляции.

У меня достаточно проектов, которые полагаются на традиционный глобальный синтаксис и включают в себя то, что я все равно буду выполнять работу по автоматизации транспиляции модулей. Я думаю, по крайней мере, мы могли бы включить команду в package.json и назвать ее «legacy-build», которая преобразует модули в three.min.js, three.js и /examples/js , которые ведут себя аналогично оригиналу. файлы сейчас. Эти файлы даже не нужно фиксировать в репо или создавать по умолчанию. Мы также можем предупредить, что они предназначены для устаревшей поддержки, они не гарантируют работу, вместо этого мы предлагаем использовать модули и т. д.

На самом деле, я думаю, что имеет больше смысла хранить их в репо и просто автоматически генерировать их путем транспиляции при сборке.

команду в package.json и назовите ее «legacy-build», которая транспилирует модули

кажется разумным. Разве Babel не был недавно объединен? так что я думаю, что это может быть выполнимо, как есть

изменить: чтобы уточнить, чтобы не было сказано, что новая команда будет выполняться кем-либо, кроме пользователей, которые хотят, чтобы указанная сборка

Неужели так уж ужасно поддерживать традиционный js-инклюд, который использует глобальную переменную в дополнение к модулю?

Я думаю, что сложность поддержания этого недооценивается. К сожалению, я не думаю, что это так просто с тем, как примеры настроены в проекте.

Давайте рассмотрим в качестве примера GLTFLoader. В настоящее время весь GTLTFLoader содержится в одном файле, что упрощает его включение в верхнюю часть HTML-файла. Одним из преимуществ модулей является то, что некоторые из больших файлов могут быть разбиты на отдельные файлы, которые GLTFLoader может импортировать в качестве зависимостей. Как должен выглядеть встроенный глобальный скрипт, если GLTFLoader зависит от четырех внешних файлов, некоторые из которых являются общими? Должны ли пользователи встроенных глобальных сценариев теперь включать все эти файлы примеров js по отдельности? Или некоторые файлы будут объединены вместе, что потребует ручного ведения списка файлов, которые можно объединять, а какие нет?

Я думаю, что единственным действительно установленным и забытым случаем является объединение всех файлов примеров js в один монолитный блок, что я не считаю разумным. Я думаю, что с любым из этих решений также будут некоторые другие накладные расходы на выпуск и документацию.

Возможно, есть лучший способ сделать это, но когда я попытался создать накопительную сборку, которая сохранила бы обратную совместимость или, по крайней мере, согласованную структуру с существующими файлами js, я столкнулся с этими проблемами.

Если я правильно понимаю, план состоит в том, чтобы по-прежнему включать «/build/three.js» в дополнение к «/build/three.module.js».

да. Однако сомнительно, имеет ли этот подход смысл.
После удаления examples/js остается всего несколько вариантов использования, где по-прежнему полезны three.js и three.min.js.

@ Mugen87

Майкл,
На самом деле ОБЯЗАТЕЛЬНО сохранить «three.min.js» еще как минимум 2 года.
Не потому, что все мои образцы основаны на нем.
А потому, что на нем основаны многие тысячи файлов и лучших собак Google!
Пример: https://www.google.com/search?source=hp&q=webgl+benchmark .

С другой стороны, с моей точки зрения, «three.min.js» означает более быструю разработку и тестирование.
Не говоря уже о том, что он работает в автономном режиме, и вам не нужен локальный хост.
Просто поместите все файлы в какую-нибудь папку, используйте Firefox и дважды щелкните файл HTML.
Я всегда любил это для развития!

Рикардо также должен подумать обо всем этом.
ваше здоровье

Удаление three.js и three.min.js можно обсудить и спланировать, когда examples/js исчезнет. Мне просто было важно подчеркнуть их утрату значимости, когда вы больше не можете импортировать файлы из examples/js .

Я думаю, что сложность поддержания этого недооценивается. К сожалению, я не думаю, что это так просто с тем, как примеры настроены в проекте.

Мне очень нравятся те моменты, которые вы продолжаете поднимать. В связывании есть абсолютно непредвиденная сложность, и пример вложенных модулей — хороший пример. К вашему сведению, я думаю, что мы можем прийти к разумным решениям о том, как обрабатывать вложенные модули, когда придет время. Я не говорю, что сценарий упаковщика будет установлен и забыт, просто он будет менее обслуживаемым.

Если придет время, когда его будет слишком сложно поддерживать, мы всегда можем отказаться от него, но я думаю, что глупо сбрасывать со счетов попытки из-за проблем, которых у нас еще нет. Это будет проще всего реализовать сейчас, пока у нас все еще есть паритет 1 к 1 между /examples/jsm и examples/js . Скорее всего, мы не будем массово реорганизовывать иерархию модулей /example/jsm , и я думаю, что когда мы это сделаем, мы сможем вносить дополнительные обновления в сборщик. Я собираюсь пойти дальше и начать работать над доказательством работы для этого (с babel, потому что он уже добавлен?), чтобы, как говорится, вложить свои деньги в то, что я говорю.

По мнению Мугена, это помогло бы сохранить некоторую актуальность для three.js и three.min.js , пока мы продолжаем их поддерживать. Это также может помочь сотням сайтов, которые могут искать обновление, совместимое с их реализацией THREE, не основанной на модулях. Рефакторинг проекта THREE для использования модулей может быть весьма обширным, даже если вы знаете, что делаете.

Я не могу говорить за других сотрудников, но я не изменю своего мнения по этой теме. Я голосую за удаление examples/js с декабрьским выпуском в 2020 году, как обсуждалось и зафиксировано здесь #18749.

Я голосую за удаление примеров/js с декабрьским выпуском 2020 года, как обсуждалось и зафиксировано здесь #18749.

У меня нет проблем с этим.
Пока "three.min.js" доступен еще пару лет...

Спасибо за вклад, Муген, я прочитал эту ветку, но она выглядит скорее как объявление, а не как объяснение решения. Я предполагаю, что упрощенная разработка является основной причиной движения в этом направлении, есть ли другие?

Я думаю, что наличие скрипта транспиляции, который мы можем запустить для генерации стилей /examples/js , должно быть хорошим компромиссом. Это должно значительно уменьшить объем технического обслуживания/усложнения, необходимого здесь. Я даже был бы в порядке, если бы это была просто команда в package.json, которую вам нужно было запускать самостоятельно, а файлы не генерировались по умолчанию. Есть преимущества для некоторых разработчиков и других, которым в любом случае потребуется транспиляция. Я бы предпочел, чтобы мы все не создавали рабочий процесс транспиляции/связки отдельно, когда что-то можно было бы сохранить в основном репо, чтобы мы могли лучше сотрудничать. :)

Я прочитал эту ветку, но она больше похожа на объявление, чем на объяснение решения.

К сожалению, мы не всегда можем привязать все действительные аргументы к одному потоку, либо потому, что реализация изменения дизайна медленно прогрессирует в многочисленных дискуссиях на протяжении многих лет, либо просто потому, что несколько потоков об одном и том же предмете создаются снова и снова (например, этот ). Соавторы стараются минимизировать шум и сегментацию, но это не всегда возможно.

Я предполагаю, что упрощенная разработка является основной причиной движения в этом направлении, есть ли другие?

Самая большая из них, которую я вижу, — это возможность использовать и импортировать подмодули, которые минимизируют избыточный код и позволяют повторно использовать реализации.

Например, большинству загрузчиков необходимо создать какую-то структуру/класс для синтаксического анализа данных, потому что каждый загрузчик должен быть самодостаточным, чтобы файлы example/js можно было использовать повторно. Однако, если мы полностью удалим немодульное ограничение, мы сможем создать единственный экземпляр класса DataParser и импортировать эту стандартную реализацию во все загрузчики, что немедленно упростит разработку, а также удалит избыточный код из все грузчики.

Да, хорошая мысль. Нам уже приходится делать грязные хаки, такие как встраивание класса Pass (базовый класс всех проходов FX) в EffectComposer только для того, чтобы гарантировать, что унаследованный код не сломается.

очень хорошие моменты, сделанные вокруг.

Получение и поддержание людей в курсе событий звучит (и по моему собственному опыту) как сложная проблема. попробую подумать над этим.

На самом деле ОБЯЗАТЕЛЬНО сохранить «three.min.js» еще как минимум 2 года.

Всегда можно будет сгенерировать сборку ES5 с помощью Babel. Вопрос, на который нам нужно будет ответить, когда дело доходит до этого, заключается в том, лежит ли ответственность за это на нас или на разработчике, использующем three.js.

Мы уже решили, что разработчик должен создавать версии ES5 файлов примеров, поэтому, вероятно, имеет смысл сделать то же самое для файлов сборки. На мой взгляд, также имеет смысл сделать это для всей библиотеки в одном релизе, а не разбивать его, но оставить three.min.js на некоторое время тоже нормально.

А потому, что на нем основаны многие тысячи файлов и лучших собак Google!
Пример: google.com/search?source=hp&q=webgl+benchmark.

Это лучший сайт, который я нашел в этом поиске, и они используют R53, поэтому я не думаю, что это изменение повлияет на них слишком сильно: https://www.wirple.com/bmark/

Как видите, старые версии three.js до сих пор прекрасно работают. После того, как мы перейдем к модулям, мы можем направить любого, кто хочет сборку ES5 без использования Babel, использовать последнюю версию до того, как мы удалили файлы ES5. Они могут проверить весь репозиторий этого выпуска и использовать документы из этой версии.

@looeee Вы затронули несколько хороших моментов. Как упоминалось выше, я согласен с тем, что здесь имеет смысл одновременно отказаться от ES5 three.min.js и three.js . Возможно, это должно быть его собственное отдельное обсуждение?

В любом случае я хотел бы прийти к консенсусу по поводу включения сценария babel в основное репо, который можно использовать для создания файлов /js/example в стиле старой школы ES5. Это никоим образом не касается того, несет ли кто-либо ответственность за предоставление этой поддержки. Есть участники, такие как я, которым понадобится эта функция. Есть преимущества для некоторых разработчиков и других, которым в любом случае потребуется транспиляция. Я бы предпочел, чтобы мы все не создавали рабочий процесс транспиляции/связки отдельно, когда что-то можно было бы сохранить в основном репо, чтобы мы могли лучше сотрудничать.

Я думаю, что это справедливый компромисс, чтобы позволить нам один файл в основном репозитории, чтобы мы могли вместе работать над сценарием транспилятора babel ES6 в ES5. Там действительно проблема? Разрешить участникам совместно работать над нужной им функцией в основном репозитории?

Я не прошу соавторов о какой-либо помощи или ресурсах для этого, я просто прошу вас разрешить людям, которым это нужно, работать над этим вместе в основном репо. Если я сделаю PR для этого, и это сработает, вы действительно проголосуете против этого?

Если я сделаю PR для этого, и это сработает

Я имею в виду, я рад видеть, что это началось

Вы действительно проголосовали бы за его отклонение?

все ставки будут сняты, если он не пройдет линтинг 😂

Там действительно проблема?

Да, так как репозиторий не должен продвигать устаревшие шаблоны кодирования.

Да, так как репозиторий не должен продвигать устаревшие шаблоны кодирования.

Официально это еще не объявлено устаревшим, если мы не увольняем three.js + three.min.js (признал консенсус ITT, что мы должны уволить и их тоже) и иметь скрипт babel, который вы должны запускать вручную самостоятельно, это едва ли яркое одобрение. Я согласен, что мы определенно должны поощрять людей использовать вместо этого модули и иметь предупреждение об этом в скрипте babel и сгенерированных файлах. Я не согласен с тем, чтобы участники совместно работали над скриптом babel для людей в ситуациях, которые не могут использовать модули по какой-либо причине, продвигая устаревший шаблон кодирования. В основном потому, что все еще бывают ситуации, когда использование модулей невозможно/нецелесообразно. Документы признают эту необходимость. Я думаю, что мы можем смело добавить один файл для людей, которым он нужен для совместной работы над ним.

Я согласен с тем, что имеет смысл одновременно отказаться от ES5 three.min.js и three.js.

Я имел в виду, что мы должны отказаться от использования examples/js, three.min.js и three.js одновременно, то есть удалить весь код ES5 в одном выпуске, а не распространять его на несколько выпусков.

@Mugen87

Да, так как репозиторий не должен продвигать устаревшие шаблоны кодирования.

Вы по-прежнему можете запускать игры DOS в Windows 10.
И это не означает, что Microsoft продвигает «устаревшие шаблоны кодирования».

Просто чтобы прояснить примеры модулей js, которые поддерживаются в этом проекте, не требуют использования узла, npm или какой-либо другой среды сборки.

Что ж, давайте не будем забывать, что создание готового приложения означает объединение вашего кода :)

Я ценю доступные инструменты, такие как Rollup, но думаю, что нам следует рассмотреть пару вопросов:

  • Справедливо ли предположить, что если разработчики хотят использовать THREE в производственной среде, им также необходимо использовать один из этих инструментов для связывания?
  • Справедливо ли отказаться от поддержки других библиотек, которые полагаются на обновления модулей ES5/UMD в папке примеров?

Мои личные ощущения по этому поводу:

Этой библиотеке десять лет. Существует огромная экосистема, основанная на модулях в папке примеров, написанных на ES5/UMD. Я не думаю, что справедливо отказываться от поддержки всей экосистемы.

Я думаю, что люди забывают, что вы все еще можете использовать ES6 без шаблона связывания модулей. Я использую ES6 каждый день, но не использую шаблоны связывания модулей в своих приложениях для внешнего интерфейса. Я работал в корпоративных магазинах, где инструменты сборки по необходимости становятся очень индивидуальными и не могут включать шаблон объединения модулей.

Что нам делать?

Давайте скомпилируем модули ES6 в модули ES5/UMD для данного дистрибутива после каждого выпуска.

Да, так как репозиторий не должен продвигать устаревшие шаблоны кодирования.

Почти для всего в жизни решение может быть отличного качества, используя старые шаблоны, методы и инструменты.

В качестве аналогии - в свободное время я люблю резать камень остроконечными стамесками. Инструменты и техники отличаются от электроинструментов, но в итоге скульптура все равно будет качественной. Лично я предпочитаю использовать точечные долота, потому что мне нравится ими пользоваться, и у меня есть навыки, необходимые для изготовления чего-то, что нравится мне или другим.

То же самое я думаю о модулях ES5/UMD. Мне удалось найти шаблоны, методы и инструменты, которые поддерживают действительно высококачественные кодовые базы, и я хочу продолжать использовать это личное предпочтение.

Давайте скомпилируем модули ES6 в модули ES5/UMD для данного дистрибутива после каждого выпуска.

Я согласен с тем, что сказал loeeee.

Справедливо ли предположить [...]

какие? Мы говорим о том, какой подход мы бы предпочли, «предположение» идет потом. Предпочтение, кажется, направлено на поощрение других к использованию модулей, но (при условии, что некоторые люди все еще хотят старый THREE) предлагает путь для тех, кто действительно этого хочет.

Давайте скомпилируем модули ES6 в модули ES5/UMD для данного дистрибутива после каждого выпуска.

Это может сделать любой; эти расходы не должны нести сопровождающие three.js. Я хотел бы повторить то, что @gkjohnson сказал выше, стоимость обслуживания каталогов examples/js и examples/jsm высока. Мы не можем делать это бесконечно, и ясно, что модули ES6 являются более современными из двух подходов. Рассмотрим следующие расходы:

  • Создание и поддержка автоматизации
  • Отладка сбоев выпуска при сбое автоматизации
  • Обеспечение того, чтобы все запросы на вытягивание обновляли исходный файл, а не сгенерированный.
  • Ведение документации, объясняющей, как используются оба рабочих процесса.
  • Ответы на отчеты об ошибках и вопросы поддержки от пользователей, пытающихся использовать рабочие процессы CJS и ES6.

Последний пункт, возможно, самый большой. Пока в этом репозитории доступны две копии всего, обе будут считаться полностью поддерживаемыми. Мы регулярно тратим время на помощь пользователям, которые путают два рабочих процесса или пытаются использовать загрузчик модулей ES6 с основной библиотекой CJS, что приводит к сложным сбоям.

Мы можем просто перефразировать проблему: все наши примеры — которые являются важными, но необязательными частями библиотеки three.js — в настоящее время вообще не используют синтаксис модуля. Не UMD, не CommonJS, не модули ES6. Они просто исправляют глобальное пространство имен THREE . Мы хотели бы обновить это, используя вместо этого синтаксис импорта/экспорта ES6, и было много ранних предупреждений о том, что это изменение было запланировано.

Существует огромная экосистема, основанная на модулях в папке примеров, написанных на ES5/UMD. Я не думаю, что справедливо отказываться от поддержки всей экосистемы.

Я не думаю, что будет справедливо сказать, что что-то в экосистеме three.js настолько зависит от глобальных пространств имен THREE.* , что его нельзя обновить, чтобы использовать синтаксис импорта/экспорта, или транспилировать в ES5, или использовать упаковщик. Здесь есть несколько обходных путей, и мы будем рады работать с пользователями, чтобы помочь найти для них подходящий вариант.

стоимость обслуживания каталогов examples/js и examples/jsm высока.

Я хотел бы копнуть в этом немного больше. Я написал множество пользовательских инструментов и скриптов автоматизации для интерфейсных приложений и буду рад помочь, чем смогу.

Создание и поддержка автоматизации
Отладка сбоев выпуска при сбое автоматизации

Помогите мне немного понять налог на поддержку, это что-то уникальное для кодовой базы THREE? По моему опыту, этот тип кода обычно самый долгоживущий и требует наименьшего обслуживания. Это сценарии, которые вы пишете один раз и не просматриваете снова в течение длительного периода времени.

Обеспечение того, чтобы все запросы на вытягивание обновляли исходный файл, а не сгенерированный.

Возможно, небольшой скрипт или тест помогут с этим в рабочем процессе релиза.

Ведение документации, объясняющей, как используются оба рабочих процесса.

Я бы также проголосовал за отказ от документации для глобальных пространств имен. Я думаю, что глупо поддерживать документацию для двух рабочих процессов. Это неплохо. Большинство библиотек, которые объединяют свой код для разных контекстов, модули UMD/ES6 имеют только один набор документации.

Ответы на отчеты об ошибках и вопросы поддержки от пользователей, пытающихся использовать рабочие процессы CJS и ES6.

Я думаю, что количество проблем, связанных с чем-то вроде этого, зависит от размера популярности THREE. Мы с вами постоянно видим подобные проблемы в Stack Overflow. Пользователь, который не может различить два рабочих процесса, скорее всего, является начинающим программистом, вдохновленным библиотекой, и просто пытается изучить основы программирования в целом.

Если цель состоит в том, чтобы уменьшить количество проблем, конкретно связанных с путаницей между двумя рабочими процессами , то удаление кода ES5, вероятно, поможет в этом, но я сомневаюсь, что объем проблем в целом изменится. Новый программист всегда застрянет на следующем вопросе, который может быть связан или не связан с библиотекой.

Как уменьшить объем вопросов в целом?

Если реальная цель состоит в том, чтобы уменьшить объем проблем в целом , может помочь более строгая политика проблем. Я вижу, вы, ребята, отлично справились с этим, уже используя теги вроде Help (please use the forum) , но, возможно, таких вещей должно быть больше.

В более общем плане было бы лучше просто не рассматривать некоторые типы вопросов, которые ТРИ участника готовы обсудить и исследовать, если они в настоящее время чувствуют себя перегруженными общим объемом.

Пара идей:

  • На момент написания статьи suggestions и enhancements имели (271) нерешенных вопросов. Эти метки, кажется, производят много шума. Может быть, только принять PR готовы / проверки, пройденные как актуальное предложение. Insta-закройте все остальное и отметьте как Discussion (please use the forum) .
  • На момент написания loaders имеют (61) нерешенных вопросов. Эта метка также создает много шума. Я вижу много проблем с этим ярлыком, связанных с suggestions и enhancements или плохо сформированными отчетами об ошибках. Может быть, взять только хорошо оформленные отчеты об ошибках и готовые PR/проверки предложений. Insta-закройте все остальное и отметьте соответственно.

Я не думаю, что будет справедливо сказать, что что-либо в экосистеме three.js настолько зависит от глобальных пространств имен THREE.*, что его нельзя обновить, чтобы использовать синтаксис импорта/экспорта, транспилировать в ES5 или использовать упаковщик.

Я согласен, что все можно обновить, но если мы найдем способ проделать небольшую работу, чтобы продолжать поддерживать этих пользователей устойчивым образом, я согласен с @Bug-Reaper в том, что он говорит:

Я бы предпочел, чтобы мы все не создавали рабочий процесс транспиляции/связки отдельно, когда что-то можно было бы сохранить в основном репо, чтобы мы могли лучше сотрудничать.

В совокупности мы бы сэкономили этим пользователям огромное количество времени на обновление их приложений/библиотек, систем сборки и документации.

Я хотел бы копнуть в этом немного больше. Я написал множество пользовательских инструментов и скриптов автоматизации для интерфейсных приложений и буду рад помочь, чем смогу.

хорошо.

Как уменьшить объем вопросов в целом?

Давайте держать это в курсе, пожалуйста. Готов продолжить обсуждение в другой теме. Это отчасти относится к моему предыдущему комментарию .

Я согласен с @Bug-Reaper в том, что он говорит:

Я бы предпочел, чтобы мы все не создавали рабочий процесс транспиляции/связки [...]

Я думаю, мы все согласны с этим.

Спасибо всем, что поделились плюсами и минусами. Всегда полезно поделиться ими, чтобы убедиться, что мы принимаем обоснованные решения.

Это то, на что я потратил несколько мозговых циклов в этом году, и я даже спросил поставщиков браузеров об их приоритетах, чтобы иметь возможность планировать заранее.

Я согласен с тем, что будущее за модулями ES6, но разработка с их помощью без карт импорта может вызвать огромные головные боли и полностью нарушить ваш рабочий процесс. Когда мы решили отказаться от поддержки examples/js , я надеялся, что импорт карт будет более популярным, но, похоже, в настоящее время это не является приоритетом для браузеров.

Из-за этого я решил приостановить устаревание папки examples/js до тех пор, пока браузеры не реализуют импорт карт. Я бы не хотел заставлять новичков узнавать о полифиллах или упаковщиках, чтобы визуализировать свой первый куб.

Я пришел к тому же выводу, что и @Bug-Reaper. Сегодня я собираюсь создать скрипт, который создает examples/js из examples/jsm файлов.

@мрдуб

Я решил приостановить устаревание папки examples/js до тех пор, пока браузеры не реализуют карты импорта.
Я пришел к тому же выводу, что и @Bug-Reaper. Сегодня я собираюсь создать скрипт, который собирает примеры/js из файлов примеров/jsm.

Мудрое решение.
👍

@mrdoob Я, конечно, принимаю твое решение, но я думаю, что это упущенная возможность. Рано или поздно разработчикам придется отойти от глобальных скриптов. И я не думаю, что Import Maps здесь будет иметь большое значение. Вместо того, чтобы «принуждать» пользователей к более совершенным и ориентированным на будущее рабочим процессам, мы позволяем им продолжать использовать глобальные сценарии. В 2020 году.

И я не думаю, что Import Maps здесь будет иметь большое значение.

На днях я видел, как кто-то делал это:

<script src="js/three.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/loaders/GLTFLoader.js"></script>
<script type="module" src="js/main.js"></script>

И внутри main.js они делали это:

import {OrbitControls} from "https://threejsfundamentals.org/threejs/resources/threejs/r119/examples/jsm/controls/OrbitControls.js";

И это действительно сработало... 😐

Мы не можем просто ожидать, что пользователи будут делать правильные вещи, они учатся и пробуют что-то, пока что-то не сработает. Задача состоит в том, чтобы найти дизайн, который поможет им поступать правильно, даже если они этого не осознают.

Проблема с модулями ES6 без карт импорта заключается в том, что пользователь не может просто скопировать OrbitControls.js в папку /js в своем собственном проекте и импортировать ее, как раньше. Это не сработает, потому что OrbitControls.js ищет ../../build/three.module.js .

С картами импорта OrbitControls.js будет просто импортировать из three . Пользователь может скопировать файл куда угодно, а затем настроить путь на карте импорта.

Карты импорта приближают нас к простоте импорта файлов, как в «старые» времена. Это будет не так просто, как раньше, но, по крайней мере, пользователю не придется беспокоиться о порядке импорта файлов. Что-то выиграть, что-то потерять.

Согласен, что карты импорта сделают импорт настраиваемым и, следовательно, более гибким. Хотя пользователю еще предстоит настроить карту импорта (и тем самым понять, что же это такое на самом деле).

Я просто думаю, что все «копировать файлы JS в папку» — это злой антишаблон, и я надеялся, что мы сможем предотвратить это, порекомендовав новым пользователям/новичкам работать с импортом CDN (что также является вариантом для разработчиков, которые не не хотите использовать сборку по каким-либо причинам). В любом случае правильные приложения (должны) использовать инструменты сборки.

Я действительно не вижу анти-шаблон.

Именно так я научился делать веб-сайты. Можно поместить файлы $# .css /css , затем изображения в папку /img и файлы $#$ .js $#$ в папку /js .

За последние месяцы я провел несколько экспериментов с использованием подхода ES6 Modules/CDN, и мне не нравится, что библиотеки поступают из другого домена, чем тот, где находится мой проект.

Одна большая вещь, которую мы теряем, когда не копируем файлы, — это возможность их редактировать. Файлы в examples/js всегда должны были быть примерами, на основе которых вы можете строить. Если бы я скопировал OrbitControls.js в свой проект, и он не делал именно то, что мне нужно, я мог бы просто изменить его, потому что это был просто локальный файл.

Вот как я использовал для настройки своих проектов:

<script src="js/libs/three.js"></script>
<script src="js/libs/three/OBJLoader.js"></script>
<script src="js/libs/three/OrbitControls.js"></script>
<script>
    console.log( THREE, THREE.OBJLoader, THREE.OrbitControls );
</script>

С картами импорта это будет выглядеть так:

<script type="importmap">
{
  "imports": {
    "three": "js/libs/three.module.js",
    "OBJLoader": "js/libs/three/OBJLoader.js",
    "OrbitControls": "js/libs/three/OrbitControls.js"
  }
}
</script>
<script type="module">
    import * as THREE from 'three';
    import { OBJLoader } from 'OBJLoader';
    import { OrbitControls } from 'OrbitControls';

    console.log( THREE, OBJLoader, OrbitControls );
</script>

Не так красиво, как раньше, но заботится о зависимостях/порядке импорта за вас и не требует сборщика.

Тем не менее, это все еще работает для людей, которые занимаются разработкой на основе пакетов. На самом деле, это делает их лучше, потому что аддоны теперь импортируются из three вместо ../../build/three.module.js .

И это действительно сработало... 😐

FWIW, похоже, это действительно работает только в небольшом количестве случаев. Когда он не работает, он выходит из строя чрезвычайно запутанным образом, и у нас было несколько зарегистрированных проблем, связанных с тем, что это происходит и с процессами сборки. Возможно, если вы беспокоитесь о том, что новичок дает им несколько способов использования одних и тех же файлов, это более подвержено ошибкам и сбивает с толку.

Возможно, это несущественно, но, возможно, стоит сообщить людям, что у них есть две копии three.js, включенные в страницу, с помощью предупреждения в консоли (даже если они одной версии), что может вызвать проблемы, если не принять меры, чтобы не смешивать их. ~ Я считаю, что React делает это по тем же причинам ~ React может просто указать на это как на возможный источник ошибки. Это меньше всего могло бы помочь отвлечь людей от смешивания этих модальностей при обучении.

Я пришел к тому же выводу, что и @Bug-Reaper. Сегодня я собираюсь создать скрипт, который собирает примеры/js из файлов примеров/jsm.

Если это новый план, я был бы рад помочь возродить # 15526 / # 15543 (которые теперь удалены из проекта), которые собирают каждый файл модуля в файл ES6. Учитывая, что некоторые примеры разбросаны по стольким файлам (например, шейдерным узлам), и нас может заинтересовать разделение некоторых модулей на несколько файлов, возможно, стоит обновить сценарий объединения, чтобы получить явный список файлов, которые мы хотим преобразовать. и вывод. Мы также должны иметь возможность автоматически создавать зависимости между выводимыми файлами.

Одна большая вещь, которую мы теряем, когда не копируем файлы, — это возможность их редактировать.

Я согласен, хотя, если мы сможем посещать занятия повсюду, я надеюсь, что-то вроде:

import orbitalcontrols from  orbitalcontrolsURL

class mycontrols extends orbitalcontrols {
// do the edits I care about
}

а потом позже

let controls = new myorbitalcontrols

Одна большая вещь, которую мы теряем, когда не копируем файлы, — это возможность их редактировать.

Я согласен, хотя, если мы сможем посещать занятия повсюду, я надеюсь, что-то вроде:

импортировать orbitalcontrols из orbitalcontrolsURL

класс mycontrols расширяет орбитальные элементы управления {
// вносим нужные мне правки
}

а потом позже

пусть элементы управления = новые myorbitalcontrols

Вы уже можете это сделать... даже если родительский «класс» — это простая функция js!

Код действительно работает (в быстром тесте отладчика):

Promise.all([
    import('https://unpkg.com/three/build/three.module.js')
        .then( mod=> [mod.Camera, mod.WebGLRenderer] ),
    import('https://unpkg.com/three/examples/jsm/controls/OrbitControls.js')
        .then( mod=> mod.OrbitControls )
])
.then( ([
    [ Camera, WebGLRenderer ],
    OrbitControls
])=> new ( class extends OrbitControls {} )( new Camera, (new WebGLRenderer).domElement )
)
.then( console.log )

... или более простой синтаксис:

(async function() {

let { Camera, WebGLRenderer } = await import('https://unpkg.com/three/build/three.module.js')
,   { OrbitControls } = await import('https://unpkg.com/three/examples/jsm/controls/OrbitControls.js')

class Con extends OrbitControls { }

let my = new Con( new Camera, (new WebGLRenderer).domElement )
console.log( my )

})()

помимо этой функции aynom и беспокойства об обещаниях async/await, круто

class mycontrols extend orbitalcontrols {
 // do the edits I care about
 }

В идеале мы должны продвигать именно этот шаблон, а не предлагать пользователям редактировать исходные файлы при внесении изменений. Однако примеры написаны без учета расширяемости, поэтому существуют серьезные ограничения на то, чего вы можете достичь. По моему опыту, вам в конечном итоге придется скопировать весь исходный пример в конструктор расширенного класса, чтобы заставить его работать, поэтому нет смысла использовать extend .

Например, наиболее часто запрашиваемое изменение для OrbitControlsограничение панорамы . Это легко сделать, как показано в скрипке @ Mugen87 из этой темы.

Короче говоря, вы добавляете векторы minPan и maxPan и фиксируете controls.target в методе controls.update .

Я попытался сделать это, расширив OrbitControls . Вы можете создать расширенный класс, и он отлично работает. Однако проблемы становятся очевидными, когда вы начинаете вносить изменения. Вы не можете просто расширить метод update :

class OrbitControlsPanLimit extends OrbitControls {
    constructor(object, domElement) {
        super(object, domElement);
    }

    update() {
        super.update();
        console.log('Custom update function');
    }
}

Этот расширенный класс работает ( глюк ), но этот новый метод OrbitControlsPanLimit.update игнорируется. Оригинальный метод OrbitControls.update все еще используется.

Вы можете перезаписать его, переопределив в конструкторе:

class OrbitControlsPanLimit extends OrbitControls {
    constructor(object, domElement) {
        super(object, domElement);

        this.update = () => {
            console.log('Custom update function');
        }
    }
}

Здесь нельзя использовать super.update() , поэтому единственный вариант — скопировать весь исходный метод обновления. Однако этот метод опирается на множество этих вещей из OrbitControls , которые являются общими для всех методов.

    //
    // internals
    //

    var scope = this;

    var changeEvent = { type: 'change' };
    var startEvent = { type: 'start' };
    var endEvent = { type: 'end' };

    var STATE = {
        NONE: - 1,
        ROTATE: 0,
        DOLLY: 1,
        PAN: 2,
        TOUCH_ROTATE: 3,
        TOUCH_PAN: 4,
        TOUCH_DOLLY_PAN: 5,
        TOUCH_DOLLY_ROTATE: 6
    };

    var state = STATE.NONE;

    var EPS = 0.000001;

    // current position in spherical coordinates
    var spherical = new THREE.Spherical();
    var sphericalDelta = new THREE.Spherical();

    var scale = 1;
    var panOffset = new THREE.Vector3();
    var zoomChanged = false;

    var rotateStart = new THREE.Vector2();
    var rotateEnd = new THREE.Vector2();
    var rotateDelta = new THREE.Vector2();

    var panStart = new THREE.Vector2();
    var panEnd = new THREE.Vector2();
    var panDelta = new THREE.Vector2();

    var dollyStart = new THREE.Vector2();
    var dollyEnd = new THREE.Vector2();
    var dollyDelta = new THREE.Vector2();

Конечным результатом является то, что вам придется скопировать почти весь исходный OrbitControls в конструктор OrbitControlsPanLimit , что противоречит цели расширения класса. Если мы не напишем элементы управления как класс с учетом расширяемости, я не думаю, что его расширение целесообразно.

спасибо @looeee за участие. Я подумал, может быть, я упустил простое решение в своих собственных усилиях, но теперь, когда вы упомянули об этом, я в значительной степени взял себя в руки.

В идеале мы должны продвигать именно этот шаблон, а не предлагать пользователям редактировать исходные файлы при внесении изменений.

Осторожно, это близко к аргументу наследования и композиции.

В идеале библиотека не должна продвигать какие-либо шаблоны. Он должен продвигать свои функции и то, как он направлен на решение ваших проблем.

Это также не должно предполагать рабочий процесс разработчиков, стек, систему сборки, вариант использования. Хорошая библиотека максимально приспособлена ко многим сложным потребностям своего сообщества.

Что новое сегодня, завтра будет старым, шаблоны приходят и уходят. Единственной константой тогда будет программное обеспечение, которое предлагает отличную поддержку для многих вариантов использования, чтобы поддерживать как можно большую обратную совместимость.

Вы по-прежнему можете запускать игры DOS в Windows 10.

наследование против аргумента композиции

пожалуйста, нет. решение этого «аргумента» состоит в том, чтобы использовать лучший инструмент для работы. есть место для наследования, композиции, функциональности, управляемого тестами... что угодно.

Поскольку мы говорим о том, как другие разработчики (используют, повторно используют, модифицируют) three.js, допустимо продвигать шаблон, который будет легко понять и использовать, не выходя за рамки функций браузера js.

продвижение не означает, что нельзя использовать другой стиль.

максимально возможная обратная совместимость

и да и нет.

Он должен продвигать свои функции и то, как он направлен на решение ваших проблем.

возможно, чтобы нам было ясно, в чем проблема/функция для вас?

Это также не должно предполагать рабочий процесс разработчиков, стек, систему сборки, вариант использования.

Я в основном согласен. Вариант использования threejs в настоящее время является браузером. предостережение, что некоторые из наших загрузчиков полезны для некоторых узловых приложений, насколько я слышал.

Единственной постоянной тогда будет программное обеспечение, которое предлагает отличную поддержку для многих вариантов использования на этом пути.

изменение является единственной константой. разработчики используют тот инструмент, который им нравится, а иногда мы пробуем что-то другое.

как в сторону:

Он должен продвигать свои функции и то, как он направлен на решение ваших проблем.

что появилось первым? особенность, закономерность или проблема?
наверняка паттерн помог решить проблему, а потом стал фичей
...или проблема возникла из-за функции, и мы нашли шаблон для ее решения?

что появилось первым? особенность, закономерность или проблема?

Что появилось первым? Курица или яйцо?
Некоторые говорят, что Петух...

Отличная дискуссия вокруг, спасибо всем за весь вклад.

Мне было бы любопытно, что вы, ребята, думаете о том, какой упаковщик (rollup, babel, посылка, веб-пакет и т. д.) лучше всего подходит для задачи транспиляции наших примеров модулей ES6. Я полагаю, что @gigablox упомянул здесь о своем опыте, и я уверен, что другие тоже.

Текущее репо уже содержит babel, rollup и пару связанных плагинов. Я пошел дальше и начал взламывать это сегодня вечером, и у меня есть чрезвычайно грубый сценарий конфигурации свертки, которым я могу поделиться:

// jsm-transpiler.js
export default [
  {
    input: './examples/jsm/controls/OrbitControls.js',
    output: {
      banner:"//warning this file was generated automatically",
      file: './examples/js/controls/OrbitControls.js',
      name:'OC',
      footer:'THREE["OrbitControls"]=OC.OrbitControls',
      format: 'umd'
    }
  }
];

Этот сценарий конфигурации объединения действительно преобразует модуль $#$1 OrbitControls .js , включающий, который назначает THREE.OribitControls соответствующий конструктор. Это сработало, и это круто :) ! Он также объединил 40 тысяч строк THREE.js в выходной файл, не так уж круто, ха-ха. Я также лениво загрязняю пространство глобальных переменных, объявляя промежуточную глобальную переменную с именем OC, чтобы помочь перенести конструктор OrbitControls в THREE.

Rollup, кажется, имеет некоторые действительно классные функции, которые, я думаю, могут решить многие наши проблемы. В частности, сопоставление и другие элементы управления для обеспечения включения/исключения правильных вложенных модулей. Возможность вводить код до и после перенесенной полезной нагрузки через свойства заголовка/нижнего колонтитула/введения/вывода.

Я с осторожным оптимизмом смотрю на то, что мы можем добиться того, что нам нужно, с помощью навороченного сценария конфигурации свертки. Но было бы здорово, если бы кто-то, кто исследовал/понял различия между многими упаковщиками, мог бы внести свой вклад. Нам понадобится что-то довольно надежное для обработки модулей, поскольку они становятся все более крутыми, и я бы поспорил, что какой-то код транспилируется лучше, чем другие.

Вот мой взгляд на это:
https://github.com/mrdoob/three.js/pull/20529

Это скрипт пользовательской сборки poc, который преобразует все модули JSM в модули с глобальным пространством имен JS примерно за 30 секунд. Имели довольно хорошие успехи с этим методом. Требуется дополнительное тестирование, но попробовал несколько более сложных модулей, таких как GLTFLoader, в привет, мир, и все было в порядке.

Не помешала бы помощь опытных мастеров регулярных выражений :), чтобы разобраться с некоторыми пограничными случаями, о которых вы можете прочитать подробнее в PR.

Намерение импорта карт Chrome для отправки:
https://groups.google.com/a/chromium.org/g/blink-dev/c/rVX_dJAJ-eI

Была ли эта страница полезной?
0 / 5 - 0 рейтинги