HTML и статические ресурсы | Vue CLI
HTML
Стартовый файл
Файл public/index.html
— шаблон, который будет обрабатываться html-webpack-plugin. На этапе сборки, ссылки на все ресурсы будут внедряться автоматически. Кроме того, Vue CLI автоматически внедряет подсказки для ресурсов (preload/prefetch
), ссылки на манифест/иконки (когда используется PWA-плагин), и ссылки на ресурсы для файлов JavaScript и CSS, созданных во время сборки.
Интерполяции
Поскольку стартовый файл используется в качестве шаблона, можно использовать синтаксис шаблонов lodash для интерполяции значений в нём:
<%= VALUE %>
для неэкранированной подстановки;<%- VALUE %>
для экранированного HTML-кода;<% expression %>
для потоков управления JavaScript.
В дополнение к значениям по умолчанию, предоставляемым html-webpack-plugin
, все переменные окружения в клиентском коде также доступны напрямую. Например, чтобы использовать значение BASE_URL
:
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
См. также:
- publicPath
Preload
<link rel="preload">
— это подсказки для браузера, указывающие на ресурсы, которые необходимо загрузить в первую очередь. Запросы на такие ресурсы будут отправлены ещё на этапе загрузки страницы, до начала её рендеринга.
По умолчанию приложение Vue CLI автоматически генерирует preload-подсказки для всех файлов, которые необходимы при первоначальном рендеринге вашего приложения.
Эти подсказки внедряются @vue/preload-webpack-plugin и могут быть изменены / удалены с помощью chainWebpack
через config.plugin('preload')
.
Prefetch
<link rel="prefetch">
— это подсказки для ресурсов, которые сообщают браузеру предварительно загрузить контент, который пользователь может посетить в ближайшем будущем, пока браузер находится в режиме ожидания после загрузки страницы.
По умолчанию приложение Vue CLI автоматически генерирует prefetch-подсказки для всех JavaScript-файлов, сгенерированных для асинхронных фрагментов (в результате разделения кода с помощью динамических импортов import()
).
Эти подсказки внедряются @vue/preload-webpack-plugin и могут быть изменены / удалены с помощью chainWebpack
через config.plugin('prefetch')
.
Примечание для многостраничных конфигураций
При использовании многостраничной конфигурации имя плагина нужно изменить в соответствии со структурой prefetch-{pagename}
, например prefetch-app
.
Например:
// vue.config.js module.exports = { chainWebpack: config => { // удаляем prefetch плагин: config.plugins.delete('prefetch') // ИЛИ // изменяем его настройки: config.plugin('prefetch').tap(options => { options[0].fileBlacklist = options[0].fileBlacklist || [] options[0].fileBlacklist.push(/myasyncRoute(.)+?\.js$/) return options }) } }
Когда prefetch плагин отключён, вы можете вручную указывать необходимые фрагменты для prefetch с помощью инлайновых комментариев для webpack:
import(/* webpackPrefetch: true */ './someAsyncComponent.vue')
Webpack добавит prefetch-ссылки когда родительский фрагмент будет загружен.
Совет
Использование prefetch ссылок нагружает канал связи. Если у вас большое приложение с множеством асинхронных фрагментов (chunks) и ваши пользователи в основном используют мобильные устройства (а значит, чувствительны к использованию канала связи), вы можете пожелать отключить использование prefetch ссылок и вручную выбирать фрагменты для prefetch.
Отключение генерации index.html
При использовании Vue CLI с существующим бэкендом, вам может потребоваться отключить генерацию index.html
, чтобы сгенерированные ресурсы могли быть использованы с другим документом по умолчанию. Для этого добавьте в файл
следующее:
// vue.config.js module.exports = { // отключение хэшей в именах файлов filenameHashing: false, // удаление плагинов webpack связанных с HTML chainWebpack: config => { config.plugins.delete('html') config.plugins.delete('preload') config.plugins.delete('prefetch') } }
Однако, это не рекомендуется потому что:
- Жёстко заданные имена файлов затрудняют реализацию эффективного управления кэшированием.
- Жёстко заданные имена файлов плохо работают с разделением кода, что генерирует дополнительные файлы JavaScript с различными именами файлов.
- Жёстко заданные имена файлов не работают с современным режимом.
Вместо этого вы должны использовать опцию indexPath, чтобы указать сгенерированный HTML в качестве шаблона вашего фреймворка на стороне сервера.
Создание многостраничного приложения
Не каждое приложение должно быть одностраничным (SPA). Vue CLI поддерживает создание многостраничных приложений с помощью опции pages
в vue. config.js
. Код приложения будет эффективно переиспользоваться между его частями для оптимизации скорости загрузки.
Обработка статических ресурсов
Статические ресурсы могут обрабатываться двумя различными способами:
Импорт в JavaScript или указание ссылки на них в шаблоне/CSS с использованием относительных путей. Такие ресурсы будут обрабатываться webpack.
Расположение в каталоге
public
и добавление ссылки на них с использованием абсолютных путей. Такие ресурсы просто копируются и не обрабатываются webpack.
Импорты относительных путей
Если вы ссылаетесь на статический ресурс, используя относительный путь (должен начинаться с .
) внутри JavaScript, CSS или *.vue
файлов, то он будет добавлен в дерево зависимостей webpack. В процессе компиляции все URL ресурсов, такие как
, background: url(...)
и CSS @import
будут обрабатываться как зависимости модуля.
Например, url(./image.png)
будет преобразован в require('./image.png')
, а тег шаблона
<img src="./image.png">
будет скомпилирован в:
h('img', { attrs: { src: require('./image.png') }})
Внутри используется file-loader
для определения конечного расположения файла с хэшем версии и правильный путь относительно корня, а также
для инлайн-встраивания ресурсов, чей размер меньше 8 КБайт, чтобы уменьшить количество HTTP-запросов к серверу.
Изменить размер можно через chainWebpack. Например, чтобы установить лимит в 4 КБайт:
// vue.config.js module.exports = { chainWebpack: config => { config.module .rule('images') .set('parser', { dataUrlCondition: { maxSize: 4 * 1024 // 4KiB } }) } }
Правила преобразования URL
Если в URL абсолютный путь (например,
/images/foo.png
), он будет оставлен как есть.Если URL начинается с
.
, он будет интерпретироваться как запрос модуля относительно текущего каталога и разрешаться на основе структуры каталогов вашей файловой системы.Если URL начинается с
~
, то всё что после него будет интерпретироваться как запрос модуля. Это означает, что вы можете ссылаться на ресурсы даже внутриnode_modules
:<img src="~some-npm-package/foo.png">
Если URL начинается с
@
, то он также будет интерпретироваться как запрос модуля. Это удобно, потому что Vue CLI по умолчанию добавляет псевдоним@
для
. (только в шаблонах)
Каталог
public
Любые статические ресурсы в каталоге public
просто копируются в каталог итоговой сборки и не будут обрабатываться webpack. Вы должны ссылаться на них, используя абсолютные пути.
Обратите внимание, что мы рекомендуем импортировать ресурсы как часть дерева зависимостей модуля, чтобы они обрабатывались webpack со следующими преимуществами:
- Скрипты и стили минифицируются и объединяются, уменьшая количество сетевых запросов.
- Недостающие файлы вызывают ошибку сборки вместо ошибок 404 для пользователей.
- Имена файлов в результате будут с хэшем, поэтому не нужно беспокоиться о том, что браузеры используют старые версии из кэша.
Каталог public
предоставляется для крайних случаев, поэтому, когда вы ссылаетесь на него по абсолютному пути, необходимо учитывать, где будет опубликовано ваше приложение. Если публикуется не в корне домена, нужно указать префикс для URL-адресов в publicPath:
В
public/index.html
или других HTML-файлах, используемыхhtml-webpack-plugin
в качестве шаблонов, необходимо добавлять префикс в ссылки с помощью<%= BASE_URL %>
:В шаблонах потребуется сначала передать
BASE_URL
в компонент:data () { return { publicPath: process.env.BASE_URL } }
А затем использовать в шаблоне:
<img :src="`${publicPath}my-image. png`">
Когда использовать каталог
public
- Вам требуется файл с определённым именем в каталоге сборки.
- У вас тысячи изображений и необходимо динамически ссылаться на их пути.
- Какая-нибудь библиотека несовместима с Webpack и у вас нет другого варианта, кроме как подключения её через тег
<script>
.
Использование сценариев предварительной загрузки | Electron
Цели обучения
В этой части руководства вы узнаете, что такое скрипт предварительной загрузки и как его использовать. для безопасного предоставления привилегированных API в процесс рендеринга. Вы также узнаете, как обмениваться данными между основными процессами и процессами рендеринга с межпроцессным взаимодействием Electron коммуникационные (IPC) модули.
Что такое скрипт предварительной загрузки?
Основной процесс Electron — это среда Node.js, имеющая полный доступ к операционной системе. Помимо модулей Electron, вы также можете получить доступ к встроенным модулям Node.js, а также любые пакеты, установленные через npm. С другой стороны, процессы рендеринга запускают веб-сайты. страницы и не запускать Node.js по умолчанию из соображений безопасности.
Чтобы объединить различные типы процессов Electron, нам понадобится специальный скрипт. называется предварительной загрузкой .
Расширение средства визуализации с помощью сценария предварительной загрузки
Сценарий предварительной загрузки BrowserWindow запускается в контексте, который имеет доступ как к HTML DOM, и ограниченное подмножество API-интерфейсов Node.js и Electron.
Сценарии предварительной загрузки вводятся перед загрузкой веб-страницы в средстве визуализации, аналогично сценариям содержимого расширения Chrome. Чтобы добавить функции в ваш рендерер которые требуют привилегированного доступа, вы можете определить глобальные объекты через API контекстного моста.
Чтобы продемонстрировать эту концепцию, вы создадите сценарий предварительной загрузки, который предоставляет доступ к вашему приложению. версии Chrome, Node и Electron в средство визуализации.
Добавить новый скрипт preload.js
, который предоставляет выбранные свойства процесса Electron . версии
объект для процесса рендеринга в глобальной переменной версии
.
preload.js
const { contextBridge } = require («электрон»)contextBridge.exposeInMainWorld («версии», {
node: () => process.versions.node,
chrome: () => process.versions.chrome,
electronic: () => process.versions.electron
// мы также можем выставлять переменные, а не только функции
})
Чтобы прикрепить этот скрипт к процессу визуализации, передайте его путь в опция webPreferences.preload
в конструкторе BrowserWindow:
main.js
const { app, BrowserWindow } = require('electron')
const path = require('path')const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path. join(__dirname, 'preload.js')
}
} )win.loadFile('index.html')
}app.whenReady().then(() => {
createWindow()
})
В этот момент средство визуализации имеет доступ к глобальные версии
, поэтому давайте отобразим это
информация в окне. Доступ к этой переменной можно получить через window.versions
или просто версии
. Создайте сценарий renderer.js
, который использует документ document.getElementById
.
DOM API для замены отображаемого текста элемента HTML на info
в качестве свойства id
.
renderer.js
const information = document.getElementById('info')
information.innerText = `Это приложение использует Chrome (v${versions.chrome()}), Node.js (v${versions. node()}) и Electron (v${versions.electron()})`
Затем измените свой index.html
, добавив новый элемент с info
в качестве свойства id
,
и прикрепите скрипт renderer. js
:
index.html
http-equiv= "Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
http-equiv="X-Content-Security-Policy"
content="default-src 'self'; script-src 'self'"
/>
Привет от рендерера Electron!
Привет от Electron визуализатор!
👋
После выполнения вышеуказанных шагов ваше приложение должно выглядеть примерно так:
И код должен выглядеть так:
- main.js
- preload.js
- index.html
- renderer. js
const { app, BrowserWindow } = require('electron')
const path = require('path' )константа createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})win.loadFile('index.html')
}app.whenReady().then(() => {
createWindow()app.on('активировать', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})приложение .on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
Взаимодействие между процессами
Как мы упоминали выше, основной процесс Electron и процесс рендеринга имеют разные обязанности. и не взаимозаменяемы. Это означает, что прямой доступ к API-интерфейсам Node.js невозможен. из процесса рендеринга или объектной модели HTML-документа (DOM) из основного процесса.
Решение этой проблемы заключается в использовании модулей Electron ipcMain
и ipcRenderer
для
межпроцессное взаимодействие (IPC). Чтобы отправить сообщение с вашей веб-страницы в основной процесс,
вы можете настроить обработчик основного процесса с ipcMain.handle
и
затем предоставьте функцию, которая вызывает ipcRenderer.invoke
для запуска обработчика в вашем сценарии предварительной загрузки.
Для иллюстрации мы добавим в средство визуализации глобальную функцию с именем ping()
который вернет строку из основного процесса.
Во-первых, настройте вызов invoke
в сценарии предварительной загрузки: ) => process.versions.node,
chrome: () => process.versions.chrome,
electronic: () => process.versions.electron,
ping: () => ipcRenderer.invoke(‘ping’)
// мы также можем выставлять переменные, а не только функции
})
Обратите внимание, как мы оборачиваем вызов ipcRenderer. invoke('ping')
во вспомогательную функцию, а не
чем выставлять модуль ipcRenderer
напрямую через контекстный мост. Вы никогда не хотите
напрямую открыть весь модуль ipcRenderer
через предварительную загрузку. Это даст вашему рендереру
возможность отправлять произвольные сообщения IPC в основной процесс, что становится мощным
вектор атаки вредоносного кода.
Затем настройте прослушиватель дескриптора
в основном процессе. Делаем это до загрузка HTML-файла, чтобы обработчик был гарантированно готов до
вы отправляете вызов invoke
из средства визуализации.
main.js
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')const createWindow = () => {
const win = new BrowserWindow({
ширина: 800,
высота: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index. html')
}
app.whenReady().then(() => {
ipcMain. handle('ping', () => 'pong')
createWindow()
})
После настройки отправителя и получателя вы можете отправлять сообщения из средства визуализации
к основному процессу через канал 'ping'
, который вы только что определили.
renderer.js
const func = async () => {
const response = await window.versions.ping()
console.log(response) // выводит 'pong'
}func()
Резюме
Сценарий предварительной загрузки содержит код, который запускается перед загрузкой вашей веб-страницы в браузер
окно. Он имеет доступ как к DOM API, так и к среде Node.js и часто используется для
предоставлять привилегированные API средству визуализации через API contextBridge
.
Поскольку основные процессы и процессы рендеринга имеют очень разные обязанности, Electron приложения часто используют сценарий предварительной загрузки для настройки интерфейсов межпроцессного взаимодействия (IPC). для передачи произвольных сообщений между двумя типами процессов.
В следующей части руководства мы покажем вам ресурсы по добавлению дополнительных функциональность вашего приложения, а затем научит вас распространять ваше приложение среди пользователей.
Компонент: Preloader в кислороде | OxyExtras
Визуально создавайте предварительные загрузчики в Oxygen для скрытия вспышек нестилизованного контента (FOUC) при загрузке контента, скрытия резервных шрифтов при активации webfonts.js или для отображения всего, что вам нравится, в течение нескольких секунд, когда посетитель впервые заходит на сайт.
Короткое видео, показывающее некоторые из предустановленных стилей по умолчаниюЭлементы управления параметрами
Тип предварительного загрузчика
- Предустановки — 10 включенных анимаций предварительного загрузчика на основе CSS.
- Изображение — добавьте собственное изображение из медиатеки.
- Пользовательский — добавьте любые элементы Oxygen в предварительный загрузчик, чтобы создать свой собственный.
Размер, продолжительность анимации
Предустановки загрузчика можно стилизовать, изменив цвет, размер, а также продолжительность анимации, чтобы ускорить или замедлить анимацию. Некоторые из загрузчиков CSS имеют внутреннюю анимацию с собственными настройками скорости.
Видимость в Builder
Этот параметр предлагает быстрый способ скрыть предварительный загрузчик, пока вы работаете внутри Builder. На переднюю часть это никак не влияет.
Конфигурация
Удалять предварительный загрузчик только после
Все содержимое страницы загружено — Предварительный загрузчик будет ждать завершения загрузки всех изображений, видео, скриптов, CSS и т. д., прежде чем сделать страницу видимой. (window.onload)
Через x секунд — предварительный загрузчик будет виден только в течение установленного количества секунд.
После того, как все веб-шрифты активны — при использовании webfonts.js для шрифтов Google или Adobe Fonts предварительный загрузчик будет ждать, пока все шрифты не станут активными (когда HTML имеет класс wf-active), прежде чем сделать страницу видимой.
Эффект затухания страницы
Предварительный загрузчик также можно использовать для придания вашему сайту красивого эффекта затухания, установив для предварительного загрузчика пользовательский режим, но не добавляя никаких элементов, только белый фон. Затем установите общий переход, перейдя в «Дополнительно»> «Эффект»> «Переходы» и установив переход примерно на 1 секунду. В результате страница будет красиво исчезать, когда пользователь просматривает сайт.
Избегайте дерганности
Чтобы предустановленные анимации не были немного дергаными на некоторых iphone, лучше не добавлять фоновые цвета во внешний div самого компонента. Вместо этого придерживайтесь элемента управления цветом фона, который находится в основных настройках.