Github address: github.com/OrangeXC/n2…

Inside the cable on the website link, because the link can change at any time, here is not directly to the website link.

Vue is based on THE SSR of NUxT. It mainly talks about what NUxT is and why it is used.

For the record, it is not recommended to read the last article, because it was version 0.8.0 when I wrote the blog, and now it is 1.0.0alpha4. Some changes have been made, and I recommend to read the latest NUxT document

Once you understand NUXT, you can easily read the following, which is simple and easy to understand. There are no complicated projects.

For my own learning purposes, I share this with you, because a lot of readers have asked Orange since the last article how to develop and deploy to the server.

Let’s get down to business

Environment set up

Nuxt-related scaffolding has been integrated into vuE-CLI, providing starter, Express, KOA, and AdonuxT

Here we use KOA2 (scaffolding will ask to use KOA1 or KOA2)

vue init nuxt/koa <project-name> cd <project-name> # move to your project npm install # or yarn install*[see note below]  npm run devCopy the code

If you have a bug, don’t hesitate to upgrade node to the latest version.

After the project runs, there is a simple outline with two pages, Index and About.

v2ex API

When writing a three-party API project, we first look at what apis are supported to determine how we should present the page.

Take a look at the official API documentation

This document is very detailed, but it only provides 4 apis, which is far from enough for us. Where does the API of this site come from

Github is a great site, and I found a file for the project: github.com/ochapman/v2…

It doesn’t matter if you don’t know go. I’m also not familiar with GO, but if you read it, you’ll find more apis than the official documentation.

This project takes the (hidden) API from this file

  • Hot topic
  • The latest topics
  • The node list
  • Node information
  • Topic details
  • Commentary on
  • The user details
  • User topic

We have implemented the front-end display of all the interfaces listed above

Routing structure

One of nuXT’s features is its directory structure for routing.

The router is determined by the Pages directory, so analyzing the interface yields the following directory structure

pages
  |
  |-- member
  |    |
  |    |-- _name.vue
  |
  |-- node
  |    |
  |    |-- _name.vue
  |
  |-- topic
  |   |
  |   |-- _id.vue
  |
  |-- index.vue
  |
  |-- new.vueCopy the code

We can clearly see our routing structure. If we are careful, we can find that params has both name and ID. Why?

V2ex provides both id and name, and any query can match the result of the url. Topic can only be queried with id, because name is not unique. When @ is a person, the comment can be directly linked to the personal details page. V2ex by default parses the link corresponding to username in the comment, so for the sake of uniformity, other places also use the name, in addition to providing invisible search. After the corresponding URL, replace it with the node or user name to search for.

component

There are only two business components that should be removed

  • Topics list
  • Comment on the list

Topic lists are in almost every list page, and comment lists are in every detail page

The basic components are muse-UI, and I like the overall design style of Material. It just happens that SSR is supported in the 2.0.3 version of Muse-UI.

Here are some issues related to the introduction of tripartite libraries

Introducing tripartite libraries

Muse-ui is recommended to use plugins for introduction because of the vue. use mount method involved

Create muse-ui.js under plugins as follows

import Vue from 'vue'
import MuseUI from 'muse-ui'
Vue.use(MuseUI)Copy the code

Then add it to nuxt.config.js

plugins: [
  { src: '~plugins/muse-ui.js', ssr: true }
]Copy the code

It is also worth noting that the Google font library needs to be introduced globally, which I inserted directly into the Link tag of the head

Link: [{rel: 'stylesheet, href:' https://fonts.googleapis.com/css?family=Roboto:300, 400500700400 italic}, {rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons' } ]Copy the code

HTTP requests use the axiOS library, which is both front and back homogeneous

Be sure to add it to the configuration file when packaging

build: {
  vendor: ['axios']
}Copy the code

An asynchronous request

Nuxt provides asyncData to request data before the page loads.

Here we use ES7 async/await to implement data requests

For example: pages/index. Vue

async asyncData () {
  try {
    const { data } = await axios.get(`https://proxy-uuptfgaypk.now.sh/topics/hot.json`)
    return {
      hotList: data
    }
  } catch (err) {
    console.error(err)
  }
}Copy the code

The hotList does not require.then operations. The hotList does not require.then operations

Need to get topic details and comments at the same time in the details page, go through two interfaces

The problem is how to request multiple resources at the same time and return when all requests are completed.

Promis + await??

No, no, no, just promis’ all method. Axios has a wrapper for it

asyncData ({ params, error }) {
  return axios.all([
    axios.get(`https://proxy-uuptfgaypk.now.sh/topics/show.json?id=${params.id}`),
    axios.get(`https://proxy-uuptfgaypk.now.sh/replies/show.json?topic_id=${params.id}`)
  ])
  .then(axios.spread(function (detail, comments) {
    return {
      detail: detail.data[0],
      comments: comments.data
    }
  }))
  .catch(error => console.log(error))
}Copy the code

This solves the problem of requesting multiple interfaces at the same time.

CORS

Cross-domain HTTP requests, which are not explained in detail here, are linked to MDN

The url of the code above is http://proxy… , why not the official https://www.v2ex.com/api

This is because the browser restricts the request for cross-domain resources. If the request is normal, an error will be reported

XMLHttpRequest cannot load https://www.v2ex.com/api/topics/latest.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:3000' is therefore not allowed access.Copy the code

Error: Access-Control-Allow-Origin does not return a header. If you open the console, it will return data, but the browser intercepts it and does not load it into the page

Another problem I encounter when playing server rendering for the first time is that I don’t get an error for the first screen refresh, but I get an error for the redirect request.

This starts from the server side rendering mechanism, the first screen request is done on the server side, there is no cross-domain problem on the server side, and the subsequent interactions and page jumps are done on the browser side, so there are similar problems. If you don’t believe me, you can console yourself to see whether the output is in the terminal console or the browser console.

There is no cross-domain request problem on the server.

Access-control-allow-origin: * in the return header, we can add access-Control-allow-origin: * in the return header

The service is actually less than ten lines of code and uses two dependencies, Express and Request

const express = require('express')
const request = require('request')
const app = express()
app.use('/', function(req, res) {
  const url = 'https://www.v2ex.com/api' + req.url
  req.pipe(request(url)).pipe(res.set('Access-Control-Allow-Origin', '*'))
})
app.listen(process.env.PORT || 3001)Copy the code

In a development environment, start the proxy service and point the URL to the local service

The above method, to be honest, is a little silly. In real projects, you can directly make the back end interface support cross-domain, of course, anyone can use your API, which is not very reasonable

Nuxt has a library for modules modules. The address is github.com/nuxt/module…

There are axiOS and proxy encapsulation, intended to solve axiOS baseUrl and proxy cross-domain restrictions, installation and configuration are very convenient, why not this time?

Good question, because there is an unknown pit, the code does not report any error, just does not take effect, can only wait for nuxT official fix the main library and plug-in bug.

The deployment of

How to deploy is the most concerned about the problem, the project is easy to write, as long as you can vUE look at the document can write.

Deployment actually officially provides two commands, packaged and run

npm run build
npm startCopy the code

You need a server with Node installed. You can install a PM2 to run the Node service

Of course like Docker, you can also use Docker to deploy

Before someone asked, saw these two things, still will not deploy, that I can do nothing, can only say, science online, tutorial a lot of.

If you just want to run your own DEMO to play, do not want to buy a server alone, also does not involve enterprise project deployment and security issues

So good! To heroku and now.sh, two providers that can run node services for free

Nuxt project how to run on these two services on the official website has written zh.nuxtjs.org/faq/heroku-…

This project is run on now.sh, which explains why the opening speed of this online link is super slow. Because we use the free service of three parties, in order to improve the utilization rate of server resources and reduce the server pressure, when no one visits the website for a period of time, the website will be automatically set as frozen

The deployment n2ex-yrgirchtae.now.sh was frozen
The deployment proxy-uuptfgaypk.now.sh was frozen
The deployment n2ex-nzkjwvytxe.now.sh was unfrozenCopy the code

This is the latest report of my console. When someone accesses it, it will switch to unfrozen. Calculated that the default frozen time is 15 minutes after no access.

I wonder if Heroku has a similar problem

In the future

This project will continue to be updated and new functions will be gradually added. If you are interested, you can mention issue or directly mention PR to me.

conclusion

From the project analysis to the development and deployment, and so a nuxt project completed, the progressive development of the pit is also as the project into them, the project is very simple, no use vuex, write here, still aren’t recommended for further use, but highly recommend play, regardless of the SSR complicated side, with a very cool.