In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article focuses on "how to achieve SSR server rendering in vue". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to achieve SSR server rendering in vue.
What is SSR
Server-Side Rendering we call it SSR, which means server-side rendering
Refers to the page processing technology in which the HTML structure of the page is spliced by the service side, sent to the browser, and then bound to its status and events to become a fully interactive page. [related recommendation: vue.js video tutorial]
Let's first take a look at the development history of the various stages of Web3:
Traditional server rendering SSR
Apply SPA to a single page
Server rendering SSR
Traditional web development
The content of the web page is rendered on the server and transferred to the browser.
Open the page to view the source code, and the browser gets all the dom structure
Single page application SPA
Single page application excellent user experience, make it gradually become mainstream, page content is rendered by JS, this way is called client-side rendering
Open the page to view the source code, and all the browser gets is the host element # app, but no content
Server rendering SSR
SSR solution. The backend renders the complete dom structure of the first screen, and the content obtained by the front end includes the first screen and the complete spa structure. After the application is activated, it still runs in spa mode.
After looking at the front-end development, let's take a look at Vue's official explanation of SSR:
Vue.js is the framework for building client applications. By default, you can output Vue components in a browser to generate DOM and manipulate DOM. However, you can also render the same component as server-side HTML strings, send them directly to the browser, and finally "activate" these static tags into fully interoperable applications on the client side.
Server-rendered Vue.js applications can also be considered "isomorphic" or "generic" because most of the application's code can be run on the server and the client
We have come to the following conclusions from the door-to-door explanation:
Vue SSR is an improved server-side rendering on SPA
Pages rendered by Vue SSR need to be activated on the client in order to interact
The Vue SSR will consist of two parts: the first screen rendered by the server, and the interactive SPA
Second, what has been solved?
SSR mainly solves the following two problems:
Seo: the search engine crawls the HTML structure of the page first. When using ssr, the server has already generated the HTML associated with the business, which is beneficial to seo.
First screen rendering: users can see the page view without waiting for all the js of the page to be loaded (the pressure comes to the server, so you need to weigh which to render with the server and which to give to the client)
However, using SSR also has the following disadvantages:
Complexity: the complexity of the entire project
Library support, code compatibility
Performance problem
Each request is the creation of n instances, otherwise it will be contaminated and the consumption will become very large
Cache node serve and nginx to determine whether the current user has expired, and cache it if it has not expired, using the result just now.
Downgrade: monitor cpu, take up too much memory, spa, and return a single shell
The server load becomes larger, compared with the front and back end separators only need to provide static resources, the server load is greater, so it should be used with caution
So before we choose whether or not to use SSR, we need to ask ourselves these questions carefully:
Whether there are only a few pages that require SEO, and whether these can be implemented using pre-rendering (Prerender SPA Plugin)
Whether the request response logic of the first screen is complex, and whether the data return is large and slow.
Third, how to realize
For homogeneous development, we still use webpack packaging, we need to solve two problems: server-side first-screen rendering and client-side activation
Here you need to generate a server bundle file for server first screen rendering and a client bundle file for client activation
The code structure is exactly the same as the previous vue application except for two different entries
Src ├── router ├─ index.js # Route statement ├── store ├─ index.js # Global status ├── main.js # is used to create a vue instance ├── entry-client.js # client, └── entry-server.js # server is activated by static content, and content is rendered on the screen.
Routing configuration
Import Vue from "vue"; import Router from "vue-router"; Vue.use (Router) / / Export the compiler function export function createRouter () {return new Router ({mode: 'history', routes: [/ / the client does not have a compiler This should be written as the rendering function {path: "/", component: {render: h = > h ('div',' index page')}}, {path: "/ detail", component: {render: h = > h ('div',' detail page')})) }
Master file main.js
Unlike before, the master file is the factory responsible for creating vue instances, and a separate vue instance is created for each request.
Import Vue from "vue"; import App from ". / App.vue"; import {createRouter} from ". / router"; / / Export the Vue instance allocation function to create a unique instance for each request. / / to pass parameters export function createApp (context) {const router = createRouter () to the vue instance; const app = new Vue ({router, context, render: h = > h (App)}); return {app, router};}
Write server entry src/entry-server.js
Its task is to create a Vue instance and specify the first screen according to the incoming url
Import {createApp} from ". / main"; / / returns a function to receive requests up and down, and returns the created vue instance export default context = > {/ / the created Promise is returned to ensure that the route or component is ready return new Promise ((resolve, reject) = > {const {app, router} = createApp (context); / / Jump to the address router.push (context.url) of the display screen / / routing is ready, return result router.onReady (() = > {resolve (app);}, reject);});}
Write client entry entry-client.js
The client entry simply needs to create a vue instance and mount it, which is called activation
Import {createApp} from ". / main"; / / create vue and router instances const {app, router} = createApp (); / / Mount router.onReady (() = > {app.$mount ("# app");}) when routing is ready
Configure webpack
Installation dependency
Npm install webpack-node-externals lodash.merge-D
Configure vue.config.js
/ / the two plug-ins are responsible for packaging client and server const VueSSRServerPlugin = require ("vue-server-renderer/server-plugin"); const VueSSRClientPlugin = require ("vue-server-renderer/client-plugin"); const nodeExternals = require ("webpack-node-externals"); const merge = require ("lodash.merge"); / / determining the configuration item and the corresponding configuration item const TARGET_NODE = process.env.WEBPACK_TARGET = = "node" according to the environment variable; const target = TARGET_NODE? "server": "client" Module.exports = {css: {extract: false}, outputDir:'. / dist/'+target, configureWebpack: () > ({/ / point entry to the server / client component of the application entry: `. / src/entry-$ {target} .js`, / / a pair of bundle renderer provides source map support devtool: 'source-map' / / target is set to node to enable webpack to handle dynamic guides in a Node-friendly manner. / / and the `vue- loader` will be told to output the code to the server when compiling the Vue component. Target: TARGET_NODE? "node": "web", / / whether to simulate the node global variable node: TARGET_NODE? Undefined: false, output: {/ / here make "Node" export module libraryTarget: TARGET_NODE? "commonjs2": undefined}, / / https://webpack.js.org/configuration/externals/#function / / https://github.com/liady/webpack-node-externals / / externalized application depends on the module. You can make the server build faster and make it into a more compact package. Externals: TARGET_NODE? NodeExternals ({/ / do not externalize the dependency modules that webpack needs to handle. / / you can add more parts types here. For example, if the * .css original vue is not processed, / / the dependent modules that modify `global` (such as polyfill) should also be listed as whitelist: [/\ .css $/]}): undefined, optimization: {splitChunks: undefined}, / / this is a plug-in that builds the entire output of the server into a single JSON component. / / the default name of the server is `vue-ssr-client- bundle.json` / / the default name of the client is `bundle.json`. Plugins: [TARGET_NODE? New VueSSRServerPlugin (): new VueSSRClientPlugin ()}), chainWebpack: config = > {/ / cli4 item add if (TARGET_NODE) {config.optimization.delete ('splitChunks')} config.module .rule ("vue") .use ("vue-loader") .tap (options = > {merge (options) {optimizeSSR: false}) );}}
Configure scripts and install dependencies
Npm I cross-env-D
"scripts": {"build:client": "vue-cli-service build", "build:server": "cross-env WEBPACK_TARGET=node vue-cli-service build", "build": "npm run build:server & & npm run build:client"}
Perform Packaging: npm run build
Finally modify the host file / public/index.html
Document
It is the location of the server rendering entrance. Be careful not to add spaces before and after it in order to look good.
Install vuex
Npm install-S vuex
Create vuex factory function
Import Vue from 'vue'import Vuex from' vuex'Vue.use (Vuex) export function createStore () {return new Vuex.Store ({state: {count:108}, mutations: {add (state) {state.count + = 1;})}
Mount store in a main.js file
Import {createStore} from'. / store'export function createApp (context) {/ / create instance const store = createStore () const app = new Vue ({store, / / mount render: h = > h (App)}) return {app, router, store}}
The server-side rendering is a "snapshot" of the application. If the application depends on storing some asynchronous data, you need to prefetch and parse the data before you start rendering.
One-step data acquisition in store
Export function createStore () {return new Vuex.Store ({mutations: {/ / add an initialization init (state, count) {state.count = count },}, actions: {/ / add an asynchronous request count action getCount ({commit}) {return new Promise (resolve = > {setTimeout () = > {commit ("init", Math.random () * 100); resolve () }, 1000);});},});}
Data prefetch logic in component
Export default {asyncData ({store, route}) {/ / the conventional prefetch logic is written in the prefetch hook asyncData / / after action is triggered, return Promise to determine the request result return store.dispatch ("getCount");}}
Server data prefetching, entry-server.js
Import {createApp} from ". / app"; export default context = > {return new Promise ((resolve, reject) = > {/ / take out store and router instances const {app, router, store} = createApp (context); router.push (context.url); router.onReady () = > {/ / get matching routing components array const matchedComponents = router.getMatchedComponents () / / throw an exception if (! matchedComponents.length) {return reject ({code: 404}) if matches match. } / / A pair of matching routing components call the possible `if () `Promise.all (matchedComponents.map (Component = > {if (Component.asyncData) {return Component.asyncData ({store)) Route: router.currentRoute,}) }}),) .then (() = > {/ / after all prefetching hooks resolve, / / store has been populated with the required state for rendering should / / append the state to the top and bottom, and the `template` option is available when renderer / / serialize the movement to `window.__INITIAL_STATE__ `in the status, and note "HTML context.state = store.state". Resolve (app);}) .catch (reject);}, reject);});}
Store should get the status before the client mounts to the application, entry-client.js
/ / Export storeconst {app, router, store} = createApp (); / / when template is enabled, context.state will be "dynamically embedded" as a window.__INITIAL_STATE__ state into the final HTML / / store should obtain the status: if (window.__INITIAL_STATE__) {store.replaceState (window.__INITIAL_STATE__);} before the client is mounted to the should program.
Client data prefetch processing, main.js
Vue.mixin ({beforeMount () {const {asyncData} = this.$options) If (asyncData) {/ / assign the fetch data operation to promise / / in the component We can perform other tasks this.dataPromise = asyncData ({store: this.$store, route: this.$route,}) by running `data (...) `after the data is ready. }})
Modify the server startup file
/ / get the spare part path const resolve = dir = > require ('path'). Resolve (_ _ dirname, dir) / / step 1: open dist/client recording and turn off the option of downloading index licenses by default, otherwise you will not be able to route app.use (express.static (resolve ('.. / dist/client'), {index: false})) / / step 2: get a createBundleRendererconst {createBundleRenderer} = require ("vue-server-renderer") / / step 3: server package address const bundle = resolve (".. / dist/server/vue-ssr-server-bundle.json") / / step 4: create renderer const renderer = createBundleRenderer (bundle, {runInNewContext: false, / / https://ssr.vuejs.org/zh/api/#runinnewcontext template: require ('fs') .readFileSync (resolve (".. / public/index.html"), "utf8"), / / host clientManifest: require (resolve (".. / dist/client/vue-ssr-clientmanifest.json")) / / client list}) App.get ('*', async (req,res) = > {/ / set url and title two important parameters const context = {title:'ssr test', url:req.url} const html = await renderer.renderToString (context); res.send (html)}) so far, I believe you have a deeper understanding of "how to achieve SSR server rendering in vue". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.