“This is the 16th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

pre-rendered

Typically, Vue projects are single-page projects, that is, rendered projects, with only one index.html.

The disadvantages are obvious:

  • Deploy to Nginx, need to dotry_files $uri $uri/ /index.htmlInternal redirection can be used to access pages through routing.
  • SEO is not friendly, search engine collection effect is not good.

Pre-render, on the other hand, takes the original single index.html and renders it into multiple directories, each of which has an index.html. This eliminates the need for internal redirected access routes and makes it easier for search engines to include them.

prerender-spa-plugin

The prerender-SPa-plugin was used for pre-rendering.

The main idea is to start the browser, grab the HTML after rendering, and then create a directory and save it as index.html.

Note:

  • At present, there is only Vue2. X Demo on the official website, which actually supports Vue3 (this Demo also uses Vue3).
  • Although the last release was in 2018 (a new release is expected soon), there is always maintenance and it can be used.

The installation

First, we install with NPM:

npm i prerender-spa-plugin
Copy the code

Note that the prerender-spa-plugin will take a while to install because there is a Chromium install.

This dependency, of course, is only used when packaging. So, a better way to install it would be:

npm i prerender-spa-plugin -D
Copy the code

Project reference

Now let’s go to the project reference, which is easy to append in two places:

  • App.vue
  • vue.config.js

App.vue

First, we append trigger events to app.vue:

mounted() {
  document.dispatchEvent(new Event('render-event'))}Copy the code

Add this trigger, which will automatically trigger the subsequent packaging and complete the rendering.

vue.config.js

According to the prerender-SPa-Plugin project documentation:

const path = require('path')
const PrerenderSPAPlugin = require('prerender-spa-plugin')

module.exports = {
  plugins: [...new PrerenderSPAPlugin({
      // Required - The path to the webpack-outputted app to prerender.
      staticDir: path.join(__dirname, 'dist'),
      // Required - Routes to render.
      routes: [ '/'.'/about'.'/some/deep/nested/route'],})]}Copy the code

In addition, some advanced uses need to be customized by introducing PuppeteerRenderer. So, my own vue.config.js configuration:

module. Exports = {...chainWebpack: config= > {
        if (process.env.NODE_ENV == "development") {
        ……
        }
        if (process.env.NODE_ENV == "production") {
            config.plugin("PrerenderSPAPlugin").use('prerender-spa-plugin'[{staticDir: path.join(__dirname, 'dist'),
                    routes: [
                        '/'.'/processIMG'.'/statisticsChars'.'/generatePWD'.'/calculateTheDate'.'/randomNumber'.'/textBase64'.'/curl'.'/mcstatus'.'/gh'.'/about'.'/mdv'].renderer: new PuppeteerRenderer({
                        headless: false.executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'./ / the corresponding App. Vue
                        renderAfterDocumentEvent: 'render-event',}),}]))}}Copy the code

I’m using a chain function. And the nice thing about this is that it’s easy for me to do if-else and so forth. Renderer property:

  • headless: This is ChromeheadlessProperty, often used for Debug. For more information:Google Chrome
  • executablePath: redirects the browser address; I’m redirecting to use the Chrome browser that comes with my computer. (Optional, can be directly not add, default call Chromium)
  • renderAfterDocumentEventVue document.dispatchEvent(new Event(‘render- Event ‘)));

The Routes array contains the pre-rendered route address.

Of course, for more optional parameters, you can also refer to the official documentation:

StaticDir needs to point to the compiled output folder.

Packaging project

After that, we can package the project:

npm run build
Copy the code

Package effect:

Take a look at the pre-rendered page:

Since I have components that use vue-meta, the pre-rendered files also have meta properties.

If you also want to use vue-meta components with prerender-SPa-plugin, see article: How do Vue Projects optimize meta tags using Vue-Meta components

Note that if something goes wrong, try:

# Delete the project node_modules
rm -rf node_modules
# reinstall
npm install
Copy the code

This file is ready for deployment.

Effect of deployment

Last time we went to the Nginx Web folder and modified the config file, we did not need to:

location / {
  try_files $uri $uri/ /index.html;
}
Copy the code

To implement the internal redirection. Because there’s a real directory, you can get rid of it.

However, data proxies are best implemented using Nginx. For example, development environment, data broker:

config.devServer.proxy({
        '/dataApiJava': {
            target: JavaBaseURL,
            pathRewrite: {'^/dataApiJava': ""},
            ws: true.changeOrigin: true
        },
        '/dataApiPython': {
            target: PythonBaseURL,
            pathRewrite: {'^/dataApiPython': ""},
            ws: true.changeOrigin: true
        },
        '/ghs': {
            target: GithubSpeedURL,
            pathRewrite: {'^/ghs': ""},
            ws: true.changeOrigin: true}})Copy the code

The corresponding Nginx configuration can be written as follows:

location /dataApiPython/{
      proxy_pass http://127.0.0.1:8099/;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header REMOTE-HOST $remote_addr;
      add_header X-Cache $upstream_cache_status;
}
location /dataApiJava/ {
      proxy_ssl_server_name on;
      proxy_passhttps://... .cn/; }location /ghs/ {
      proxy_ssl_server_name on;
      proxy_passhttps://... /gh/; }Copy the code

I’m going to show you three configurations, as needed.

END

At this point, our front-end pre-rendering is complete. This SEO is good. But compared with SSR, it still lacks advantages. The advantage is that it is easy to deploy and configure and the disadvantage is that it is difficult to build. If you have dozens of routes that need to be pre-rendered, prerender-SPa-plugin is not as easy to render as SSR.

Someday, I will share SSR with you. It’s really good. Dig another hole.

By the way, are you curious about the CompressionPlugin attribute in my screenshots? It’s actually gz compressed. I have an opportunity to share with you how to optimize the project using compression-webpack-plugin.