preface

Recently, I want to learn something new in my spare time, so I began to contact server side rendering (SSR), spent a week to learn and combat, and then in the weekend high imitation nuggets of a SSR Demo project.

Nuxt is a smooth out of the box technology stack. The whole project integrates VUE + Nuxt + AXIos + vuex + VUE-Router (Nuxt comes with vuex and VuE-Router).

The project currently implements the following functions

  • Server-side rendering

  • Static page deployment

  • The nuggets home page

  • Nuggets recommendation list

  • Scrolling paging load

  • Different terminal layout ADAPTS

Full project address: NuxT-SSR-Demo

Front-end AC group: 731175396

First, the effect drawing

1, the PC

2. Mobile terminal

After looking at the finished renderings, let’s start our actual combat tour

Ii. Actual combat of the project

Before a project starts, I like to put up an empty shelf. So here’s the old rule. Let’s take everyone and build the shell of the project.

1. Use the Starter template

For project initialization, I use the starter template provided on the Nuxt website directly

#Install the vue - cli
npm install -g vue-cli
#Initialize the project
vue init nuxt-community/starter-template nuxt-ssr-demo
#Install dependencies
cd nuxt-ssr-demo
npm install # Or yarn install
#Start a local service
npm run dev
Copy the code

Visit http://localhost:3000 and now let’s take a look at the initialized project directory

├ ─ ─ assets CSS, ├─ Components Related ├─ Layouts Route Layout ├─ Middleware ├─ Pages Route Page ├─ Static Route Resources ├─ Pages Route Page ├─ Store Vuex Related ├─ Nuxt.config.js NuxT related Configuration ├─ Package. json dependency Related ├─ readme.md projectCopy the code

If you have been in touch with VUE, you may wonder why there are no files related to router routing. Don’t panic, Nuxt will automatically parse the files under Pages into routes for you. So in the next development, remember not to add files under Pages, each vue file under Pages is a route.

2. Introduce Axios

I. Install dependencies

npm i axios -S
Copy the code

Ii. Encapsulation axios

In order to facilitate development later in the project, it is necessary to have a layer of encapsulation for AXIos, which is a good habit to keep in mind.

Create a service directory under the root directory and create config.js and index.js files under it. The following code is for reference only. If your project needs to do some additional configuration, you can extend it by yourself

In config.js, write:

import http from 'http'
import https from 'https'

export default {
  // Custom request headers
  headers: {
    post: {
      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    'X-Requested-With': 'XMLHttpRequest'
  },
  // Set timeout
  timeout: 10000.// Whether to carry Token across domains
  withCredentials: true.// Response data format json/blob /document/arrayBuffer/text/stream
  responseType: 'json'./ / for the node. Js
  httpAgent: new http.Agent({
    keepAlive: true
  }),
  httpsAgent: new https.Agent({
    keepAlive: true})}Copy the code

In index.js, write:

import axios from 'axios'
import qs from 'qs'
import config from './config'

const service = axios.create(config)

// Serialize the POST pass parameter
service.interceptors.request.use(
  config= > {
    if (config.method === 'post') config.data = qs.stringify(config.data)
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
// Return result processing
service.interceptors.response.use(
  res= > {
    return res.data
  },
  error => {
    return Promise.reject(error)
  }
)

export default {
  / / post method
  post (url, data) {
    console.log('post request url', url)
    return service({
      method: 'post',
      url,
      params: data
    })
  },
  / / get methods
  get (url, data) {
    console.log('get request url', url)
    return service({
      method: 'get',
      url,
      params: data
    })
  },
  / / delete method
  delete (url, data) {
    console.log('delete request url', url)
    return service({
      methods: 'delete',
      url,
      params: data
    })
  }
}
Copy the code

Iii. Cross-domain processing

Those of you who have used VUE know that for cross-domain projects, VUE-CLI encapsulates the proxy option in WebPack. What it exposes is an option called proxyTable, which is a combination of Proxy in Webpack and its tripartite plug-in http-proxy-Middleware.

Unfortunately, Nuxt does not have a proxyTable configuration item for cross-domain configuration. Fortunately, in Nuxt you can handle cross-domains directly by configuring HTTP-proxy-Middleware. Fortunately, Nuxt officially provides two packages to handle axios cross-domain issues.

  • @nuxtjs/axios
  • @nuxtjs/proxy

First, install

npm i @nuxtjs/axios @nuxtjs/proxy -D
Copy the code

Then configure it in nuxt.config.js

modules: [
  '@nuxtjs/axios'].axios: {
  proxy: true
},
proxy: {
  '/api': {
    target: 'xxx.target.com'.pathRewrite: { '^/api': ' '}}}Copy the code

It’s important to note that since it’s server-side rendering, we always have to know whether the current address is part of a route jump or part of an AXIOS request. So we need to write the following judgment in service/index.js

// Determine whether it is a route jump or an AXIOS request
if (process.server) {
  config.baseURL = `http://${process.env.HOST || 'localhost'}:${process.env.PORT || 3000}`
}
Copy the code

Then you can safely use your AXIos to make cross-domain requests

3. Manage VUEX

Let’s take a look at some of the files we need in our Store directory

├─ actions.js Axios request Related ├─ index.js main entry file ├── simulation.js State operation Related ├─ state.js initial state relatedCopy the code

Let’s take a look at the contents of each file

i. actions.js

import request from '~/service'

const api = '/api'

export const banner = async (store, params) => {
  return await request.get(`${api}/v1/get_banner`, params)
}
Copy the code

ii. state.js

export default {
  counter: 1.isPhone: false
}
Copy the code

iii. mutations.js

export function INCREMENT (state) {
  state.counter++
}

export function PCORPHONE (state, bool) {
  state.isPhone = bool
}
Copy the code

iv. index.js

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import * as mutations from './mutations'
import * as actions from './actions'

Vue.use(Vuex)

const store = (a)= > new Vuex.Store({
  state,
  mutations,
  actions
})

export default store
Copy the code

Then you can use it on the page

<template>
  <div class="page">
    <button @click="handleClick">{{ counter }}</button>
    <p>{{ banner.name }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  async asyncData ({ store, error }) {
    // Perform batch processing on AXIos
    let [ res ] = await Promise.all([
      store.dispatch('banner')
    ]).catch((e) = > {
      error({ statusCode: 404.message: 'Post not found'})})return {
      banner: res.banner
    }
  },
  computed: {
    ...mapState({
      counter: state= > state.counter
    })
  },
  methods: {
    handleClick () {
      this.$store.commit('INCREMENT')}}}</script>
Copy the code

4. Global component management

Nuxt’s project, unlike vUE’s, provides a main entry file for configuring global components. However, it is easy to do this. All you need to do is to write the configuration introduced by the component into the plugins directory according to the Nuxt specification

For example, if I wanted to introduce the tripartite component library, element-ui.js, I would simply create a new file in the plugins directory and write

import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI)
Copy the code

It is then introduced in the nuxt.config.js file

plugins: [
  '~/plugins/element-ui'
]
Copy the code

Finally, you can use components from the Element-UI component library in your projects.

Of course, if you want to configure your own local global components, the same is true. Create a new js file in the plugins directory, import your file, and then import it in the nuxt.config.js file.

5. Global style management

Unlike component management, the CSS must be stored in the assets directory. For example, now I need a main. CSS file to dynamically toggle the route jump.

First, you need to write the reset style in assets/main.css

.page-enter-active..page-leave-active {
  transition: opacity .2s;
}

.page-enter..page-leave-active {
  opacity: 0;
}
Copy the code

Then, you can just import in nuxt.config.js

css: [
  '~/assets/stylus/main.styl'
]
Copy the code

For more uses of Nuxt, I will not introduce one, please refer to: nuxt.js documentation official website

Then about the specific development of the project, is also common, here I will not expand on the description. If you want to find out, go to Github. If you have any questions, you can add the old driver group 731175396 and ask me in the group.

In the next section, I’ll talk about some of the points of project deployment

Iii. Project deployment

For those of you at this stage, make sure you have your own server. If not, feel to buy one, now Ali cloud and Tencent cloud are engaged in activities, very cheap oh ~

OK, the article continues. Before getting into the deployment tutorial, let’s take a look at a few commands provided by Nuxt

The command describe
nuxt Start a hot loaded Web server (development mode)localhost:3000
nuxt build Build applications with Webpack, compress JS and CSS resources (for distribution)
nuxt start Start a Web server in build mode (nuxt buildWill be executed first)
nuxt generate Compile the application and generate HTML files based on the route configuration (for static site deployment)

1. Static page deployment

As can be seen from the documents provided on the official website, the command used to deploy the static page is nuxt generate. During the execution, the dist directory will be generated under the root directory, which contains all the packaged files required by the static page.

One important thing to note here is that if you have an AXIos request in your project, remember to enable a local service locally, otherwise an error will be reported when executing the AXIos request during packaging. Before, we used node process to determine whether to jump or request to the runtime environment, and the packaging of requests is independent of node environment

I. use gh – pages

Here, I’m going to assume that nuxt generate will work and generate the dist directory.

For the sake of parallel development of the project, we usually ignore the package files in the.gitignore file, but our static page deployment requires all the package files in the dist directory. So here we will use gh-Pages to publish packaged files to our Git repository

#Install the gh - pages
npm i gh-pages -D
Copy the code

Then write the configuration in package.json (of course you can create a new file to publish)

"scripts": {
  "deploy": "gh-pages -d dist"
}
Copy the code

Execute NPM run deploy and your dist directory will be sent to the GH-Pages branch of your repository

Ii. Start deployment

Once the files are packed and uploaded, the first thing you need to do is connect to your server. Clone your project from the CD to the server root directory in the data/ WWW directory. Then switch to the GH-Pages branch

Next, start to configure your nginx (if you haven’t downloaded nginx yet, please do it yourself)

 server {
  The default is 80
  listen 81;
  Service name (either domain name or IP address)
  server_name 123.12.123.12;
  Server root directory
  root  /data/www/nuxt-ssr-demo;
  Main entry file
  index  index.html;
  # Reverse proxy
  location /api/ {
    proxy_passhttps://xxx.target.com/; }}Copy the code

Then restart nginx

sudo service nginx restart
Copy the code

You can then access your deployed static page at http://123.12.123.12:81

2. Server-side rendering deployment

See the above static page deployment, detailed students will ask. Static page deployment eliminates the advantage of server-side rendering.

Yes, it’s totally OJBK to do static deployment if your project is just static pages. But if requests are involved, go ahead and deploy on the server

Before you start, make sure you have the Node environment set up on your server. For those of you who do not, I recommend using NVM to install Node. Next, start deploying

I. Perform service proxy

As a first step, switch the Previous Git project under clone to the main development branch, and then modify your package.json for later convenience

"scripts": {
  "build": "npm run lint && nuxt build && npm start",
  "start": "nuxt start"
}
Copy the code

Step 2: Start the service

npm run build
Copy the code

Step 3: Configure your nginx file

Upstream can be used to configure multiple NodeJS nodes for load balancing
Keepalive sets the keepalive time. If this is not set, it may result in a large timewait
# proxy_pass Reverse proxy forward http://nodejs

upstream nodenuxt {
    server 127.0.0.1:3000; # nuxt project listens on port
    keepalive 64;
}
server {
  listen 82;
  server_name 118.25.109.133;
  
  location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Nginx-Proxy true;
    proxy_cache_bypass $http_upgrade;
    proxy_pass http://nodenuxt; # Reverse proxy}}Copy the code

Finally, restart the nginx service

sudo service nginx restart
Copy the code

Ii. Use PM2 as the process daemon

If we had followed the above steps, the server would have been disconnected frequently and our service would have been disconnected. So in order to guard our Nodejs process, I will use pm2 to guard the process

Install pM2 globally first

npm i pm2 -g
Copy the code

Then go to the project directory and execute

pm2 start npm --name "nuxt-ssr-demo" -- run build
Copy the code

Then, mom doesn’t have to worry about my NodeJS process stopping at a moment’s notice

For pm2 usage, please input pm2 –help and check by yourself

conclusion

This is the end of the article, so I want to make a little summary here. In a week of learning and actual combat, the output of a high imitation digging SSR Demo at the same time, but also stepped on some pits.

For Nuxt, in the use of the level, is relatively simple, easy to use. Compared with VUE-SSR, it greatly simplifies the configuration of development, so that developers can only think about business development, and do not worry too much about the configuration of files. Nuxt monitors changes in pages directory files and automatically generates routes, bypassing the usual configuration of routes.

However, Nuxt as a whole still needs to be improved. Currently, there are only a limited number of community-related tripartite plug-ins and relatively few references on the market.

Anyway, I hope the Nuxt community gets better and better

Finally, if you want to see the source code of the project, I will put the link here one last time

Full project address: NuxT-SSR-Demo

Front-end AC group: 731175396

Personal ready to pick up their own public number, after the weekly guarantee of a high quality good article, interested partners can pay attention to a wave.