Nuxt.js is a lightweight application framework based on vue.js, which can be used to create server rendering (SSR) applications and can also act as a static site engine to generate static site applications

According to their own in this aspect of a road to go to the black, touch rolling belt climb tram pit experience, next I will give you from the following aspects or in the future contact with this knowledge of the code friends for a full range of explanation and analysis.

  1. background
  2. Overview of the NUXT framework
  3. Baidu spider crawler mechanism
  4. A Preliminary Study on NUXT (Development Environment Construction)
  5. Deep NuxT SSR (Server rendering)
  6. Multi-environment configuration (development, test, production)
  7. Nginx reverse proxy
  8. Pm2 daemon node configuration
  9. Server-side Docker container deployment front-end engineering
  10. conclusion
background

Recently due to the company’s business needs, the mall website to do SEO optimization. Because the front end of the first version is written with pure VUE, webpack integrated by VUE-CLI and code compression processing to generate a string of STATIC JS files. Because baidu spider cannot carry on to the pure JS web page to crawl to collect. So not conducive to the site’s ranking. Nuxt is a vUE based SSR framework created by the VUE team, which is simple and easy to use, avoiding the front-end siege of the lioness to build their own node.js services. However, we initially adopted the static deployment of NUxt, Nuxt generate, which could solve part of the requirements. However, after each update, the front-end had to manually execute the command packaging. And through baidu spider climb trend chart shows this way is not ideal. Finally, we still use nuXT on the original basis of the second way to do SSR processing, online after baidu spider climb trend chart shows a great degree of improvement, conducive to SEO, and the official website is baidu included pages also gradually increased. That’s the end of it.

Overview of the NUXT framework

As a framework, NUXT integrates vuE2, VUE-Route, VUEX, VUE SSR, VUE-meta and other components/frameworks. Nuxt framework provides two deployment modes: 1. Static deployment (pre-render) — via the nuxt generate command. This command statically transforms each route into the corresponding HTML file according to the route configuration of the application. 2. SSR deployment — Build a Web service through nuxt build and then start a Web service through nuxt start. The main method is asyncData/ FETCH. This allows us to get or process data asynchronously 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, the first parameter is set to the context object of the current page. You can use the asyncData method to fetch data. Nuxt.js returns the data returned by the asyncData component data method to the current component.

Note: Due toasyncDataMethods are called before the component is initialized, so there is no way to refer to the component instance object through this within the method.

The FETCH method is used to populate the application’s store data before rendering the page, similar to the asyncData method except that it does not set the component’s data.

If the fetch method is set for a page component, it will be called before each load of the component (before the server or switch to the destination route). The first parameter of the FETCH method is the context object of the page component. We can use the FETCH method to fetch data to populate the application’s state tree. To make the fetch process asynchronous, you need to return a Promise, and nuxt.js waits for that Promise to complete before rendering the component.

Warning: You cannot use this internally to fetch a component instance; fetch is called before the component is initializedCopy the code

Probably understand these knowledge can do SSR work, routing environment configuration can go to nuXT Chinese official website

Baidu spider crawler mechanism

Baidu spider is baidu search engine of an automated program, it will continue to visit the collection of web pages on the Internet, articles, videos, etc., through the capture of links to include the site, calculate the weight of the site and ranking. Static websites such as pure HTML are friendly to Baidu Spider, and Baidu Spider will hardly climb js dynamic websites, such as websites built by Vue/React and compressed by webpack/gulp and other construction tools. Baidu spider crawl site is from the main station began to climb, according to the site exposed in the chain in turn to deep climb. The setting of meta, website TDK optimization, website structure optimization, external chain, original article also play a great role in SEO, but this paper is mainly from the technical level, it is mainly for the processing of internal chain of the website and based on vUE and other current technology flow to do SSR processing.

A Preliminary Study on NUXT (Development Environment Construction)

The installation

I use the scaffolding creat-NuxT-app created by the Nuxt. js team to build here.

NPX (NPM v5.2.0+) node (v4.0+)Copy the code

My development environment NPM v5.5.1 node v8.9.1 win10 enter the following command in terminal

npx create-nuxt-app nuxt-demo
Copy the code

And then you’ll see

When executing a command

npm run dev
Copy the code

When you see the picture below congratulations on successfully building the projectWhen you interact with the back end, in order to solve cross-domain problems, this side needs to passproxyUse of localThe node serverDo a reverse proxy innuxt.config.jsIn the configuration

Module. exports= {modules: ['@nuxtjs/axios'], axios: {proxy: true, // enable proxy credentials: true}, proxy: [['/API, {target: 'http://example.com/api', / / (backend request address) changeOrigin: true, pathRewrite: {' ^ / API ':'}}]]}Copy the code

Attached are nuxt.config.js and package.json that we just built

// nuxt.config.js

module.exports = {
  mode: 'universal',
  /*
  ** Headers of the page
  */
  head: {
    title: process.env.npm_package_name || '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  /*
  ** Customize the progress-bar color
  */
  loading: { color: '#fff' },
  /*
  ** Global CSS
  */
  css: [
    'element-ui/lib/theme-chalk/index.css'
  ],
  /*
  ** Plugins to load before mounting the App
  */
  plugins: [
    '@/plugins/element-ui'
  ],
  /*
  ** Nuxt.js dev-modules
  */
  buildModules: [
    // Doc: https://github.com/nuxt-community/eslint-module
    '@nuxtjs/eslint-module',
  ],
  /*
  ** Nuxt.js modules
  */
  modules: [
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    '@nuxtjs/pwa',
    // Doc: https://github.com/nuxt-community/dotenv-module
    '@nuxtjs/dotenv',
  ],
  /*
  ** Axios module configuration
  ** See https://axios.nuxtjs.org/options
  */
  axios: {
  },
  /*
  ** Build configuration
  */
  build: {
    transpile: [/^element-ui/],
    /*
    ** You can extend webpack config here
    */
    extend (config, ctx) {
    }
  }
}

Copy the code
//package.json {"name": "nuxt-demo", "version": "1.0.0", "description": "for a nuxt demo about SSR ", "author": "kevin xie", "private": true, "scripts": { "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server", "build": "nuxt build", "start": "cross-env NODE_ENV=production node server/index.js", "generate": "nuxt generate", "lint": "Eslint - ext js, vue - ignore - path. Gitignore.", "test", "jest"}, "dependencies" : {" nuxt ":" ^ 2.0.0 ", "cross - env" : "^ 5.2.0" and "express", "^ 4.16.4", "element - UI" : "^ version 2.4.11", "@ nuxtjs/axios" : "^ 5.3.6", "@ nuxtjs/pwa" : "^ 3.0.0-0", "@ nuxtjs/dotenv" : "^ 1.4.0"}, "devDependencies" : {" nodemon ":" ^ 1.18.9 ", "@ nuxtjs/eslint - config" : "^ 2.0.0," "@ nuxtjs/eslint - module", "^ 1.0.0", "Babel - eslint" : "^ 10.0.1", "eslint" : "^ 6.1.0", "eslint - plugin - nuxt" : "> = 0.4.2," "@ vue/test - utils" : "^ 1.0.0 - beta. 27", "Babel - jest" : "^ 24.1.0", "jest" : "^ 24.1.0", "vue - jest" : "^ 4.0.0-0"}}Copy the code

Deep NuxT SSR (Server rendering)

If you don’t need to do SSR processing just do itnuxt generateNuxt will generate the static page for you and then execute itnuxt buildAfter packagingDist fileYou can get it up on the server, but thisseoNot very friendly but a bit better than the previous VUE build. But if you want to do SSR processing, you need to do it in a different way, which is the second way provided by NUxT. Build a Node server on the server and run directly on it. In this case, the configuration needs to be changed, and the request with the background needs to be changed, instead nuxT provides usasyncData/fetch. Since NUxT is also developed based on VUE, the lifecycle is the same, but NUxT is triggered on the server sidebeforeCreatecreatedTwo life cycles. Second, NuxT has its own server rendering process.

Nuxt.js provides several different methods to use asyncData methods. You can choose one that you are familiar with:

  1. Returns aPromise, nuxt.js will wait for thatPromiseAfter it is parsed, the component’s data is set to render the component.
  2. useasyncawait
  3. Use the callback function
Return to the Promise
export default {
  asyncData ({ params }) {
    return axios.get(`https://my-api/posts/${params.id}`)
      .then((res) => {
        return { title: res.data.title }
      })
  }
}
Copy the code
Use async or await
export default {
  async asyncData ({ params }) {
    const { data } = await axios.get(`https://my-api/posts/${params.id}`)
    return { title: data.title }
  }
}
Copy the code
Use the callback function
export default {
  asyncData ({ params }, callback) {
    axios.get(`https://my-api/posts/${params.id}`)
      .then((res) => {
        callback(null, { title: res.data.title })
      })
  }
}
Copy the code

Also note that vuex state tree is used when you need to obtain cookies or server stored sessions for login processing. There is a very useful method in the state tree called nuxtServerInit

actions: {
  nuxtServerInit ({ commit }, { req }) {
    if (req.session.user) {
      commit('user', req.session.user)
    }
  }
}
Copy the code

Multi-environment configuration (development, test, production)

Because in an engineering project, we all have the acceptance process of development, testing and production. Often we connect to different databases for testing and production, and request domains are different. Therefore, in order to facilitate development, we need to configure multiple environments. In SPA we can set the cross-env node environment variable in package.json, but in SSR this doesn’t work on the server request. Here I was looking for Google for a long time and finally got it via @nuxtjs/dotenv. Also note that @nuxtjs/axios provides environment variables API_URL to overwrite baseURL and API_URL_BROWSER to overwrite browserBaseURL, which is useful in multi-environment configurations. You can import it in nuxt.config.js and use it in module.

require('dotenv').config({path: '.env'})
module.exports={
	modules: [
		'@nuxtjs/axios',
		['@nuxtjs/dotenv', {
		   filename: process.env.NODE_ENV == 'production' ? '.env.prod' : process.env.NODE_ENV == 'test' ? '.env.test' : '.env.dev'
		}]
	]
}
Copy the code

You can also configure the relevant environment configuration files in the root directory.

.env.dev

NODE_ENV=development
API_URL_BROWSER=http://localhost:3000
API_URL=http://localhost:3000/api
Copy the code

.env.test

NODE_ENV=test
API_URL_BROWSER=http://test.example.com
API_URL=http://test.example.com/api
Copy the code

.env.prod

NODE_ENV=production
API_URL_BROWSER=https://www.example.com
API_URL=https://www.example.com/api
Copy the code

When you make cross-domain requests with AXIos, you can automatically configure baseURL for Axios based on the environment.

import axios from 'axios';
const axiosInstance = axios.create({
	timeout: 10000,
	baseURL: process.env.API_URL
})
Copy the code

You can declare a variable in the nuxT-link or a link that you want to jump to to do the same for the domain name.

export default {
	data () {
		return {
			BASE_PATH: process.env.API_URL_BROWSER
		}
	}
}
Copy the code

Nginx reverse proxy

In the build environment, I need to use Nginx as a proxy server to solve the cross domain. Because the front and back ends of our project may be deployed on different services.

Upstream nodenuxt {server 127.0.0.1:3000; #nuxt keepalive 64; } server { listen 80; server_name https://www.example.com; 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

Pm2 daemon node configuration

When we configure the above, NPM start on the server will work, but our project will always fail. In order to keep the server process permanent, we need to use pM2 to daemon the Node process. It can also be used for automatic restarts, performance monitoring, and load balancing. NPM install pm2 -g Pm2 start NPM –name “nuxt-demo” — run start //(nuxt-demo is your project name in package.json) /node_modules/nuxt/bin/nuxt when we run NPM dev, we actually use NPM to start the file. After we CD into our project directory, we can finally execute the following command to start:

pm2 start ./node_modules/nuxt/bin/nuxt.js -- start
Copy the code

This will run the project, but we can’t see the log when the project reports an error, so I’m here in the root directory by configuring pm2.config.js.

Module. exports = {apps: [{name: 'nuxt-demo',// CWD: './',// current working path #script: 'NPM ',// current working path #script:' NPM ',// './node_modules/nuxt/bin/nuxt.js',// or you can simply execute the script args: 'run start',// autorestart: true, // automatically restart error_file: 'logs/nuxt-demo-err.log',// error log out_file: 'logs/nuxt-demo-out.log', // Normal run log exec_mode: Min_uptime: '60s',// Application startup mode, supporting fork and cluster mode min_uptime: '60s',// Application startup mode is considered abnormal when the application runs less than the time restart_delay: '60s',// Restart delay instances: 4,// Start 4 instances, only in cluster mode, for load balancing watch: true,// Monitor directory changes, once changes, automatically restart watch: ['.nuxt', 'nuxt.config.js'],// Monitor watch_delay: 1000,// Monitor delay ignore_watch: ['node_modules'],// exclude watch_options from monitor directory: {// Listen configuration 'followSymlinks': false, 'usePolling': true}}]}Copy the code

Here I refer to this configuration file in package.json. Just execute the command in the server. (If an error occurs, you may need to install Babel translation, which is compatible with IE.

npm install babel-cli babel-core babel-preset-es2015 --save-dev
Copy the code
{
	"scripts": {
		"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server --exec babel-node",
		"build": "nuxt build",
		"start:test": "cross-env NODE_ENV=test node server/index.js pm2 start pm2.config.js --exec babel-node",
		"start:prod": "cross-env NODE_ENV=production node server/index.js pm2 start pm2.config.js --exec babel-node",
	}
}
Copy the code

Server-side Docker container deployment front-end engineering

Create a Dockerfile by referring to this article

FROM node:alpine RUN mkdir -p /usr/local/service/nuxtdemo RUN chomd -R 777 /usr/local/service/nuxtdemo WORKDIR /usr/local/service/nuxtdemo COPY nuxt_demo.tar.gz /usr/local/service/nuxtdemo RUN cd /usr/local/service/nuxtdemo && tar Gz RUN rm -rf nuxt_demo.tar.gz ENV HOST "0.0.0.0" RUN NPM config set registry https://registry.npm.taobao.org RUN npm install -g pm2 RUN npm install RUN npm run build EXPOSE 3000 CMD ["npm", "run", "start:test"] #CMD ["npm", "run", "start:prod"]Copy the code

And then build the image

docker build -t nuxt-demo
Copy the code

Start the container

docker run -dt -p 3000:3000 nuxt-demo
Copy the code
Note: after the server is deployed, 0.0.0.0:3000 access is required, so we need to configure the host number and port at the front end. I failed in package.json, but successfully configured in nuxt.config.js.Copy the code
Module. exports = {server: {host: '0.0.0.0', port: 3000}}Copy the code

conclusion

In general, in the coding world, we need to keep learning. There is no problem that cannot be solved, so just stick to it. If you don’t understand the above content, I will try my best to answer your questions. Finally, if you like this article, please pay attention to xiao Sheng and give a thumbs-up. The attached:

Records of the Great Epidemic

Ji Hai end, geng Zi spring, Jingchu epidemic, infected tens of thousands of people, the fear, lift national defense, all closed doors, no car boat road, lane empty. However, the Wolf also move, salivating and waiting, Chinese burr in the back. Lucky dragon soul not dead, wind and rain stand. Medical selfless, fearless police, people together! Politicians, doctors, soldiers, carry tripod retrograde yong war! Merchants, famous men, common people, benevolent and righteous people, neighbors offering gifts and donations, sighing mountains and rivers in foreign lands, wind and moon in the same sky, not to wear clothes at all! The strength of the almighty is of one mind; More than a month, epidemic in addition, the final victory. One hundred years later, good weather, peaceful country and peaceful people!