Сообщество - Web-технологии

Web-технологии

169 постов 3 817 подписчиков
11

Редирект ссылок с ограничениями по переходам по географическому положению, времени и количеству переходов

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

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

Редирект ссылок с ограничениями по переходам по географическому положению, времени и количеству переходов Javascript, Web-Программирование, Pikaweb, Видео, Длиннопост

Идея проекта LinkBooster ( https://boostup.link ) - возможность перенаправления ссылок  с ограничениями по количеству переходов, географическому расположению и времени действия:

Редирект ссылок с ограничениями по переходам по географическому положению, времени и количеству переходов Javascript, Web-Программирование, Pikaweb, Видео, Длиннопост

То есть, для создания ссылки на Pikabu для доступа только из России с ограничением в 100 переходов, которая будет активна в течении 12 часов, надо выбрать следующие параметры:

Редирект ссылок с ограничениями по переходам по географическому положению, времени и количеству переходов Javascript, Web-Программирование, Pikaweb, Видео, Длиннопост

А вот и пример того, как будет выглядеть сгенерированная ссылка:

https://api.boostup.link/cd-sDMfXZsyL7Z-78

Также можно запретить переход по ссылке из определенной страны:

Редирект ссылок с ограничениями по переходам по географическому положению, времени и количеству переходов Javascript, Web-Программирование, Pikaweb, Видео, Длиннопост

Ну а вообщем,

Буду очень рад любым комментариям, а пока - буду работать.

Показать полностью 3 1
128

Во все тяжкие: Веб-разработчик с нуля. 1 год

Во все тяжкие: Веб-разработчик с нуля. 1 год IT, Программирование, Карьера, Javascript, Веб-Разработка, Frontend, Web, Длиннопост

"Еще до встречи с Юнаковым он уже жил по правилу: не отступать и не теряться. Не вышло—повтори. Правило, чем-то напоминающее цирковой обычай: не удался прыжок, упал с лошади или с проволоки — повтори, не откладывая в долгий ящик, повтори, преодолевая боль и страх, повторяй до тех пор, пока не добьешься своего, иначе тебе никогда не избавиться от неуверенности в решающий момент. Александр Крон - "Капитан дальнего плавания".


ЦельSenior Frontend Developer.

Язык: JavaScript.

Возраст: 29 лет.

Работа (настоящее время): Trainee Frontend Developer в компании "Корус Консалтинг СНГ".

Локация: г. Санкт-Петербург.


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


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


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


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


Моя жизнь не заканчивается программированием. Для меня программирование сейчас - это лишь сфера, которая мне показалась год назад очень хорошей для того, чтобы освоить определенные навыки и почувствовать под ногами опору в профессиональной сфере. Сейчас она мне кажется до сих пор такой сферой. Получилось ли это? Еще нет, я в начале пути, но определенно кое-какие успехи есть, и чувствую я себя увереннее. И я абсолютный противник такого образа жизни, при котором мышление человека фиксируется на одной плоскости и практически никогда оттуда не смещается. Иногда, да, требуется длительная фокусировка на сфере, но не фиксация.


Что касается программирования - то это обычная профессиональная плоскость, со своими особенностями и определенными требуемыми навыками. Она интересная, как и многие другие сферы, но она не особенная.


Сейчас у меня начался второй месяц стажировки и учебы в компании "Корус Консалтинг СНГ". Могу с уверенностью сказать, что за этот месяц я понял и освоил, с помощью преподавателя, больше, чем за несколько месяцев самостоятельной работы. Это к тому, что если есть возможность учиться у кого-то, кто уже прошел такой же путь - то обязательно делайте это. Еще я понял, что конкретные технологии абсолютно не имеют значения. React, Vue, Angular... это все не важно. Если вы понимаете главные принципы построения программы, принципы взаимодействия ее частей и тот язык на глубоком уровне, на базе которого происходит всё это построение, то вы очень быстро перейдете на любую абстракцию и будете спокойно ее использовать.


Меня недавно спросили -"Как закреплять элементарные основы по JS (if, for, простые функции) на практике? откуда брать задания? с задачами на learn-javascript я более менее справляюсь, но этого мало."

Хочу написать для всех. Задайте себе вопрос: К чему вы идете? Вы хотите научиться решать задачки с Codewars или вы хотите устроиться в компанию и решать коммерческие задачи, тем самым зарабатывая деньги? Если ответ второй, то тогда начните с тестовых заданий в компании (или компанию, если есть такая, в которую вы хотите попасть). И пляшите от тестового задания. Всё, что вам необходимо знать и уметь для решения этой и подобных задач, с полным понимаем, того что вы делаете, и будет тем, куда вам необходимо прикладывать усилия. Про собеседования, на которых вас заставляют решать задачи, абсолютно никак не связанные с будущими задачами на работе - я промолчу.


В связи с этим, я решил помочь таким же как и я и создал базу тестовых заданий для frontend разработчиков. На данный момент она пополняется исключительно теми заданиями, которые присылали мне. По мере возможности, я буду ее пополнять. Я думаю, еще порядка 15-20 заданий, я в ближайшие дни туда выложу. Так же, приветствую пулреквесты. На гитхабе есть подобный репозиторий, но там очень мало тестовых, и в основном задания от крупных компаний. Но ведь больше как раз маленьких компаний, и было бы хорошо +- понимать, какие тестовые могут быть в этой компании и вообще, какие навыки и знания будут требоваться при работе там, с учетом особенности сферы и т.д. С другой стороны это позволит работодателям не расслабляться и постоянно менять тестовые. Дабы действительно брать на работу только тех, кто решил задачу, а не тех, кто скопировал решение из чужого репозитория или канала на ютубе, а потом будет сидеть и тупить на работе.


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


На этом я хочу сегодня закончить. Развиваемся дальше. Впереди у меня еще месяц стажировки, TypeScript и React. Но об этом в следующем отчете.


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



Артем OWIII.

Контакты: Instagram, Github.

Показать полностью
15

С нуля до Frontend-разработчика. Первый месяц

С нуля до Frontend-разработчика. Первый месяц HTML, CSS, Верстка, Web, Веб-Разработка

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

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

С нуля до Frontend-разработчика. Первый месяц HTML, CSS, Верстка, Web, Веб-Разработка

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


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



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


Показать полностью
14

Готовый телефонный справочник на NODE.JS с админкой

Всем здравствуйте. Начну с истории.

Устроился я на работу техником(в тех отдел), через какое-то время ковыряться с компами поднадоело и поговорив с начальником мне предложили заняться разработкой. Опыт верстки и программирования на php был. Первой задачей была "сделать телефонный справочник", погуглив я не нашел готовых решений, тогда начальник предложил WordPress. Ну не долго думая поставил на наш сервер WP, начал пробовать сделать и понял, что все как-то не так.

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

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

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

Начав искать новые варианты я наткнулся на node.js, и подумал "а почему бы не написать все самому". К тому же идея управлять бекэндом и фронтом при помощи одного языка мне очень нравилась.

Сказано - сделано, начал учить и сразу писать. Было много трудностей, куча камней и т.д, к тому же начальник уже стучал по голове со словами "ну когда уже". Ну пришлось "поговнокодить" т.к это изрядно ускоряло процесс.

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

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

Для чего?

Во-первых это опыт.

Во-вторых я люблю заниматься подобным.

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

В-четвертых хочется помочь людям которым тоже понадобиться такая штука.

Готовый телефонный справочник на NODE.JS с админкой Nodejs, Javascript, Web-Программирование, Длиннопост

Тут присутствую 2 группы кнопок

1) Left(main)

2)Center(second)

Для удобства понимания на данный момент используется в качестве кнопок branch(отделение) и floor(Этаж), но в целом можно задать все что угодно.

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

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

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

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


Если кто-то будет пользоваться этим справочником то доступ

Адресс админки: домен/panel/admin

login: 'admin',

password: 'wwqe1rws'

Меняется в файле passport.js



Тут перед нами разворачивается 2 кнопки.

Первая - просто добавление кнопок и людей.

Готовый телефонный справочник на NODE.JS с админкой Nodejs, Javascript, Web-Программирование, Длиннопост

Вторая более запутанная для настройки связей и удаления записей.

Готовый телефонный справочник на NODE.JS с админкой Nodejs, Javascript, Web-Программирование, Длиннопост

Первым делом на кнопки Edit вас встретит поиск, при помощи него вы ищите человека с которым хотите делать манипуляции.

Готовый телефонный справочник на NODE.JS с админкой Nodejs, Javascript, Web-Программирование, Длиннопост

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

Готовый телефонный справочник на NODE.JS с админкой Nodejs, Javascript, Web-Программирование, Длиннопост

Следующая кнопка Edit button, тут вы переименовываете кнопки.

Готовый телефонный справочник на NODE.JS с админкой Nodejs, Javascript, Web-Программирование, Длиннопост

Теперь заглянем в кнопку Edit у конкретной записи. Тут можно отредактировать данные либо удалить запись.

Готовый телефонный справочник на NODE.JS с админкой Nodejs, Javascript, Web-Программирование, Длиннопост

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

Для начала обратим внимание на поле link main - тут вы указываете какому отделению принадлежит этот контакт, таких полей 2. В Одном вы можете порвать связь, во втором вы добавляете новую.

В поле link main data вы указываете этаж у связки записей "отделение-контакт". В поле link second вы можете порвать эту связь.

Т.е последовательность добавления такая

На вкладке add добавляем кнопки и записи, идем в edit, жмем Assign all и настраиваем этажи для отделений. Затем ищем запись, жмем assign у нужной и присваиваем ее к отделению, затем указываем на каком этаже внутри этого отделения нужно выводить запись.

Админка получилась запутанная но все же все достаточно просто.

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

В общем я открыт для критики и советам

Код справочника https://github.com/ura2rist/Open-Phone-Book

Так же если есть какие-то вопросы или т.п то можно написать в телегу @urifcof там я тоже сразу окажу поддержку)

Показать полностью 6
26

С нуля до Frontend-разработчика. Начало

С нуля до Frontend-разработчика. Начало Веб-Разработка, Frontend, Web, HTML, CSS, Верстка, Длиннопост

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

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

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

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

1) Думаю, самый народный способ изучить основы HTML и CSS это воспользоваться бесплатными курсами от HTML Academy.
Затем эти знания можно закрепить пройдя бесплатные задания на FreeCodeCamp. (Basic)

2) Советую скачать бесплатно курс, который писал здесь (п. 2)

!Либо можете найти ссылку на скачивание zip-файла в комментариях в этом посте!
Посмотрев первый модуль, вы уже отточите свои базовые знания + будет настроено пространство.

3) После этого сразу советую изучить препроцессор CSS  (хотя его и ставят в середину обучения, считаю его надо учить сразу после основ). Про них можно узнать в модуле 2  - 025  из того курса, либо из любого другого видео на YouTube.

4) Изучаем основы Git/Github. Из курса Модуль 3 - 041, либо на YouTube. В начале необходимо уметь только пушать проекты в репозиторий. имхо)

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

Сложно описать сколько времени у вас займет на обучение данного материала, но в среднем можно предположить 2/3 недели.

После этого можно уже с головой углубляться в верстку.

Мой план обучения на ближайшее время:
1) Практикуем верстку с помощью Bootstrap Grid (ее многие недолюбливают, но я хотел бы закрепить эти знания);
2) Продвинутая верстка с Flexbox без интерактива;
3) Стараемся настолько набить руку, чтобы могли сверстать почти любой проект без интерактива;
4) Основы JS;
5) Поверхностное изучения JQuery и добавления интерактива на сайты.
6) Продвинутый JS;
7) React.js
8) Создаем портфолио;
8) Стараемся устроиться на работу джуном.

План на следующую неделю:
1) Доделать проект из курса (модуль 2);
2) Найти и сверстать самостоятельно пару лендингов с помощью сетки + делать их "резиновыми".

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

Все получилось сумбурно, я еще дилетант в этом деле, так что рад любой критике и пожеланиям :)

Показать полностью
294

Пост про современный фронтенд

Пикабушники народ странный. И методы у них странные. Но, что занимательно, эти методы работают. Не так давно я оставил безобидный комментарий про JS, и, по нелепому стечению обстоятельств, неожиданно попал под радары половины сайта и получил что-то около четырехсот подписчиков. Почему? А не знаю. Люди просто подписывались на меня, хотя я ничего им не обещал. Даже не давал намеков. Ты оставил комментарий про JS, я на тебя подписался и теперь ты мне торчишь целый пост про JS. Не знаю, как это работает, но раз вы это читаете, то их план исполняется.

Пост про современный фронтенд Javascript, Nodejs, Длиннопост

Само собой, я понятия не имел о чем писать. Уроков и без меня хватает на любой вкус и цвет. И серьезных и несерьезных. Но потом я, все таки, задумался. Прям со всей силы. И как итог, додумался до этого поста. Очень надеюсь, что это единственное, что я напишу про JS, только чтобы вас, четырех сотен, не разочаровывать. Я не особо то горю желанием писать целые курсы, да и куда уж мне, скажем прямо


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


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

Node.js


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


И я вас прекрасно в этом понимаю. Когда я пытался в это вникнуть, меня сбивал с толку этот node.js. Я очень хотел изучить какой-нибудь крутой и современный фреймворк по типу React, Angular или Vue. Но каждый раз, когда я пытался это сделать, диктор из видеоуроков упорно начинал с node.js, который я не понимал от слова совсем. Это сильно сбивало с толку, а все из-за одного единственного нюанса.


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


И сейчас я постараюсь все расставить по своим местам.


Начнем с того, что JavaScript (только не упадите) — это скриптовый язык. Что это значит? Это значит, что программы для этого языка пишутся в обычном текстовом файле, отличающимся от обычного файла только другим расширением. И все, вот она ваша программа. Открываете блокнот, пишете там console.log(‘Hello World’) и сохраняете в формате .js. Вот и все, ваша программа готова. Вы восхитительны.


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


Каждый скриптовый язык работает так. И Python, и PHP, и, прости господи, Perl. И у каждого свой интерпретатор.


Где же нам, тогда, взять интерпретатор для нашего JS? Ну, самое очевидное — использовать браузер, куда он, само собой, встроен по умолчанию. Браузеры, можно сказать, это естественная среда обитания JS. Вам придется постараться, чтобы найти в сети сайт, работающий без единой строчки этого, позвольте выразиться, кода (DarkWeb не считается!). А заодно, можете попробовать найти в современном мире хоть одно устройство, на котором этого самого браузера нет. Сейчас они везде. Буквально. А раз браузер — это интерпретатор, значит, ваша замечательная программа сработает на любом из этих устройств. Теоретически, само собой.


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


А так, не покидает чувство, пардон, стерильности этого языка. И тут на сцену врывается NODE.JS! Платформа (читай как интерпретатор), которая позволяет вам запускать свой ненаглядный JS прямо из под операционной системы, а не из под браузера! Ваш любимый жаваслипт больше не хер собачий, нужный только для написания жалких сайтиков! Теперь, на нем можно писать настоящие взрослые программы! Можете теперь смело подойти к вашему знакомому Python программисту, который всю жизнь смотрел на вас как на говно, расстегнуть ширинку, и вывалить ему на стол ваш огромный мощный движок V8 (Не автомобильный, просто так интерпретатор назвали. Ну круто же! V8!)


И да, само собой, на Node.js можно написать и сервер, кто же вас остановит. Именно написать, потому что, опять таки, из-за того что node все называют серверным JavaScript, многие думают, что можно просто его скачать, установить, и сразу получится нечто вроде PHP в придачу со встроенным в него Nginx. А потом оказывается, что ничего такого там и в помине нет, и чтобы сервер заработал, надо его сначала написать. Доколе!


Но не будем о серверах. Мы уже поняли, что node не только про это. Но по прежнему непонятно, нахрена он нам нужен, ведь приложения для компа мы тоже писать, вроде как, не планировали. Пока.


А нужен он для удобства. На основе node.js мы будем создавать для себя собственную среду разработки. Мы, конечно, будем писать на JavaScript очень многое, ведь мы, все таки, фронтенд разработчики. Вот только этот код, пусть он и написан на JavaScript, исполняться на Node не будет, Node будет работать только с нашими файлами, ведь в отличии от браузерного JS он это умеет!


Более того, он не умеет многое из того, что умеет браузерный JS, так что большую часть кода, даже банальный и всеми любимый alert() вы там не запустите. И это логично. Как вы обратитесь, к примеру, к объекту window, который есть в браузере, если в node.js никакого window не существует?


Знаю, о чем вы думаете. Ты тут столько времени объяснял, что теперь наш JS может работать на компе, но теперь говоришь, что мы этот код даже запускать на Node не будем. Какого хера...


Сейчас все объясню подробнее.


Давайте вернемся в прошлое (для кого-то, впрочем, все еще настоящее, но это мы и пытаемся исправить). Раньше, разработка фронтэнда представляла собой подключение пары библиотек через обычный тег <script>, пару собственных скриптов и, конечно, CSS стили. HTML, CSS, JS. Все прекрасно и лаконично.


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


И сам JavaScript, будь он неладен, не стоит на месте! Он обновляется, в него добавляют новые возможности, делают его удобнее а иногда даже исправляют в нем старые косяки. И ведь очень хочется писать на самой свежей и красивой версии, со всеми ее возможностями. Но, конечно же, эти современные версии не поддерживаются старыми браузерами. Как быть? Ну, либо писать на старых версиях, либо на новой, но потом перегонять ее в старую. С помощью онлайн утилит, вроде babeljs.io/repl. И так каждый раз. Не очень то удобно. Особенно если вы там накодили на целый вагон.


Да и кому, в общем то, нужен этот идиотский нелогичный JavaScript? Хочу писать на новом, модном, молодежном TypeScript! А вот потом, когда я напишу на нем свою роскошную программу, я перегоню ее уже в JS. А потом этот JS перегоню в JS старой версии, для больше поддержки. А потом то, что получилось, еще прогоню через оптимизатор, для экономии места. Не такая уж и длинная цепочка.


Но и этот HTML уже достал, честно говоря. Шаблонизатор хочу! Буду теперь клепать странички с околосветовой скоростью на pug, потом pug превращать в обычный HTML, и уже туда вставлять свой пережатый перетранслированный JS. Ну и сжимать в конце. Скорость загрузки - наше все! Нам дорог каждый килобайт.


Ах да, забыл, только лохи в 2К20 прописывают стили на лоховском CSS. Все уже давно пересели на Less, SCSS, SASS и тому подобное, с шикарными возможностями, невероятным удобством и мега скоростью! Но да, надо бы сжать да перегнать.


Благодаря всем этим технологиям мы оптимизировали скорость нашей разработки в разы! Да, мы потратили полдня чтобы все это в итоге привести обратно к HTML, CSS и JS, чтобы хоть какой-то браузер нас понял, но мы по прежнему восхитительны и современны!


Вот для чего вам нужен Node.js. Для автоматизации. Только представьте, что у вас есть огромный набор исходных файлов, все разбросанные по своим папочкам, с идеальной архитектурой, на каких угодно технологиях. Современный и большой проект! А потом вы ввели одну единственную команду в консоль и начала происходить настоящая магия! Все это дерьмо превратилось в обычную статику! На выходе вы получаете самые обычные HTML страницы, в каждую из которых подключен всего один общий файл со всеми вашими стилями, сжатый и переведенный в обычный CSS, да еще и с автоматическим добавлением всех этих надоедливых префиксеров и костылей для старых браузеров. И всего один единственный JS файл, в котором объединены все ваши скрипты и весь код из ваших библиотек. Причем, только нужный код! И да, само собой, все сжато и в самом поддерживаемом формате. По итогу, проект, который в исходном виде весил под сотню мегабайт, на выходе превратился в набор страничек общим весом в 5 килобайт! Это ли не чудо?


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


О, вам и этого мало? Тогда я подготовил вам напоследок самое сильное колдунство. Истинное мракобесие и самую темную сторону магии! Страница может даже не перезагружаться! Ее части просто будут заменяться динамично! Вы можете разместить на ней текстовую область, напечатать что-то в ней, потом вернуться в редактор и изменить атрибуты тега или внешний вид этой же самой текстовой области. У вас даже текст внутри нее не пропадет! Состояние вашего приложения сохранится неизменным, и это не дешевые фокусы, перезагрузки реально не происходит.


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


Для того, чтобы установить себе node, вам надо тупо его скачать с официального сайта. Ничего сложного в его установке нет.

NPM


Итак, с Node.js мы разобрались. Он крут, офигеннен и V8. Вот только это просто платформа для запуска программ. Самих программ для этой магии еще попусту нет. И не самим же нам их писать! Мы установим готовые модули для Node.js.


Разумеется, это теперь будет осуществляться не так, как мы привыкли. Не надо лезть в интернет, искать библиотеки и скачивать их на комп вручную. Хотя, конечно, и так тоже можно. Кто же вас остановит. Но мы не психи.


После того, как вы установите node.js на свой компьютер, сразу вместе с ним установится програмка npm. Npm - это менеджер пакетов. Именно эта штука будет отвечать за загрузку нужных вам модулей и библиотек из общего репозитория. И не только за загрузку, но и за установку, обновление, удаление и так далее и до бесконечности. На то она и менеджер. И чтобы прикоснуться к ее чарующему миру, нам нужно просто напросто создать новую папку с названием вашего блистательного проекта. Желательное, конечно, называть латиницей, без всяких пробелов и спец знаков, иначе потом будете долго выть.


Тут начинается страшное. Для многих. Консоли! Но какими бы страшными они не казались, к ним придется привыкать, ибо работать через них придется много. Очень скоро вы поймете, что консоль - ваш друг. Ну и будете чувствовать себя мамкиным хакером.


К счастью, там ничего сложного. Разберетесь. Просто заходите через консоль в вашу созданную папку и инициализируете там проект npm. Инициализация будет представлять из себя создание в этой папке служебных файлов npm. И пока он их создает, он будет спрашивать вас кое-какие вещи, чтобы заполнить информацию об авторе. Можете пока все пропустить, это не суть как важно. Важно то, что в конце он создаст важный файлик - package.json.


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


Таким нехитрым образом, вам не обязательно повсюду таскать с собой огромную папку node_modules, куда устанавливаются все библиотеки. Они сами установятся, был бы package.json.


У npm есть альтернативы. Самый популярный из которых Yarn. По факту, то же самое, только лучше, быстрее, выше, сильнее. Можете установить его. Само собой, это уже отдельная программа, а не модуль для node. Ее вы просто ищите и скачиваете в интернете с официального сайта.


Также, стоит упомянуть и то, что при установке любой из библиотек в папке node_modules появится не одна единственная папка с нужной вам библиотекой. Все слегка сложнее, но не пугайтесь, вам об этом заморачиваться не придется. Устанавливаемая вами библиотека для своей работы может использовать другие библиотеки. А те — третьи. И так далее, до победного конца.


В этом и прелесть менеджеров, что он сам этим всем занимается, иначе это было бы попусту невозможно для человека. Например, в одном из своих проектов я использую 24 модуля. А в папке node_modules их уже 807. Такая вот арифметика. Кажется страшным, но на самом деле это здорово. Чтобы один и тот же код не повторялся в нескольких библиотеках, они используют какие-то общие библиотеки. В конечном счете, это позволяет значительно уменьшить повторяемость кода а значит и выходной вес объединенного файла. Просто помните, что каким-то мистическим образом из всех этих файлов будет выбрано только все самое нужное и сожмется в считанные килобайты.

Webpack


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


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


Вы задаете ему точку входа. Это ваш главный js файл. Вы указываете где он хранится и что с этим файлом надо будет делать. Например, в классическом примере, он находится в папке src и называется index.js. Он его берет и помещает туда, куда вы ему пропишете в настройках. По умолчанию это папка dist, а сам файл будет называться, по умолчанию, bundle.js.


Но не будете же вы весь код хранить в index.js, так ведь? ТАК ВЕДЬ?


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


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


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


Если вы в ваш HTML файл подключите два скрипта, то они, как бы, склеятся в единую программу. Как будто это один файл. И если в первом файле вы объявили какую-то переменную, а потом решили вывести его во втором, то это сработает.


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


Все остальное в нем — закрыто. Если в вашей точке входа вы сделали импорт двух JS файлов один за другим, то надо помнить, что они независимые модули. Если в одном файле вы объявили переменную, а во втором файле вы попытаетесь ее вывести, то ничего не сработает. Второй файл ничего не знает о переменных, которые находятся в первом файле. И даже главный файл, в который вы импортировали оба этих файла, ничего об этой переменной не знает. Логика каждого отдельного файла инкапсулирована и недоступна для любых других. Это как кокон, у которого есть только вход и выход. Что то импортируется на вход и экспортируется через выход. Что там происходит внутри кокона — секрет)


Откровенно говоря, при попытке импортировать эти два файла в ваш index.js не произойдет вообще ничего. Они просто отработают и все. Разве что второй файл выведет ошибку, так как во время работы он попытается вывести переменную, которой для него не существует. А вот первый файл, по сути, вообще ничего не сделает. Да, он создал переменную. Которая так в нем и осталась.


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

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


let importantNumber = 42
export default importantNumber

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


import bukvalnoLubayaPeremennaya from './fileOne.js'
console.log(bukvalnoLubayaPeremennaya) //42

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


Главное, что нужно уловить из всего этого, это то, что мы не импортируем файл. Мы импортируем что-то из файла.


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


const $ = require('jQuery');

Здесь мы назначили jQuery привычную переменную в виде доллара. Но можем любую другую. Как я уже сказал, require это почти то же самое, что и import. Об их различиях (кроме того что одна из них новая а другая - старая) почитаете как нибудь сами.


Ну вот, с JS мы более менее разобрались. Но только лишь с ним.


Вспомним опять import и require. Import более новая и удобная возможность, вот только она не будет работать. Почему? Потому что это возможности новой версии языка JavaScript (на самом деле ECMAScript, но не заморачивайтесь), и они не поддерживаются. Зачем мы тогда написали import, а не require? Вот тут то и начинается самое интересное. Мы будем перегонять написанный нами код из новой и удобной версии - в старую, но поддерживаемую. И рыбку съедим, и пик точеных избежим.


Для этого существуют специальные плагины для вебпака, называемые лоадерами (loaders). Мы прописываем специальные инструкции, согласно которым вызывается тот или иной лоадер. В данном случае, мы хотим, чтобы каждый раз, когда вебпак сталкивался бы с файлом формата .js, он запускал babel-loader. Этот лоадер, в свою очередь, автоматически запустит для файла плагин, который называется просто babel (Если вы помните, сайт для перегонки, который я скидывал, был babeljs.io/repl). Нам надо установить в наш проект и сам babel, и babel-loader который служит перемычкой между babael и webpack, а так же один из пресетов для babel, что то вроде настроек. Порой лоадеры не работают сами по себе.


И вуаля! Наши новомодные import и export прекрасно работают, потому что babel перевел их в старый формат за нас.


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


Например, вы можете импортировать в ваши js файлы не только другие js файлы, но и какие только захотите! Хотите импортировать css? Пожалуйста. Так и пишите

import './style.css'


Но как? Да очень просто. Вебпак все так же продолжает гулять по файлам через эти импорты, и каждый раз смотрит на то, что и с каким файлом надо делать. Ага, попался js, значит, надо прогнать его через babel-loader. Ага, а теперь попался css, значит, надо прогнать его сначала через css-loader, а потом еще и через style-loader.


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


Например, импортировали мы файл в формате SASS. На этом типе файла у нас в настройках висят сразу 3 лоадера. Первый это sass-loader. Он берет файл и превращает его из sass в обычный и привычный нам css. Потом уже идет css-loader, который добавляет поддержку такого импорта. В конце идет style-loader, он берет весь этот css и вставляет его в шапку нашей будущей страницы. Т.е объединяет все собранные стили и прописывает прямо в HTML.


Вместо style-loader можно использовать, к примеру,  mini-css-extract-plugin. Он, в отличии от style-loader, не прописывает стили в шапку страницы, а собирает их в отдельный файл css и просто его подключает. Прямо как bundle.js.


И так вы можете делать для всех типов файлов. Картинки, шрифты, HTML - все что угодно. Главное для каждого прописать свои правила, что с этими файлами делать и куда их складывать.


Отдельного внимания заслуживает HTML, потому что, как правило, не HTML подключают в JS, а наоборот. Для этого есть html-webpack-plugin, он тоже прописывается в настройках вебпака и в нем явно указывается ссылка на HTML. Именно этот плагин скопирует эту HTML страницу куда надо, сделает с ней что надо, и, самое главное, сможет встроить ссылку на получившийся бандл прямо внутрь. Вам не придется прописывать ее самому.


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


Но что там с локальным сервером разработки? Это плагин webpack-dev-server, который, во многом, использует тот же самый файл с настройками вебпака. Только не создает готовый проект а разворачивает сервер для удобной разработки. Сам следит за обновлениями в файлах, сам обновляет страницу, и именно к нему можно подключить модуль замены содержимого без перезагрузки.


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

Фронтэнд и Бекэнд.


Если вы вдруг хотите начать писать и бенкенд на node.js, то у вас может что-то переклинить в голове, ведь теперь и там и там будет JS, как же его отличить друг от друга?


Ну, код сервера уже будет исполняться самим node.js, и настраивать его нужно так, чтобы он работал уже с готовыми файлами, которые подготовит вам вебпак. Вам придется отказаться от прелестей, которые даст вам webpack-dev-server, потому что заставить их работать синхронно - та еще задача. Но с другой стороны, представить себе ситуацию, где вам нужно прям одновременно работать и с фронтендом и с бенкэндом в одно и то же время — достаточно сложно.


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

Итог


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

Показать полностью
71

Во все тяжкие: Веб-разработчик с нуля. 10 месяцев

Во все тяжкие: Веб-разработчик с нуля. 10 месяцев IT, Программирование, Карьера, Javascript, Веб-Разработка, Frontend, Web, Длиннопост

Нет, конечно не уволили, я сам уволился. Произошло это два дня назад.


Цель — Senior Frontend Developer.

Язык: JavaScript.

Возраст: 28 лет;

Работа (настоящее время): - в поиске.


Привет всем, друзья! Как ваши дела? Что нового? У меня вот, как видите перемены. Моя совесть не выдержала, что я незаслуженно получаю зарплату выше рыночной для джуна, и медленно подгрызала меня изнутри(шутка, но не про зп).


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


Что же заставило меня уйти из этой компании:


1. Меня заставляли писать на notepad++. Благо я воспротивился и установил себе vscode, но потом после этого был неприятный разговор и упреки.

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

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

4. Отсутствие таск-раннеров по типу gulp, grunt, не говоря уже про webpack.

5. Запрет на использование фрэймворков, хотя я особо на это не жаловался, мне и чистого JS за глаза. Но роста хотелось.

6. Отсутствие тех. заданий и требований, а самое главное - отсутствие кода ревью.

7. Запрет на SPA. Сначала я написал приложение как SPA, но после пришлось переделывать, чтобы страницы рендерились и отдавались с сервера. Тихий и медленный ужас.


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

Всё остальное адекватно, ребята с кем работал хорошие, по зп все шикарно, официально и т.д.


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


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


1. Прочитал пару книжек Стива Круга по юзабилити и тестированию(ниже по ссылке в инсте).

2. Посетил JavaScript Evening в компании DINS (Dino Systems) и послушал два доклада: API design for front-end и «Алгебраические типы данных в TypeScript».

3. Посмотрел интересный и полезный курс по JS шаблонам проектирования.

4. Успел покопаться в документации по extJs и сделать одно приложение, но тестовое от компании так и не сделал. Не осилил. Очень сложный фрэймворк.

5. Прочитал половину книги "Грокаем алгоритмы".

6. Сверстал пару тестовых за последние 4 дня, смотреть в гитхабе. Новые на подходе.

7. Изучал много документации и углублялся в разные API браузера.


И да, я завел инстаграм. Там не будет гламурных фотографий. Там я буду делать небольшие рецензии на книжки, которые прочитал, фоточки с митапов и конференций, может чего еще. В общем, так сказать продолжение моего блога в <img>.

Подписывайтесь :)


Всем хорошего времени суток и успеха! А я пойду делать тестовые и гонять по собеседованиям и искать команду, в которой смогу развиваться как специалист и дорасти до Senior!


Артем, OWIII.

Показать полностью
16

От новичка в JS до трудоустройства. История фейла

Всем привет. Я вернулся. Последний пост был около полугода назад. Где-то в тот же период закончились мои попытки самостоятельно выучить JS.

Причин на то несколько:
1. Очень сложно начать применять на практике изученое без какого-либо постоянного менторства.
2. Уделять время изучению стало сложнее, т.к. нужно было брать дополнительные подработки.
3. Не понимание своих возможностей. Прежде всего, из-за того, что не с чем сравнивать.
4. Русскоязычное сообщество. Попытки найти решение той или иной задачи превращаются в соревнование по сарказму и хамству.

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

Спустя несколько месяцев я устроился на позицию Junior Project Manager и успешно прошел испытательный срок. И, да, мне нравится эта работа. Это совершенно новый взгляд на работу о котором можно написать не один материал. Я очень доволен и абсолютно не жалею о том, что не получилось изучить JS.

Всем большое спасибо, кто действительно пытался помочь мне!

Мои подписки
Подписывайтесь на интересные вам теги, сообщества,
пользователей — и читайте персональное «Горячее».
Чтобы добавить подписку, нужно авторизоваться.
Отличная работа, все прочитано!