От автора: почти каждое современное веб-приложение использует какую-то зависимость, это даже не считая предпочтительного JavaScript-фреймворка. Хотя большинство зависимостей доступно через NPM, многие из них также предоставляют ссылку на версию CDN (Content Delivery Network), так что она может быть включена в любой проект без дополнительных усилий или этапов сборки.
Но есть также немало популярных сторонних библиотек, которые не предоставляют пакет NPM и полностью полагаются на реализацию через тег script. Типичными примерами являются интеграция электронных рассылок, контактные формы и Stripe SDK для обработки платежей.
Наличие только CDN-ссылки дает некоторые преимущества, такие как возможность безпроблемного обновления авторами без необходимости для разработчиков обновлять свое программное обеспечение, но также имеет свои недостатки, особенно при работе с современными средами JavaScript.
Интеграция, особенно когда это требуется только на одной странице, становится более сложной. Кроме того, разработчикам приходится иметь дело с асинхронной загрузкой скриптов.
Давайте посмотрим, как мы можем добавить такие сторонние зависимости в проект на Nuxt.js!
Загрузка в Nuxt.js сторонних скриптов глобально
С Nuxt.js загрузка сторонних скриптов является простой задачей, когда они нужны везде. Единственное, что нужно сделать, это добавить соответствующую ссылку в объект head nuxt.config.js проекта, и vue-meta сделает всю тяжелую работу.
1 2 3 4 5 6 7 8 9 |
// nuxt.config.js export default { head: { title: 'My awesome project', // Other meta information script: [ { hid: 'stripe', src: '//js.stripe.com/v3/', defer: true } ] } } |
Это откладывает выполнение скрипта, но загружает его на каждой странице, что не подходит, если вам нужны только определенные страницы, например страница оплаты.
Добавление сторонних скриптов на отдельные страницы
Но благодаря Nuxt и vue-meta, вы также можете включить скрипт в компоненты страницы, которые будут загружать его только на те страницы, где вы добавили скрипт.
Ключевым элементом здесь является функция head в компонентах страницы, которая работает аналогично объекту в nuxt.config.js:
1 2 3 4 5 6 7 8 9 10 11 |
// /pages/payment-page.vue export default { head() { return { title: 'Payment Page - My awesome project', // Other meta information script: [ { hid: 'stripe', src: '', defer: true } ] } } } |
Это выглядит очень похоже на то, что мы делали раньше, но это не окончательное решение.
Проблема
Как объясняется во введении, разработчикам приходится иметь дело с двумя состояниями, касающимися стороннего скрипта, который загружается таким образом: до его загрузки и когда он доступен.
При использовании Nuxt в режиме SSR первоначальный запрос к странице (где запускается SSR ) не будет иметь первого состояния. Если после первого запроса вы перейдете на страницу, содержащую сторонний скрипт, разработчики должны обработать дополнительное состояние, потому что даже хук жизненного цикла mounted может быть выполнен до загрузки скрипта.
В прошлом встречались некоторые проблемы, особенно, когда ваш код зависел от API стороннего скрипта, как это имеет место при использовании Stripe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<template> <div> <!-- How do I know when Strip is ready? --> <SomeComponentDependingOnStripe/> </div> </template> <script> // /pages/payment-page.vue export default { head () { return { title: 'Payment Page - My awesome project', // Other meta information script: [ { hid: 'stripe', src: '<//js.stripe.com/v3/>', defer: true } ] } } } </script> |
Решение: vue-meta в помощь
Когда возникают подобные проблемы, я бы, вероятно, мог порекомендовать библиотеку, подобную VueScript2, которая самостоятельно обрабатывает загрузку асинхронных скриптов. Но это приведет к большей сложности и увеличению размера пакета. Хорошая новость заключается в том, что vue-meta сопровождающий pimlie представил опцию callback версии 2.1, которая позволяет разработчикам манипулировать атрибутами Vue после загрузки скрипта.
С помощью этой опции мы можем обеспечить, чтобы зависящая от скрипта логика была выполнена после того, как скрипт будет полностью доступен. Это также означает, что связывание сторонних скриптов, которые зависят друг от друга, теперь стало проще. Итак, давайте адаптируем наш пример выше и добавим обратный вызов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<template> <div> <SomeComponentDependingOnStripe v-if="isStripeLoaded"/> </div> </template> <script> // /pages/payment-page.vue export default { data () { return { isStripeLoaded: false } }, head () { return { title: 'Payment Page - My awesome project', script: [ { hid: 'stripe', src: '<//js.stripe.com/v3/>', defer: true, // Changed after script load callback: () => { this.isStripeLoaded = true } } ] } } } </script> |
PS: vue-meta также ввел опцию skip, позволяющая загружать эти скрипты даже условно, например, когда появляется способ оплаты.
Заключение
Загрузка сторонних скриптов с помощью Nuxt всегда была простой, когда это необходимо было глобально. С помощью vue-meta обрабатывать логику зависимости до того, как станет доступна сторонняя зависимость, теперь стало намного проще.
Убедитесь, что вы используете последнюю версию vue-meta, чтобы получить преимущества от недавно введенных функций. Если вы используете Nuxt, vue-meta включен по умолчанию и должен быть уже обновлен. Когда вы используете проект Vue, например, через vue-cli, убедитесь, что в package.json задана версия vue-meta от 2.0.0, и обновите зависимости с помощью npm update или yarn upgrade.
Я надеюсь, что вы узнали кое-что новое из этого поста. Если это так, пожалуйста, не забудьте поделиться со своими коллегами!
Автор: Alexander Lichter
Источник: //vueschool.io
Редакция: Команда webformyself.