最近在做seo优化,开发完成后需要与原有的spa项目进行合并,下面是合并步骤及部署时的nginx配置
使用的ssr框架是nuxt,spa项目为vue
目录
将ssr项目中未做ssr的页面用a标签进行跳转至spa项目
由于我们的门户项目比较复杂,不同的域名要对应不同的主题色,然后再加上dev,rc,uat,prod四个环境,所以需要通过对当前环境的判断来生成对应的url+spa项目的路由进行页面跳转(暂时不知道如何在服务端渲染阶段获取地址栏信息,望赐教)
下面是我配置的运行脚本
有三个主题站点,分别是本地,浙江,常州
四个运行环境,dev,rc,uat,prod
这里使用cross-env在每个指令中注入自定义环境变量用以进行区分
这里需要注意的是server阶段注入的变量不会在代码中被使用
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"dev:zhejaing": "cross-env NODE_ENV=development VUE_APP_CURRENT_REGION=zhejiang nodemon server/index.js --watch server",
"dev:changzhou": "cross-env NODE_ENV=development VUE_APP_CURRENT_REGION=changzhou nodemon server/index.js --watch server",
"build": "nuxt build",
"build:rc": "cross-env ENVIRONMENT=rc nuxt build",
"build:uat": "cross-env ENVIRONMENT=uat nuxt build",
"build:prod": "cross-env ENVIRONMENT=prod nuxt build",
"build:zhejiang": "cross-env VUE_APP_CURRENT_REGION=zhejiang nuxt build",
"build:zhejiang.rc": "cross-env ENVIRONMENT=rc VUE_APP_CURRENT_REGION=zhejiang nuxt build",
"build:zhejiang.uat": "cross-env ENVIRONMENT=uat VUE_APP_CURRENT_REGION=zhejiang nuxt build",
"build:zhejiang.prod": "cross-env ENVIRONMENT=prod VUE_APP_CURRENT_REGION=zhejiang nuxt build",
"build:changzhou": "cross-env VUE_APP_CURRENT_REGION=changzhou nuxt build",
"build:changzhou.rc": "cross-env ENVIRONMENT=rc VUE_APP_CURRENT_REGION=changzhou nuxt build",
"build:changzhou.uat": "cross-env ENVIRONMENT=uat VUE_APP_CURRENT_REGION=changzhou nuxt build",
"build:changzhou.prod": "cross-env ENVIRONMENT=prod VUE_APP_CURRENT_REGION=changzhou nuxt build",
"build:analyze": "nuxt build --analyze",
"start": "cross-env NODE_ENV=production node server/index.js",
"start:rc": "cross-env NODE_ENV=production ENVIRONMENT=rc node server/index.js",
"start:uat": "cross-env NODE_ENV=production ENVIRONMENT=uat node server/index.js",
"start:prod": "cross-env NODE_ENV=production ENVIRONMENT=prod node server/index.js",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue ."
},
然后在nuxt.config.js中的env中进行配置
env: {
'VUE_APP_CURRENT_REGION': process.env.VUE_APP_CURRENT_REGION,
'CURRENT_ENV': env,
},
之后将自定义的环境变量进行判断生成与环境站点对应的url地址
const getBaseUrl = () => {
if (!process.env.VUE_APP_CURRENT_REGION) { // 湖南站点
let port = ':15012'
switch (process.env.CURRENT_ENV) {
case 'rc':
port = ':15008'
break
case 'uat':
port = ':15042'
break
case 'prod':
port = ''
break
default:
port = ':15012'
}
return 'http://42.48.104.46' + port
} else { // 其余分站点
const regionMap = {
zhejiang: 'zj',
changzhou: 'cz'
}
return `https://${regionMap[process.env.VUE_APP_CURRENT_REGION]}-${process.env.CURRENT_ENV || 'dev'}-in.ccyunchina.com`
}
}
将url放入常量中在代码中进行使用
关于注入可以参考nuxt(插件)
将spa项目中做了ssr的页面用a标签进行跳转至ssr项目
由于spa项目可以获取window.location对象,所以实现起来没有那么复杂
'SEO_URL': `${location.protocol}//${location.hostname}${process.env.NODE_ENV === 'production' ? '' : ':3000'}`,
然后在代码中通过常量的方式进行引入
由于需要做seo优化的多位不需登录的页面,所以需要对头部的登录信息做一次判断,同时对登录信息做一个储存
在store中进行用户信息的刷新和储存
refreshUserFromDisk({ commit, dispatch }) {
try {
const localStorageStr = localStorage.getItem(constant['COMMON|LOCAL_STORAGE'].base)
const localStorageObj = JSON.parse(localStorageStr)
if (localStorageStr == null || localStorageObj.user.userInfo == null) {
commit('SET_IS_LOGIN', false)
commit('SET_JWT', null)
return
}
commit('SET_USER_INFO', localStorageObj.user.userInfo)
commit('SET_IS_LOGIN', localStorageObj.user.isLogin)
commit('SET_JWT', localStorageObj.user.userInfo.jwt)
dispatch('initEnterprise')
// commit('SET_UN_READ_MESSAGE_COUNT', localStorageObj.user.unReadMessageCount)
} catch (e) {
console.warn('加载用户从localStorage失败')
}
},
在原来的spa项目中修改登录后的跳转逻辑
在sep项目进行登录跳转时将当前页面的地址放入参数referrer中然后跳转至spa项目的登录路由
location.href = this.$constant['COMMON|PORTAL_URL'] + '/login?referrer=' + this.$route.fullPath
在spa项目中将已进行seo优化页面的url放入一个数组中,通过遍历判断是否为seo地址,之后进行seo项目地址的跳转
/**
* 判断是否seo优化后的url
* @param url
* @returns {boolean}
*/
export function isSeoUrl(url) {
const seoUrl = ['/', '/financial', '/government', '/medical', '/partner', '/project', '/school/publicClass', '/school/askDetail', '/school/circleDetail', '/school/courseDetail', '/upload', '/introduce/about', '/introduce/system', '/newsDetail', '/partnerDetail']
return seoUrl.some(v => {
return url.includes(v)
})
}
**************省略若干行**********
if (isSeoUrl(query.referrer)) {
// seo相关页面
window.location.href = window.globalVue.$constant['COMMON|SEO_URL'] + query.referrer
}
将服务器中nginx的80或443端口的location /
通过proxy_pass代理至ssr项目启动后的端口
location / {
proxy_pass http://127.0.0.1:3000;
}