Comments 287
Факт в том, что все упомянутые в посте вещи — это IMHO необходимый для 2016 года минимум, которым каждый сильный инженер должен если и не владеть, то хотя бы иметь представление о. Это не rocket science.
И нельзя так написать про любую технологию, в том же C# нет такой жести, новые версии обратно совместимы с предыдущими, интерфейсы официальных компонентов пишутся по одному паттерну, есть нормальная документация. И с NuGet нет такой жести, какая бывает с Npm пакетами, где выход новой минорной версии компонента может ломать всё приложение.
Речь идет о стеке приемов и технологий. Этот стек я выше имел в виду, когда говорил о том, что он войдет в будущий computer science, как 40-50 лет назад (или когда там) в него вошли алгоритмы сортировки или концепции функционального программирования, например.
Вот список статей, обосновывающих, почему классы в ES6 это кривой костыль, создающий проблемы, а не решающий их: Not Awesome: ES6 Classes
Или вот: How to Use Classes and Sleep at Night
Другой пример: в JS в catch() у try-catch нельзя фильтровать по «типу» исключения. Всегда пишется просто catch (e). Почему? Возможно, из-за того, что до появления концепции и конструкции async-await поверх промисов мало кто исключения в JS использовал широко (в силу асинхронной природы большинства операций исключение, выброшенное в одном месте, очень сложно поймать в правильном месте). Для фронтенда это и не было особо важно: во фронтенде инвертированный поток управления, но для серверного языка ИМХО исключения очень важны и удобны! К счастью, async-await вдыхает новую жизнь в исключения в JS и их поимку — она стала предсказуемой:
try {
a = await aaa();
B = await bbb();
} catch (e) {
Поймали!
}
В функциональных языках и без исключений как-то живут. А серверные языки сейчас как раз в сторону функциональщины двигаются, да и не любят там исключения в общем-то, всё чаще пишут что-то подобное (если интересно) и тихо ненавидят яву за её checked-exceptions:
Try<MyResult> attempt = Try.of(this::doMyWork);
MyResult result = attempt
.recover(this::tryToRecover)
.getOrElse(myDefaultResult);
Или просто сразу пишут stateless и повторяют попытку в случае исключения.
И таки да, вроде как вот такая конструкция будет работать в JS: onClick={::this._myOnclick}
И таки да, вроде как вот такая конструкция будет работать в JS: onClick={::this._myOnclick}
Таки нет, к сожалению — убрали её из черновиков стандарта.
О, прикольно, вернули в stage 0. В какой-то момент его вообще реджектили просто.
Не совсем понял вопрос, видимо. Конструкция
bla(::this.bar)
превращается в
bla(this.bar.bind(this));
Не вижу тут потенциальных утечек (во всяком случае, таких, которые не возникли бы при любом другом прокидывании this — через ту же стрелочную функцию, например). Про реакт сказать ничего не могу — не использую его.
Может быть, это экономия на спичках, конечно.
Здесь речь идёт о том, что когда вы делаете так:
render() {
<Component onAction={this.handleAction.bind(this)}
}
, то Component
при каждом рендере родителя будет получать новый обработчик onAction
, а значит должен перерендерится, и так далее. Хотя, на самом деле, обработчик один и тот же, просто .bind(this)
на каждый вызов возвращает новую функцию. Для решения этой проблемы и предлагается биндить заранее, можно через стрелочный синтаксис:
handleAction = () => {}
render() {
return <Component onAction={this.handleAction}
}
либо декоратором (как на свойство класса, так и на весь класс).
А сколько элементов этого списка войдут в необходимый для 2017 года минимум?
Можно оценить, например, сравнив с необходимым для 2015 года минимумом.
Использую js с 2003 года и то что происходит сейчас во многом похоже на лютый треш :(
Ну, как вам сказать. Как ни крути, для серьёзного проекта приходится использовать библиотеки или фреймворки. Чтобы собрать и пожать релиз — нужен какой-то бандлер. И то и другое можно написать самому, но зачем?
В итоге отрасль дробится на условные «цеха», где все делают одно и то же, но каждый по своему. В итоге реальным профессионалом стать проблематично, появляется новая «фишка» и всех отбрасывает на нулевой уровень. Переход разработчиков с проекта на проект затруднён, вот писал ты 2 года на React, а теперь переходишь на Angular, сколько времени понадобится на адаптацию? Грустно это.
Все эти надстройки, описанные в статье, к сожалению, лишь костыли над кривым языком. И меня реально пугает, что его пытаются тащить во всё более серьёзные вещи, типа веб-серверов и микроконтроллеров.
P.S. Чтобы не было недопонимания, под кривизной JS я подразумеваю то, что он изначально разрабатывался для несложных манипуляций с пользовательским интерфейсом. Он изначально не предполагал многопоточности, серьёзных возможностей для работы с исключениями, быстродействия. Он реально был написан на коленке. Как «Ока», практически. А сейчас из него пытаются Камаз сделать.
И отдельно хочется прокомментировать: «Это был отличный язык для веба в 90х и начале нулевых». А сейчас для веба есть еще какой-то язык?
Сейчас на нём можно писать приложения любой степени сложности используя все те костыли, которые указаны в статье. Хотя это не верно, у JS есть принципиальные ограничение, например он не работает с файловой системой, в самом языке нет такой функциональности, она реализуется за счёт внешних модулей (например в составе NodeJs) и в принципе не реализована в среде веб-браузера. То же самое относится к хранению данных, есть внешние библиотеки, реализующие доступ к LocalStorage браузера и базе данных, но это не часть языка, это именно внешняя библиотека, которая в одних браузерах реализована, а в других нет.
JavaScript — это костыль на костыле, пирамида костылей. Хотите что-то реализовать — не забудьте заглянуть на http://caniuse.com чтобы проверить, где эти костыли реализованы.
Приложения любой степени сложности на, например, упомянутой nodejs можно писать на нативном ES6 безо всех этих костылей. JavaScript сегодня — не только браузер. Тут уже скорее вся остальная появившаяся инфраструктура приводит к появлению костылей для того чтобы в браузере работало "как там".
он не работает с файловой системой, в самом языке нет такой функциональности
Язык и не должен работать с файловой системой сам по себе. Это задача стандартных библиотек.
Сравним C#:
string text = System.IO.File.ReadAllText(@"path/to/file");
и JS:
let text = require('fs').readFileSync('path/to/file');
/offtop
А вам бы действительно хотелось, чтобы JS в веб-браузере мог работать с вашей файловой системой?
Всяко лучше, чем дотнет.
Ну вы в курсе, да, что языку уже двадцать лет, и он значительно изменился за это время?
Область применения языка изменилась гораздо сильнее, чем изменились возможности языка.
Вот например, одна из фундаментальных особенностей языка — нестрогая динамическая типизация. Для написания DHTML, особенно в середине девяностых, это была киллер-фича: пишем пару строчек и всё волшебным образом работает. Вполне возможно, что именно низкий порог вхождения помог JS приобрести свою популярность на ранних этапах.
Пока двадцать лет веб был относительно простым и дышал романтикой юношеского максимализма, противоположная сторона IT — суровый и серьезный энтерпрайз — также развивался и накапливал опыт. Умные дяди выяснили, что статическая типизация позволяет повысить качество приложений и сократить время разработки: ошибки ловятся компилятором на ранних этапах разработки, автокомплит работает лучше, появляется простор для оптимизаций. Более того, объем кода от этого не только не раздувается, а даже наоборот — современные компиляторы типа C# \ Scala \ Rust могут в большинстве случаев вывести тип самостоятельно, лишь изредка опираясь на подсказки со стороны программиста.
Седые и скучные энтерпрайзеры открыли еще несколько любопытных вещей. Например, если в языке есть средство сделать поля/методы классов приватными, у новичка или невнимательного программиста сокращается шанс случайно напортачить. Если различать и грамотно использовать структуры данных, приложение будет работать быстрее и потреблять меньше ресурсов. А с помощью многопоточности можно ускорить приложение еще сильнее.
Теперь, когда к веб-приложениям предъявляются требования уровня энтерпрайза, было бы вполне логичным перенять этот опыт. Но большая часть сообщества видит в этом только ущемление собственной свободы и протестует с упорством, достойным лучшего применения. Вместо этого изобретается «свой особый путь».
Нужны приватные поля? Вместо этого изобрели новый базовый тип
Symbol
, который сложно понять и всё равно можно обойти. Вместо потоков — веб-воркеры, без примитивов синхронизации и с урезанными возможностями взаимодействия. Вместо классического наследования — прототипное. Список можно продолжать довольно долго.Парадокс ситуации в том, что в сложившуюся таким стихийно-бунтарским образом инфраструктуру вложено так много человеко-часов, что признать ее ошибки слишком досадно, а пытаться их исправить — слишком сложно. Однако жить как-то надо, поэтому народ пользуется, и сил вкладывается еще больше.
Сейчас на нём можно писать приложения любой степени сложности.
Можно, но при этом приходится изобретать решения для проблем, которых вообще не должно было возникнуть. Например, как сделать словарь, ключи которого являются объектами? Очевидного способа нет, можно попробовать несколько экстравагантных, каждый со своими особенностями и ограничениями? А если нужно получить слабую ссылку? Увы, никак — есть WeakMap, но он работает немного по-другому.
Особенно иронично, что некоторые типично динамические трюки в JS сделать сложнее, чем в языках, обычно считающихся статически типизированными. Например, как перехватить обращение к любому полю и получить название этого поля в виде строки? В ES6 для этого будет новый класс Proxy, который пока не везде поддерживается и с горем пополам полифиллится. В это же время аналогичный функционал в C# был доступен еще в 2010 году.
20 лет производителями браузеров были потрачены не зря, интерпретаторы заоптимизированы по самое «не могу»
Двадцать лет были потрачены как раз-таки зря: пришлось придумывать решения для проблем, которые в статически типизированных языках вообще не существуют. Результат, безусловно, похвальный — но у пользователя по-прежнему масса возможностей написать код так, чтобы сломать оптимизации.
Нужны приватные поля? Вместо этого изобрели новый базовый тип Symbol, который сложно понять и всё равно можно обойти. Вместо потоков — веб-воркеры, без примитивов синхронизации и с урезанными возможностями взаимодействия. Вместо классического наследования — прототипное.
Тут я с вами очень сильно не соглашусь. Прототипное наследование намного мощнее вашего так называемого «классического». Классы это новая (лишняя) сущность по отношению к объектам — это blueprint'ы объектов — тогда как прототипы придерживаются самого настоящего классического ООП принципа «всё есть объект»: наши прототипы это тоже объекты. То есть, прототипное наследование на деле куда более «классическое», оно проще, оно фундаментальнее. Оно объектное.
Символы точно так же куда более общая концепция, чем приватные поля. Приватные поля — это атрибут «классов», они не имеют смысла в рамках модели, в которой классов нет (в JS классы это лишь сахар для настоящих объектных прототипов — для тех несчастных, кто не освоил их — чтобы сгладить переход из других языков).
Например, символы позволяют делать свойства без строкового имени вообще (анонимные), исключая конфликты с существующими полями:
field = Symbol ()
obj[field] = ...
Что позволяет расширять объекты мета-информацией, доступной только тем, кто в ней заинтересован, не вступающей в конфликт с чем-то еще. Скажем, вместо метода .toString () у объектов, процедуры распечатки объектов могли бы экспортировать соответствующий символ. Вот как это сделано в библиотеке string.ify например:
Boolean.prototype[Symbol.for ('String.ify')] = function () {
return this ? 'yes' : 'no' }
String.ify ({ a: { b: true }, c: false })
// '{ a: { b: yes }, c: no }'
Мы говорим «класс» — подразумеваем «тип», т.к. объявление классов и интерфейсов — это по сути объявление типа.
Когда тип объявлен, мы можем указать, что вот эти переменные содержат объекты именно данного типа. Мы можем выполнить что-то вроде isInstance(), тем самым быстро проверив, содержит ли переданный нам объект нужный набор методов и свойств. У нас упрощается генерация документации, ведь мы можем указывать тип и пользоваться инструментами вроде jsdoc.
С нашим кодом становится гораздо проще работать статическим анализаторам и IDE, тогда как в случае использования прототипов для чего-то кроме эмуляции классов даже WebStorm от JetBrains начинает путаться, выводя неверные подсказки.
В общем, для крупных проектов отсутствие простого способа указания типов очень неудобно.
Посмотрите в сторону Flow.
Прототипное наследование намного мощнее вашего так называемого «классического».
В этом и суть проблемы: хорошо в теории, плохо на практике. «Классическое» наследование близко к железу — можно определить адрес каждого поля на этапе компиляции и потом пользоваться очень быстрыми операциями доступа к памяти по смещению.
Прототипное же наследование предполагает, что пользователь может в любой момент творить грязные трюки, расширяя прототипы или вообще подменяя их. Несмотря на то, что большинство пользователей в здравом уме этого не делает, компилятор по стандарту все равно вынужден обмазывать всё бесконечными проверками и инлайн-кешами. Приходится делать выбор между сложностью устройства компилятора, расходом памяти и производительностью. И кому нужна эта «мощь» такой ценой?
Хорошая аналогия — рекурсия в ФП. Отличная математическая концепция, хорошо позволяющая описать любое циклическое вычисление. По факту же, в компиляторе без tail call optimization пользоваться ей опасно.
Cимволы позволяют делать свойства без строкового имени вообще (анонимные), исключая конфликты с существующими полями
Сначала поставили прототипное наследование во главу угла, а теперь героически решаем возникшие проблемы с помощью символов.
Что позволяет расширять объекты мета-информацией, доступной только тем, кто в ней заинтересован
Для собственных объектов в «классическом» наследовании то же самое можно сделать с помощью интерфейсов, и даже больше — явная реализация интерфейса позволяет объекту иметь даже несколько методов с одинаковым названием, и они не будут пересекаться. Символы же всё равно упираются в строки, и точно так же можно получить коллизии, потому что
Symbol.for("a") === Symbol.for("a")
.Для чужих же объектов такое вообще лучше не делать, потому что прототипы глобальны и изменение может иметь непредвиденные последствия в других модулях. Именно по этой причине prototype.js так быстро попал в ранг антипаттернов.
Это, мягко говоря, неправда. Например, вот.
>Вместо этого
>Вместо этого
>Вместо этого
>Вместо
Парадокс ситуации в том, что вы по какой-то причине считаете, что есть только один правильный путь, в то время как это не так.
>Например, как сделать словарь, ключи которого являются объектами?
Map же.
>Увы, никак — есть WeakMap, но он работает немного по-другому.
А вы думали, что наличие «Weak» в слове «WeakMap» имеет какое-то отношение к «получению слабых ссылок»? Ведь есть же спецификация, ну.
>будет новый класс Proxy
И это нормально. Когда-то и в C# такой возможности не было — сами же это говорите. То, что сейчас происходит с JS — это восхитительно. Буквально на наших глазах язык превращается из сугубо нишевого в, так сказать, настоящий. Взрослеет, растет. Особенности его применения (многочисленные вендоры браузеров, в частности) этот рост затрудняют, и это понятно. Но растет же!
>по-прежнему масса возможностей написать код так, чтобы сломать оптимизации.
Это только в JS так?
Если позволите, я и на другой комментарий отвечу.
>хорошо в теории, плохо на практике
Почему? Кстати, вы почему-то в этом комментарии раз 5 упоминаете компиляцию. Какое она имеет отношение к JS?
> творить грязные трюки
Почему вы считаете это грязными трюками? Вот это прям особенно интересно.
>Symbol.for(«a») === Symbol.for(«a»).
Это касается только символов в глобальном реестре.
Это, мягко говоря, неправда.
Соглашусь, это спорный момент. Мнения на этот счет есть разные. Однако я еще не видел, чтобы на динамически типизированных языках писали приложения, к которым предъявляются особые требования к надёжности (банковское ПО, бортовые компьютеры, и т.д.)
есть только один правильный путь, в то время как это не так.
Уже описал в предыдущем комментарии. Прототипное наследование требует либо жирной прослойки в рантайме, либо безумно сложной реализации VM. Как следствие, языков с прототипным наследованием гораздо меньше, чем с «классическим» — кроме EcmaScript, Lua и LISP я других толком не знаю.
Это только в JS так?
Статически типизированный язык имеет больше ограничений, поэтому больше гарантий. На основании них можно выполнять массу оптимизаций, недоступных динамически типизированным языкам. Запутать компилятор можно в любом случае, но для этого потребуется сильно больше кода и есть шанс, что программист подумает — «как-то слишком сложно получается, возможно я делаю что-то не так?».
Кстати, вы почему-то в этом комментарии раз 5 упоминаете компиляцию. Какое она имеет отношение к JS?
JIT.
Почему вы считаете это грязными трюками?
Расширять прототипы встроенных объектов опасно по причине возможных конфликтов. Методы-расширения решают проблему, но в JS их невозможно реализовать по причине динамической типизации. Что же касается подмены прототипа, то тут сам Брендан Эйк признается, что идея была отстойная.
Если вы делаете крупный продукт, и особенно если отвечаете головой за его качество — избегать операций с потенциально неизвестными побочными действиями вполне логично. Я знаю только два варианта, когда это может быть оправдано — дебаг и написание самомодифицирующегося кода.
Это касается только символов в глобальном реестре.
Виноват. Действительно, это верно только для символов, полученных через
Symbol.for
. Но тогда становится еще страннее: если Symbol
придуман как раз для того, чтобы к данным мог получить доступ только тот, для кого они предназначены, зачем сразу же закладывать дыру в абстракции, создавая глобальный реестр символов и Object.getOwnPropertySymbols
? Object.getOwnPropertySymbols
нужен, чтобы можно было склонировать объект. Например если вы миксины делаете, без этого никак. Или для отладки, чтобы например в консоли было видно, че там за символы у объекта. Дырой было бы, если бы эту информацию нельзя было бы получить — это как раз разрушило бы консистентность.
данным мог получить доступ только тот, для кого они предназначены
Это так и есть. Ведь если у вас нет ссылки на символ (и он безымянный, не через реестр), то вы не можете никакой осмысленный доступ к свойству такому получить. Это как квантовая информация, она вроде бы есть, а вроде бы и нет. Но её можно скопировать, вот за этим и нужно.
Вы из тех, кто не осилил прототипы и замыкания?
В javascript этого нет и никогда не было. Те же == и ===, null и undefined, родовая травма в виде isNan. Чтобы на нём писать, его надо заучивать, реально. Нужно помнить, что при == будет приведение типов, а при === не будет. Нужно помнить, что в объекте error есть свойство message, которое хранит сообщение об ошибке. Нужно помнить, что проверять есть ли свойство нужно через if(foo.bar), потому что сравнения с null или undefined будет недостаточно. На том же хабре полно статей о подводных камнях js.
Нет, так нельзя проверять, есть ли свойство. Сдается мне, что не работаете вы с JS с 2003 года.
У меня API все на питоне написано, datetime.date по стандарту как «yyyy-mm-dd» передается, приходится каждый раз на входе в ангуляр парсить строку, а, потом, на выходе собирать. Ненавижу JS.
по стандарту как «yyyy-mm-dd» передается, приходится каждый раз на входе в ангуляр парсить строку, а, потом, на выходе собирать. Ненавижу JS.Вы сами конвертируете в строку, а потом жалуетесь, что приходится парсить. Передавайте/получайте сразу дату, и при чем здесь JS?
неадекватен по API, по моему мнению, — Date
Эта проблема встречается в большинстве языков, к сожалению. Работа с датой и временем — сложная штука. В некоторых случаях народ успел оглянуться и посмотреть на следы от грабель на телах конкурентов ,)
2. Void — объект-обертка над void, так же, как и Integer над int.
3. см. п.1. и тогда всё логично.
А вообще есть конечно там некая толика всеобщего JS-раздолбайства, человек просто пример неудачный привел.
isNaN(NaN); // true - ок
isNaN(1); //false - ок
isNaN(undefined); // true - ну... допустим ок
isNaN("foobar"); // true - ок
isNaN("1"); // false - ... эээ
isNaN(false); // false - ... нуу
isNaN(null); // false - пожалуй с меня хватит.
Я думаю хорошо было бы если бы оно в действительности только на NaN true возвращало, что и пытался донести staticlab
caller
или invoker
или context
, хотя и они тоже плохие. Ну уж хотя бы нет коннотаций с Java-шным this'ом.Ну вот куда это годится?
var MyObj = function () {
this.fn = function () {console.log(this)};
}
a = new MyObj();
a.fn();
// MyObj
var b = a.fn;
b();
// Window
‘Sometimes when I'm writing Javascript I want to throw up my hands and say "this is bullshit!" but I can never remember what "this" refers to.’
— Ben Halpern @bendhalpern 20 Mar 2015
Кормлюсь js c 2006, и то, что сейчас происходит, в последние лет 5 — во многом лютый офигенчик.
Что у нас было тогда? Prototype c весьма странной идеей и расплывчатой ответственностью. Примерно такой же Motools. jQuery, чей подход мне не нравился вообще никогда, с его бесконечными отвратительными плагинами. Потом появился переусложненный ExtJS, императивный на всю голову qooxdoo и прочие странные порождения сумрачного корпоративного гения. Единственный приличный был y5, который умер, где и родился — в недрах яндекса. Backbone, при всех его недостатках, был лучом света в темном царстве.
Бандлер/минификатор был либо родом из серверного фреймворка (везде со своими идиосинкразиями), либо самописный (которые моя бабушка описала бы как «мальчик-то он хороший, только дрищется»). Все они писались серверными программистами без малейшего понятия, что же все-таки нужно фронтендеру. RequireJS, опять таки при всех своих недостатках, опять же был лучом света и т.д.
Сборка происходила в лучшем случае Makefile-ом. Это, конечно, довольно универсальная система, но на винде из коробки ее нет. grunt/gulp/webpack более кроссплатформенные решения в этом смысле, плюс не надо переключаться с JS на чей-то эзотерический синтаксис.
Про юнит-тесты я вообще молчу. Да, был, например, QUnit, но в отсутствие нормальной модульной системы и ее поддержки, пользоваться им было довольно грустно.
В общем, сейчас в 99% случаев можно найти «точное такое же, но с перламутровыми пуговицами». И да, никто не запрещает и сейчас писать так же, как в 2003 — все в одном-двух файлах, без сжатия и склейки, без сторонних библиотек. Просто сейчас мы делаем гораздо более сложные вещи, которые в двух файлах уже не уместить (оставим неуместное использование тяжелых фреймворков на простеньких страничках на совести тех, кто так делает).
С другой стороны, тогда и порог вхождения был гораздо ниже, изучаешь синтаксис языка, читаешь документацию к Prototype и вперёд фигачить.
То что происходит сейчас замечательно описано в статье, её показать человеку, который только входит во фронтэнд, он с высокими шансами станет как бабушкин мальчик. Делается то всё просто, если знаешь как, а чтобы во вё разобраться надо немеряно времени потратить. Т.е. порог вхождения вырос на порядок как минимум.
Ну это понятно:) Но ведь и сложность задач возросла. Если надо склепать какой-нить лендинг-пейдж/визитку или там галерейку для сайта на вордпрессе — можно все так же, window.onload = function() {}
и вперед, и это нормально. Я бы «удивился», если кто-то предложил использовать react + babel для этого, все либы будут весить гораздо больше пользовательского кода, а выигрыш минимален. Я же говорю, никто не запрещает сейчас делать так же, как и тогда — только если вы попробуете те подходы на сложном приложении, вам будет грустно.
Сейчас везде так. Видели оригинал? Или вот покажи мне сейчас кто-нибудь стэк для написания десктопных приложений, я буду таким же мальчиком. Подозреваю, если бы братьям Райт показали «Конкорд», они бы тоже сказали: «ну да, круто, но у нас вот из говна и палок можно за час собрать, и летает». Сравните телефоны сейчас и во времена Белла. Да, сейчас все сложнее, зато и воможностей больше. А звонить-то можно и по-прежнему.
Фактически, все новые приложения на платформах MS (Windows 10, Windows.Store, Windows.Phone, Silverlight) пишутся на WPF, который стандартизирован.
При этом новые технологии, появляющиеся в рамках .net framework (async/await, EntityFramework) вплетаются в WPF без нарушения обратной совместимости.
Спасибо. А UWP сюда каким боком относится? Я слышал, что можно что-то там делать на JS, можно ли сделать live tile и как? Пригодится ли мне WinJS или это сугубо набор контролов? Я знаю, что есть кросс-платформенное Mono и что оно в какой-то мере отстает от мейнстримного .net, оно умеет в WPF?
Я не только из риторических целей спрашиваю, мне правда хочется сделать кое-какое приложение в виде живой плитки.
Есть ещё Apache Cordova, там можно, насколько я понимаю на JS писать.
Но опять же, у .net идеология, что всё компилируется в байт-код MSIL (а-ля ассемблер), который затем, во время исполнения, компилируется в нативный код, специфичный для платформа. Скорее всего, там просто сделан компилятор, который превращает JS в MSIL (байт-код).
Есть ещё Apache Cordova, там можно, насколько я понимаю на JS писать.
Это просто обертка над WebView (точнее, генератор таких оберток под каждую нужную платформу). В WebView показывается ваша страничка (оффлайн, она лежит в ресурсах приложения). Обертка обеспечивает проброс нативных API платформы.
Расскажите мне лучше то, чего я не знаю.
Я, честно говоря, не изучал его глубоко, не приходилось сталкиваться.
Ну вот видите. Вы пишете на .net и не можете мне про него рассказать. А у JS, видите ли, сложный и запутанный стэк.
.net же огромная платформа, которая делится на множество направлений.
Изначально были Windows.Forms, Asp.Net Web Forms, .net CE, .net embedded. Потом появились WPF, WCF, WWF, ASP.NET MVC. Windows CE канул в Лету и на смену ему пришёл .net под Windows Phone, сейчас активно развивается UWP (в рамках мобильных платформ) и Asp.Net Web API (в рамках веба), выделившийся из ASP.NET MVC. Сейчас активно .net Core развивается. Из этого списка я вообще не трогал UWP, .net Embedded и чуть-чуть трогал .net Core. Про остальное спрашивайте, расскажу.
У нас в компании похожий стек, только про Hadoope
Потом осознать, что потратил месяц, просто чтобы начать понимать, что значат все эти термины. Прикинуть, что на освоение позволяющее использовать все это в реальной работе уйдет от года(а за это время появится еще много чего). Ну и плюнуть на все это и за выходные освоить Dart. За вторые выходные написать то самое TodoMVC которое просто будет работать.
И началось постепенное разделение ИТ-людишек на два класса — кровожадная элита, которая делает какой-либо рантайм js (неважно, браузер, нода, embed-версию) и всех остальных, которым дали js и песочницу, а постоянное нахождение в ней эволюционно отупляет даже самых способных голодранцев.
И это отупление относятся и к бизнесу, то есть менеджерам, владельцам бодишопов и прочим, которым надо чтобы дела делались и всё было внешне ровно и красиво, как огромный js-копролит, возвысившийся над планетой.
И то же самое относится к исполнителям, то есть огромной толпе буллшит-кодеров, которым просто надо жить и кушать, и плевать, что своими копытцами поддерживаешь огромный чёрный js-копролит, возвысившийся над планетой.
И все, вообще все понимают, насколько js унылое дерьмо, но целая планета трудится над этим дерьмом, затыкая носы ради великого доллара на вершине js-копролита.
— Да, я как раз занимаюсь фронтендом, юзаю пару тулз.
— Круто. Я щас делаю простое приложение — обычный TODO-лист, используя HTML, CSS и JavaScript, и планирую заюзать JQuery. Это норм?
— Не-не-не. Для обычного TODO-листа слишком много оверхеда. Пишешь софт на любом удобном языке, подрубаешься через telnet и юзаешь. Если хочешь секурности — используй ssh.
При том, что выбор языков носит исключительно косметический характер (в стиле «мне не нравится синтаксис»), т.к. возможности сходны, и вряд ли можно найти такую задачу, которую легко решить к примеру на Python+Django, но невозможно на PHP.
Да, есть дарт, есть тайп/кофе/*скрипты и на некоторых из них даже почти удобно писать, но это всё просто запихивание того же самого под ковёр. Не видно, но всё равно попахивает.
И да, я понимаю, почему альтернатив нет — браузеров много, и пропихнуть эту самую альтернативу почти нереально, но ситуация от этого менее плачевной не становится.
Недостаточно трэша. Теперь мы хотим в качестве бэкенда использовать не какую-нибудь ноду, а ASP.NET (не Core) с бандлами. Когда для сборки React, минификации, трансляции less используются не обычные front-end инструменты, а куча разных пакетов вроде DotLess, ReactJS.NET. В Core куда удобнее, имхо — bower, grunt и прочее веселье.
Я тоже не понимаю этого. Примерно так: ты новичок, изучаешь новую технологию, читаешь гайды, а там показан такой путь и сказано, что это труЪ и кошерно.
Хотя у бандлов в асп.нет есть преимущество перед конкретно Gulp\Grunt — с помощью их и web essentials можно на лету пересобирать. Сохранил css\less, и у тебя сразу изменения в браузере, а не подождал, пока watch grunt'а увидел, пересобрал и потом обновляешь страницу.
Но такую магию вроде позволяет WebPack. Я тоже за родные для фронтенда инструменты.
Ну уж ivereload для стилей и grunt умел (точнее, grunt-livereload).
Тогда нам срочно нужно поколение детей-индиго, способных за 2 дня освоить стэк техгологий из этой статьи
Но обычно стоит задача написать реально сложное web-приложение, и вот тут все эти технологии уместны и нужны. То что их много, они сложные, и постоянно меняются — безусловно вводит в ярость человека, который привык к тому, что может написать пару сток на js в перерывах между своим .net mvc или типа того, и считать себя full-stack. Я бы посоветовал таким людям смирится, и просто сосредоточится на своей технологии, а front-end оставить тем, кого все эти слова не смущают.
Это шаг назад по сравнению с redux, потому что теряется predictability. Выглядит мощно да, но и goto
в C выглядел мощно. А потом все поняли, что это верный способ себе ногу отстрелить.
Ага, как и setjmp и longjmp. Только эти вещи используются в очень частных случаях, и только когда это реально оправдано. Observables это реально интересная вещь — ложится на наши естественные ментальные модели хорошо. Как и гото, например. Он ведь тоже когда-то появился, потому что это для нашего мышления естественная штука. Проблема в том, что наши ментальные модели зачастую говно. Человеку свойственно ошибаться и нести чушь.
То есть, иногда встает выбор — либо учить что-то новое и прорывное (новую ментальную модель) — что дает принципиально новые возможности (как функциональный подход и redux) — либо заниматься луддизмом, и цепляться за mutable state, просто потому что мы уже привыкли так мыслить, а новые парадигмы мы в голове помещать не хотим. Но время все расставляет по местам, думаю что штуки типа mobx для менеджмента состояний будут оправданы только в маленьких простых приложениях, а в больших и сложных это будет шаг назад в сравнении с Redux. Это чем-то похоже на дилемму из статьи, кстати (jquery vs react).
Они как-раз специфичные. А goto — нормальная, довольно распространенная практика в Си
> либо заниматься луддизмом, и цепляться за mutable state
mutable state отличная, рабочая парадигма. Идеологи реакта прославляют иммутабельность потомучто она критична для работы реакта — это его прямое ограничение. Как только кто-то сделает «реакт без принудтельного stateless и виртуального DOMа» все забудут этот недохаскель как страшный сон.
В чистом C возможно. Но в C++ это не так. Я писал на C++ много лет (3D графика), и мне ни разу не пришлось использовать goto
. Хотя он там есть. Я именно об этом и говорю — наличие инструмента не делает его использование оправданным.
Так же и мутабельность — это только выглядит «удобным», как гото когда-то выглядел удобным, пока не появились лучшие инструменты. И точно так же находились те, кто считал, что старый подход лучше, потому что «удобнее». Вы думаете мало было холиваров насчет гото? Вот и mutable state ждет такая же судьба. Останется уделом низкоуровневых вещей каких-то, где без этого вообще нельзя. А на макроуровне это забудут, как страшный сон.
У реакта иммутабельность это не ограничение. Это как говорить что автомобиль это ограничение, потому что он плавать не умеет, а вы умеете. Да, он не умеет плавать, зато он ездит в десять раз быстрее чем вы бегаете. И в реальности это намного важнее. Я полагаю, что вы когда рассуждаете об этом, как об ограничении — то за деревьями не видите леса, не понимая до конца преимуществ иммутабельности в макромасштабе. Я кстати об этом написал статью сегодня.
> не понимая до конца преимуществ иммутабельности в макромасштабе
Расскажите о преимуществах иммутабельности в макромасштабе, будте так добры
Вот и mutable state ждет такая же судьба.
Останется уделом низкоуровневых вещей каких-то, где без этого вообще нельзя.
А на макроуровне это забудут, как страшный сон.
Пруфлинк бы. А то каждый месяц кто-нибудь не слишком хорошо знакомый с историей развития языков открывает для себя immutable state и предрекает немедленную кончину объектов с изменяемым состоянием, а они все, гады такие, не помирают и не помирают никак.
А не помирают они потому, что есть задачи, которые хорошо решать в парадигме чистых вычислений, а есть задачи, которые естественнее и удобнее решать в рамках ООП. Например, складской учет, оперирующий ящиками и коробками, можно, конечно, решить без изменяемых объектов — но количество костылей, которые придется нагородить вокруг, заставит глаза кровоточить гораздо раньше, чем первый пререлиз увидит свет.
Нет серебряной пули: вот единственно верный ответ на этот вопрос. Есть масса задач, в которых давно отправленный на пенсию Backbone даст сто очков форы любому новомодному redux’у. Поэтому фанатиков технологий и недолюбливают в любом мало-мальском энтерпрайзе.
https://habrahabr.ru/post/308154/
На высокоуровневых задачах в вебе про mutable state уже забыли. Я в прошлом году писал WYSIWYG редактор который работал с изменяемым состоянием, хранящимся напрямую в DOM. Было очень сложно добиться безглючности и понятности кода, а также работы штук типа стека undo/redo. Сейчас я смотрю на последние разработки редакторов типа Slate или Draft.js — это невероятно, насколько иммутабельность помогла им выстроить хорошую архитектуру, позволяющую в разы больше, чем возможно было до того.
Я вам говорю: «разные задачи — разные инструменты, например, забивать гвозди удобнее молотком, а закручивать шурупы — отверткой».
Вы мне в ответ: «я и еще три крутых пацана вчера забивали гвозди, ничего круче молотка нет, вообще все все все уже давно отказались от отверток».
Ну ок. Пруфлинк засчитан.
Так вы посмотрите с чего ветка-то началась, пример goto не просто так был приведён. Каждая новая технология не отменяет старой, но расширяет горизонт возможностей, а старая технология остается в рамках этого расширенного горизонта маленькой нишей. Сегодня люди до сих пор используют и C++, и ассемблер даже — но на прикладном уровне этого уже нет давно. Вот так же и mutable state — это старая парадигма, которая не способна решать «бытовые» задачи, с которыми люди сталкиваются сегодня. Просто это новые задачи, новые вызовы. В рамках которых люди действительно уже отказались от «отверток». А отвертки остались в своей области применимости.
Во-первых, immutable states и чистые функции примерно настолько же «новая» парадигма, насколько и goto.
Во-вторых, mutable states живее всех живых во многих прикладных задачах. То, что вы почему-либо с таким классом задач не сталкивались, означает только то, что ваши задачи удобнее решать с неизменяемыми объектами. Вы пока не привели ни единого аргумента, почему бы это было так, кроме «мамой клянус», «сам писал целый год целый проект» и «совершенно очевидно». Это все детский сад.
Вот вам простой пример: я у себя в блоге накладываю на фотографии информацию о месте съемки, которую вытаскиваю сырой из EXIF и хожу из клиента в nominatim, который отвечает не всегда, поэтому я успокаиваюсь после двух отлупов. Предложите мне вариант проще, чем хранить «по этой фотографии опрос окончен» в самом объекте и рисовать общую карту с маркерами по факту «все объекты успокоились» — и я уверую.
Задача которую вы описываете — это не высокоуровневая задача, это как раз область применимости отверток.
> То, что вы почему-либо с таким классом задач не сталкивались
С чего это я не сталкивался? Я с таких задач и начинал, можете резюме глянуть. В детстве 3D движки писал (DX/GL), там таких задач как раз полно. Это все лоу левел.
Я вам привел совершенно конкретный пример весьма сложной высокоуровневой задачи (WYSIWYG редактор), где immutable state упрощает код на порядок, делая его предсказуемым, высокопроизводительным и легко расширяемым: https://github.com/ianstormtaylor/slate#principles
А вы мне про какие-то EXIF из фоток. Детский сад...
Вот так же и mutable state — это старая парадигма, которая не способна решать «бытовые» задачи, с которыми люди сталкиваются сегодня.
По-моему, это ваши слова, поправьте, если ошибаюсь. Теперь на сцене появляются какие-то «высокоуровневые» задачи. Ну ок, визивиг, «immutable state упрощает». И что из этого следует, кроме того, что есть пример задачи, где неизменяемое состояние — благо? С этим тезисом даже самые отъявленные оописты не спорят. Вот только он ничего не доказывает.
Если бы вы с самого начала использовали слово «некоторые» вместо «все» (даже «большинство» можно было бы стерпеть) — я бы вообще не встрял. Каждый волен восторгаться новыми религиями, хоть каждый год.
Напоминаю еще раз важный момент, который вы в ответах успешно игнорируете: immutable state — ровесник goto. У него было время убить вокруг вообще все живое. Но этого не случилось. Потому что не для всех задач это благо. Вот и все.
Рано или поздно ваша высокоуровневая задача захочет восстанавливаться из локалстораджа при переоткрытии браузера (ну, если она для людей, конечно, а не для демонстрации высокоуровневости). И voilà.
Вы напрасно сравниваете гото и иммутабельность, в плане их «старины», пытаясь из этого какие-то выводы сделать. Гото это чисто инженерное решение, которое было обусловлено низкоуровневой архитектурой вычислительного железа. Оно старое просто потому что компы старые.
Иммутабельность же появилась именно как абстрактная академическая идея, и оставалось игрушкой, пока не появились задачи, в которых это очевидно удобно. То есть миру нужно было просто дорасти до таких задач. Это сложные, высокоуровневые задачи, очень далекие от архитектуры железа и гото. Они не могли возникнуть сразу, это вопрос эволюции.
Точно так же как и другие вещи из функциональных языков, типа лямбд или замыканий. Представьте себе, лямбда-исчислению уже скоро будет 100 лет. И вот только-только это становится мейнстримом.
Вы просто путаете теплое с мягким.
Я кстати уверен что в будущем люди не то что «забудут недохаскель». Но реально перейдут на хаскель. Ну точнее его браузерную инкарнацию какую-нибудь, типа Elm. Очевидно же, что все к тому идет, просто не революционным, а эволюционным путем. JS все больше и больше становится похож на это, в какой-то момент уже просто не будет смысла использовать JS, все свитчнутся на какой-нибудь транспилируемый в него язык. Они и сейчас есть, такие языки, просто люди еще не понимают до конца, зачем они нужны — но это в какой-то момент станет очевидно всем. И появление таких вещей как React/Redux в массовом сознании это очень мощные сигналы к этому.
Не было в JS ничего подобного до прихода реакта. В нем, насколько я понимаю, иммутабельность нужна чтобы реакту быстро найти изменения. То есть для того чтобы его внутренности правильно отработали. Разработчику-пользователю фреймворка она ничего кроме чувства собственной важности не дает. Поправьте, если я ошибаюсь
Пользователю фреймворка это дает React, лол. Он был бы невозможен без этого. Я именно об этом и говорю, это не просто «быстро найти изменения», это и есть ключевой момент во всем этом. В макро масштабе.
И тут интересный дальше момент — это определяет архитектуру нашего приложения. То есть, выгодно юзать Redux. А это уже все прямиком пришло их функциональных языков, из Elm в частности. И постепенно никакого смысла в том чтобы использовать JS вместо Elm не будет. Потому что Elm позволяет еще и статически верифицировать всю программу так, что у вас вообще нет runtime exceptions. А это и есть ультимативная цель всего этого замеса.
Не совсем так, Реакт может работать и с изменяемым состоянием.
Все эти недавно бывшие кодерами на похапе или полгода верставшие лендинги люди раздувают ценность знаний новых технологий, и их реально нанимают работать на хорошие должности. А на деле эти люди освоили пару алгоритмов или парочку фреймворков типа Angular2 и иже с ними.
Все больше кажется, что охотнее нанимают не спецов, пусть и в драных кедах, а людей, умеющих себя подороже продать, освоивших что-то интересное, но не знающих даже основ.
Отовсюду слышно, что с радостью нанимают «молодых и перспективных» разработчиков, у которых горит в глазах огонь при виде новейших технологий. Люди поопытнее уже прошли эти круги ада новых и модных технологий как минимум пару раз, и подход у них более практический.
Имхо, разумеется.
— А как в этот Webpack'e подключить стили?
— Ну тут все просто, ставишь precss, postcss-loader, postcss-import, css-loader, style-loader, file-loader, normalizr, normalizr.css, autoprefixer
— Поставил все как вы сказали, но картинки не загружаются.
— Очевидно вы забыли установить image-webpack-loader
Перечитал статью — так и не понял над чем смеяться? С указанным стеком познакомился за месяц, за два-три месяца активной работы втянулся до уровня заглядывать в доки не больше пяти раз за день, второй год успешно на этом зарабатываю. То есть если даже оно все разом сейчас умрет — я считаю что свои инвестиции времени я отбил. Что не так? Где можно прийти с улицы и начать грести лопатой? При чем здесь кривизна языка разработанного на коленке? Современный js от того языка довольно далеко ушел. В каком языке достаточно знать только язык что бы продуктивно работать? Java? С++? (программируем сфероиды в вакууме, ага) Почему webpack — костыль, а make никсов — произведение исскуства? npm чем то хуже (или лучше) других менеджеров пакетов? Мужики, в любой нише придется изучать инфраструктуру, не потянули js — не расстраивайтесь. Да, сейчас порог вхождения для джисера гораздо выше чем было раньше. И уровень проектов — выше. И js давно вышел из песочницы броузера. Но это не повод расстраиваться — есть масса других ниш, другие стеки, возможно стоит начать с них )
make — стандартный инструмент. И будет стандартным и через 5, и через 10 лет.
webpack такой же стандартный инструмент фронтэнда (да уже и не только)
Надо нафигачить простейший SVM? Так, что у нас там есть… liblinear, libsvm, dlib. Мне ещё потом ручками надо будет запрогать логистическую регрессию, то есть, минимизировать функцию, в dilb это тоже есть, да ещё и в обобщённом виде, значит, выбираем его. Какой там API… За полчасика посмотрели, изучили, примеры почитали, можно писать. Ой, медленно, надо для матриц дёргать что-то этакое… О, есть же Intel MKL! А его как раз dlib тоже поддерживает! Пересобрали dlib с поддержкой MKL, вау, псевдообратная Пенроуза-Мура для матрицы 200000×200000 теперь берётся не 600 секунд, а 50!
А теперь то же самое но с гуями и что бы работало на винде, макоси, иос, андроид, зоопарке пингвинов и трех bds-дях.
Вы теплое с мягким зачем сравниваете? Как только Вы заденете гуй и портирование — тремя либами не отделаетесь.
Вы теплое с мяким зачем сравнваете? В браузере вы сделаете из всего перечисленного только гуй
В КАКОМ броузере? Вы понимаете что если сравнивать разработку фронтенда с разработкой пользовательского десктопного ПО то правильнее будет брать не разработку под одну платформу а сразу под весь зоопарк. Никто же приходит со словами — а сваяй ка мне, любезный, фронт под хром 52 версии. Никаких стилей, проект развиваться не будет, вот ТЗ — оно актуально на ближайшие 10 лет. (в таком раскладе да — бабель не нужен, куфсе меняем на custom elements, на webpack забиваем — делаем сборку с npm парой самописный скриптов и радуемся жизни) Но нет такого, как правило хотят весь зоопарк за редкими исключениями (кому то старые ослы не нужны, кто то на мобильные может не заморачиваться — по разному) Тут возникает бабель, потому что фрагментация и хочется писать на прямом языке под старые броузеры.
Далее — раз уж мы пишем приложение на все платформы, все для пользователя — давайте уже его писать так что бы пользователь (владелец сайта) мог легко менять темы (путем эксплуатации верстальщика). Ага? Да, для фронта для этого нужны инструменты для стилей. Тут уже всякие less и иже сними с поддержкой в webpack.
jsx (tsx) — шикарный инструмент который можно использовать и без реакта, спокойно переключаясь от верстки к коду — то есть в процессе программирования DOM елемент объявляется и используется и как верстка и как js объект. Темплейты становятся не нужны. Опять же tsx/jsx транспайлить удобено webpack-ом (просто потому что он изначально спроектирован для сборки фронтов)
Про сборку всего этого ливера в один модуль — в статье откровенный бред, webpack легко и непринуждено позволяет собирать в несколько, группировать общеиспользуемые.
Не хочу аппелировать к мысли о том что миллионы леммингов не ошибаются — но в этой ситуации прежде чем отмахнуться со словами "это не надо" может лучше сначала подумать — а зачем эти люди разрабатывают и использует эти инструменты? Можно спросить у самих этих людей, если сам сообразить не можешь. Но не надо натягивать свой опыт в ДРУГОЙ области к пониманию этой. Ведь по большому счету даже если взять только фронтенд — задачи которые перед ним ставятся — не ставятся в промышленных масштабах больше нигде. Никто не разрабатывет софт который ДОЛЖЕН работать на десятках платформ. Никто не разрабатывает софт который ДОЛЖЕН компилироваться десятком компиляторов. Не так часто к софту предъявляется требование легкой кастомизации интерфейса. Просто это разные области и соответсвенно разные инструменты.
А ведь кроме фронта есть расширения для броузеров, есть кодогенерация (swagger/raml) есть много чего чего нет в других нишах. Тут как в ресторане: не нравится — не ходи )
Вы верстаете странички для браузера
Как минимум до конца года. А там глядишь новый «стандарт» родится
webpack такой же стандартный инструмент фронтэнда (да уже и не только)
Для библиотеки, которой судя по ченжлогам еще трех лет нет смелое утверждение
стандарт это не то чему 10 лет а то что в мейнстриме (если мы говорим о стандартах де факто) Ок, расскажите мне про сборку фронта при помощи make+configure (я знаю что это возможно, более того — я собирал такой проект — именно это позволяет мне сравнивать трудозатраты)
И это не либа и даже не таск раннер — это билдер.
стандарт это не то чему 10 лет а то что в мейнстриме
Когда-то в мейнстриме были хаки для IE, который не поддерижвал стандарты. Как это назвать по вашей логике? :)
Необходимо запилить с нуля сервис для визуализации. Множество кастомных чартов со всякими плюшками. Для визуализации понятное дело выбран d3.js, ибо адекватных аналогов по сути дела нет, если нужен баланс между готовыми фишками и широкой кастомизацией. Но поставлять при этом надо не только голые чарты, а еще несколько кусков, то есть требуется компонентный подход. Ну и естественно выбор (не мой, меня к проекту подрубили уже слишком поздно) пал на React.
И тут начинается самое интересное. В реакте все крутится вокруг virtual dom, а в d3 вокруг обычного дом. Хочешь чтобы эти 2 вещи работали друг с другом как надо? Вот тебе мегакостыль под названием ReactFauxDom (по сути дела лайтовый рескин jsdom). Подрубил, сделал все — работает, можно успокоится. По крайней мере так думал ведущий разработчик, пока не прилетел таск на запиливание анимации. И тут выяснилось что хрен тебе а не анимация. Либо иди нафиг, либо пили мегакостыли. После гуглинга самым «лучшим» из костылей оказался вот этот. Я когда увидел реализацию, у меня чуть глаза на лоб не вылезли. Люди на полном серьезе предлагают на каждом фрейме анимации (16ms) обновлять состояние компонента! Тут конечно можно во всем винить разработчика, который выбрал такой стек, но чтобы бы пришлось делать, если бы на проекте, где все изначально было запилено с реактом, пришлось бы вставлять визуализацию с d3? Делать вот такие жуткие вещи, за которые в приличном обществе расстреливать надо?
Спасибо, интересно очень именно про негативные стороны React узнать. Потому что все пишут про его положительные стороны, а вот недостатки обходят стороной. А ведь в них вся соль. Мне вот совершенно непонятно пока, как в реакте с его уровнем абстракции от DOM делать какие-то супер динамичные вещи.
К примеру, у меня есть проект WYSIWYG редактора, который юзает голый DOM (и именно это позволило сделать такой UI, а также кастомный undo/redo стек для DOM):
Я понятия не имею как подобное можно было бы реализовать в рамках модели React. Но очень интересно.
Всему свое время. Просто его код пока еще слишком плох для opensource (много проприетарщины и левых зависимостей), и я хочу его отрефакторить перед публикацией, но никак не могу найти время на это. Тут очень важно maintainability, потому что у меня нет времени это развивать самому (мне за это не платят), а комьюнити могло бы помочь. Вообще-то он валяется на гитхабе, но пока что в реально стремном состоянии, not for human consumption.
По сравнению с реактом — это голый дом, т.к. к нему прямой доступ, оно работает напрямую с его узлами (без виртуальной прослойки). На реакте я такое не знаю как сделать, мне кажется это просто невозможно на данный момент. По поводу эксепшенов я хз, я это вообще не планировал публиковать пока что, пока не отвяжу это от проприетарных библиотек. Зря я ссылку выложил.
О, замечательная штука. Меня правда больше заинтересовал Draft.js сейчас фейсбучный — т.к. он куда более примитивный, для образовательных целей больше подходит. В общем, щас буду думать, как такую механику взаимодействия реализовать для React-based редакторов, может это не так уж и сложно, как кажется. Потому что очень хочется перейти на VirtualDOM и иммутабельность состояния — плюсы от этого перевешивают все минусы, когда речь заходит о такой сложной вещи, как современные контент-редакторы.
http://radiokot.ru/forum/viewtopic.php?f=17&t=109995
first class citizen
я даже не знаю, что это такое
(ну и замыканий в довесок).
чего уж там, я не осилил концепцию яваскрипта, потому что входил в программирование с классических языков с четкой структурой и типизацией, где функция никак не может быть переменной и тем более без имени
сейчас учу шарп, так мне он очень по нраву
питон пробовал — синтаксис не понравился, скобочек нет
по го нет русских видео лекций
по шарпу нашел годный ресурс по обучению
Если это троллинг, то я на него почти повёлся. В ином случае вам стоит изучить Haskell (или его браузерную инкарнацию Elm), иначе ну нельзя же таким быть! Особенно вот это понравилось:
питон пробовал — синтаксис не понравился, скобочек нет
Если это троллинг
да у меня что ни пост, то все думают, что троллинг
чего тролльного в моем посте и на что ты повелся?
В ином случае вам стоит изучить Haskell
а зачем он мне? я только краем уха слышал про него
Особенно вот это понравилось
чего тут смешного? у языка должен быть приятный синтаксис, чтобы кровь из глаз не текла
В Си и Паскале можно создать функцию-переменную и передать ее в качестве пареметра в другую функцию
что скобочки не ставятся — это косяк, я где-то когда-то упоминал об этом
т.е. они статически забиты в памяти и тупо выполняются друг за другом, а хотелось включать их по желанию
я подумал, что у функции должен быть адрес и этот адрес можно как-то указать в переменной или массиве и потом выбирать индекс
загуглил и нашел
т.е. я даже не знал что такое есть, просто предположил, основываясь на понимании языка и устройстве всего этого дела
я даже понял, что примерно искать
тут я четко вижу, что я присвоил переменно ор адрес функции с именем doubling
один косяк — нет скобочек после имени, что вызывает путанницу при чтении незнакомого кода
ну и в яваскрипте я даже не знаю, зачем это нужно
не стал осиливать
да и особо не силен
Practice makes perfect… Или «дорогу осилит идущий». Вы же просто не хотите идти.
Вы же просто не хотите идти
а кто хочет идти по грязи?
я помню ит 16 лет назад и что сейчас
все усложняется, нет разумной достаточности
то же самое с телефонами — процессоры с кучей ядер и гигагерцами, экраны с таким разрешением, что мой 24" монитор отдыхает
и для чего это все, если этот телефон еле тянет 1 день? поэтому я юзаю смартфон 5 летней давности, который даже на батарейке 5 летней работает больше суток
мы покупали одинаковые телефоны с корешем в 2011 году, а он сменил уже кучу телефонов за это время
вот даже посмотри на редактор для каментов тут — есть куча ненужных кнопок, но самая нужная кнопка цитирования не вставляет маркированный текс
а эта фишка была реализована много лет назад на форуме ixbt
зачем мне изучать сложные языки, системы, железо, если они никто не делает простых и полезных вещей?
сейчас смотрю ролик про тоету 91 года, которая проехала лям километров и движок не сдох, кузор не прогнил
наворотов там столько, что некоторые до сих пор нигде не используются у других производителей и навороты полезные
Насчет телефонов я с вами согласен. Я вообще телефон не использую уже пару лет как — не хочу кормить зажравшихся операторов связи, которые отчаянно не хотят быть просто «трубой для данных», и ведут себя как цыгане на рынке, пытаясь обобрать пользователя до последней копейки. Это не партнерство, это не сотрудничество — это воровство… И бороться с этим можно только прекратив эти «отношения». Но это так, оффтоп :)
Но если вы думаете, что концепция «функций как объектов первого класса (first class citizen)» и замыканий вам подобным образом чем-то навредит, обокрав ваше внимание и время — то это вы зря. Мне вот есть с чем сравнивать, могу вас уверить, что это вас только обогатит, сократив ваши трудозатраты. Ну это конечно, если вы собираетесь зарабатывать написанием кода. В ином случае вам это, действительно, не нужно...
— А что насчет React?
— Фу
— Фу??
— ФУУ!!!
сравнивать jsx и smarty немного некорректно — это перпендикулярные вещи. А кроме jsx в реакте нет ничего что выживет после принятия custom elements. Как только они перестанут быть драфтом — имхо, они порвут всех на районе. Биндинги и иммутабельность к ним спокойно прикручивается либами, да и сам реакт можно прикрутить, на переходный период, если не хочется терять наработки.
Ну а как же реактивность? Реакт — это же не только абстракция для кастомных элементов.
Для реативности такой монстр не нужен — достаточно Proxy. На мой взгляд, не навязываю но говорю достаточно настойчиво — один свой проект решил реализовать без оглядки на совместимость, так как хочется, для души так сказать. Так вот на современном js (typescript точнее) и современных броузерах все эти чудесные фреймворки отлетают как шелуха, заменяясь где парой строк где одним небольшим модулем. Что то уже в процессе устаканилось, что то еще формируется — но в общем и целом — мое мнение, повторюсь, react не выживет (по крайней мере в том виде что он есть сейчас) Связка tsx + custom elements + Proxy порвала все мои притязания (причем без shadow dom и templates) Может как нибудь напишу статью подробнее — так в одном комментарии все не разберешь и не аргументируешь, так что воспринимайте как мою хотелку, не более )
Сами custom elements не решают основную проблему, которую решает реакт — проблему рендеринга из динамических данных. Именно поэтому React как раз перпендикулярная им вещь. В доках реакта где-то даже есть заметка, как юзать реакт вместе с custom elements.
«Убить» реакт мог бы LazyDOM — это нативная браузерная реализация VirtualDOM, которая основана на DOM API (т.е. виртуальные элементы имеют тот же API что реальные дом узлы — что позволяет юзать их вместе с любым старым кодом, который основан на манипуляциях с реальным DOM, типа джиквери плагинов). Но это пока только экспериментальная концепция.
В самом реакте юзать кастомы геморройно да и не надо. А вот в кастомах использовать реакт — да, можно и в принципе (на первый взгляд) может даже имеет смысл. А биндинги и реактивность, как я уже выше ответил — легко реализуется через Proxy.
Интересно было бы посмотреть на proxy-based решения. Я сам недавно достаточно много времени посвятил исследованиям возможностей Proxy для реактивности, но пришел к выводу что модель React сильнее, т.к. не требует заворачивания данных в какие-то врапперы, т.е. она менее инвазивна.
Не будет ли реализация на основе прокси иметь те же ограничения и слабости, что и Нокаут?
Какой-то хакатон.
Один чувак пытается поднять всю ниииобозримую инфраструктуру, не успевает, говорит ок, отосплюсь — закончу, а второй за час пишет один .html с jquery внутри, который делает ровно то что нужно. Да, его не расширить путем написания конфига с каким-нибудь препроцессором, там нет автосборки, минификации, линтера, bowera grunta с gulp'ом, там нет react'a и всей прочей хипстотни. Но он просто работал.
Самый смак, что когда первому показали результат — он просто не понял что сделали, в его категориях просто не было такого варианта.
Вопрос в том, что:
Я щас делаю простое приложение — обычный TODO-лист, используя HTML, CSS и JavaScript
Ну и в том, что доживет ли кто-нибудь из этих проектов до стадии, когда эта разница в поддержке станет заметна без микроскопа
А вот что реально пугает — так это то, что некоторые люди, за всем фасадом просто забывают (или не знают, что пугает еще больше), что там, внутре
И во столько же раз быстрее. Где эта грань, когда становится легче на реакте поддерживать, проходит?
И одновременно стало проще — но на другом уровне. Такой стек технологий ведь не просто так возник, это именно ответ на вызовы современности, это реакция на необходимость делать вещи, которые лет 5 назад были просто немыслимы из-за сложности реализации.
То есть оно «все усложнилось» разве что только в какой-то статичной системе отсчета… ну типа, если вы в 2016 все еще ориентируетесь на проекты уровня 2008 года, то это действительно кажется чем-то безумным. Я занимаюсь веб-фронтендом примерно с того года как раз, и прекрасно помню, как я тогда несколько недель (на голом DOM / HTML / CSS) возился с проектом, на который сегодня у меня ушел бы один рабочий день. Тогда просто не было таких инструментов.
Браузеры остались те же, CSS/HTML/JS остался тот же, сегментация увеличилась в разы, но это тяжело считать позитивным фактором. Мы научились героически преодолевать проблемы, которые сами создаем?
А то что знатные веб-програмисты любят обмазываться всякими gulp-ами и yeoman-ами — это их выбор, который на конечный результат влияет не так сильно, как им кажется:
Браузер поддерживает gz-сжатие, так что предварительно сжимать текстовые файлы не не так уж и нужно (по крайней мере пока у вас не 50 мегабайт кода и верстки за раз)
Современные браузеры открывают с десяток keep-alive соединений на каждой странице и выкачивают через них все необходимые ресурсы с сервера. На другой стороне nginx может отдавать сотни тысяч файлов особо не напрягаясь
Так скажите мне, зачем вы сжимаете и склеиваете?
Возьмем для примера js-рантайм прекрасного парсера antlr4. В разобранном виде 64 файла, 640 килобайт + обязательно require.js. В .gz — те же 64 файла, 240кб. Плюс десяток соединений все-таки довольно долго забирает 64 файла.
В склеенном и минифицированном — один файл 160 кб. Склеенный и минифицированный в .gz — 38кб. Все еще не понятно зачем?
А в проекте у нас например уже в районе 300 своих js-файлов. Считать оверхед для всего проекта я не буду, мысль понятна, думаю.
> Плюс десяток соединений все-таки довольно долго забирает 64 файла
В моих изысканиях не более чем в полтора раза для 50 маленьких файлов
Да, и такие чудеса встречаются. Самое интересное что они сами никаких скриптов для сборки не предоставляют и официально предлагают использовать через require в таком виде, в каком она есть. И "из коробки" оно не собирается, приходится чуть-чуть дополнять.
В моих изысканиях не более чем в полтора раза для 50 маленьких файлов
Полтора раза — это очень много, я тут за каждую 0.1 секунды борюсь для нашего довольно тяжелого приложения)
Ну и как я уже написал проект — он ведь не только из парсера состоит. Есть еще некоторое количество вендорских библиотек и очень много своих файлов. Плюс, как правильно заметили ниже, браузер просто не умеет работать с es6 imports.
А еще амазоновский балансер до сих пор не поддерживает http/2, который мог бы частично решить проблему.
Ну склеивать удобно хотя бы потому, что браузер не поддерживает директивы import
и require
. А любой более-менее сложный проект это сотни файлов, связанных такими зависимостями.
Каким образом вы это на HTML страничку доставите? Будете вручную script
теги прописывать для каждого, еще и вручную нужный порядок подключения высчитывая?
Конечно же, вы возьмете webpack
, укажете ему «точку входа» (js-файл), и он разрешит все дерево зависимостей, высрав это в один файл, который вы можете банальным script
тегом подключить. Как бонус — вебпак поддерживает горячую перезагрузку модулей.
Я вот буквально прямо щас настраиваю у нас в сервере Webpack HMR (hot module replacement) + React HotReload. Очень удобная вещь — я жму Ctrl-S в редактируемом модуле, и моментально получаю в браузере обновленный код, без перезагрузки страницы. А поскольку архитектура React/Redux предполагает разделение кода и данных, то при такой замене кода «на горячую», даже не теряется состояние моих компонентов. Это очень круто и дает 100% буста продуктивности.
Так и делал. Если сторонняя библиотека, то подключаю ее через тег script. Если своя, неделимая либа, склеиваю (cat 1.js 2.js… > lib.js). Если просто файлы проекта — подключаю по отдельности. Потому-что на некоторых страницах требуется лишь часть этих файлов.
> Будете вручную script теги прописывать для каждого, еще и вручную нужный порядок подключения высчитывая?
Вы тоже вручную прописываете. причем сильно больше прописываете, т.к. import-ы надо дублировать в каждом файле
imprt'ы прописывает IDE. На них не нужно отвлекаться.
Но при этом мне проще мейнтейнить свой проект, т.к. каждый модуль знает только то, от чего он зависит. И плоский список всех зависимостей получается как производное от этого.
А у вас получается делокализация — скажем, я поменял модуль A так, что он теперь зависит от модуля B. И эту информацию мне нужно добавить в какое-то совершенно третье место («главный заголовочный файл», со плоским списокм всех зависимостей), в котором никак не отражена связь между модулями. Это значит, что если модуль A перестанет зависеть от B, то «мусорная» зависимость с высокой вероятностью останется в том третьем файле, потому что вы забудете про неё. Или кто-нибудь еще забудет. В общем, у меня был опыт разработки проекта где именно таким образом все делалось — я не юзал import/require для декларирования межмодульных зависимостей, и поимел все возможные связанные с этим проблемы. Самая жесть началась, когда я попытался сделать свой код re-usable, расшарив его между многими проектами. Сразу же возникает такого рода проблема, что вам нужно во всех этих проектах менять список зависимостей, когда в каком-то модуле что-то меняется. Это приводило к труднообнаружимым багам, к избыточности кода, и так далее.
Если бы я с самого начала использовал import/require и автоматическое разрешение зависимостей (webpack), то сэкономил бы кучу времени...
Причем это АРХИТЕКТУРА за два-три месяца уже успела несколько раз поменяться, тесты написанные вначале сломались, а чинить их никто не собирается, но зато появился новый красивый дэшборд для вебпака, который нужно скорее добавить в репозиторий проекта.
Вопрос «Успеете ли вы до дедлайна предоставить какую-то рабочую версию» был встречен недоумением и обидками.
Сейчас в вебе все идет почему-то в обратную сторону.
It’s the future