понедельник, 19 ноября 2018 г.

A programmer: jQuery

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


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

Нюанс в том, что поскольку jQuery работает с разметкой страницы, его нужно прописывать не в , а перед закрывающим тегом
- для того, чтобы разметка страницы загрузилась до вызова jQuery. Если же все-таки прописывать в , то содержание js-файла должно быть заключено в следующую обертку:
jQuery('document').ready(function() {
    // код
    });

Как он в принципе работает? Очень просто. В самом общем виде команда выглядит следующим образом:

jQuery('document').ready();

Здесь вместо 'document' надо указать теги (селекторы), а вместо ready() - метод, описывающий, что с ними надо сделать (например, что-то добавить/удалить, скрыть/покачать и т.д.).

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

jQuery('button').on('click', function() {
    // код
    });

Собственно, и все. Описание методов и событий - см. на сайте jQuery.

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

var value = jQuery('input').val();

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


понедельник, 29 октября 2018 г.

A programmer: Web UI

Продолжаю обзаводиться дипломами. на этот раз - курс, который совмещает в себе основы DOM, HTML/CSS, JavaScript, jQuery.



  Снова на Прометеусе - см.: https://prometheus.org.ua/.

четверг, 25 октября 2018 г.

A programmer: Quality Assurance

В перерывах между другими делами решил посмотреть курс по введению в Quality Assurance - заодно и сертификат получил.


Курс на Прометеусе, если что - см.: https://prometheus.org.ua/.

воскресенье, 14 октября 2018 г.

A programmer: JavaScript #12

Очень простое и очень классное введение в то, как работает JavaScript на фронтенде.



P.S.: Проблема с MongoDB пока решилась тем, что я не закрываю соединение с базой данных (если хочу с ней ещё что-то делать)

db.close();

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


четверг, 11 октября 2018 г.

A programmer: JavaScript #11

На этот раз не столько мой собственный опыт (хотя и он тоже), а объяснение асинхронности в JavaScript - прекрасный ролик!


А пришел я к этой теме, когда моя программа стала выдавать:

MongoError: server instance pool was destroyed

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

четверг, 13 сентября 2018 г.

A programmer: HTML/CSS

UPD к предыдущему посту: Уж не знаю почему, но там все заработало, как надо, без внесения каких-либо изменений - на самом деле, скорее всего, я просто не так проверял. Но это странно, потому что, насколько я смог выяснить, - работать и не должно было, поскольку функция res должна срабатывать только один раз, а значит послать можно или на фронтенд, или в базу. Но в итоге res.render(); посылает, и туда, и туда. Разобраться с этим надо бы, но пока отложу на потом. К тому же задача вытащить последнюю введенную запись из базы тоже не получилась у меня, потому что идентификатор генерируется только в базе и мне он неизвестен, а как вставлять поле даты/времени, я пока не выснил - значит, тоже не потом. Кстати, если кто-то знает ответы на эти вопросы, пожалуйста, пишите.

Я несколько переживаю, что не сделал полноценный CRUD для работы с базой данных. Но есть два "но". Во-первых, если посмотреть то задание, которое я себе сформулировал, то там об этом речь и не идет: "Задача приложения - показывать пользователю страницу с формой и собирать введенные им данные в базу данных". То есть формально я задачу выполнил, и все в порядке. А во-вторых, я все-таки хочу это сделать, но так, чтобы все комманды сразу посылались с более-менее вменяемого фронтенда - поля-кнопочки и все такое. А для этого надо вернуться к верстке. Я, конечно, 10 лет назад заканчивал онлайн-курсы по HTML/CSS, но никакой практики с тех пор практически не имел, и основательно подзабыл почти все, что знал. Поэтому сегодняшний пост об основах HTML/CSS.

HTML (HyperText Markup Language) - это, собственно не язык, а разметка документа, которая говорит браузеру, как именно надо отображать его содержание. Если посмотреть на HTML-код документа, мы увидим, что это самое содержание помещается между угловыми скобками, внутри которых и находится тэги со всякими разными описаниями. Так, допустим, этот абзац заключен в тэг, в котором записаны параметры оформления абзаца:


Для удобства повторяющееся оформление выносят в отдельный css-файл (CSS - Cascading Style Sheets), ссылку на который просто вставляют в итоговый html-документ. Вот таким образом:



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

CSS-файл выглядит приблизительно так:



То есть это набор блоков, обозначенных фигурными скобками. Перед блоком стоит селектор (идентификатор элемента), а внутри него - описание стиля для этого элемента посредством указания свойства и его значения.

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

id="header" в html-документе, значит #header {} - в css-файле, или

class="header" в html-документе, значит .header {} - в css-файле.

Еще один пример вот:


Здесь показано, как еще можно указывать селекторы (* означает применить глобально ко всему документу).

Ну и напоследок. Существуют отдельные разработанные библиотеки стилей, которые просто можно подключать в свой документ. Один из самый популярных - Bootstrap

Bootstrap

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

понедельник, 10 сентября 2018 г.

Впечатления дня #1


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

Одно из них критиковало “поиск мечты”. Потому что не только сама по себе мечта мотивирует, но некоторые достигаемые тобой результаты в той деятельности, которой ты занимаешься, даже если ты от этой деятельности не в восторге. Суть, соответственно, в том, чтобы не гнаться за “мечтой”, “призванием”, “миссией” или “делом всей жизни”, а найти что-то, что тебе просто “довольно интересно”, и добиваться мастерства в этом - а дальше видно будет. В этом смысле с социологией у меня так или почти так.

В другом речь шла о том, что в зрелом возрасте неплохо начинать бизнес или вообще что-то новое. Жалобы на старость и “отсталость от времени” нерелевантны, как минимум, по двум причинам. Во-первых, сейчас люди живут дольше, и если тебе сейчас 40-50 лет, то впереди у тебя еще около 30-40. Если из твоего нынешнего возраста вычесть малосознательное детство, то окажется, что впереди у тебя едва ли не большая часть сознательной жизни - ты что, собираешься все это время “доживать”? Звучит нелепо. Во-вторых, в отличие от тех молодых, у кого в руках только технические навыки жизни в современном мире, которые действительно являются преимуществом, у тебя преимущество другого рода - опыт, который им просто негде взять. В то время как техническим навыкам ты можешь научиться. Отсюда вывод - не ной и иди учись! И сделай, наконец, что-нибудь стоящее в своей жизни.

Третье видео - интервью с Брайаном Трейси, весьма известное. И ключевой совет там такой: “Если ты не знаешь, как добиться того, чего ты хочешь, спроси у того, кто уже добился этого, как он достиг успеха”. Ну а дальше - следуй совету и повторяй его действия. Правильные причины создадут правильный результат.

четверг, 6 сентября 2018 г.

A programmer: JavaScript #10

О главном - Часть II (не последняя).

Как это часто бывает, не всё проходит гладко. Я изначально хотел сделать CRUD (Create Read Update Delete - методы работы с базой данных) в отдельном файле, но не получилось быстро найти ответ, как это сделать (поищу позже), поэтому слил всё в один файл. Заодно написал и ввод в базу данных (попутно уточнив новый способ образения к коллекции - стр. 18 - спасибо stackoverflow).

Но оказалось, что введенные данные на страницу выводятся, как и раньше, а в базу не добавляются. Изучение вопроса показало, что поскольку в JavaScript'e всё происходит асинхронно (в противном случае надо специально настраивать и проч.), то нельзя посылать два разных ответа, а у меня именно так и было:

  • в одном случае я посылал данные на фронтенд,
  • в другом - в базу данных.

Пришлось пока оставить что-то одно, я оставил базу данных. Следующая ощибка вылетела с сообщением, смысл которого сводился к тому, что закрыть базу данных надо только один раз, а не два, что я и сделал. В итоге файл получил следующий вид (я специально не показываю здесь GET-запрос для экономии места):


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

Но как же всё-таки вывести введенные данные на веб-страницу? Снова-таки, быстрого решения я не нашел, поэтому пойду немного в обход: возьму-ка я эти данные из базы данных! Но об этом - в следующий раз...

среда, 5 сентября 2018 г.

A programmer: JavaScript #9

Сегодня речь, наконец, пойдет о главном - о связи фронтенда с базой данных (Часть I). В написании фронтенда мы остановились на вводе логина и пароля в форму на сайте и их выводе в консоль. В написании функционала для работы с базой данных мы остановились на вводе данных в нее вручную. Осталось это соединить. Пока что мы сделали так, чтобы запускались оба сервера - вебсервер и сервер базы данных. Что дальше?

Для начала решил подправить сам файл страницы. Во-первых, чтоб чуть более красивенько, а во-вторых, чтобы введенные емйл и пароль показывались тут же, на этой же странице. Прекрасная идея - и как удобно! Но возник вопрос: что показывать, когда данные ещё не введены в форму, точнее - как?

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


var data = {email: 'your email', pass: 'your password'}; - это и есть наш "промежуточный" файл.

На странице - вот так:


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

вторник, 4 сентября 2018 г.

A programmer: JavaScript #8

И ещё одна маленькая, но важная добавка - воспользовавшись хорошим советом, я залил свой проект на GitHub: https://github.com/OleksiyMusiyezdov/sveta


Как это делать? Вот так:

git init - создаём репозиторий (локальный), предварительно создав соответствующий на https://github.com

git add . - добавляем туда все файлы проекта (надо находиться в папке проекта) для отслеживания

git commit -m "Initial commit" - закрепляем изменения

git remote add origin https://github.com/OleksiyMusiyezdov/sveta - подключаемся к удалённому репозиторию

git push -u origin master - заливаем проект в удалённый репозиторий

А подробнее, например, здесь (три маленьких видео): Git - для новичков

понедельник, 3 сентября 2018 г.

A programmer: JavaScript #7

Уже надоело ходить вокруг да около и связать-таки базу данных с фронтендом, но все-таки сегодня ещё об одной важной (для себя, по крайней мере) вещи должен сказать. Речь о подключении собственных модулей. Как написано в туториалах и прочем (точнее, как я понял сначала), для того, чтобы модуль подключался с помощью require

var database = require('./database');

надо его код экспортировать с помощью

module.exports = () => { код };

Оказывается, не всегда, а только тогда, когда собираешься этот код потом вызывать как функцию. В противном случае - то есть, чтобы код подключаемого модуля просто отрабатывался при его подключении - делать этого не надо. Более того, если так сделать, то код внутри module.exports отрабатываться не будет, а будет ждать отдельного вызова (через функцию - в нашем случае: database(); ).

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


Это главный файл, в котором подключается модуль (строка 3).


Это модуль. Пока всё.

четверг, 30 августа 2018 г.

A programmer: JavaScript #6

Сегодня немного о вводе, поиске и выводе (пока опять в консоль). Для того, чтобы искать и выводить что-либо из базы данных, надо это сначала туда ввести. В прошлый раз мы сделали только тестовое добавление элемента. Сегодня - множественное добавление. Для этого сначала подготовим небольшой файл с именем persons.json:


Это набор объектов, который мы вставим в нашу базу данных. Делается это вот так:


В строке 5 мы подключаем наш файл, в строке 10 подключаем нашу коллекцию, в строке 15 выводим результат:


Поиск осуществляется с помощью специального объекта, которому присваивается значение collection.find():


В строке 10 мы создаем этот объект.
В строке 12 на нем вызываем функцию, которая возвратит данные, приведенные к массиву.
В строке 13 внутри этой функции осуществляем поиск по нашей базе данных, задав условие поиска.
В строке 15 выводим найденный результат:


Как видим, пока всё просто, главное - не забыть перед этим запустить сам сервер и указать правильный путь к хранилищу данных :).

вторник, 28 августа 2018 г.

A programmer: JavaScript #5

Грусть-печалька, с одной стороны, она же большая радость, с другой стороны, а именно: я нашел классное описание всего того, что я хотел сделатьь и описать здесь. Печалька потому, что уже кто-то это сделал, а радость - потому что уже кто-то это сделал, и я могу почитать и лучше понять! Вот такая вот диалектика, впрочем не в первый раз. А сам ресурс вот - спасибо автору:

 Building a Simple CRUD Application with Express and MongoDB

Итак, мы остановились на том, что программа обрабатывает наш POST-запрос и выводит то, что ввёл пользователь, в консоль. А нам надо в базу данных. Значит, продолжаем:

8. Устанавливаем MongoDB в проект:

npm install mongodb --save

9. Теперь мы можем использовать MongoClient - основной класс для работы с базами данных:



Комментарии не очень видны, поэтому ещё раз:

  • в строке 1 мы подключили модуль mobngodb и сразу взяли из него MongoClient;
  • в строке 2 мы указали url для нашей базы данных - помните, мы говорили, что 27017 - это порт, который используется для работы с базой данных?;
  • в строке 4 мы создаем соединение с указанным url, если подключение произошло без выброса ошибки (err), то мы имеем в нашем распоряжении объект (db) для работы с базой данных (оногда его обозначают client);
  • в строке 5 мы через него получаем нашу базу данных (users), которая теперь внутри программы выступает как collection;
  • в 7 строке мы вставляем в базу данных тестовый объект (документ), созданные в строке 6 (просто чтобы увидеть, что у нас всё работает);
  • в строке 9 проверяем, нет ли ошибки;
  • в строке 13 выводим результат в консоль;
  • в строке 15 закрываем соединение.

В итоге в консоли видим такой вывод:


Здесь _id - это уникальный идентификатор элемента коллекции, который создается автоматически.

Как видим - всё работает! Собственно говоря, мы могли бы не добвалять ввод объекта в базу данных, а просто подключиться, проверить подключение и выйти. Тогда всё выглядело бы ещё проще:


А ещё один хороший ресурс вот:

Ещё один хороший ресурс

пятница, 24 августа 2018 г.

A programmer: JavaScript #4

Вчера написал мало, потому что случился затык с тем, что те уроки, которые я слушал (а я предпочитаю видеоуроки), были слишком разные: в одном запускали сервер, но он работал только с консолью; в другом дошли до POST-запросов, выводили их на страницу, но не в базу данных; в третьем работали только с базой данных в собственной консоли; в четвертом делали всё, что нужно, но подключали дополнительный пакет mongoose, который часть необходимой работы делал неочевидной. В итоге я запутался и решил сделать всё сначала, самостоятельно, по возможности без дополнительных пакетов. Задача приложения - показывать пользователю страницу с формой и собирать введенные им данные в базу данных. Сегодня - первая часть.

1. Поскольку всё с самого начала, то создаём папку с проектом и в консоли переходим в неё.

2. С помощью комманды npm init создаём package.json.

3. Создаём файл index.js и пишем в нём сервер - такой, который писали в первом посте про JavaScript. Кстати там мой код (а не из Википедии), который должен создавать и запускать веб-сервер, не должен работать, потому что там не указан адрес '127.0.0.1' - простите, не проверил. Правильный код вот:


Если всё в порядке, в консоли видим Web-server is working, а в браузере по адресу 127.0.0.1:3000 - HTML.

4. Как показали беглые разыскания, совсем без дополнительных пакетов ничего не получится. Поэтому решил всё-таки вернуться к express, а с тем, как работать без него, разберусь потом. Для начала его надо установить: npm install express. Тот же самый сервер с использованием express выглядит так:


Единственное отличие - он пока ничего не показывает в браузере.

5. Чтобы исправить это, установим и укажем шаблонизатор - ejs. Создадим папку views, в которой будут лежать шаблоны. Далее - создадим шаблоны (файлы с расширением .ejs вместо .html - я о них упоминал уже) и сделаем маршрутизацию. Теперь наш код выглядит так:


и отображает страницу /views/404.ejs

6. Это, разумеется, тренировка - давайте всё-таки переименуем файл в form.ejs. Теперь зададим код для шаблона, например, такой:

Выглядит вот так (стили и прочее я не прикручивал - только функционал):

7. Добавим обработчик для POST-запроса (как в прошлом посте) и сделаем вывод, пока что в консоль. Для этого просто добавим в обработчик строку console.log(req.body); Ура!

Не работает... Сервер запускается, страница ввода видна, но в обработчик не заходит. Почему?

Проверяем всё. Оказывается, забыли добавить в код формы указание на метод. Добавляем:


Не работает. Хотя в обработчик запроса уже заходит, но в консоли показывает пустое тело {}. То есть не парсит. Почему?

Потому что в строки, где описывается ввод имейла и пароля не добавили атрибут name. Добавляем:

name="email"
name="pass"

Проверяем - работает!

Итак - повторение пройденного получилось в целом неплохим. На сегодня хватит, пожалуй.

A programmer: JavaScript #3

Сегодня немного о базе даных MongoDB и обработке POST-запроса. В прошлый раз мы просто показывали пользователю определенную страницу в зависимости от того, что он нажал или ввел в адресной строке. Но часто бывает необходимо сохранить какую-то информацию, которую пользователь вводит на сайте. Для этого используют базы данных. Базы данных бывают реляционные и нереляционные. Реляционные - это те, которые предполагают отношения между своими составными частями, нереляционные - простые наборы (коллекции) документов, в которых сами документы могут быть самыми разными. MongoDB - нереляционная база данных, и выбрана из соображений простоты.



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

mongod.exe - сервер базы данных и
mongo.exe - консольный терминал для работы с базой данных

Обычно (если у вас Windows и вы не меняли путь для установки) она имеет приблизительно такой вид:

C:\Program Files\MongoDB\Server\4.0\bin

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

mongod --dbpath <адрес желаемого места хранения данных>

Запустив это, вы увидите много букв, среди которых должно быть сообщение о том, что сервер запущен на порте 27017. Далее вы можете запустить mongo.exe и работать в коммандной строке терминала, а можете установить и использовать графический интерфейс. Чтобы всё это работало в нашем проекте, надо установить соответствующие пакеты (например, через npm install <имя пакета>) - mongod и mongodb. Проследите, чтобы они появились в разделе dependencies файла package.json. Теперь можно работать - у вас есть сервер базы данных и инструменты для работы с ним.

Но для начала следует отвлечься на одну важную деталь. Обычно пользователь вводит сразу несколько "кусочков" информации на странице и только потом отправляет всё сразу на сервер.


Очевидно, что GET-запрос для этого не подходит. Для этого нужен POST-запрос - он обрабатывает формы. Естественно, для этого вы должны разместить соответствующий код с формой у себя на странице (код для указанной выше формы можно посмотреть на bootstrap'е). Обработчик POST-запроса в коде программы будет выглядеть следующим образом (на всякий случай отмечу, что это только засть кода из файла):


Здесь мы видим подключение модуля body-parser и использование его для того, чтобы распарсить (определенным образом считать) то, что введено в форму. В качестве вывода имеем итоговую страницу (about-success), куда передаются на вывод эти же данные (req.body).

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

четверг, 23 августа 2018 г.

A programmer: JavaScript #2

Для начала небольшой disclaimer.

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

Во-вторых, прошлый пост получился большой и много о чём. Поэтому придется внести некоторую структуру в излагаемое. Итак, кроме моих мотивов, связанных с изучением JavaScript'a, содержательно в прошлом посте речь шла о NodeJS и создании веб-сервера.

Соответственно, в этом посте - о маршрутизации и верстке.


Умное слово "маршрутизация" в данном конкретном случае означает то, что мы определяем то, что программа должна показывать пользователю, если он совершил то или иное действие. Собственно, в прошлом посте об этом уже сказано. Там мы использовали объект app для того, чтобы работать с библиотекой express. Если бы мы не использовали  express, наша маршрутизация выглядела бы иначе:


То есть мы бы указывали маршрут через проверку условий if-else, а результат был бы тот же. Просто подключив express, мы написали отдельные обработчики, что, мне кажется, удобнее.

В чем ещё есть отличия с примером из прошлого поста? В том, что мы подключили модуль fs - он обеспечивает ввод-вывод данных. Как я говорил, можно подключить и собственный модуль. Тогда пришлось бы написать:

const some_module = require('/some_module');

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

module.exports.some_value = some_value;

Но вернемся к маршрутизации и верстке. Итак, пусть мы написали обработчики, которые должны показывать нужные страницы в зависимости от запроса. Возникает вопрос: а где же страницы? Они лежат в папке с проектом. Там могут лежать сами страницы - например, какой-нибудь index.html, а могут - шаблоны (обычно в папке /views). Поскольку мы работаем с express, то шаблоны у нас - это файлы с расширением .ejs, которые выглядят, например, вот так:


Похоже на обычный html-файл - почему это шаблон? Потому что в нём есть исполняемый функционал. Он заключен в соответствующие скобки <% ... %> или <%= ... %> (в первом случае имеется в виду некоторое действие, во втором - просто вывод заданного параметра). Естественно, что выводимые параметры должны быть переданы шаблону в файле с маршрутизацией. В нашем примере - это параметр newsId, а также объект obj с параметрами  title, id и массивом paragraphs.

Здесь также видим, что командой include подключается файл header.ejs, находящийся не в самой папке /views, а в подпапке /blocks (строка 11). А в 8 строке подключается файл со стилями, который находится по адресу /public/css. Собственно, в шаблон можно подключить и сторонний код, например, из библиотеки bootstrap. А дальше всё зависит от фантазии и чувства вкуса.

На сегодня всё.

среда, 22 августа 2018 г.

A programmer: JavaScript #1.

Мои метания вокруг программирования привели меня к JavaScript'у. На самом деле это несколько странно, учитывая, что ещё полгода-год назад я учился программировать для Android с тем, чтобы написать несколько набольших полезных программ и выложить в Play Store (он же Play Market). Я видел в этом то преимущество, что эти программы были бы свидетельством моего умения, во-первых, и, возможно, по мере их (программ) развития, приносили бы какую-нибудь копеечку, во-вторых. Собственно, я планирую к этому ещё вернуться.


Но JavaScript для меня оказался привлекательным рядом дополнительных плюсов:

  • Под Android из моих друзей никто не программирует, а значит, спросить совета у живого человека было бы затруднительно. В свою очередь, на курсах по Java, на которые я ходил 2 года назад, я познакомился с Лёшей (фамилию уточнять не буду, ибо не уполномочен), который оказался замечательным ментором. А он некоторое время назад как раз получил работу как JavaScript-программист. Значит, в крайнем случае мне есть с кем проконсультироваться.
  • Как я знаю, JavaScript является весьма востребованным языком программирования, и порог вхождения в него существенно ниже, чем для Java. С некоторых пор я существенно более, чем раньше, заинтересован в том, чтобы найти работу в IT.
  • JavaScript заточен под Web-разработку, а мне ещё в детстве нравилось то, что теперь наывается версткой (стенгазеты - наше всё:)).

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

Лёша предложил мне попробовать сделать приблизительно такое же тестовое задание, которое обычно дают при приёме на работу:

  • поднять сервер NodeJS;
  • сделать к нему фронт на каких-нибудь шаблонах (например, на ejs);
  • подключить базу данных (MongoDB или PostgreSQL);
  • сделать в БД пару таблиц со связями;
  • сделать к ним CRUD;
  • вывести их на фронт;
  • дополнительно - какой-нибудь функционал для работы с таблицами;
  • дополнительно - аутентификацию.

Собственно, этим я и занимаюсь уже второй месяц - пока, к сожалению, не так интенсивно, как хотелось бы. Зачем я вдруг решил поделиться этим с "миром"? Затем, что мне нужен конспект, а писать его только самому себе - скучно. Плюс Ричард Фейнман справедливо полагал, что лучший способ что-то понять и выучить - это рассказать об этом другим. Это же я имел в виду, например, когда выкладывал свои учебные результаты по Java. Теперь собираюсь быть более последовательным, чем тогда.

***
Для чего нужен и в чём особенность JavaScript'a? Если коротко, то JavaScript изначально заточен на то, чтобы сделать вебстраницы интерактивными. Хотя впоследствии на нём стали писать и серверную часть, и всё остальное, главное в нём именно это - поэтому он и входит третьим элементом в стэк веб-технологий:


Особенностью JavaScript'а является то, что это язык со слабой типизацией - то есть типы использующихся объектов не должны быть строго типизированы, как в Java, например. В этом есть свои недостатки, но в то же время за счет этого JavaScript более прост в изучении.


NodeJS - это программная платформа для JavaScript'а, то есть то, что и позволяет работать JavaScript'у, в том числе и в первую очередь в качестве языка для веб-сервера. Так, чтобы создать веб-сервер нужен следующий код (скан из Википедии):



Зачем нужен сервер? Вопрос вроде бы странный, но у меня он почему-то возник на горизонте сознания, поэтому стоит ответить на него. Если вспомнить, что веб-приложения выполняют некоторый код (то есть, в сущности, производят вычисления), то возникает вопрос, где - грубо говоря, на каком оборудовании - эти вычисления происходят? Это может быть либо компьютер пользователя ("клиент"), либо удаленный компьютер, специально предназначенный для этого ("сервер"). Другими словами, всё то, что происходит не на компьютере пользователя (в случае веб-приложений - в браузере), происходит на сервере. Но для этого там должно быть установлено сообветствующее программное обеспечение (в нашем случае - NodeJS), которое и взаимодействует с "железом". Вот мы на основе этого программного обеспечения создаем свой веб-сервер. Мой вариант выглядит вот так:


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

Пока что запуск нашего файла выводит в консоль заданный текст. А что вообще делает наш сервер? Он "слушает", что делает пользователь. То есть он воспринимает его действия на переданной ему нами странице (в нашем случае это http://127.0.0.1:3000/) и должен как-то реагировать на эти действия. Собственно, наша задача и состоит в том, чтобы сервер на определенные действия (запросы) реагировал определенным образом.

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

Самый простой вариант - пользователь что-то ввёл в строке браузера после http://127.0.0.1:3000/ (то есть, находясь на том сервере, который мы "слушаем"). Например, он набрал "http://127.0.0.1:3000/about", желая получить информацию, допустим, о сайте (ну или чаще - нажал кнопку, соответствующую этому действию). Такое действие называется GET-запрос - это когда передаваемый пользователем запрос достаточно простой и может передаваться через строку браузера. Если мы хотим, чтобы наше приложение в ответ на этот запрос что-то сделало, мы, соответственно, должны это запрограммировать. Например так:


Здесь: если пользователь ничего не делал, показываем ему файл "index", если набрал "about", показываем ему файл "about" (оба файла лежат в другом месте).

Главный нюанс состоит в следующем - чтобы всё, что мы написали, работало, мы должны использовать объект app (на котором вызываем функцию get), а чтобы его использовать, мы должны подключить модуль "express" - одну из библиотек, работа с которыми (а не только с синтаксисом) и является, пожалуй, сутью программирования на том или ином языке. NodeJS как раз и хорош тем, что позволяет легко подключать разные модули - как чужие, так и написанные самостоятельно.

Разумеется, соответствующие файлы должны находиться в папке проекта. Для того, чтобы удобно закачивать себе всё, что нужно, NodeJS имеет собственный пакетный менеджер (npm - node packages manager), хотя есть и сторонние разработки (например, yarn). С его помощью легко инсталлировать нужные модули себе в проект.

И тут появляется нюанс. Часть модулей нужны для функционирования приложения, а часть - только для его разработки (например, проверка синтаксиса или стиля кода). Если над проектом работают больше одного человека, последние модули могут быть не нужны кому-то другому (а место занимать), значит, надо как-то обозначить, чтобы при клонировании проекта они не загружались автоматически. Это, как и другие вещи, описываются в файле package.json.

Собственно, когда мы инициализируем новый проект в IDE (я использую Atom), нам как раз и предлагается определить некую базовую информацию, которая будет записана в package.json. Выглядит он приблизительно так:


Здесь среди прочего (имя, версия, описание, автор, лицензия, стартовый файл и т.д.) указаны зависимости (внешние пакеты - "depenencies", с указанием их версий), которые надо подгружать в наш проект автоматически, зависимости, использующиеся для разработки, о которых мы говорили ("devDependencies"), скрипты, выполняемые при старте, и т.д.

***

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