Первоначально из колонки Zhihu, добро пожаловать на вниманиеzhuanlan.zhihu.com/p/55357377
Приближается китайский Новый год 2019, пора подвести итоги технического накопления команды за прошедший год. За последний год поддерживаемый нами бизнес, связанный с данными, вырос как на дрожжах: объем кода двух основных продуктов уровня платформы достиг 300 000+ строк и 800 000+ строк соответственно, количество модулей TS превысило 1000, а количество совместных разработчиков увеличилось до 20+. По историческим причинам среда разработки основана как на React, так и на Angular.Учитывая сложность продукта, нехватку персонала и различную техническую подготовку, мы пробовали различные методы полировки системы инструментов для повышения эффективности разработки. Ниже приведены пять основных выбранных методов.
1. Управление состоянием на основе Redux
С 2013 года реагирован на сегодняшний день, почти 6 лет, передний конечный кадр постепенно образует трехногируемые усилия реагирования / Vue / угловой. Несколько лет назад он также был посвящен однонаправленному связыванию и двунаправленному связыванию, и теперь три основных кадра имеют примерно одного одностороннего привязки, а двусторонние привязки являются простым синтаксисом. Разница между каркасом становится меньше, а также библиотека компонентов Ant-Design / Fusion-Design / NG-Zorro / Elementui, выбирая любую из ваших знакомых структур для завершения бизнеса.
Какой следующий основной вопрос? мы думаем, что этогосударственное управление. Для простых приложений удобно и быстро использовать состояние в компонентах, но по мере увеличения сложности приложения данные будут разбросаны по разным компонентам, и связь между компонентами станет чрезвычайно сложной. Мы попробовали нативный Redux, идеи Fractal, саморазработанный фреймворк Mobx, Angular Service и, наконец, считаем, что Redux по-прежнему остается одним из лучших вариантов для обработки сложных потоков данных приложений.
К счастью, в дополнение к сообществу React, в сообществе Vue есть аналогичный Vuex, в сообществе Angular есть NgRx, предоставляющий почти такие же возможности, и даже NgRx может беспрепятственно использовать redux-devtools для отладки изменений состояния.
Независимо от того, как вы оптимизируете, всегда следуйте трем принципам Redux:
в общем | метод | поднятые проблемы |
---|---|---|
Single source of truth | Компонент без сохранения состояния, данные поступают из Store | Как организовать Магазин? |
State is read-only | Состояние может быть изменено только путем запуска действия | Завышенное количество действий, много стандартного кода |
Changes are made with pure functions | Редьюсеры — это чистые функции | Как бороться с побочными эффектами, много стандартного кода |
Эти три вопроса мы задаем через самоисследованиеiron-reduxбиблиотека для решения, за этим стоит следующее:
Как организовать действия?
- Тип действия должен быть уникальным в глобальном масштабе, поэтому мы добавляем префикс к типу действия, что на самом деле является концепцией пространства имен.
- Чтобы продолжить опыт, сцена запроса (выборки) должна иметь дело с 3 состояниями, соответствующими 3 действиям ЗАГРУЗКИ/УСПЕХА/ОШИБКИ, мы передаем
FetchTypes
тип для автоматической генерации соответствующих 3 действий
Как организовать Store/Reducer?
- просмотр редуктора и не нужно соответствовать, и дерево состояния присутствия приложения, в то время как сборка дерева, в соответствии с их необходимостью, организуется, по дереву состояний, чтобы связать одну или несколько ветвей, чтобы соединить дерево компонентов
- Сократите шаблонный код, создав несколько предустановленных типов данных. Для данных, возвращаемых Fetch, мы определяем тип AsyncTuple, чтобы сократить шаблонный код.
- Четкая организационная структура, первый слой - ROOT, второй слой - каждая страница, третий слой - карточка на странице, четвертый слой - данные карточки, поэтому самое глубокое разделение в основном не превышает 5 слоев
В итоге мы получаем следующее плоское дерево состояний. Большой, но организованный, вы можете быстро и однозначно получить доступ к любым данным.
[Дерево состояний Redux]Как уменьшить шаблонный код?С родным Redux общий запрос обрабатывается следующим образом. Очень избыточен, поэтому многие критикуют Redux.
const initialState = {
loading = true,
error = false,
data = []
};
function todoApp(state = initialState, action) {
switch (action.type) {
case DATA_LOADING:
return {
...state,
loading: true,
error: false
}
case DATA_SUCCESS:
return {
...state,
loading: false,
data: action.payload
}
case DATA_ERROR:
return {
...state,
loading: false,
error: true
}
default:
return state
}
}
После использования железа-редукса:
class InitialState {
data = new AsyncTuple(true);
}
function reducer(state = new InitialState(), action) {
switch (action.type) {
/** 省略其它 action 处理 */
default:
return AsyncTuple.handleAll(prefix, state, action);
}
}
На две трети меньше кода! !
В основном он делает две вещи:
- Введено значение по умолчанию
AsyncTuple
типа, то есть{data: [], loading: boolean, error: boolean}
такая структура данных; - использовать
AsyncTuple.handleAll
Для обработки трех действий ЗАГРУЗКА/УСПЕХ/ОШИБКА код handleAll очень прост, просто используйте if, чтобы оценить суффикс действия.тип.Исходный код находится вздесь.
Раньше React и Angular были двумя очень сложными для согласования фреймворками, и на разработку тратилось много сил. Используя легковесный iron-redux, полностью следуя основным принципам Redux, наш внутреннийОн реализует повторное использование почти всех кодов, кроме слоя компонентов. Спецификация разработки и библиотека инструментов согласованы, и разработчики могут легко переключаться, а дополнительные затраты, вызванные различиями в инфраструктуре, сведены к минимуму..
2. Полностью используйте TypeScript
TypeScript в настоящее время является большим хитом, согласно2018 stateofjs, более 50 % использования и 90 % удовлетворенности, даже JestПереключиться с Flow на TS. Если вы еще не использовали его, вы можете подумать о переключении на него, что определенно принесет большое улучшение проекту. В прошлом году мы перешли от частичного использования TS к полному переходу на TS, включая собственную разработанную библиотеку инструментов и т. д.
Самым большим преимуществом TS является то, что он предоставляет мощные возможности статического анализа и в сочетании с TSLint позволяет реализовать более строгие ограничения проверки кода. Поскольку традиционный EcmaScript не имеет статического типа, даже с ESLint он может выполнять только самые простые проверки, и некоторые проблемы с опечатками могут быть обнаружены после появления ошибок в сети.
На следующем рисунке показана обычная 4-уровневая архитектура для интерфейсных приложений.После того, как код и инструменты полностью охватывают TS, реализуется статический анализ всей ссылки от внутреннего API-интерфейса до компонента View, и он имеет отличные возможности подсказок и проверки кода.
[Диаграмма взаимодействия между интерфейсом и сервером]В дополнение к упомянутому выше iron-redux мы также вводимPontРеализуйте выборку из внешнего интерфейса, который может автоматически сопоставлять внутренний API с вызываемыми внешними методами запроса.
Принцип реализации Pont: (франц. мост) — это разработанная нами структура внешнего слоя выборки. Подключенный серверный API использует Java Swagger, который может предоставлять метаинформацию обо всех API, включая тип и формат запросов и ответов. Pont анализирует метаинформацию API для создания функций выборки TS.Эти функции выборки имеют идеальный тип и монтируются под модулем API. Эффект взятия числа в окончательный код следующий:
Эффекты, достигаемые Pont:
- Автоматически сопоставлять URL-адрес, метод в соответствии с именем метода и идеально соответствовать коляскам, типу ответа и может автоматически запрашивать
- После изменения внутреннего API-интерфейса запрос, связанный с внешним интерфейсом, автоматически сообщит об ошибке, и больше не нужно беспокоиться о том, что внутренний интерфейс незаметно изменит интерфейс, а внешний интерфейс не знает об этом.
- Документы соглашения о внешнем и внутреннем интерфейсе больше не нужны, и код используется для обеспечения того, чтобы выборка внешнего интерфейса и определение внутреннего интерфейса были точно такими же.
Кроме того, iron-redux может получать формат данных ответа интерфейса Pont и выводить определение статического типа всего дерева состояний Redux, а данные в Store имеют идеальную подсказку типа. Эффект следующий:
наконецTS делает код более надежным, особенно для крупных проектов, компиляция почти означает нормальную работу, а также добавляет уверенности в рефакторинге..
3. Вернуться к Sass/Less
В 2015 году мы начали практиковать CSS-модули, в том числе стилизованные компоненты и т. д. К 2019 году решение css-in-js все еще обсуждается, хотя оно и решает некоторые проблемы, присущие языку CSS, но также значительно увеличивает Новички недостаточно дружелюбны, затраты на глобальное покрытие стилей высоки, обработка псевдоклассов сложна, а в сочетании с библиотеками компонентов, такими как AntD, есть ямки. В то же время сообщество Sass/Less также быстро развивается, особенноStylelintЗрелости CSS можно избежать с помощью технических ограничений.
- Глобальное загрязнение: принято, что каждый файл стиля может иметь только один класс верхнего уровня, например
.home-page{ .top-nav {/**/}, .main-content{ /**/ } }
. Правило Stylelint можно использовать для обнаружения и предупреждения о наличии нескольких классов верхнего уровня. - Управление зависимостями не является тщательным. С помощью css-загрузчика webpack этого достаточно.
- Переменные JS и CSS являются общими. Что касается совместного использования переменных между JS и Sass/Less, мы нашли собственное решение:
// src/styles/variables.js
module.exports = {
// 主颜色
'primary-color': '#0C4CFF',
// 出错颜色
'error-color': '#F15533',
// 成功颜色
'success-color': '#35B34A',
};
// webpack.config.js
const styleVariables = require('src/styles/variables');
// ...
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader?sourceMap&minimize',
{
loader: 'sass-loader',
options: {
data: Object.keys(styleVariables)
.map(key => `\$${key}: ${styleVariables[key]};`)
.join('\n'),
sourceMap: true,
sourceMapContents: true
}
}
]
}
//...
В файлах scss на переменные можно ссылаться напрямую.
// page.scss
.button {
background: $primary-color;
}
4. Инструменты разработки охватывают всю ссылку
В 2019 году вам практически невозможно разрабатывать фреймворки уровня React/Angular/Vue, и нет необходимости изобретать колеса, такие как Ant-Design/Fusion-Design/Ng-Zorro. Неужели нет шансов?
Конечно, есть еще много возможностей в сочетании с вашим собственным процессом разработки продукта. Ниже приведена блок-схема разработки обычных проектов.Если любая ссылка глубокая, есть возможности для улучшения. Если вы сможете уменьшить одну или несколько ссылок с помощью инструментов, ценность будет еще выше.
Просто перейдите по ссылке [Разработка], чтобы развернуться, существует множество масштабируемых сценариев:
Типичным примером является то, что мы разработали инструменты интернационализацииkiwi. Он также имеет совершенство типа TS, очень сильную подсказку в области копирайтинга, а также:
- Плагин VS Codekiwi linter, китайская копия будет автоматически отмечена красным цветом, а если уже есть переведенная копия, то ее можно будет автоматически заменить
- Команда Shell проверяет все непереведенные тексты и отправляет их переводчикам пакетами.
- Скрипты Codemod автоматически переносят старые решения интернационализации на Kiwi по очень низкой цене.
В дополнение к вышеперечисленным трем пунктам в будущем мы также планируем разработать плагины для браузера для проверки отсутствия копии и использовать Husky для автоматического машинного перевода отсутствующей копии перед отправкой в git и так далее.
В будущем, если вы предоставите только одну кодовую базу, ее ценность будет очень ограничена. Вы можете обратиться к приведенной выше таблице и разработать соответствующие расширения, чтобы обогатить экологию. Если вы новичок, рекомендуется изучить принцип компиляции и соответствующую спецификацию разработки расширения.
5. Строгий и тщательный обзор кода
Всего за последний год мы провели более 1200 Code Reviews (CR), многие коллеги стеснялись упоминать MR в начале, чтобы гоняться за чужими обзорами, CR вошло у всех в привычку. Благодаря CR любая строка кода в проекте была затронута как минимум двумя людьми, что снижает большинство низкоуровневых ошибок и повышает качество кода, а также является одним из самых быстрых способов помочь новичкам расти.
[Один из скриншотов проекта MR]
Несколько советов по Code Review:
- No magic
- Explicit not implicit
- Охват важнее глубины, а охват преследует 100%
- Частота важнее смысла ритуала.Вы можете просматривать чужие коды, когда сидите в автобусе и сидите на корточках в туалете и включаете свой мобильный телефон.Нет необходимости организовывать специальную встречу.
- Гранулярность должна быть как можно меньше, можно использовать один компонент и один метод, который можно комбинировать с Git Flow.
- Он будет обработан в течение 24 часов. Если нет проблем, он будет объединен напрямую. Если есть проблема, вы должны оставить комментарий и предоставить действие.
- Для кода, который нужно запустить и ревью уже поздно, его можно сначала слить и запустить, а потом уже после запуска добавить ревью.
- Он нуждается в продвижении сверху вниз, имеет идеальные спецификации и регулярно обобщает опыт обзора для обогащения спецификаций разработки.
- CR нужен не только для того, чтобы находить ошибки, видеть хороший код, не скупиться на похвалу
- Суть в том, чтобы поощрять больше общения между разработчиками, учиться друг у друга и создавать техническую культурную атмосферу.
Суммировать
Конечно, вышеперечисленные 5 пунктов — это еще не все наши технологии. Кроме того, мы также занимались разработкой мобильных терминалов, визуальными диаграммами/WebGL, Web Worker, GraphQL, оптимизацией производительности и т. д., но они все еще находятся на техническом уровне и в определенной степени будут использоваться совместно в будущем.
Если вы также занимаетесь подготовкой или разработкой сложных интерфейсных приложений, а команда имеет различный технический опыт, вы можете обратиться к вышеуказанным 5 пунктам, использовать Redux для достижения стандартизированного, четкого и предсказуемого управления состоянием и глубоко совершенствовать TypeScript для повышения надежности кода. Используйте различные инструменты Lint, чтобы вернуться к простому и удобному CSS, постоянно совершенствуйте свои собственные инструменты разработки, чтобы обеспечить эффективные спецификации разработки, и строго и тщательно применяйте проверку кода, чтобы способствовать общению людей и совершенствованию.
Links
- Мост:github.com/nefe/pont
- Киви:github.com/nefe/kiwi
- iron-redux: GitHub.com/what-share/iron-th…
- The State of JavaScript 2018
Мы все еще набираем, добро пожаловать на электронную почту резюме, письма будут возвращены. shaoyin.ssy@alibaba-inc.com