1. Why use nuxt.js? 2. Nuxt project construction 3. Asynchronous data loading 4. Token processing logic 5. Mysql access 6Copy the code

1. Why use nuxt.js?

Before we get to nuxt.js, let’s take a look at the front-end page development process. For more than 20 years since the birth of the Web, The ratio of front-end resource allocation goes through a small amount of HTML + a small amount of CSS, a large amount of HTML + a large amount of CSS + a small amount of JavaScript, a large amount of HTML + a large amount of CSS + a large amount of JavaScript, and a small amount of HTML + a large amount of CSS + a large amount of JavaScript. And the trend of all-in-JS is becoming more and more obvious. With the support of development frameworks such as React\Vue\Angular, BOTH HTML and CSS can be written in JS, which generates CSS code and JavaScript code for rendering HTML in a browser environment. Because JavaScript started later than HTML and CSS, Web pages were originally static HTML, and CSS and JavaScript were gradually added. SEO crawler can capture information by analyzing HTML documents of websites, but it cannot support the capture of JavaScript scripts. Even in today’s popular CSR rendering schemes such as React and Vue, only Google crawler can initially simply support SPA, which needs special processing in code writing. Traditional server-side rendering SSR schemes use server-side programming languages or frame-matched HTML template engines to compile data into HTML documents, such as FreeMaker for Java and Pug for Node.js. A template engine can be thought of as a powerful string processing factory.

Nuxt.js is a commonly used server-side rendering scheme SSR. The main advantage of SSR compared with CSR is that it supports SEO (search engine optimization) and the first screen time is short. It can obtain the main content on the server and generate HTML and send it to the browser. In this process, more detailed information can be provided for SEO to capture. The SPA scheme usually returns an HTML document with only timely line code and a large number of JavaScript files to the browser side. The HTML document contains almost no important information of the page, and the page content is mainly generated by the logic in the JavaScript file and added to the DOM. On the first screen rendering, now a lot of large and medium-sized projects on the front page will request a large amount of data, SSR projects can put the first screen needs to be done the key data request on the server, in most cases the server network infrastructure is much stronger than C client browser, this can save a lot of time request, the user sees the page, is a has a key data available pages. SPA pages usually send network requests after the page is loaded, resulting in a longer blank screen and poor user experience.

However, not all front-end projects are recommended to use SSR. Due to the insufficient support capability of nuxt. js and next. js frameworks, there are still many limitations in developing front-end in SSR projects, such as life cycle and common hooks are not as rich as CSR SPA projects. However, in the projects with strong requirements for SEO and first screen rendering time, such as enterprise official website, product list and other projects, we hope that the page can be captured by search engines as much as possible and the white screen waiting time of users can be reduced as much as possible, so we can adopt SSR framework for development.

Nuxt.js is a lightweight application framework based on Vue. It can be used to create server-side rendering applications, or act as a static site engine to generate static site applications, with elegant code structure layering and hot loading features. Nuxt.js implements exhortation support out of the box, using SSR, Node.js servers to render Vue based components into HTML and transfer them to the client instead of pure javascript. Using SSR will bring a huge SEO boost, a better user experience, and more opportunities than traditional Vue SPA.

2. Nuxt.js project construction

The nuxt.js team created the scaffolding tool create-nuxt-app to build the Nuxt.js project, which can be created using the following command: Px creation-nuxt-app < project name > or YARN Create nuxt-app < project name > will let you select the integrated server framework (such as Express\Koa\Hapi), and select the required UI framework, test framework, development mode, and so on. Express init Nuxt-community/Express-template nuxt-Express we can also create nuxT project manually, Start by installing nuxt dependencies from package.json. If we use express-template to create a project, the resulting project directory looks like this:

| - server Node. Js code storage directory file directory | | - routes API interface code -- users. | js API interface code file -- index. Js core file, General configuration interface layer | - assets are placed not compile static resources such as LESS and SASS | -- - | CSS - img. | | - components common component directory - Footer vue | | -- - layouts layout file directory Default. Vue default layout (mandatory), you can also write your own layout, specify in the page to use the layout file, if not specified, Defaults to using the default layout | -- error. Vue page fault when the layout of the default display | | - middleware is used to store application middleware - routing component catalog pages, Each file will appear as a separate page | -- _id. Vue routing component files (compiled automatically generate routing / : id) | -- index. Vue routing component files (corresponding to the routing /) | - | public function plugins directory -- axios. Js | - The static static file directory, the directory will not be compiled webpack | | - store used to organize the application state of vuex tree -. Eslintrc. Js. | - gitignore | -- nuxt. Config. Js for custom configuration, Can override the default configuration | -- package. Json | -- README. MdCopy the code

The key here is the nuxt.config.js file, in which you can personalize nuxt project deployment, HTML-generated configuration items (such as title, head, CSS, plugins), package configuration options, routing configuration, environment variable configuration, and a wealth of other options.

3. Asynchronous data loading

Nuxt.js encapsulates the $HTTP and $AXIos components, making it easy to use these web request modules in the browser to request data from the background in the front page, just like a normal SPA application.

We mentioned that nuxt.js can be used in SEO. What makes nuxt.js special is that it extends Vue. Js to add a method called asyncData that allows you to asynchronously fetch or process data before setting the component’s data. The asyncData method is called before each load of the component (page component only). It can be invoked before a server or route is updated. When this method is called, HTTP and HTTP and HTTP and AXIOS components are provided in the method arguments by default, and the asyncData method can be used to fetch data, Nuxt.js returns the data returned by asyncData’s data fusion component method to the current component. This allows us to complete the first screen data request on the server side, populate the data with HTML, and send it back to the browser.

Nuxt projects can provide interface forwarding and server-side rendering only as an intermediate layer, or they can cover a full back-end provisioning service. In the official website project, our background service and nuxT application are in the same project. First, we specify the address of the background interface in the nuxt.config.js file. All interfaces starting with/API will request the server directory under the root directory:

/*
** Server Middleware
*/
serverMiddleware: {
'/api''~/server'
},
Copy the code

We have modified the server directory so that it can be a single application providing both internal and external services. The entire service is an Express application. The structure of the server directory is clearer and simpler:

| - server Node. Js code storage directory | - controllers controllers directory, the logic of the interface processing | -- users. Js user relevant controller, associated with the database table processing, Refers to the corresponding models | - middleware interface middleware, can do some permissions, cookies and other aspects of the general processing | -- check. Js. | | - layer models data directory - user js user read about table processing logic, Reference the js. | | - mysql database operation directory - db js general configuration database connection | -- SQL. Js SQL statement list, we put all the SQL statements in here, Convenient we unified audit routing directory | | - routes API interface -- index. Js routing assignment middleware | -- users. Js user related routing management, refer to the user controller and the interface middleware | -- index. Js core file, general configuration interface layerCopy the code

4. Token processing logic

Token management is required when there are functional modules such as registration and login in the system. In the nuxT project background, we can use Express-JWT just like express applications.

Express-jwt has a variety of encryption schemes, here we use RSA scheme, the public and private keys are stored in the root directory. Generally, tokens are generated after successful login and returned to the browser in the return message, which is saved by the browser and added to headers in the next interface. Express-jwt provides a ready-made interface to generate tokens:

// Note that the default Token must start with Bearer+ space
const privateKey = fs.readFileSync('rsa_private_key.pem')
const token = 'Bearer ' + jwt.sign(
  {
    user_id: user.id,
    isLogintrue
  },
  privateKey,
  {
    algorithm'RS256'})return res.send({
  code: constants.SUCCESS,
  token,
  user,
  msg'Login successful'
})
Copy the code

Token verification is processed in the server/index.js interface general logic. Express-jwt is used in the middleware of interface request, which automatically verifies the token with the public key. We can set the interface path without token resolution. If the token check passes, the interface goes to the next step. If the token check fails, an UnauthorizedError error is returned and processed.

import fs from 'fs'
import express from 'express'
import expressJwt from 'express-jwt'
const createError = require('http-errors')

// Create express instance
const app = express()
const publicKey = fs.readFileSync('rsa_public_key.pem')
app.use(expressJwt({
  secret: publicKey, // The signature key
  algorithms: ['RS256'// Set the algorithm (this is not written in the official documentation, but it will be an error if not configured)
}).unless({
  path: ['/api/users/login'.'/api/users/getcaptcha'.'/api/test'./\/api\/portal/i// A path that does not go through Token resolution
}))
// error handler
app.use(function (err, req, res, next{
  if (err.name === 'UnauthorizedError') {
    // It can be handled according to its own business logic
    return res.send({
      code'401'.msg'You are not logged in yet, please log in first'})}// set locals, only providing error in development
  res.locals.message = err.message
  res.locals.error = req.app.get('env') = = ='development' ? err : {}
  // render the error page
  res.status(err.status || 500)
  res.render('error')})module.exports = app
Copy the code

5. Add mysql

Take a look at the config-Lite gadget. By default, it reads the files under the config folder in the root directory. According to the current system environment development\production, it demotes to find the corresponding file configuration such as JS \json\node\yml\yaml, and merges with the default configuration to generate the final configuration file under the current environment. It allows us to read the current configuration without having to change the configuration we use when switching environment variables.

We can use a variety of common types of databases, express application services framework by good access capabilities. In the research institute portal website, we use the commonly used mysql database. Here, we need to use the connection tool mysql NPM package for Express access to mysql. First in config\development.js we define the database connection-related configuration

module.exports = {
  mysql: {
    // Test the server
    host'127.0.0.1'.port'3306'.user'your-database-username'.password'your-password'.database'your-database-name'.waitForConnectionstrue.connectionLimit50.queueLimit0}}Copy the code

In server\mysql\db.js, we define how to access the database. Database connection can use a single request connection, connection pool, poolCluster and other schemes. The specific API can be checked in mysql package in Github. Our example uses normal connection pooling, which the mysql NPM tool automatically closes when a connection is complete.

import mysql from 'mysql'
const config = require('config-lite') ({filename: process.env.NODE_ENV,
  config_basedir: __dirname,
  config_dir'config'
})
const pool = mysql.createPool(config.mysql)
export default pool
Copy the code

In models, we can reference a pool to perform database related operations. For example, userModels, pool.query provides a database connection pool operation method. The first parameter of the method is an SQL statement

import pool from '.. /mysql/db'
import { UserSql } from '.. /mysql/sql'

findOne (param) {
    return new Promise(function (resolve, reject{
      pool.query(UserSql.findOne, [param.username], function (error, results, fields{
        if (error) {
          console.error(error)
          reject(error)
        }
        resolve(results[0])})})}Copy the code

6. Session persistence

In config\default.js, we need to configure the parameters of the session:

module.exports = {
  portparseInt(process.env.PORT, 10) | |8001.session: {
    name'aaa'.secret'bbb'.id' '.captcha' '.cookie: {
      httpOnlytrue.securefalse.maxAge365 * 24 * 60 * 60 * 1000}}}Copy the code

In the configuration parameters, parameters related to cookies and token generation keys are declared. In the server\index.js file, we introduce the session middleware

import session from 'express-session'
app.use(session({
  name: config.session.name,
  secret: config.session.secret,
  resavefalse.captcha: config.session.captcha,
  saveUninitializedfalse.cookie: config.session.cookie
}))
Copy the code

However, session persistent storage is not implemented in this way, and session loss occurs when the project is restarted during development. We need to initialize sessionStore in server\mysql\db.js:

import mysql from 'mysql'
const config = require('config-lite') ({filename: process.env.NODE_ENV,
  config_basedir: __dirname,
  config_dir'config'
})
const session = require('express-session')
const MySQLStore = require('express-mysql-session')(session)
const pool = mysql.createPool(config.mysql)
export const sessionStore = new MySQLStore({}/* session store options */, pool)
export default pool
Copy the code

In the server\index.js file, add persistent configuration to the interface session. This will automatically add a session table to the mysql database, storing session_id, Expires, data and other information. Persistent sessions can be destroyed, cleared, or reloaded into memory if necessary.

import { sessionStore } from './mysql/db'
import session from 'express-session'
app.use(session({
  name: config.session.name,
  secret: config.session.secret,
  resavefalse.captcha: config.session.captcha,
  saveUninitializedfalse.cookie: config.session.cookie,
  store: sessionStore
}))
Copy the code

The above is the first time to use nuxt.js to do a little summary of the project, welcome your criticism