小編給大家分享一下構(gòu)建vueSSR項(xiàng)目之如何配置node以及vue-cli3,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
公司主營(yíng)業(yè)務(wù):成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。成都創(chuàng)新互聯(lián)推出博山免費(fèi)做網(wǎng)站回饋大家。
前言
服務(wù)端部分做完,再去做vuex的部分,這樣就會(huì)很清晰。
vue ssr是分兩個(gè)端,一個(gè)是客戶端,一個(gè)是服務(wù)端。
所以要做兩個(gè)cli3的配置。
那么下面就直接開始做吧。
修改package.json的命令
//package.json :client代表客戶端 :server代表服務(wù)端 //使用VUE_NODE來(lái)作為運(yùn)行環(huán)境是node的標(biāo)識(shí) //cli3內(nèi)置 命令 --no-clean 不會(huì)清除dist文件 "scripts": { "serve:client": " vue-cli-service serve", "build":"npm run build:server -- --silent && npm run build:client -- --no-clean --silent", "build:client": "vue-cli-service build", "build:server": "cross-env VUE_NODE=node vue-cli-service build", "start:server": "cross-env NODE_ENV=production nodemon nodeScript/index" }
修改vue.config.js配置
添加完相關(guān)腳本命令之后,我們開始改造cli3配置。
首先要require('vue-server-renderer')
然后再根據(jù)VUE_NODE環(huán)境變量來(lái)決定編譯的走向以及生成不同的環(huán)境清單
先做cli3服務(wù)端的入口文件
// src/entry/server.js import { createApp } from '../main.js' export default context => { return new Promise((resolve, reject) => { const { app, router } = createApp(context.data) //根據(jù)node傳過(guò)來(lái)的路由 來(lái)調(diào)用router路由的指向 router.push(context.url) router.onReady(() => { //獲取當(dāng)前路由匹配的組件數(shù)組。 const matchedComponents = router.getMatchedComponents() //長(zhǎng)度為0就是沒(méi)找到該路由所匹配的組件 //可以路由設(shè)置重定向或者傳回node node來(lái)操作也可以 if (!matchedComponents.length) { return reject({ code: 404 }) } resolve(app) }, reject) }) }
這里是cli3的配置
//vue.config.js const ServerPlugin = require('vue-server-renderer/server-plugin'),//生成服務(wù)端清單 ClientPlugin = require('vue-server-renderer/client-plugin'),//生成客戶端清單 nodeExternals = require('webpack-node-externals'),//忽略node_modules文件夾中的所有模塊 VUE_NODE = process.env.VUE_NODE === 'node', entry = VUE_NODE ? 'server' : 'client';//根據(jù)環(huán)境變量來(lái)指向入口 module.exports = { css: { extract: false//關(guān)閉提取css,不關(guān)閉 node渲染會(huì)報(bào)錯(cuò) }, configureWebpack: () => ({ entry: `./src/entry/${entry}`, output: { filename: 'js/[name].js', chunkFilename: 'js/[name].js', libraryTarget: VUE_NODE ? 'commonjs2' : undefined }, target: VUE_NODE ? 'node' : 'web', externals: VUE_NODE ? nodeExternals({ //設(shè)置白名單 whitelist: /\.css$/ }) : undefined, plugins: [//根據(jù)環(huán)境來(lái)生成不同的清單。 VUE_NODE ? new ServerPlugin() : new ClientPlugin() ] }), chainWebpack: config => { config.resolve .alias .set('vue$', 'vue/dist/vue.esm.js') config.module .rule('vue') .use('vue-loader') .tap(options => { options.optimizeSSR = false; return options; }); config.module .rule('images') .use('url-loader') .tap(options => { options = { limit: 1024, fallback:'file-loader?name=img/[path][name].[ext]' } return options; }); } }
node相關(guān)配置
用于node渲染 必然要攔截get請(qǐng)求的。然后根據(jù)get請(qǐng)求地址來(lái)進(jìn)行要渲染的頁(yè)面。
官方提供了vue-server-renderer插件
大概的方式就是 node攔截所有的get請(qǐng)求,然后將獲取到的路由地址,傳給前臺(tái),然后使用router實(shí)例進(jìn)行push
再往下面看之前 先看一下官方文檔
創(chuàng)建BundleRenderer
createBundleRenderer
將 Vue 實(shí)例渲染為字符串。
renderToString
渲染應(yīng)用程序的模板
template
生成所需要的客戶端或服務(wù)端清單
clientManifest
先創(chuàng)建 服務(wù)端所需要的模板
//public/index.nodeTempalte.html <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="/favicon.ico" rel="external nofollow" > <meta charset="utf-8"> <title>vuessr</title> </head> <body> <!--vue-ssr-outlet--> </body> </html>
node部分
先創(chuàng)建三個(gè)文件
index.js //入口
proxy.js //代理
server.js //主要配置
//server.js const fs = require('fs'); const { resolve } = require('path'); const express = require('express'); const app = express(); const proxy = require('./proxy'); const { createBundleRenderer } = require('vue-server-renderer') //模板地址 const templatePath = resolve(__dirname, '../public/index.nodeTempalte.html') //客戶端渲染清單 const clientManifest = require('../dist/vue-ssr-client-manifest.json') //服務(wù)端渲染清單 const bundle = require('../dist/vue-ssr-server-bundle.json') //讀取模板 const template = fs.readFileSync(templatePath, 'utf-8') const renderer = createBundleRenderer(bundle,{ template, clientManifest, runInNewContext: false }) //代理相關(guān) proxy(app); //請(qǐng)求靜態(tài)資源相關(guān)配置 app.use('/js', express.static(resolve(__dirname, '../dist/js'))) app.use('/css', express.static(resolve(__dirname, '../dist/css'))) app.use('/font', express.static(resolve(__dirname, '../dist/font'))) app.use('/img', express.static(resolve(__dirname, '../dist/img'))) app.use('*.ico', express.static(resolve(__dirname, '../dist'))) //路由請(qǐng)求 app.get('*', (req, res) => { res.setHeader("Content-Type", "text/html") //傳入路由 src/entry/server.js會(huì)接收到 使用vueRouter實(shí)例進(jìn)行push const context = { url: req.url } renderer.renderToString(context, (err, html) => { if (err) { if (err.url) { res.redirect(err.url) } else { res.status(500).end('500 | 服務(wù)器錯(cuò)誤'); console.error(`${req.url}: 渲染錯(cuò)誤 `); console.error(err.stack) } } res.status(context.HTTPStatus || 200) res.send(html) }) }) module.exports = app; //proxy.js const proxy = require('http-proxy-middleware'); function proxyConfig(obj){ return { target:'localhost:8081', changeOrigin:true, ...obj } } module.exports = (app) => { //代理開發(fā)環(huán)境 if (process.env.NODE_ENV !== 'production') { app.use('/js/main*', proxy(proxyConfig())); app.use('/*hot-update*',proxy(proxyConfig())); app.use('/sockjs-node',proxy(proxyConfig({ws:true}))); } } //index.js const app = require('./server') app.listen(8080, () => { console.log('\033[42;37m DONE \033[40;33m localhost:8080 服務(wù)已啟動(dòng)\033[0m') })
做完這一步之后,就可以預(yù)覽基本的服務(wù)渲染了。
后面就只差開發(fā)環(huán)境的配置,以及到node數(shù)據(jù)的傳遞(vuex)
npm run build npm run start:server 打開localhost:8080 F12 - Network - Doc 就可以看到內(nèi)容
最終目錄結(jié)構(gòu)
|-- vuessr |-- .gitignore |-- babel.config.js |-- package-lock.json |-- package.json |-- README.md |-- vue.config.js |-- nodeScript //node 渲染配置 | |-- index.js | |-- proxy.js | |-- server.js |-- public//模板文件 | |-- favicon.ico | |-- index.html | |-- index.nodeTempalte.html |-- src |-- App.vue |-- main.js |-- router.config.js//路由集合 |-- store.config.js//vuex 集合 |-- assets//全局靜態(tài)資源源碼 | |-- 備注.txt | |-- img | |-- logo.png |-- components//全局組件 | |-- Head | |-- index.js | |-- index.scss | |-- index.vue | |-- img | |-- logo.png |-- entry//cli3入口 | |-- client.js | |-- server.js | |-- 備注.txt |-- methods//公共方法 | |-- 備注.txt | |-- mixin | |-- index.js |-- pages//源碼目錄 | |-- home | | |-- index.js | | |-- index.scss | | |-- index.vue | | |-- img | | | |-- flow.png | | | |-- head_portrait.jpg | | | |-- logo.png | | | |-- vuessr.png | | |-- vue | | | |-- index.js | | | |-- index.scss | | | |-- index.vue | | |-- vueCli3 | | | |-- index.js | | | |-- index.scss | | | |-- index.vue | | |-- vueSSR | | | |-- index.js | | | |-- index.scss | | | |-- index.vue | | |-- vuex | | |-- index.js | | |-- index.scss | | |-- index.vue | |-- router//路由配置 | | |-- index.js | |-- store//vuex配置 | |-- all.js | |-- gather.js | |-- index.js |-- static//cdn資源 |-- 備注.txt
以上是“構(gòu)建vueSSR項(xiàng)目之如何配置node以及vue-cli3”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)頁(yè)標(biāo)題:構(gòu)建vueSSR項(xiàng)目之如何配置node以及vue-cli3
轉(zhuǎn)載來(lái)于:http://jinyejixie.com/article12/ppjgdc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、外貿(mào)建站、網(wǎng)站排名、軟件開發(fā)、ChatGPT、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)