Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Что может быть проще, чем написать "Hello, world" и нажать Enter? Несколько секунд и программу можно отправлять в продакшн и поставлять клиентам. И тут приходит начальник и говорит: "Погоди-ка. А где тесты?". И ты такой: "Блииин!". И садишься писать тесты.
А кроме тестов, вашу программу "Hello, world", скорее всего, чтобы она попала в продакшн, придется обвесить кучей финтифлюшек в соответствии с гайдами, принятыми в вашей компании. Например, камментами в особом формате.
И вот веселый кодинг превращается в скучнейшую рутину.
Когда я начал программировать на Apex для Salesforce, я был поражен количеством подготовительной работы, которую нужно провести, чтобы задеплоить код в продакшн. Тут уже на начальник, а сама система требует, чтобы код был покрыт минимум на 75% тестами.
А еще есть best practice, которая не то чтобы "хочу исполняю, а хочу нет", а имеющая почти статус конституции. Например, "bulkify everything", потому что ты думаешь, что код вызовется один раз, а он та-дам - и вызовется раз 200 за одну транзакцию, и Salesforce governor limits скажут тебе "прощай". Как и работодатель и клиенты.
И сам Apex тоже довольно многословный. Что это за создание пустого массива в 21 веке?
List<Account> accs = new List<Account>();
Ну ладно, Апекс Апексом, но, разумеется, все вышеописанное, превращающее праздник в рутину, касается индустрии профессионального программирования в целом. Тесты писать надо, гайды исполнять тоже надо на любом языке. Так создание простого класса, выводящего в консоль "Hello, world", превращается в необходимость написания десятков или даже сотен строк шаблонного кода.
Естественно, никто в здравом уме с нуля в таком случае не пишет. Copy/Paste наше все. При этом программирование превращается в еще более увлекательное занятие по исправлению в скопированном куске имен, типов, констант, каментов и т.д. Да-да, RegExp и все такое, но прям с регэкспом значительно веселее?
Помучился я, помучился, и решил написать сниппет-менеджер своей мечты.
Какие были предварительные требования:
Написать нужно быстро, за 10-15 вечеров.
Сниппеты должны храниться в сети, но не в централизованной базе, потому что не хочу поддерживать серверную инфраструктуру. Не должно быть ни одного серверного скрипта.
Сниппет-менедежр должен иметь встроенный движок какого-нибудь языка программирования типа Python или JavaScript, на котором можно будет писать что-то вроде макросов.
Макросы должны исполняться интерактивно, выдавая результат мгновенно по мере написания. Не так, что полчаса пишешь, потом жмешь кнопку Run и еще полчаса занимаешься исправлением ошибок.
Браузер - единственное, что нужно для работы сниппет-менеджера. Никаких инсталляций, локальных баз данных, работ с файловой системой и т.д.
После долгой внутренней борьбы было принято решение писать на Flutter под веб. На мой взгляд, Flutter на сегодняшний день реальный чемпион по скоростному созданию приложений. Года полтора назад я посмотрел на него и поразился стройности общей концепции фреймворка и модерновости языка Dart. Однако тогда Flutter for web работал в экспериментальном режиме, поэтому веб-приложения казались сыроватыми. Но недавно Flutter for web выкатили в стабильный канал, поэтому, наверное, пришло время попробовать его в боевом режиме.
За две недели не получилось, но за месяц удалось написать первую версию сниппет-менеджера, готового к реальному использованию. Он доступен по ссылке https://apexwidget.com.
Сниппет - это просто кусочек кода, который хранится в ApexWidget, и который вы можете скопипастить. Но сниппет сам по себе - это еще и макрос, который исполняется встроенным интерпретатором JavaScript.
Все, что вы напишите в редакторе, моментально отобразится во вьюере. Напишем, "Hello, world".
Как видите, все работает, но никакого фана, хотя даже в таком виде уже можно что-то сохранять и куда-то копипастить. Но напишем что-нибудь поинтереснее: Result: ${2+2*2}
Интерпретатор выполнил код внутри блока ${...} и выдал во вьюер готовый результат. Собственно, интерпретатор воспринял содержимое блока ${...} как js-выражение и его исполнил. А что если мы хотим писать что-то посложнее и побольше, чем одно выражение? Для этого ApexWidget поддерживает блоки <%...%>. Внутри этих блоков можно писать любой код JavaScript.
Это очень напоминает то, как работает html-рендерер ejs для Node.js. Или схожим образом работали старые asp-страницы: код внутри блока <%...%> исполнялся на сервере, а все, что вне этого блока, транслировалось как есть в клиентский браузер. Похожим образом, сегодня работают даже PHP страницы. Только в ApexWidget вместо сервера - Editor, а вместо браузера - Viewer, поэтому скрипт исполняется мгновенно.
Приведу также пример работы с циклами.
<%
let names = ['Ross', 'Rachel', 'Monika', 'Chandler', 'Phoebe', 'Joey'];
%>
Hello, everybody!
<%for (let i = 0; i < names.length; i++) {%>
${names[i]}
<%}%>
В ApexWidget программисту доступен объект dataset, который является коллекцией различных данных: мужские и женские имена, фамилии, набор фраз, список гостиниц с данными геолокации и т.д. Просмотреть весь dataset можно, введя в редакторе команду ${JSON.stringify(dataset, undefined, 4)}. Все это нужно для генерации фейковых данных для тестов.
ApexWidget может выводить результат не только во вьюер, но и в браузер, что очень полезно для автоматической генерации документации. Для того, чтобы контролировать формат вывода во вьюер или в браузер, программисту доступна глобальная булева переменная inBrowser.
Сниппеты хранятся в базе данных в сети, но не в централизованной. Для того, чтобы использовать ApexWidget, вам необходимо создать собственную базу данных на Airtable.com. Airtable позволяет бесплатно хранить в базе данных 1200 строк. Если этого мало, то впоследствии можно открыть неограниченное количество бесплатных баз и переключаться между ними. Либо можно купить подписку на Airtable, но я надеюсь, вам это никогда не понадобится, потому что мне пока сложно представить, кому может понадобиться больше 1200 сниппетов.
В ApexWidget есть очень подробный мануал, как открыть аккаунт на Airtable.com и создать базу данных. Конечно, это займет у вас какое-то время (минут 10), но в этом есть и преимущество. База данных, которую вы создадите, это не моя база данных, а ваша собственная. Я ее не контролирую, так как не имею к ней доступа, ее контролируете только вы.
Не знаю, как вы, а я очень впечатлен возможностями, которые открывает ApexWidget:
Можно писать сниппет-макросы любой сложности для любых нужд. Ввел несколько параметров и тут же получил целую связку шаблонов классов и тестов, разве это не прекрасно?
Можно писать небольшие утилиты для собственного использования, которые будут всегда под рукой. Например, билдер крон-выражений или какой-нибудь нестандартный калькулятор.
Можно создавать даже веб-страницы и небольшие веб-приложения. Мануал для ApexWidget в виде веб-страницы полностью создан в нем самом.
Буду рад любым предложениям и конструктивной критике.