At the end of the middle of the year, I wrote a project with nuxt.js for several months and finally made some modifications to go online. It’s not easy. This article will start from why to use nuxt.js, and then discuss the problems encountered in the process of use and solutions.
The body of the
1、为什么要使Nuxt.js?
When the site needs SEO, the front-end development process is roughly divided into: will set the background template with not set the background template is divided into two kinds.
Do not set template is very troublesome, every time to write the page to the background to set, set the front end to check the style is not the original appearance, there is no change, and then to connect the interface, so often is in urging the background
Now advocate the front and back end separation, how should we achieve the front and back end separation and to achieve SEO optimization?
Thanks for creating the vue-server-renderer plugin. See the tutorial on how to use the plugin.
A brief summary of the principle of the plug-in: the need to display data requests in the Node layer to process, and then read the corresponding page configuration file output data to the page.
Why should I use nuxt.js when I have this plugin?
Because when using plug-ins to build server rendering, can not solve the file hot update caused by the entire running program crash problem
Switching from SPA form to Nuxt.js is seamless and doesn’t have any major hurdles, provided you read through the official documentation.
PS: If you can’t find the answer on Baidu, you can go to Github of nuxt.js to look at the issue, which can basically find the answer you want, this method is really very effective.
Basic applications and configurations
Create a project
For the configuration of the project, I chose:
-
Server: Koa // If you want to do something at the Node layer please choose the Node framework to be more flexible
-
UI framework: None
-
Test framework: Jest
-
Nuxt mode: Universal // This is server-side rendering, SPA mode does not have server-side rendering
-
Use integrated Axios
-
Using EsLint
The environment variable
In actual projects, there are local, test, grayscale, production and other environments. Using @nuxtjs/ Dotenv can help us conveniently manage our environment variables
npm i @nuxtjs/dotenv -s
Copy the code
Create a new file named.env, or any other name (.env is the default file to read, see official documentation for more gestures).
You need to configure the modules module in nuxt.config.js
nuxt.config.js
module.exports = { modules: [['@nuxtjs/dotenv']],} ['@nuxtjs/dotenv'],}Copy the code
Take baseUrl for example:
DEV_BASE_URL = ' http://xxx.cn' TEST_BASE_URL = ' https://xxx.cn' PROD_BASE_URL = ' https://xxx.cn'Copy the code
Package. json configure-start script command adds variable BASE
{
"scripts":{
"dev": "cross-env NODE_ENV=development BASE=dev nodemon server/index.js --watch server",
"build-test": "cross-env NODE_ENV=production BASE=test nuxt build",
"start-test": "cross-env NODE_ENV=production BASE=test node server/index.js",
"build": "cross-env NODE_ENV=production BASE=prod nuxt build",
"start": "cross-env NODE_ENV=production BASE=prod node server/index.js",
"generate": "nuxt generate"
}
}
Copy the code
nuxt.confug.js
require('dotenv').config() let baseUrl = '' switch (process.env.BASE) { case 'dev': baseUrl = process.env.DEV_BASE_URL break; case 'test': baseUrl = process.env.TEST_BASE_URL break; case 'prod': baseUrl = process.env.PROD_BASE_URL break; default: baseUrl = process.env.PROD_BASE_URL break; } module.exports = {baseUrl: baseUrl, baseUrl: baseUrl, process.env. BaseUrl}Copy the code
An asynchronous request
The official recommendation is to use @nuxtjs/axios. Although some axios apis are missing, it is strongly recommended.
It doesn’t tell you how to encapsulate all interfaces in a project. Do you want to write all interfaces in plugins for global injection? Emmm, so I used Axios again. Let me know if you do.
AsyncData method
This method is performed by server-side rendering, and the initial request for SEO page data is placed in this method.
asyncData
So to write:
export default {
asyncData ({ params }) {
return axios.get(`https://my-api/posts/${params.id}`)
.then((res) => {
return { title: res.data.title }
})
}
}
Copy the code
Hey, how the page data does not come out? Do not add async and await
export default {
async asyncData ({ params }) {
const { data } = await axios.get(`https://my-api/posts/${params.id}`)
return { title: data.title }
}
}
Copy the code
Let’s see if it’s all right.
Note that the page is rendered after asyncData, and if multiple interface requests are written without optimization, the page will be blank for a long time
In order to improve the rendering efficiency, we must shorten the request time. Here, we need the cooperation of the background students to aggregate multiple interfaces into one interface. We can also use axios.all(same with promise. Always remember to write catch to catch exceptions.
asyncData is called every time before loading the page component and is only available for such. It will be called server-side once (on the first request to the Nuxt app) and client-side when navigating to further routes. This method receives the context object as the first argument, you can use it to fetch some data and return the component data.
Plugins
The official website says:
Nuxt.js allows you to execute JS plug-ins before running vue.js applications. This is especially useful when you need to use your own libraries or third-party modules.
This means that a function or attribute value is written here and injected into a Vue instance (client), context (server) or even store(Vuex). That’s where you can use the values of the functions or properties that you wrote.
For example, add a notification plugin (same with custom global components)
After installing the plug-in, add the file vue-notifications. Js to the plugins directory:
import Vue from 'vue'
import VueNotifications from 'vue-notifications'
Vue.use(VueNotifications)
Copy the code
Plugins need to be configured in nuxt.config.js
export default {
plugins: [
{ src: '~/plugins/vue-notifications', ssr: false }
]
}
Copy the code
System plug-ins that do not support SSR are used only by browsers. You can add SSR :false to the end of the plug-in
Personally, it is not recommended to introduce a large number of plug-ins here, otherwise the package will be quite large. I mainly register global filters and global components in the project, and try to use the plug-ins on other pages wherever possible.
Error: Window or Document object not defined?
See this problem when using a date plug-in in a component and wonder: is the component script being executed on the server (node layer)? Remove it and it’s normal
The official document – “FAQ can be found in the solution.
Before the change:
import * as lang from "vuejs-datepicker/src/locale/index.js";
import Datepicker from "vuejs-datepicker";
Copy the code
After the change:
let lang = null, Datepicker = null; if (process.client) { lang = require("vuejs-datepicker/src/locale/index.js")["zh"]; Datepicker = require("vuejs-datepicker/dist/vuejs-datepicker.js")}Copy the code
CSS preprocessor
I’m using less syntax. For convenience, I don’t need to import global variables and mixins every time. I can use @nuxtjs/style-resources to do this.
The installation
npm i @nuxtjs/style-resources --save--dev
Copy the code
configuration
Nuxt. Config. Js:
module.exports = { modules: [ "@nuxtjs/style-resources" ], styleResources: { less: [". / assets/SCSS/variable. Less "/ / be sure to use relative paths, here can't use @ with ~]},}Copy the code
Permission to verify
The official website has a concept of middleware in routing, which is defined as follows:
Middleware allows you to define a custom function to run before a page or set of pages are rendered
Why does this definition look like a navigation guard
Yes, their roles are similar, but the difference is that this middleware is called both on the server side and on the client side. Middleware can also be called individually on a page
1. Nuxt.config. js: export default {... Router: {middleware: 'stats'}} 2. Pages /index.vue export default {middleware: ['auth', 'stats']}Copy the code
You can try to understand this in your project by doing the following.
Print the user-agent in your request header in the middleware/auth.js component of your project
export default function (context) {
context.userAgent = process.server ? context.req.headers : navigator.userAgent;
console.log(context.userAgent)
}
Copy the code
You will see:
– When the user enters the page for the first time, refreshes the page, or jumps to a new TAB, the userAgent prints the information on the command console
– When the current window jumps to a route, the userAgent prints the route on the browser console. In that case, we can do permission validation and route interception here
Token storage
PC sites tend to be multi-page, not SPA, so Vuex is out of the question.
To synchronize data on multiple pages, you can consider saving it in localstorage. The browser also provides relevant APIS for listening, and you can refer to the MDN document for details
window.addEventListener("storage", function(e) {
});
Copy the code
Points to note:
-
Server required, static page tests have no effect
-
Must be cognate (you can use postMessage across domains, but there are security issues)
-
A page can only receive notifications from other pages
Packaging optimization
The vendors. App. js package is over 4M, so it must be big. Let me see which little brother is doing something, open the analyze.
nuxt.config.js
Export defualt{build: {analyze: true, // Enable pack analysis}}Copy the code
NPM run build, the package will automatically open the page in the browser
The problem was obvious, and optimization began: Aliyun upload SKD dominated, dynamic loading, other plug-ins where used where added.
After all the changes:
Open the Gzip again, and you’re done
If UI framework is used in the project, it is recommended to load or use CDN as required
What about the first screen
Let’s look at the results of Performance
Rendering speed with the original background rendering basic no gap, no long white screen waiting.
To be continued
-
Exception catching, error reporting, monitoring
-
How to add typescript to your project (this is also a pit that almost didn’t work out)
-
Do some simple automated tests
-
.
conclusion
The English version of nuxt.js does have more information than the Chinese version. There are some strange translations in The Chinese version. It is better to read the English version.
The framework is more convention than configuration. If you build it with vue-server-renderer, you’ll get more clarity.
It has been nearly a year since I started learning, tested in a small scale, and then launched a large project. Some pits forget when I step on them, and I will come back to replenish them when I think of them.
Welcome to leave a message to exchange ~