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

Вы можете просмотреть структуру файла index.html в ветке dev моей начальной версии. Он перечисляет только один компонент, <listing> компонент, который загружается через отдельный файл JS. JS наивно создает экземпляр Vue для загрузки некоторых данных (статистики, относящейся к сайтам, работающим в службе), когда страница завершает загрузку. Вы увидите, что используется jQuery, а также некоторые функции ES6, такие как let (используется неправильно), но также и объявления переменных var… не очень хорошо, но, эй, я не против показать вам свой дрянной код, потому что все мы путешествуем от дрянного до менее дрянный, чтобы со временем получить достойный код.

Мне понравилось, как Vue позволил мне начать изучение фреймворка самым простым способом, следуя некоторым из тех же функций, которые продвигали евангелисты веб-компонентов. Наряду с импортом HTML вы можете использовать синтаксис <script type=”text/x-template”> для загрузки шаблона, используемого экземпляром Vue и помещенного внутри другого HTML в качестве тега компонента. «Вот шаблон, использованный для замены тега <listing> в файле index.html.

Чего не хватает?

Что ж ... в моем первоначальном исследовательском приложении Vue не хватает многих хороших вещей. Конфигурация, которую можно разместить в хранилище Vuex, устанавливается через глобальный объект siteConfig. vue-router мог заменить созданный мной объект Vue только для хранения маршрутов. Однофайловые компоненты Vue (SFC) могут объединять шаблоны, JS и CSS в более краткую и удобную для навигации базу кода. ESLint может помочь уменьшить количество ошибок и помочь разработчикам придерживаться лучших практик точно так же, как добавление модульных и E2E-тестов. Ах да, и поскольку Safari не любит (или не хочет) импортировать файлы HTML, один разработчик, который предпочел Safari, не мог использовать приложение в своем браузере. Войти в инструменты сборки…

По мере роста приложения я знал, что «делаю это неправильно» в основном из-за отсутствия SFC и команды dev serve / run, которая добавляла бы горячую перезагрузку, линтинг и т. Д. Для улучшения опыта разработчика. Я также знал, что не понимал большинства деталей, необходимых для работы. Итак, я был на распутье, и я подумал, что должен проверить и посмотреть, есть ли какие-нибудь стартовые комплекты, которые я мог бы установить, чтобы помочь мне улучшить свое понимание необходимых частей, чтобы все это работало. Я знал, что существуют стартовые наборы для React и Angular, поэтому не думал, что у меня возникнут проблемы с поиском одного для Vue.

Шаблон Vue Webpack

Проект« vue-webpack-markerplate предоставил все навороты, необходимые для преобразования моего приложения, созданного со статическими файлами, в приложение, которое использовало узел для обслуживания приложения в режиме разработки и создания приложения для развертывания на производственном сервере. Честно говоря, я слепо принял значения по умолчанию, так как я не знал, что, черт возьми, делаю, и шаблонный проект был настоятельно рекомендован в списке Vue Awesome на GitHub. В настоящее время я не видел проект, указанный на этой странице, но это, вероятно, потому, что он устарел после того, как vue-cli 3 стал зрелым.

После рефакторинга моего приложения в ветке 1.x структура изменилась в соответствии с Webpack Boilerplate, включая кучу точечных файлов, папки тестирования, сборки и конфигурации, а также большое количество зависимостей узловых модулей 😬. Теперь я мог обслуживать версию приложения, которая работала в Safari, добавляла код и перезагружала компоненты при изменениях файлов и позволяла мне объединять весь код Vue в SFC. Довольно мило, а ?!

Навигация по кодовой базе приложения была немного более запутанной, но как только я добавил компоненты через Vue.use() и разместил маршруты в vue-router, я в основном придерживался папки src/components для разработки функций. Я также добавил src/pages для зеркалирования маршрутов и поместил только компоненты, используемые «страницами», в каталог src/components.

Перенесемся в октябрь 2018 г.

В основном я разработал приложение «Lil 'Shrugger» самостоятельно, хорошо это или плохо, и одной из моих постоянных целей было задокументировать и написать тесты для приложения, чтобы его можно было передать другим разработчикам, если меня не было рядом или занят работой над чем-то другим ... и сотрудничество, ура! Неспособность написать тесты и документацию - довольно распространенное явление во время цикла разработки, и я все время становлюсь жертвой этой болезни.

Я разработал несколько тестов, которые последовательно проходили локально, но не работали на Travis CI, нашем любимом средстве выполнения тестов CI. Причина была в… Селен, как вы уже догадались. Взаимодействия пользовательского интерфейса загружались медленно, и по какой-то причине компоненты не монтировались и не монтировались правильно. После некоторого уговора я решил, что пора переключить фреймворки тестирования на использование чего-то, что не было основано на Selenium для E2E-тестов.

В процессе переключения среды тестирования я понял, что не обновлял зависимости… когда-либо… ох, это нехорошо. Поскольку это приложение использовалось только для внутренних целей, я полагаю, что я не воспринимал его так серьезно, как у меня было бы производственное приложение с управлением пользователями, базой данных и более широким охватом, чем 10 или около того сотрудников, использующих его. Я также на некоторое время заблокировал размещенную версию приложения через HTTP Basic Authentication.

Я не так уж хорошо разбираюсь в обновлении узловых модулей и подумал, что работает runningnpm update; однако у меня все еще остались устаревшие пакеты, поскольку некоторые версии зависимостей были привязаны к определенным версиям. Вместо того, чтобы пытаться выяснить, что потребуется для обновления всех 43 устаревших зависимостей, я подумал, что было бы гораздо лучше использовать время для воссоздания проекта с использованием обновленной версии стандартного шаблона.

Введите vue-cli 3

К моему большому сожалению, шаблонный проект, с которого я начал свой рефакторинг, уже устарел, когда я снова посмотрел. Они сказали мне использовать вместо этого vue-cli. Посмотрев на страницу проекта, я увидел много частей, которые были включены в шаблон, 1.x, версия моего приложения также была включена в vue-cli 3. ESLint, E2E и модульное тестирование, Webpack и Babel. Часть с графическим интерфейсом выглядела интересно, но я не пробовал это делать.

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

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

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

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

Сравнение App.vue и main.ts

После создания моего проекта через интерфейс командной строки моим первым шагом было сравнение файлов App.vue и main.js. Файл App.vue содержит шаблон и некоторые CSS, используемые для основного приложения. В моем приложении также был тег <script>, который добавлял кучу часто используемых компонентов, но я не думаю, что мне следовало все настраивать таким образом. Файл App.vue, созданный vue-cli, теперь включает только шаблон и немного CSS.

В файле main.js создается и отображается экземпляр Vue. В текущей версии моего приложения создание экземпляра Vue имеет синтаксис, отличный от синтаксиса, созданного в vue-cli 3.

// Old code...
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App },
});

// New code...
new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount('#app');

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

Основное отличие здесь - включение функции рендеринга, монтируемой на #app, вместо присоединения App компонента и шаблона к элементу. При сравнении Vue с React я был сбит с толку тем, что думал, что вы можете использовать шаблоны только во Vue, а функции рендеринга принадлежат React. Однако у вас есть выбор использовать функции рендеринга, а также шаблоны в приложении Vue. Мне нужно будет прочитать больше документации по функциям рендеринга и JSX во Vue, но я знаю, что у вас есть возможность использовать оба варианта, хотя в большинстве случаев вы захотите придерживаться шаблонов.

import './registerServiceWorker';

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

TypeScript и декораторы

Вы заметите, что я использовал расширение JavaScript для файла main.js, потому что я хотел отразить старую версию своего приложения. Поскольку я выбрал подключаемый модуль TypeScript при создании новой версии приложения, все «файлы JS» вместо этого используют расширение TypeScript .ts. Насколько я могу судить, TypeScript не используется в файле main.js, но я заметил, что он используется во всех других файлах TypeScript (TS). Все мои предыдущие файлы JS нужно будет преобразовать в файлы TS, и вы можете посмотреть HelloWorld.vue, чтобы увидеть пример синтаксиса аннотаций некоторых типов TS, а также способы использования декораторов.

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
  @Prop() private msg!: string;
}
</script>

В объявлении переменнойprivate msg!: string; вы можете видеть, что переменная msg должна иметь тип string и не может содержать нулевое или неопределенное значение. Восклицательный знак, называемый оператором ненулевого утверждения, сообщает компилятору, что переменная не может быть нулевой или неопределенной, поэтому вам не нужно проверять, является ли значение истинным, прежде чем пытаться получить к нему доступ. По сути, это синтаксический сахар, но он делает ваш код более читабельным, ИМХО.

Шаблон проектирования Decorator используется для динамического добавления поведения к объекту, не влияя на какое-либо другое поведение в классе. Вы можете думать об этом шаблоне проектирования как о функции, заключающей в себе другую функцию, но добавляющей дополнительное поведение к исходной функции при ее вызове. В этом коде использование @Prop() позволяет сократить синтаксис, необходимый для объявления свойства, а также добавить поддержку TS для проверки типов. Я предполагаю, что обычный литерал объекта, который я использовал для объявления свойств и их типов, не позволяет TS выводить ту же информацию.

Я не знаком с декораторами в JS / TS или шаблоном проектирования, поэтому вам следует прочитать этот пост в блоге о декораторах в JS, этот пост в блоге, объявляющий о лучшей поддержке TypeScript в Vue и определение шаблона Decorator. Узнать больше. Декораторов сейчас нет в спецификации JS, но Babel позаботится о преобразовании вашего кода во время компиляции, чтобы вы могли использовать их сегодня.

Эти изменения были самым большим, что я заметил с первого взгляда на то, что vue-cli 3 сгенерировал для новой версии моего приложения. Я также заметил, что файлов было меньше, и из-за этого изменения стало легче ориентироваться в кодовой базе. Не знаю, как им это удалось, но молодец!

Я буду больше писать о фактическом преобразовании / обновлении кодовой базы по мере того, как буду заниматься этим процессом. Я надеюсь, что вы хорошо представляете, как я пришел к изучению Vue, и что вам не нужно начинать с причудливого генератора CLI, чтобы понять основные части фреймворка. Мой код был не так хорош, когда я только начал работать над приложением, но, когда я облажался, я смог сравнить свои ошибки с «правильным способом работы», который я позже увидел при использовании шаблонного проекта Webpack, а теперь и при использовании vue- cli 3.