Алекс, спасибо за статью. Всё здорово. Мы сами используем Grafana для мониторинга Kubernetes-кластера и в целом довольны. Вопрос не совсем по теме, но понравилась, как схема нарисована. Что использовали, если не секрет? В чём рисовали?
Я говорил о том, что опытные разработчики будут переходить с PHP на более высокооплачиваемые позиции. Соответственно, в этом сегменте будет возрастать концентрация Junior'ов.
Не ради холливара, но истины для. На хабре была отличная статья про стили кодирования, где в том числе исследовалась эта важная тема. Там автор как раз приводил пример какой головной болью грозит использование как single-var, так и tab-intend. Очень хорошая статья была.
Store используется для хранения состояния приложения. Если мы делаем какой-либо переиспользуемый компонент, он не использует store — все параметры ему передаются через props. Если мы делаем компонент бизнес-логики, то это значит, что нам нужно отобразить данные из одного store по определённому фильтру или категории (которые передаются ему через props). Это возможности для этого должны быть в реализацию самого store.
Подробней о предназначении state и props можно почитать здесь.
Как раз недавно обсуждали плюсы и минусы статической типизации.
Есть у меня опасения, что TypeScript, Flow и пр. превратят JS в CSharp.
Ведь успех и гибкость JS в его:
а) простоте — всего 7 базовых операторов делают его привлекательным и комфортным для входа новичков, которые втянувшись начинают развиваться, что делает JS самым популярным;
б) свободе и демократичности — мы можем использовать подходы, наиболее подходящие как проектам, так и их отдельным частям.
Если обратить фокус на сам вопрос типизации.
Было бы интересно услышать преимущества статической типизации перед директивами в стиле jsdoc:
/**
* @param {object|object[]} recipients - one recipient or collection of them
* @param {string} message - message body
* @param {boolean} [system=false] - message type
*/
var sendMessage = function (recipients, message, system) {
// ...
};
/**
* @param {...string} parts
* @example
* var users = activeUsers.map(function (user) {
* return user['id'] + ":" + user["login"];
* });
* sendLog(“activeUsers: ", _users);
*/
var sendLog = function () {
// ...
};
Здесь я вижу явные преимущества директив перед статической типизацией:
Код будет работать «из коробки», без пре-процессинга.
Мы легко можем включать-отключать обработку директив.
Мы можем достаточно понятно описывать вариации параметров, структуру, значения по умолчанию, особенности их использования и т.д.
Смесь человеко-понятного текста позволяет создавать нам документацию внутри кода, что достаточно удобно, ведь главная проблема документации — её актуальность.
Мы имеем достаточно высокую читабельность — в IDE мы можем свернуть блоки с комментариями нажатием “горячей” кнопки и работать с самой логикой, скрыв мета-информацию. Это позволяет легко сфокусироваться на знакомом коде. При разработке крупных приложений, где логика первична, API знакомо, а команда боле-менее устоявшаяся — это важно.
В целом, директивы, как элементы изначально направляющие компилятор (вспомним хотя бы C++), а теперь пре-процессоры достаточно давнее и удобное явление.
К примеру, мы имеем большой проект и использовали jslint:
/*jslint vars: true*/
Но в какой-то момент решили переключиться на eslint.
Этот подход не обязывает нас рефакторить весь проект — мы просто меняем директивы в новых модулях и постепенно обновляет прошлые:
/*eslint eqeqeq:0, curly: 2*/
Тут мы замечаем важное качество — изолированность директив. Они не влияют друг на друга и могут обрабатываться в любом порядке. В то время, перенося контроль типов, как сервисную операцию, в надмножество языка и тем самым меняя язык (как в примере Flow, TypeScript и пр.), мы не можем так свободно и прозрачно их комбинировать и связываем себе руки.
Например, подход React создал необходимость появления JSX. Но как JSX будет сочетаться с TypeScript? Какой пре-процессор должен сначала пройти по исходному коду? И сочетаемы ли они вообще?
Мне кажется, было бы полезней развивать и перерабатывать jsdoc и пре-процессоры для его обработки, оставив языку свободу. В современном мире веб-разработки итак хватает проблем с интеграцией решений между собой и об этом я писал в своей недавней статье.
Опять же, имеется ввиду сборка для продакшн = после минимизации.
«Правильно» — это очень относительно, у каждого ведь своё «правильно». У меня оно немного другое. Не лучше, не хуже — просто другое. Поэтому тут было бы удобней сделать плагином, они как раз для таких случаев предназначены. Это действительно просто.
1. Да, без проблем. Но если в директорию вы решите поместить readme-файл? А если тесты для него? Как это исключать? Действительно логичней и чище было бы декомпозировать, исходя из того, что есть модуль, в котором указаны его основные зависимости. У тех в свою очередь могут быть другие. Например:
var componentTemplate = require('./component.jade');
require('./component.css');
module.exports = contentTemplate;
— в этом случае webpack подключит шаблон, CSS и фоновое изображение. При этом вы можете спокойно и без проблем создавать документацию, разные сценарии сборки, тестирования и пр.
Другой вариант — использовать подход для подключения bower-модулей, изложенный в статье. Он без проблем подключит bower.json с таким фрагментом (реальный пример из жизни — компонент ladda-bootstrap):
Тут важно осознавать, что модуль должен вернуть что-то — объект или функцию. В случае со списком выше — тут просто. А вот если вы подключите по вашему примеру заведомо неизвестный набор jade-шаблонов, как вы с ними будете работать? В случае с webpack — один шаблон = одна функция:
var messageTemplate = require('./template/message.jade');
$('#messages').append(messageTemplate({userName: 'vintage', ...});
2. Во многом ответил в предыдущем пункте. Согласен про то, что если есть проект, в котором для модулей много CSS-файлов, то будет затратно их подключать по отдельности — тут можно либо собрать всё предварительно через gulp/grunt, либо написать плагин по образу и подобию: github.com/lpiepiora/bower-webpack-plugin
И всё сообщество будет вам благодарно! С webpack вообще всё возможно. Он разве что кофе не готовит.
3. Require.js так и был устроен — там это вынужденная необходимость, ведь сборщик немаленький. Но в случае с webpack, как kossnocorp, речь идёт о 243 байтах — мы на HTTP-запрос к отдельному загрузчику можем больше потерять.
Всё верно, я тоже использовал изначально встроенный ResolverPlugin, пока не столкнулся с проблемой.
Возьмём пример по этой ссылке:
...
plugins: [
new webpack.ResolverPlugin([
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
])
...
Как видим, этот плагин позволяет искать в директории запрошенного модуля файл bower.json и если он найден — возвращать файл, указанный в секции «main». Однако, я столкнулся с тем, что модуль bootstrap в своём описании содержит целую цепочку файлов (что логично):
Есть ещё большая группа iOS-разработчиков (где более 1000 человек): https://t.me/ios_ru
Подробней о предназначении state и props можно почитать здесь.
Как раз недавно обсуждали плюсы и минусы статической типизации.
Есть у меня опасения, что TypeScript, Flow и пр. превратят JS в CSharp.
Ведь успех и гибкость JS в его:
а) простоте — всего 7 базовых операторов делают его привлекательным и комфортным для входа новичков, которые втянувшись начинают развиваться, что делает JS самым популярным;
б) свободе и демократичности — мы можем использовать подходы, наиболее подходящие как проектам, так и их отдельным частям.
Если обратить фокус на сам вопрос типизации.
Было бы интересно услышать преимущества статической типизации перед директивами в стиле jsdoc:
Здесь я вижу явные преимущества директив перед статической типизацией:
Код будет работать «из коробки», без пре-процессинга.
Мы легко можем включать-отключать обработку директив.
Мы можем достаточно понятно описывать вариации параметров, структуру, значения по умолчанию, особенности их использования и т.д.
Смесь человеко-понятного текста позволяет создавать нам документацию внутри кода, что достаточно удобно, ведь главная проблема документации — её актуальность.
Мы имеем достаточно высокую читабельность — в IDE мы можем свернуть блоки с комментариями нажатием “горячей” кнопки и работать с самой логикой, скрыв мета-информацию. Это позволяет легко сфокусироваться на знакомом коде. При разработке крупных приложений, где логика первична, API знакомо, а команда боле-менее устоявшаяся — это важно.
В целом, директивы, как элементы изначально направляющие компилятор (вспомним хотя бы C++), а теперь пре-процессоры достаточно давнее и удобное явление.
К примеру, мы имеем большой проект и использовали jslint:
Но в какой-то момент решили переключиться на eslint.
Этот подход не обязывает нас рефакторить весь проект — мы просто меняем директивы в новых модулях и постепенно обновляет прошлые:
Тут мы замечаем важное качество — изолированность директив. Они не влияют друг на друга и могут обрабатываться в любом порядке. В то время, перенося контроль типов, как сервисную операцию, в надмножество языка и тем самым меняя язык (как в примере Flow, TypeScript и пр.), мы не можем так свободно и прозрачно их комбинировать и связываем себе руки.
Например, подход React создал необходимость появления JSX. Но как JSX будет сочетаться с TypeScript? Какой пре-процессор должен сначала пройти по исходному коду? И сочетаемы ли они вообще?
Мне кажется, было бы полезней развивать и перерабатывать jsdoc и пре-процессоры для его обработки, оставив языку свободу. В современном мире веб-разработки итак хватает проблем с интеграцией решений между собой и об этом я писал в своей недавней статье.
«Правильно» — это очень относительно, у каждого ведь своё «правильно». У меня оно немного другое. Не лучше, не хуже — просто другое. Поэтому тут было бы удобней сделать плагином, они как раз для таких случаев предназначены. Это действительно просто.
— в этом случае webpack подключит шаблон, CSS и фоновое изображение. При этом вы можете спокойно и без проблем создавать документацию, разные сценарии сборки, тестирования и пр.
Другой вариант — использовать подход для подключения bower-модулей, изложенный в статье. Он без проблем подключит bower.json с таким фрагментом (реальный пример из жизни — компонент ladda-bootstrap):
Тут важно осознавать, что модуль должен вернуть что-то — объект или функцию. В случае со списком выше — тут просто. А вот если вы подключите по вашему примеру заведомо неизвестный набор jade-шаблонов, как вы с ними будете работать? В случае с webpack — один шаблон = одна функция:
2. Во многом ответил в предыдущем пункте. Согласен про то, что если есть проект, в котором для модулей много CSS-файлов, то будет затратно их подключать по отдельности — тут можно либо собрать всё предварительно через gulp/grunt, либо написать плагин по образу и подобию:
github.com/lpiepiora/bower-webpack-plugin
И всё сообщество будет вам благодарно! С webpack вообще всё возможно. Он разве что кофе не готовит.
3. Require.js так и был устроен — там это вынужденная необходимость, ведь сборщик немаленький. Но в случае с webpack, как kossnocorp, речь идёт о 243 байтах — мы на HTTP-запрос к отдельному загрузчику можем больше потерять.
Возьмём пример по этой ссылке:
Как видим, этот плагин позволяет искать в директории запрошенного модуля файл bower.json и если он найден — возвращать файл, указанный в секции «main». Однако, я столкнулся с тем, что модуль bootstrap в своём описании содержит целую цепочку файлов (что логично):
Для того, чтобы подключить эти файлы и создан модуль BowerWebpackPlugin.