Резюме использования prerender-spa-плагина

JavaScript Puppeteer NPM Webpack

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

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

Зачем использовать prerender-spa-plugin

Есть две основные причины:

1. SEO: SEO приложений SPA относительно плохое, большинство страниц, просканированных сканером, имеют только страницы входа, но страницы входа почти не содержат контента, поэтому рейтинг поиска очень низкий.

2. Первый экран: страница входа, сгенерированная webpack, в основном имеет только один основной js, а сама страница не имеет контента, поэтому до загрузки js все, что видит пользователь, пусто. Чтобы решить эту проблему, указанная статическая страница обычно отправляется в фоновый режим, а запрос пользователя напрямую возвращает статическую страницу, так что пользователь все еще может что-то увидеть до загрузки основного js. Но с этим тоже будут проблемы.Например, если мы хотим сделать компонент Loading и поставить его на первый экран, то это очень хлопотно, а это еще и затраты на общение с фоном (на самом деле здоровяк не не хочу всегда полагаться на фон -_-). Так что, если мы можем напрямую создать хорошее впечатление над разворотной страницей, оно должно быть превосходным.

Это роль prerender-spa-plugin, он может напрямую генерировать html со статической структурой, и вы можете поместить то, что хотите отобразить на первый экран.

Установить

Выполните npm i prerender-spa-plugin, но если вы не сможете перелезть через стену, вы столкнетесь с ямой.

Подключаемый модуль prerender-spa-plugin должен полагаться на puppeteer, подключаемый модуль браузера без заголовка, разработанный Google. Этот подключаемый модуль загружает последнюю версию хрома (около 200 миллионов+), поэтому, если вы не можете пройти стена, вы получите ошибку при загрузке.

Как показано на рисунке, этот шаг можно пропустить, задав параметры, но если его пропустить, то при вызове будет выдано сообщение об ошибке.

Большинство найденных в интернете решений направлены на использование самого puppeteer, и перезапуск с указанием локального пути, но prerender-spa-плагин находится вне puppeteer, поэтому неприменим. Процесс борьбы с этой проблемой относительно долгий, я опишу его ниже Здесь я сначала расскажу об использовании после того, как это может быть через стену.

Конфигурация в вебпаке

Основная цель создается после подстановки сборки html, и поэтому необходимо внести поправки в этот документ webpack.prod.conf.js, как правило, есть инструмент создания шаблонов плагина html-webpack-plugin, если он используется в этом документе, если вы не перемещаете, потому что плагин предварительно нужен, этот плагин генерирует html в качестве шаблона, вам нужно только добавить новую конфигурацию в конфигурацию html-webpack-plugin.

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const baseWebpackConfig = require('./webpack.base.conf')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
 
const webpackConfig = merge(baseWebpackConfig, {
    plugins: [
        // vue-cli生成的配置中就已有这个了,不要动
        new HtmlWebpackPlugin({
            filename: config.build.index,
            template: 'index.html',
            inject: true,
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
            },
            chunksSortMode: 'dependency'
        }),
        
        // 在vue-cli生成的文件的基础上,只有下面这个才是我们要配置的
        new PrerenderSPAPlugin({
            // 生成文件的路径,也可以与webpakc打包的一致。
            // 下面这句话非常重要!!!
            // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
            staticDir: path.join(__dirname, '../dist'),
            
            // 对应自己的路由文件,比如index有参数,就需要写成 /index/param1。
            routes: ['/', '/index', '/skin', '/slimming', '/exercise', '/alPay', '/wxPay'],
            
            // 这个很重要,如果没有配置这段,也不会进行预编译
            renderer: new Renderer({
                inject: {
                  foo: 'bar'
                },
                headless: false,
                // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
                renderAfterDocumentEvent: 'render-event'
            })
        })
    ]
})

Пока что, если только для личного использования, то все в порядке, и после триггерного события docurender-event в js требуются предварительно отрендеренные страницы (например, vue, чтобы добавить функцию dispatchEvent, смонтированную в main.js), выполнить сборку запуска npm будет генерировать предварительно -отрендеренный html, но конкретные элементы конфигурации вы можете перейти к prerender-spa-plugin на github View https://github.com/chrisvfritz/prerender-spa-plugin

Ступай на яму

Прежде всего, наш проект должен быть интегрирован в инженерные инструменты, которые должны использовать все разработчики, поэтому нам нужно рассмотреть две только что установленные проблемы:
1. Предполагая, что все разработчики не могут обойти стену, как скачать этот плагин?
2. Не слишком ли большой 200M хром? Очевидно, было бы слишком раздуто устанавливать такой большой плагин для каждого проекта.

В ответ на эти две проблемы мы, наконец, обсудили следующие решения:
1. Превратите prerender-spa-plugin в наш собственный компонент (сокращенно myPlugin)
2. Укажите зависимость puppeteer в myPlugin на глобальный myPUppeteer (первоначально он указывал на свой собственный puppeteer)
3. Сделать компонент puppeteer, который зависит от prerender-spa-plugin, нашим собственным (для удаления сильных зависимостей, называемых myPuppeteer)
4. Я лично скачиваю последние версии хрома для разных систем на фтп компании
5. Измените адрес загрузки хрома в компоненте myPuppeteer, чтобы он указывал на ftp.
6. Добавьте сообщение об ошибке в myPlugin и предложите разработчику установить myPuppeteer глобально, если требование не удается выполнить puppeteer.

Конечный результат этой операции: нашим разработчикам нужно только один раз установить myPuppeteer глобально при первом использовании плагина, и проблем с сетью не будет.

Конечно, каждый проект по-прежнему нуждается в установке myPlugin.

Вот как это сделать в этом порядке.

Этапы реализации

шаг первый/второй

Первое, что нужно сделать, это найти, где кукловоду полагаются

1. В prerender-spa-plugin:

2. В @prerender/renderer-puppeteer:

Поэтому нам нужно заменить предложение, зависящее от puppeteer, в @prerender/renderer-puppeteer.

try{
    puppeteer = require('prerender-browser')
}catch(err){
    console.log("You are using prerender-html-plugin to generate html but no puppeteer installed");
    console.log("If you don't want this function, you can set prerender to false in marauder.config");
    console.log("If you want this function, you can run:1、npm install -g prerender-browser  2、npm link prerender-browser");
}

prerender-browser — это компонент myPuppeteer, указанный выше.

try catch должен иметь возможность выводить сообщения об ошибках в консоль во время использования.

Здесь вы можете видеть, что я предложил вам выполнить две команды узла

1. npm install -g prerender-browser

2. npm link prerender-browser

Это включает ссылку на глобальный пакет:
Когда я установил его глобально и сослался на код, я обнаружил, что он по-прежнему сообщает о неопределенных ошибках. После запроса обнаруживается, что require будет запрашивать необходимые пакеты от node_modules до глобальной переменной верхнего уровня. Если он установлен глобально, но не вступает в силу, это связано с тем, что глобальный путь node_modules не настроен в переменной среды.

Таким образом, есть много способов установить переменные среды в Интернете, но есть еще один простой способ напрямую выполнить команду node link . Команда npm link может связать пакет npm из любого места с глобальной средой выполнения, чтобы не было проблем со ссылками, которые невозможно найти.

Шаг третий/четвертый/пятый

Две переменные, DEFAULT_DOWNLOAD_HOST и downloadURLs, можно найти в файле BrowserFetcher.js puppeteer.Замените эти две переменные адресами ресурсов, к которым можно получить доступ внутри компании.

const DEFAULT_DOWNLOAD_HOST = 'http://www.fanqiangma.com';
const downloadURLs = {
  linux: '%s/chromium-browser-snapshots/Linux/chrome-linux.zip',
  mac: '%s/chromium-browser-snapshots/Mac/chrome-mac.zip',
  win32: '%s/chromium-browser-snapshots/Win32/chrome-win32.zip',
  win64: '%s/chromium-browser-snapshots/Win64/chrome-win32.zip',
};

Здесь есть еще две ямы:

1. Номер версии будет указан в адресе загрузки кода BrowserFetcher.js, например:

const url = util.format(downloadURLs[this._platform], this._downloadHost,revision);

Редакция представляет номер версии. Этот номер версии читается от Public Package.json. Этот параметр используется для сращивания загруженного URL, а также используется для указания адреса выполнения Chromium. Здесь нам нужно только изменить адрес загрузки, поэтому я удалил параметр редакции из URL-адреса, который должен быть разделен с номерами версий в коде, в противном случае это подскажет, что загрузка не может быть загружена.

2. Даже если его можно будет загрузить во время установки, он сообщит об ошибке, что экземпляр puppeteer не может быть закрыт во время выполнения. Глядя на код, обнаруживается, что puppeteer должен указать адрес установки хрома при запуске (функция запуска), и здесь также нужен параметр ревизии выше, а функция запуска в Puppeteer.js изменена.

  static launch(options) {
    options.executablePath = this.executablePath('revision');
    return Launcher.launch(options);
  }

Код здесь довольно запутанный, и я не очень его понимаю.Почему я просто изменил адрес загрузки, но не указал автоматически каталог запуска?Кто заинтересован, может изучить его.

СОВЕТЫ:

Есть две небольшие проблемы при извлечении и публикации компонентов:
1. После разделения компонентов на свои компоненты некоторые зависимости нужно добавить в package.json вручную, можно добавлять по одной согласно подсказкам.
2. Столкнулся с очень идиотской ошибкой, когда npm выпускал компоненты.Во-первых, Taobao source не может публиковать компоненты.Его надо заменить на npm source,но большинство npm исходников которые я нашел в интернете на тот момент были http:// www.npmjs.org. С этой зависимостью установки исходного кода проблем не возникнет, но если вы хотите его опубликовать, он должен быть https://registry.npmjs.org, иначе будет сообщено об ошибке. Меня это очень беспокоило, я поначалу никогда не сомневался в правильности источника npm, и действительно была проблема, когда Windows использовала npm для отправки пакетов. . . . .

конец

На этом вся работа завершена, и после тестирования наша небольшая группа партнеров с удовольствием генерирует статические страницы.

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

Справочная статья:
1,Решение для сбоя установки puppeteer
2,Проект Vue занимается поисковой оптимизацией (предварительный рендеринг prerender-spa-plugin)