2017 был годом, когда Vue.js взорвался, React возвестил сильного конкурента, и его царствование было оспорено (на момент написания этой статьи количество звезд Vue и React на github приближалось). В этом году наша команда внедрила стек технологий Vue для более чем десяти крупномасштабных проектов и добилась хороших результатов с точки зрения эффективности разработки, производительности страницы и удобства обслуживания. Мы надеемся извлечь повторно используемые функциональные компоненты в этих проектах и использовать их для последующих проектов, чтобы уменьшить повторяющуюся разработку и повысить эффективность. колесо», основанная на Vue 2. На повестку дня поставлена библиотека компонентов мобильного пользовательского интерфейса.
Процесс разработки библиотеки компонентов в целом проходит гладко. Вот несколько вопросов и мыслей, которыми можно поделиться с вами.
Варианты строительных лесов
Несмотря на то, что в нашей команде для создания каркасов этих проектов стека технологий Vue в основном используется веб-пакет, мы все еще колебались между веб-пакетом и Rollup при выборе каркаса для библиотеки компонентов.
Rollup кажется более подходящим для разработки библиотек компонентов, он собирает все модули в одну функцию, что более эффективно в исполнении, поддерживает Tree Shaking, упаковывает только необходимый код, а выходной файл меньше (позже вебпак поддержал его ). Но после всестороннего рассмотрения мы все же выбрали webpack в качестве инструмента для упаковки. Во-первых, по плану демо-демо и страницы документа тоже находятся в этом каркасе, поэтому есть спрос на такие функции, как разбиение кода и горячая загрузка, а возможности Rollup в этом плане гораздо меньше, чем у веб-пакет. Кроме того, эта библиотека компонентов разрабатывается и поддерживается несколькими людьми, а стоимость разработки на основе существующих каркасов веб-пакетов ниже и эффективнее. Выбор веб-пакета позволяет нам больше сосредоточиться на создании колес.
Пакет
Даже если в качестве инструмента для упаковки выбран webpack, мы не хотим, чтобы сценарии использования этой библиотеки ограничивались проектами webpack.Должны поддерживаться такие сценарии, как AMD/CMD или даже прямая ссылка через теги скрипта. Для этого нам нужно установить выходной формат в файле конфигурации веб-пакета Параметр для настройки — output.libraryTarget, который имеет следующие необязательные значения:
- "var" (по умолчанию) выводится как переменная
var MyLibrary = _entry_return_ ;
- "this" выводится как свойство this
this["MyLibrary"] = _entry_return_ ;
- "окно" выводится как свойство объекта окна
window["MyLibrary"] = _entry_return_ ;
- "global" выводится как свойство глобального объекта
global["MyLibrary"] = _entry_return_ ;
- "commonjs" выводится как свойство экспорта
exports["MyLibrary"] = _entry_return_ ;
- "commonjs2" выводится как module.exports
module.exports = _entry_return_ ;
- "amd" выводит как модули AMD
- «umd» доступен для всех определений модулей, что позволяет ему работать с CommonJS/AMD/globals.
Очевидно, нам нужно установить значение output.libraryTarget в «umd», чтобы наша библиотека могла работать в различных сценариях.
Другим элементом настройки, связанным с упаковкой библиотеки, является output.umdNamedDefine.Если для параметра output.libraryTarget установлено значение umd, а для параметра output.library также задано значение true, то присваивается имя модулю AMD.
webpackConfig.output = {
path: path.resolve(__dirname, 'dist'),
publicPath:"/",
filename: '[name].js',
library: 'xxx', //模块名称
libraryTarget: 'umd', //输出格式
umdNamedDefine: true //是否把模块名作为AMD输出的命名空间
};
Библиотека компонентов Vue предоставляет только компоненты.Сам файл Vue должен быть представлен пользователем библиотеки компонентов в проекте, и библиотеку не нужно упаковывать. Таким образом, мы можем добавить Vue к внешним файлам.
externals: {
vue: 'vue'
}
Таким образом, Vue не будет упакован. Однако существует проблема, заключающаяся в том, что при обращении к Vue в виде тега скрипта в окне висит имя переменной «Vue», а не нужное нам «vue», поэтому при использовании будет сообщено об ошибке vue undefined Это.
К счастью, элемент конфигурации externals в webpack поддерживает передачу объекта, который может указывать разные имена для разных форм экспорта. Таким образом, следующий способ записи может решить эту проблему.
тип компонента
Планируемая библиотека компонентов Vue включает три типа существования: Компонент, Директива и Фильтр.
Более особенными являются компоненты класса модального всплывающего окна (Modal), такие как Dialog, Toast и так далее. На странице может быть много модальных окон, и во многих сценариях поведение пользователя вызовет только некоторые из них.Уместно ли писать все модальные окна, которые могут всплывать (особенно асинхронные и сложные по структуре) на странице? ? Является ли для многостраничных приложений громоздким и излишним писать каждую страницу или инкапсулировать еще один слой компонентов? Этот вопрос обсуждался на Zhihu.You Da (you Yuxi, автор Vue.js) сам давал советы, участвуя в обсуждении.Когда компоненты вложены в несколько слоев, Modal следует размещать в корневом компоненте, а затем в подкомпонент.Инициируется событиями. В конкретных приложениях его следует использовать таким образом, что соответствует «управляемому состоянием», за который выступает Vue. Однако в библиотеке компонентов мы все же надеемся предоставить более удобный и общий способ использования компонентов модального типа.
Ссылаясь на практику превосходных библиотек компонентов, таких как Element UI, мы подключили компонент типа Modal к Vue.prototype, сделав его методом экземпляра Vue, который можно установить один раз и вызывать глобально.
this.$dialog(options);
Поэтому типы компонентов нашей библиотеки компонентов также включают «методы экземпляра».
Область CSS компонента
Для компонента мы хотим, чтобы его CSS применялся только к элементам в текущем компоненте, поэтому мы добавляем атрибут scoped в тег стиля одностраничного файла Vue каждого компонента. После компиляции случайно сгенерированный уникальный атрибут (например, data-v-f3f3eg9) будет автоматически добавлен к HTML-тегу, а соответствующий селектор CSS также будет добавлен с одноименным селектором атрибута (например, .example[data -v-f3f3eg9]) , поэтому CSS внутри компонента ограничен.
После компиляции:
Атрибут scoped действительно может достичь цели установки области действия стиля компонента, что в основном позволяет избежать влияния стиля в компоненте на внешний вид, но он также создает другую проблему, заключающуюся в неудобстве внешнего переопределения внутреннего стиля. . Независимо от того, насколько общей является функция компонента и насколько гибок интерфейс, до тех пор, пока задействован пользовательский интерфейс, неизбежно, что он не может соответствовать всем требованиям стиля проекта, поэтому ему должно быть разрешено переопределять некоторые или даже весь стиль компонента по мере необходимости в конкретном проекте. Тем не менее, область видимости генерирует имена свойств случайным образом, чтобы усложнить переопределение стилей.
После компромисса мы удалили атрибут scoped из компонента и использовали стратегию класса, чтобы стили внутри компонента не влияли на внешний вид. Конечно, атрибут scoped не лишен смысла, он больше подходит для использования в конкретных приложениях и не лучший выбор для компонентов с высокой возможностью повторного использования.
Сборки по требованию и индивидуальные сборки
По мере продвижения проекта компонентов в библиотеке компонентов становится все больше и больше, на данный момент их более 40, а файлы после сборки становятся все больше и больше. Если приложение использует только несколько компонентов в библиотеке, нет необходимости использовать полный пакет сборки, поэтому нам нужно предоставить способ его использования по запросу. В первые дни мы позволяли пользователям устанавливать библиотеку компонентов через частный npm, а затем напрямую ссылаться на исходный код компонента в каталоге src в соответствии с потребностями самого приложения для загрузки по требованию. Этот метод имеет большие ограничения, поскольку указанный исходный код не был скомпилирован, и пользователю необходимо иметь дело с зависимостями компонентов.Работы по компиляции, такие как шаблоны ES6/SCSS/Vue, также должны быть выполнены пользователем в его собственный проект, громоздкий и подверженный ошибкам, и сложно поддерживать другие сценарии вне webpack. Мы предполагаем предоставить индивидуальный способ сборки, чтобы включить упаковку по требованию. Сначала позвольте пользователю выбрать, какие компоненты необходимы, а затем сгенерируйте персонализированный файл конфигурации на основе этой информации, а затем создайте на основе этого файла и, наконец, упакуйте и скомпилируйте только те компоненты, которые указаны пользователем.
Итак, как вы взаимодействуете с пользователями и собираете пользовательские инструкции? Более удобный способ — через Интернет, например, предоставить страницу на домашней странице проекта, позволяя пользователям выбирать компоненты в Интернете, а затем загружать созданные файлы. В соответствии с текущим позиционированием нашей библиотеки компонентов рекомендуемый способ ее использования — установка через приватный npm, поэтому сначала мы вводим кастомную сборку через интерфейс командной строки (CLI).
Пользователям нужно только выполнить команду «npm run custom» в терминале, чтобы получить список всех компонентов, выбрать необходимые компоненты с помощью клавиатуры, а затем нажать Enter, строительные леса начнут автоматически завершать оставшиеся персонализированные строительные работы.
Через несколько мгновений в каталоге dist появится сборочный пакет, содержащий только компоненты, выбранные пользователем, с гораздо меньшим размером файла, чем полная версия.
Таким образом, выбранный компонент пройдет через полный процесс построения каркаса библиотеки компонентов, автоматически обработает зависимости компонентов, скомпилирует ES6/SCSS/Vue и другие грамматики, а встроенные файлы также напрямую поддерживают теги AMD/CMD/script. и другие сценарии могут лучше удовлетворить потребности использования по запросу.
значок
Компоненты пользовательского интерфейса библиотеки компонентов неизбежно будут содержать небольшие значки, и вам необходимо найти подходящий способ обработки этих значков.
При разработке приложений некоторые картинки иногда конвертируются в кодировку Base64 и помещаются в код, что увеличит объем данных примерно на 30%, поэтому для больших картинок этот метод не подходит. Для мелких иконок абсолютный объем добавляемых данных невелик, но может уменьшить один http запрос, что тоже является схемой оптимизации. Однако библиотеки компонентов более чувствительны к объему данных, чем обычные приложения, и такой подход — не лучшее решение.
Другим классическим решением для работы с маленькими значками является CSS Sprite, но этот метод ссылки на значки, основанный на точной информации о местоположении, не так популярен в макетах на основе rem для мобильных устройств, потому что сам макет rem трудно быть точным. используется для библиотеки компонентов, это также доставляет некоторые неудобства при обращении по запросу.
Для мелких иконок больше нужна векторная схема на мобильной стороне, которая естественно подстраивается под экраны различной плотности пикселей.
В библиотеке компонентов более популярная схема ICON FONT, основанная на шрифтах CSS3 (@font-face), заключается в размещении значков в файле пользовательского шрифта. Есть много преимуществ, таких как:
- ICON имеет векторное присутствие в шрифтах и популярен на мобильных устройствах.
- Хорошая совместимость с браузерами, веб-шрифты не изобретены в CSS3 и фактически поддерживаются более ранними браузерами (включая IE6), хотя есть некоторые различия, в конце концов, есть способ быть совместимым.
- С помощью CSS можно управлять такими стилями, как цвет и прозрачность ICON, и даже можно реализовать цветовые градиенты.
Мы не выбрали решение ICON FONT, мы считаем, что решение SVG больше подходит для библиотеки мобильных компонентов:
- Хотя SVG имеет плохую совместимость в некоторых устаревших браузерах на стороне ПК, он имеет хорошую совместимость на мобильной стороне.
- ICON FONT считается текстом, поэтому некоторые браузеры сглаживают его, что может привести к менее резкому значку и снижению четкости.
- Управление стилем SVG является более гибким, чем ICON FONT, и может даже управлять цветом каждой части значка для получения цветных значков. И это невозможно для ICON FONT
- ШРИФТ ICON обычно вставляется на страницу с псевдообъектом или псевдоклассом, и на его отображение влияют «высота строки», «вертикальное выравнивание», «интервал между буквами», «интервал между словами» и шрифт. связанные свойства CSS, а также символы шрифта. Дизайн сам по себе влияет. SVG — это метка на странице, которая удобнее в управлении и имеет лучшую семантику.
- В сочетании с элементом символа может быть реализован так называемый «спрайт SVG», то есть многие значки SVG объединяются вместе, а на указанный значок ссылается идентификатор, который можно использовать повторно. Этот метод более удобен, чем CSS Sprite, потому что нет необходимости заботиться о конкретной информации о местоположении значка.
SVG Sprite не нужно собирать вручную.С помощью svg-sprite-loader из webpack можно легко реализовать динамическую генерацию SVG Sprite, а загрузка иконок по требованию — это не мечта.
Что ж, из-за нехватки места на этот раз я расскажу о многом.Чтобы получить больше контента, пожалуйста, обратите внимание на общедоступный аккаунт нашей команды «Исследование полного стека».
Расширенное чтение
- Библиотека компонентов NutUI –nutui.jd.com
- вывод веб-пакета.libraryTarget -Веб-пакет Просто .org/config как у ATI...
- умд –github.com/umdjs/umd