Init.js: руководство о том, почему и как использовать полностековый JavaScript

Опубликовано: 2022-03-11

История

Итак, у вас и вашего соучредителя есть отличная идея для бизнеса, верно?

Вы добавляли функции в своем уме.

Часто вы спрашиваете мнение потенциальных клиентов, и всем им это нравится.

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

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

"Сделанный! Оно работает!" ты говоришь. Ваше доказательство концепции прошло успешно! Осталось только упаковать его в веб-приложение.

«Хорошо, давайте создадим сайт», — говорите вы.

И тут вы осознаете истину: вам нужно выбрать язык программирования; нужно выбрать (современную) платформу; нужно выбрать несколько (современных) фреймворков; вам необходимо настроить (и приобрести) хранилища, базы данных и хостинг-провайдеров; вам нужен интерфейс администратора; вам нужна система разрешений; Вам нужен контент-менеджер.

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

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

«Я ошеломлен», — говорите вы, чувствуя себя ошеломленным. Ваша энергия уже не та, что была раньше. Вы пытаетесь собрать вещи воедино, но это слишком много работы.

Ваше доказательство концепции медленно увядает и умирает.

Предложение

Отказавшись таким образом от множества идей, я решил разработать решение. Я называю это проектом «Init» (или init.js).

Суть идеи в том, чтобы иметь один проект, чтобы запустить их все, позволить разработчику или техническому основателю принять все эти важные решения одновременно и получить соответствующий стартовый шаблон на основе этих решений. Я знаю, что скажут недоброжелатели: «Невозможно применить одно решение ко всем проблемам» (ненавистники возненавидят). И они могут быть правы. Но мы можем сделать все возможное, чтобы создать приблизительное решение, и я думаю, что Init подходит к этому довольно близко.

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

  • Компоненты

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

  • Простота разработки

    Какая-то проблема, где-то есть решение, которое лучше всего написать на Brainf*ck. Но реализовать это решение (в Brainfuck) будет практически невозможно, не говоря уже о чтении. Это будет стоить вам времени и огромных усилий. В общем, вы должны использовать языки и платформу, которые упрощают разработку, а не усложняют ее для вас (или для тех, кто может работать над ней позже).

  • Сообщество

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

Помня об этих целях, я покажу вам, как я принимал собственные решения при создании Init.

По своей сути Init использует преимущества парадигмы «полного стека JavaScript» (некоторые называют ее или ее подмножество стеком MEAN). Работая с таким стеком, Init может использовать только один язык, создавая невероятно гибкую и полнофункциональную среду для разработки веб-приложений. Короче говоря, Init позволяет вам использовать JavaScript не только для разработки клиента и сервера, но также для сборки, тестирования, создания шаблонов и многого другого.

Но давайте ненадолго притормозим и спросим себя: действительно ли стоит использовать JavaScript?

Почему я выбрал JavaScript

Я работаю веб-разработчиком с 1998 года. Тогда мы использовали Perl для большей части нашей серверной разработки, но даже с тех пор у нас был JavaScript на стороне клиента. С тех пор технологии веб-серверов сильно изменились: мы прошли волну за волной языков и технологий, таких как PHP, AP, JSP, .NET, Ruby, Python, и это лишь некоторые из них. Разработчики начали понимать, что использование двух разных языков для клиентской и серверной сред усложняет ситуацию. Первоначальные попытки унификации под единый язык пытались создавать клиентские компоненты на сервере и компилировать их в JavaScript. Это не сработало, как ожидалось, и большинство этих проектов потерпели неудачу (например, ASP MVC заменил веб-формы ASP.NET, а GWT, возможно, будет заменен в ближайшем будущем Polymer). Но по сути это была отличная идея: единый язык на клиенте и сервере, позволяющий нам повторно использовать компоненты и ресурсы (это ключевое слово: ресурсы ).

Ответ был прост: поставить JavaScript на сервер.

На самом деле JavaScript родился вместе с серверной частью JavaScript в Netscape Enterprise Server, но в то время этот язык просто не был готов. После многих лет проб и ошибок наконец появился Node.js, который не только поместил JavaScript на сервер, но и продвигал идею неблокирующего программирования, навсегда изменив способ написания «fread» (I/O) (читайте здесь для большего).

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

Но эти идеи не были новыми — так почему же они стали такими популярными в Node.js? Простое неблокирующее программирование может быть достигнуто несколькими способами. Возможно, проще всего использовать обратные вызовы и цикл обработки событий. В большинстве языков это непростая задача: в то время как «обратные вызовы» являются обычной функцией в некоторых других языках, цикл событий — нет, и вы часто сталкиваетесь с внешними библиотеками (например, Python с Tornado). Но в JavaScript обратные вызовы встроены в язык, как и цикл обработки событий, и почти каждый программист, который хотя бы баловался JavaScript, знаком с ними (или, по крайней мере, использовал их, даже если они не совсем понимают, что такое событие). петля есть). Внезапно каждый стартап на Земле смог повторно использовать разработчиков (т. е. ресурсы) как на стороне клиента, так и на стороне сервера, решив проблему с объявлением о вакансии «Требуется гуру Python».

Внезапно каждый стартап на Земле смог повторно использовать разработчиков (т. е. ресурсы) как на стороне клиента, так и на стороне сервера, решив проблему с объявлением о вакансии «Требуется гуру Python».

Итак, теперь у нас есть невероятно быстрая платформа (благодаря неблокирующему программированию) с невероятно простым в использовании языком программирования (благодаря JavaScript). Но достаточно ли? Будет ли это продолжаться? Я уверен, что JavaScript будет занимать важное место в будущем. Позвольте мне рассказать вам, почему:

  • Функциональное программирование

    JavaScript был первым языком программирования, привнесшим функциональную парадигму в массы (конечно, первым был Lisp, но большинство программистов никогда не создавали готовых к использованию приложений с использованием Lisp). Lisp и Self, оказавшие наибольшее влияние на Javascript, полны новаторских идей. Эти идеи могли бы освободить наш разум для исследования новых техник, паттернов и парадигм. И все они переносятся на JavaScript. Взгляните на монады, числа Черча или даже (для более практичного примера) функции коллекций Underscore.js, которые могут сэкономить вам строки и строки кода.

  • Динамические объекты и наследование прототипов

    Объектно-ориентированное программирование без классов (и без бесконечных иерархий классов) позволяет быстро разрабатывать (создавать объекты, добавлять методы и использовать их), но, что наиболее важно, сокращает время рефакторинга во время задач обслуживания, позволяя программисту вместо этого изменять экземпляры объектов. классов. Эта скорость и гибкость прокладывают путь для быстрого развития.

  • JavaScript — это Интернет

    JavaScript был разработан для Интернета, он существует с самого начала и никуда не исчезнет. Все попытки уничтожить его потерпели неудачу: см., например, крах Java-апплетов, замену VBScript на TypeScript от Microsoft (который компилируется в JavaScript) и кончину Flash от рук мобильного рынка и HTML5. Невозможно заменить Javascript, не нарушив работу миллионов веб-страниц, поэтому нашей целью в будущем должно быть его улучшение. И нет никого лучше для этой работы, чем Технический комитет 39 из ECMA.

    Хорошо, альтернативы JavaScript рождаются каждый день, например, CoffeeScript, TypeScript и миллионы языков, которые компилируются в JavaScript. Эти альтернативы могут быть полезны на этапах разработки (через исходные карты), но они не смогут заменить JavaScript в долгосрочной перспективе по двум причинам: их сообщества никогда не будут больше, а их лучшие функции будут приняты сценарием ECMA (т. е. JavaScript). ). JavaScript — это не язык ассемблера: это язык программирования высокого уровня с исходным кодом, который вы можете понять — поэтому вы должны его понимать.

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

Сквозной JavaScript: Node.js и MongoDB

Итак, вот причины для использования JavaScript. Теперь я буду использовать JavaScript как причину для использования Node.js и MongoDB.

  • Node.js

    Node.js — это платформа для создания быстрых и масштабируемых сетевых приложений — примерно так и написано на сайте Node.js. Но Node.js — это нечто большее: это предпочтительная среда выполнения для любого приложения JavaScript с доступом к вводу-выводу. Даже если вы не планируете писать основное серверное приложение с помощью Node.js, вы можете использовать инструменты, созданные на основе Node.js, для улучшения процесса разработки. Например: Mocha.js для модульного тестирования, Grunt.js для автоматизированных задач сборки или даже Brackets для полнотекстового редактирования кода.

    Итак, если вы собираетесь писать приложения JavaScript для сервера или клиента, вам следует взглянуть на некоторые примеры Node.js, поскольку они вам понадобятся и будут использоваться ежедневно. Есть несколько интересных альтернатив, но ни одна из них не составляет даже 10% сообщества Node.js.

  • MongoDB

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

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

Компонентизация сервера с помощью Express.js

Компонентизация на стороне сервера никогда не бывает легкой. Но с Express.js (и Connect.js) появилась идея «промежуточного программного обеспечения». На мой взгляд, промежуточное ПО — лучший способ определить компоненты на сервере. Если вы хотите сравнить его с известным шаблоном, он довольно близок к каналам и фильтрам.

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

Мы называем эти «части конвейера» «промежуточным ПО». Ясно, что мы можем создать два типа промежуточного программного обеспечения:

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

  • Финалы : Те, кто несет полную ответственность за окончательный ответ. Они обрабатывают и изменяют запрос и ответ, но им не нужно делегировать следующему промежуточному программному обеспечению. На практике рекомендуется в любом случае делегировать полномочия следующему промежуточному программному обеспечению, чтобы обеспечить архитектурную гибкость (т. е. добавление дополнительных промежуточных программ позже), даже если этого промежуточного программного обеспечения не существует (в этом случае ответ будет направлен прямо клиенту).

В качестве конкретного примера рассмотрим компонент «менеджер пользователей» на сервере. Что касается промежуточного программного обеспечения, у нас будут как финальные, так и промежуточные версии. Для нашего финала у нас будут такие функции, как создание пользователя и перечисление пользователей. Но прежде чем мы сможем выполнить эти действия, нам нужны наши промежуточные звенья для аутентификации (поскольку мы не хотим, чтобы неаутентифицированные запросы поступали и создавали пользователей). После того, как мы создали эти промежуточные звенья аутентификации, мы можем просто подключить их в любом месте, где мы хотим превратить функцию, ранее не прошедшую проверку подлинности, в функцию, прошедшую проверку подлинности.

Одностраничные приложения

Проект Init фокусируется на создании одностраничных приложений (SPA). Большинство веб-разработчиков не раз испытывали искушение попробовать свои силы в SPA. Я создал несколько (в основном проприетарных) и могу с уверенностью сказать, что это просто будущее веб-приложений. Вы когда-нибудь сравнивали SPA с обычным веб-приложением в мобильном соединении? Разница в отзывчивости составляет порядка десятков секунд.

Вы когда-нибудь сравнивали SPA с обычным веб-приложением в мобильном соединении? Разница в отзывчивости составляет порядка десятков секунд.

SPA — это будущее Интернета, так зачем вам создавать свой продукт в устаревшей форме? Распространенный аргумент, который я слышу, заключается в том, что люди беспокоятся о SEO. Но если вы все делаете правильно, это не должно быть проблемой: у самого Google есть очень хорошее руководство о том, как это сделать, и здесь также есть несколько хороших комментариев.

MV* на стороне клиента с Backbone.js, Marionette.js и Twitter Bootstrap

Много было сказано о фреймворках MVC* для SPA. Это сложный выбор, но я бы сказал, что в первую тройку входят Backbone.js, Ember.js и Angular.js.

Все трое очень хорошо зарекомендовали себя. Но какой из них лучше для вас?

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

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

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

В случае с Init я хотел охватить большинство сценариев, поэтому выбрал Backbone.js для простого создания SPA и Backbone.Marionette.View для компонентизации. Таким образом, каждый компонент представляет собой простое приложение, а конечное приложение может быть настолько сложным, насколько мы этого хотим.

Стилизация также является сложной задачей, но мы снова можем рассчитывать на то, что фреймворки нас выручат. Для CSS нет ничего лучше, чем Twitter Bootstrap, который предлагает полный набор стилей, готовых к использованию «из коробки» и легко настраиваемых.

Bootstrap был создан с использованием языка LESS и имеет открытый исходный код, поэтому мы можем изменить его, если это необходимо. Он поставляется с множеством элементов управления UX, которые хорошо задокументированы на сайте Bootstrap. Кроме того, есть модель настройки, которая позволяет вам создавать свои собственные. Это определенно человек для работы.

Лучшие практики: Grunt.js, Mocha.js, Chai.js, RequireJS и CoverJS

Наконец, мы должны определить некоторые из наших лучших практик и посмотреть, как Init может помочь вам реализовать и поддерживать их. Наше решение основано на нескольких инструментах, которые сами основаны на Node.js.

  • Mocha.js и Chai.js :

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

    Существуют тысячи фреймворков модульного тестирования для JavaScript. Так зачем использовать Mocha.js? Короткий ответ: он гибкий и полный.

    Длинный ответ: у него есть две важные функции (интерфейсы, отчеты) и одно существенное отсутствие (утверждения). Позволь мне объяснить.

    • Интерфейсы : может быть, вы привыкли к TDD-концепциям наборов и модульных тестов, или, может быть, вы предпочитаете BDD-идеи спецификаций поведения с «описать» и «так и должно быть». Mocha.js позволяет использовать оба подхода.

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

    • Отсутствие библиотеки утверждений : это не проблема, Mocha.js был разработан, чтобы позволить вам использовать библиотеку утверждений по вашему выбору, что дает вам еще большую гибкость. Есть много вариантов, но здесь в игру вступает Chai.js.

    Chai.js — это гибкая библиотека утверждений, которая позволяет использовать любой из трех основных стилей утверждений:

    • Assert : классический стиль утверждения из старой школы TDD. Например:

       assert.equal(variable, ”value”);
    • Expect : стиль утверждений с цепочкой, наиболее часто используемый в BDD. Например:

       expect(variable).to.equal(“value”);
    • Должен : также используется в BDD, но я предпочитаю Expect, потому что Должен звучит повторяющимся со спецификацией поведения «это («должен сделать что-то..»)». Например:

       variable.should.equal(“value”);

    Chai.js прекрасно сочетается с Mocha.js. Используя только эти две библиотеки, вы можете писать тесты в TDD, BDD или в любом другом стиле.

  • Грунт.js :

    Grunt.js позволяет автоматизировать задачи сборки, от простого копирования-вставки и объединения файлов до предварительной компиляции шаблонов, компиляции языка стилей (например, SASS и LESS), модульного тестирования (с mocha.js), линтинга и минификация кода (например, с помощью UglifyJS или Closure Compiler). Вы можете добавить свою собственную автоматизированную задачу в Grunt или выполнить поиск в реестре Grunt, где есть сотни и сотни доступных плагинов (опять же, использование инструментов, за которыми стоят большие сообщества, окупается). Grunt также может отслеживать ваши файлы и запускать действия при их изменении.

  • Требуется JS :

    RequireJS может показаться просто еще одним способом загрузки модулей с помощью AMD, но я могу заверить вас, что это гораздо больше. Чтобы понять почему, нам сначала нужно упомянуть идею пространства имен модулей (например, demo.views.hello), которое позволяет избежать загрязнения глобального пространства имен, заключая каждый модуль в свое собственное пространство имен. Проблема в том, что эти модули нельзя использовать повторно: если вы измените пространство имен одного «экземпляра», вы измените пространство имен всех «экземпляров». В отличие от этого, RequireJS позволяет вам определять повторно используемые модули с самого начала. (Кроме того, это поможет вам использовать внедрение зависимостей, чтобы ваши модули не обращались к глобальным переменным.)

  • ОбложкаJS :

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

Использование ветвей для переключения функций

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

По сути, каждая ветвь представляет функцию или функцию, которую пользователь может захотеть включить. Если вы начинаете проект с нуля, начните с минимальной ветки, которая вам понадобится, а затем добавьте другие технологии путем слияния с нужными ветвями. Например, предположим, что вы хотите начать свой проект с Backbone.js и Marionette.js. Что ж, вы можете начать с ветки Backbone.js и объединить ее с веткой Marionette, продолжая добавлять каждую часть функциональности, которую вы хотите добавить.

init.js и Javascript

На данный момент эту идею слияния для добавления функциональности можно использовать только для технологических шаблонов (например, Backbone, Node, Express). Но в будущем вы сможете переключаться между серверной (например, с MongoDB на Postgres) и клиентской реализацией.

Начните проект с Init и разверните его на Heroku уже сегодня

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

  1. Создайте каталог для своего проекта (или используйте существующий).
  2. Создайте свой репозиторий с помощью «git init» (или используйте существующий репозиторий).
  3. Добавить пульт с инициализацией

     git remote add init git://github.com/picanteverde/init.git
  4. Получите нужную ветку

     git pull init usermanager
  5. Получите файл процесса Heroku

     git pull init heroku-webprocess
  6. Установив Heroku Toolbelt, создайте приложение Heroku.

     heroku create
  7. Отправьте свою основную ветку в Heroku

     git push heroku master
  8. Посетите свое приложение, запущенное и работающее на Heroku!

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

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