что такое сео
Поисковая оптимизация, поисковая оптимизация, это и есть сео. (Конечно, больше). Но тут особо нечего сказать.
SEO-принципы
На самом деле работа, проделываемая поисковыми системами, достаточно сложна, поэтому здесь мы кратко расскажем об общем процессе. В дальнейшем также будет описано, как оптимизировать SEO на основе этих моментов.
- Сканирование страницы: паук запрашивает страницу с сервера и получает содержимое страницы.
- Анализ и хранение: анализируйте полученный контент и включайте качественные страницы
- Поисковая сортировка: когда пользователь ищет ключевые слова, сортирует включенные страницы в соответствии с определенными правилами и возвращает результаты пользователю.
Зачем делать сео оптимизацию
Конечно, это делается для того, чтобы «пауки» могли добраться до вашего контента, чтобы больше людей могли узнать о вашем контенте. Конечно, не все системы веб-сайтов должны это делать. Если вы похожи на корпоративную систему открытого доступа, в этом нет необходимости. Вы можете использовать ее сами. Зачем вам сообщать об этом другим. Однако, если вы продаете систему oa, вы можете просто выполнить предварительную визуализацию, а затем настроить маршрутизацию домашней страницы только при настройке маршрутизации.
Это требуется только для систем, которым требуется рекламный трафик, таких как новостные сайты и сайты интернет-магазинов.
Предварительный рендеринг Vue
Предварительный рендеринг — это на самом деле использование плагинов. очень простой
нужны плагины
prerender-spa-plugin
puppeteer
конфигурация веб-пакета
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, '../dist'),
//需要进行渲染的的页面路由
routes: ['/', '/aaa'],
renderer: new Renderer({
// 触发渲染的时间,用于获取数据后再保存渲染结果
renderAfterTime: 10000,
// 是否打开浏览器,false 是打开。可用于 debug 检查渲染结果
headless: false,
// 在项目的main.js入口中使用 `document.dispatchEvent(new Event('render-event'))`
renderAfterDocumentEvent: 'render-event', // render-event: 声明的方法名
})
})
})
Конфигурация main.js
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
render: h => h(App),
mounted() {
document.dispatchEvent(new Event('render-event'))
},
})
Предварительная рендеринга является самым простым решением, но он подходит только тогда, когда у вас есть меньше страниц (меньше маршрутов), потому что когда у вас есть больше страниц, вы обнаружите, что предварительная рендеринга станет медленнее.
vue-ssr рендеринг на стороне сервера (официальный)
ограничение
- Обратите внимание, что сервер вызывает только два хука, beforeCreat и created, поэтому вы не можете сделать что-то вроде инициализации таймера в created, а затем уничтожить таймер в смонтированном или уничтоженном, иначе сервер будет медленно истощаться этими таймерами (Что делает это значит?то есть если я запущу в среде node,он выполнит эти два метода в странице,как показано на рисунке ниже)
-
Из-за однопоточного механизма при рендеринге на стороне сервера в процессе происходят операции, аналогичные синглтонам, поэтому все запросы будут совместно использовать операции этого синглтона, поэтому для обеспечения независимости между каждым запросом следует использовать фабричные функции.
-
Если вы используете сторонний API в хуках beforeCreat и created, вам необходимо убедиться, что не будет ошибок при запуске API на стороне узла, таких как инициализация операции запроса данных в созданном хуке, что является нормальным и разумно. . Однако, если вы используете для работы только XHR, возникнут проблемы при рендеринге на стороне узла, поэтому вам следует использовать axios, стороннюю библиотеку, поддерживаемую как браузером, так и сервером.
-
Самый важный момент: не используйте API документов, которые работают только на стороне браузера в общем коде, и наоборот, не используйте API, которые работают только на стороне узла. (Кажется, ссылки на vue доступны. В Интернете говорят, что это можно установить через переменные веб-пакета. Метод, который я использую, будет упомянут ниже)
Подготовительные работы (здесь в качестве примера взят самый простой проект vue+webpack)
Инициализировать проект
vue init webpack vue-ssr-demo
cd vue-ssr-demo
npm install
npm run dev
Прежде всего, мы должны посмотреть, может ли проект быть запущен, прежде чем мы сможем продолжить, верно? Если здесь ошибка, то непосредственно ищите, как инициализировать проект с помощью vue+webpack, их должно быть много.
package.json
Это просто размещено здесь для всеобщего обозрения
Начинать
Установите зависимости и запустите проект
npm i -D vue-server-renderer
vue-server-renderer и версия vue должны быть согласованы
Добавить тестовую страницу
<template>
<div>
Just a test page.
<div>
<router-link to="/">Home</router-link>
</div>
<div><h2>{{mode}}</h2></div>
<div><span>{{count}}</span></div>
<div><button @click="count++">+1</button></div>
</div>
</template>
<script>
export default {
data () {
return {
mode: process.env.VUE_ENV === 'server' ? 'server' : 'client',
count: 2
}
}
}
</script>
Два новых файла js в src
Создайте два js в каталоге src
src
├── entry-client.js # 仅运行于浏览器
└── entry-server.js # 仅运行于服务器
entry.client.js
import { createApp } from './main'
const { app, router } = createApp()
// 因为可能存在异步组件,所以等待router将所有异步组件加载完毕,服务器端配置也需要此操作
router.onReady(() => {
app.$mount('#app')
})
entry.server.js
// entry-server.js
import { createApp } from './main'
export default context => {
// 因为有可能会是异步路由钩子函数或组件,所以我们将返回一个 Promise,
// 以便服务器能够等待所有的内容在渲染前,
// 就已经准备就绪。
return new Promise((resolve, reject) => {
const { app, router } = createApp()
// 设置服务器端 router 的位置
router.push(context.url)
// 等到 router 将可能的异步组件和钩子函数解析完
router.onReady(() => {
const matchedComponents = router.getMatchedComponents()
// 匹配不到的路由,执行 reject 函数,并返回 404
if (!matchedComponents.length) {
// eslint-disable-next-line
return reject({ code: 404 })
}
// Promise 应该 resolve 应用程序实例,以便它可以渲染
resolve(app)
}, reject)
})
}
Изменить конфигурацию маршрутизации
Чтобы избежать влияния синглетонов, мы в основном экспортируем новый экземпляр маршрутизатора для каждого запроса:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export function createRouter () {
return new Router({
mode: 'history', // 注意这里也是为history模式
routes: [
{
path: '/',
name: 'Hello',
component: HelloWorld
}, {
path: '/test',
name: 'Test',
component: () => import('@/components/Test') // 异步组件
}
]
})
}
Изменить main.js
import Vue from 'vue'
import App from './App'
import { createRouter } from './router'
export function createApp () {
// 创建 router 实例
const router = new createRouter()
const app = new Vue({
// 注入 router 到根 Vue 实例
router,
render: h => h(App)
})
// 返回 app 和 router
return { app, router }
}
изменение конфигурации веб-пакета
Также есть три конфигурационных файла, инициализированных vue-cli: base, dev и prod. Мы по-прежнему сохраняем эти три конфигурационных файла, просто добавляем webpack.server.conf.js.
build
├── webpack.base.conf.js # 基础通用配置
├── webpack.client.conf.js # 客户端打包配置
└── webpack.server.conf.js # 服务器端打包配置
Конфигурация webpack.prod.conf.js (конфигурация на стороне клиента)
Изменить webpack.base.conf.jsКонфигурация записи записи: ./src/entry-client.js. Таким образом, исходная конфигурация dev и конфигурация prod не будут затронуты.
Конфигурация на стороне сервера также будет ссылаться на базовую конфигурацию, но переопределит запись в server-entry.js посредством слияния. Создание клиентского манифеста клиентского манифеста
преимущество:
- Может заменить html-webpack-plugin для ввода правильного URL-адреса ресурса, если в сгенерированном имени файла есть хэш.
- При рендеринге пакетов с помощью функции разделения кода по требованию в веб-пакете мы можем обеспечить оптимизированную предварительную загрузку ресурсов/предварительную выборку данных для блоков, а также можем интеллектуально вводить необходимые асинхронные блоки в виде тегов скрипта, чтобы избежать запроса Waterfall на стороне клиента, и улучшенный TTI - time-to. -интерактивный.
На самом деле это очень просто, ввести плагин в конфигурацию prod и настроить его в плагине:
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
// ...
// ...
plugins: [
new webpack.DefinePlugin({
'process.env': env,
'process.env.VUE_ENV': '"client"' // 增加process.env.VUE_ENV
}),
//...
// 另外需要将 prod 的HtmlWebpackPlugin 去除,因为我们有了vue-ssr-client-manifest.json之后,服务器端会帮我们做好这个工作。
// new HtmlWebpackPlugin({
// filename: config.build.index,
// template: 'index.html',
// inject: true,
// minify: {
// removeComments: true,
// collapseWhitespace: true,
// removeAttributeQuotes: true
// // more options:
// // https://github.com/kangax/html-minifier#options-quick-reference
// },
// // necessary to consistently work with multiple chunks via CommonsChunkPlugin
// chunksSortMode: 'dependency'
// }),
// 此插件在输出目录中
// 生成 `vue-ssr-client-manifest.json`。
new VueSSRClientPlugin()
]
// ...
webpack.server.conf.js (конфигурация на стороне сервера)
Конфигурация сервера полезна для запуска и установки нового плагина: npm i -D webpack-node-externals
const webpack = require('webpack')
const merge = require('webpack-merge')
const nodeExternals = require('webpack-node-externals')
const baseConfig = require('./webpack.base.conf.js')
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
// 去除打包css的配置
baseConfig.module.rules[1].options = ''
//baseConfig.module.rules[1].options = '' // 去除分离css打包的插件(有安装并使用esline的情况)
//baseConfig.module.rules[0].options = '' // 去除分离css打包的插件(没有安装esline的情况)
module.exports = merge(baseConfig, {
// 将 entry 指向应用程序的 server entry 文件
entry: './src/entry-server.js',
// 这允许 webpack 以 Node 适用方式(Node-appropriate fashion)处理动态导入(dynamic import),
// 并且还会在编译 Vue 组件时,
// 告知 `vue-loader` 输送面向服务器代码(server-oriented code)。
target: 'node',
// 对 bundle renderer 提供 source map 支持
devtool: 'source-map',
// 此处告知 server bundle 使用 Node 风格导出模块(Node-style exports)
output: {
libraryTarget: 'commonjs2'
},
// https://webpack.js.org/configuration/externals/#function
// https://github.com/liady/webpack-node-externals
// 外置化应用程序依赖模块。可以使服务器构建速度更快,
// 并生成较小的 bundle 文件。
externals: nodeExternals({
// 不要外置化 webpack 需要处理的依赖模块。
// 你可以在这里添加更多的文件类型。例如,未处理 *.vue 原始文件,
// 你还应该将修改 `global`(例如 polyfill)的依赖模块列入白名单
whitelist: /\.css$/
}),
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
'process.env.VUE_ENV': '"server"'
}),
// 这是将服务器的整个输出
// 构建为单个 JSON 文件的插件。
// 默认文件名为 `vue-ssr-server-bundle.json`
new VueSSRServerPlugin()
]
})
Изменить команду упаковки
Если cross-env не найден, установите npm i -D cross-env
"scripts": {
//...
"build:client": "node build/build.js",
"build:server": "cross-env NODE_ENV=production webpack --config build/webpack.server.conf.js --progress --hide-modules",
"build": "rimraf dist && npm run build:client && npm run build:server"
}
Изменить index.html
原来的
- Самый простой способ — создать отдельный html-шаблон для режима разработки. . . (упомянуто ниже)
- Режим рендеринга на стороне сервера также интегрирован в режим разработки, поэтому вполне надежно, находятся ли производственная среда и среда разработки в режиме рендеринга на стороне сервера. (официальный пример делается так) (этого пока делать не будем)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue-ssr-demo</title>
</head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
Команда выполнения
npm run build
Затем вы можете увидеть два сгенерированных файла json в каталоге dist: vue-ssr-server-bundle.json и vue-ssr-client-manifest.json.
Эти два файла будут применяться на стороне узла для рендеринга на стороне сервера и внедрения файлов статических ресурсов.
server.js в корневом каталоге (js работает на стороне сервера)
(В официальном примере используется экспресс, поэтому в этой демонстрации в качестве серверной стороны будет использоваться koa2. Конечно, не имеет значения, koa это или экспресс...)
npm i -S koa
Создайте server.js в корневом каталоге проекта со следующим содержимым
const Koa = require('koa')
const app = new Koa()
// response
app.use(ctx => {
ctx.body = 'Hello Koa'
})
app.listen(3001)
Измените код server.js
Необходимо установить промежуточное ПО для статических ресурсов koa: npm i -D koa-static
const Koa = require('koa')
const app = new Koa()
const fs = require('fs')
const path = require('path')
const { createBundleRenderer } = require('vue-server-renderer')
const resolve = file => path.resolve(__dirname, file)
// 生成服务端渲染函数
const renderer = createBundleRenderer(require('./dist/vue-ssr-server-bundle.json'), {
// 推荐
runInNewContext: false,
// 模板html文件
template: fs.readFileSync(resolve('./index.html'), 'utf-8'),
// client manifest
clientManifest: require('./dist/vue-ssr-client-manifest.json')
})
function renderToString (context) {
return new Promise((resolve, reject) => {
renderer.renderToString(context, (err, html) => {
err ? reject(err) : resolve(html)
})
})
}
app.use(require('koa-static')(resolve('./dist')))
// response
app.use(async (ctx, next) => {
try {
const context = {
title: '服务端渲染测试', // {{title}}
url: ctx.url
}
// 将服务器端渲染好的html返回给客户端
ctx.body = await renderToString(context)
// 设置请求头
ctx.set('Content-Type', 'text/html')
ctx.set('Server', 'Koa2 server side render')
} catch (e) {
// 如果没找到,放过请求,继续运行后面的中间件
next()
}
})
app.listen(8080)
.on('listening', () => console.log('服务已启动'))
.on('error', err => console.log(err))
местный старт
Запустите команду запуска службы:
node server.js
Доступ к браузеру: localhost:8080, на снимке экрана показана страница, успешно обработанная сервером.
Развернуть на сервер
При деплое на сервер нужно положить на него весь файл, а потом запустить в папке npm run build (если не ставить на него node_modules, то нужен npm install), а потом npm run build и потом node сервер.js
Как отлаживать код локально
Сначала создайте новый htmldev.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="app"></div>
</body>
</html>
Измените команды в package.json
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
- Установите любые зависимости, если вам напомнили, что зависимостей нет
- Измените версию, если вы столкнулись с несовместимой версией веб-пакета.
Измените index.js в папке конфигурации.
Изменить конфигурацию webpack.dev.conf.js
Как использовать для использования объекта документа/окна
Кое-какие ответы нашла в интернете, но примеров нет, может не нашла, потому что не так открыла, поэтому могу практиковаться только по идеям тех ответов. (Конечно, лучше всего не использовать эти два предмета (ручная собачья голова))
Но если вы должны использовать его, вы можетеDefinePlugin через веб-пакетЧтобы определить переменную для оценки текущей операционной среды (эта переменная доступна в предыдущем файле конфигурации), давайте посмотрим
webpack.server.conf.js
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
'process.env.VUE_ENV': '"server"'
})
webpack.prod.conf.js
new webpack.DefinePlugin({
'process.env': env,
'process.env.VUE_ENV': '"client"' // 增加process.env.VUE_ENV
})
мы можем пройтиprocess.env.VUE_ENVЭто используется для определения текущей рабочей среды, например
mounted() {
if (process.env.VUE_ENV == "server") {
console.log("服务端");
} else {
console.log("客户端");
console.log(document.getElementById("ooooo"));
}
}
Введение файлов стилей css
Я попробовал это сам здесь. Кажется, что приведенное выше суждение должно быть сделано в файле main.js, а затем я использую require('xxx') для его импорта. Я не могу импортировать его напрямую. Если есть другие методы , Пожалуйста, оставьте сообщение.
Часть использования vue-ssr воспроизводится вздесь(Впрочем, я сам в него когда-то постучал, и поднял и решил те проблемы, с которыми столкнулся. У него есть то, чего нет у меня, а у меня есть то, чего нет у него, хахахаха)
фреймворк nuxt.js
Это похоже на vue framework.Если вы использовали vue scaffolding, вы можете начать работу, просмотрев официальную документацию (это о начале работы, а не о квалифицированном использовании)
Здесь рекомендуется смотреть великого бога Наггетсов напрямуюличный блог
Если что-то не так с вышеизложенным, пожалуйста, оставьте сообщение в области комментариев, я внесу изменения вовремя, спасибо. . . . .
личные жалобы
В последнее время компании нужно это использовать, поэтому я пошел исследовать это и оставил свою дорогую библиотеку компонентов (больше не хочу ее писать). Я тут все это видел, можешь кстати подвигать мышкой и поставить лайк.