美文网首页
教你如何搭建 Vue SEO 的 SSR

教你如何搭建 Vue SEO 的 SSR

作者: 酷酷的凯先生 | 来源:发表于2021-06-11 13:58 被阅读0次

# 前言

VueSEO 大家都不陌生,一般有两种,一种是预渲染插件 prerender-spa-plugin,主要用于只需要部分页面的情形。另一种是后端渲染 Vue SSR,比较彻底的一种方案,比较受欢迎。

# 举个例子

SSR 也并没有大家想的那么深奥,上代码。。。

第一步:安装插件 vue-server-renderer、webpack-node-externals、lodash.merge、cross-env

npm i --save-dev vue-server-renderer webpack-node-externals lodash.merge cross-env

第二步:更改路由导出

const router = new Router({
    mode: 'history',
    routes,
});

// ssr 输出
export default function createRouter() {
    return new Router({
        mode: 'history',
        routes,
    });
}

// 普通输出
// export default router;

第三步:在 src 根目录下创建 app.js

// 创建 vue 实例
import Vue from 'vue'
import App from './App.vue'
import createRouter from './router'

export default function createApp() {
    const router = createRouter();
    const app = new Vue({
        router,
        render: h => h(App)
    });

    return { app, router }
}

第四步:在 src 目录下分别创建 entry-client.js、 entry-server.js

// entry-client.js ==> 挂载、激活app
import createApp from './app'

const { app, router } = createApp();

router.onReady(() => {
    app.$mount('#app');
})

// entry-server.js ==> 将来渲染首屏
import createApp from './app'

export default context => {
    return new Promise((resolve, reject) => {
        const { app, router } = createApp();
        // 进入到首屏
        router.push(context.url)
        router.onReady(() => {
            resolve(app);
        }, reject)
    });
}

第五步:配置 vue.config.js

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");
const TARGET_NODE = process.env.WEBPACK_TARGET === "node";
const target = TARGET_NODE ? "server" : "client";

module.exports = {
    css: {
        extract: false,
    },
    outputDir: "./dist/" + target,
    configureWebpack: () => {
        if (process.env.WEBPACK_TARGET !== "node") return
        return ({
            entry: `/src/entry-${target}.js`,
            devtool: "source-map",
            target: TARGET_NODE ? "node" : "web",
            node: TARGET_NODE ? undefined : false,
            output: {
                libraryTarget: TARGET_NODE ? "commonjs2" : undefined
            },
            externals: TARGET_NODE ?
                nodeExternals({
                    // whitelist
                    allowlist: [/\.css$/]
                }) : undefined,
            optimization: {
                splitChunks: undefined
            },
            plugins: [TARGET_NODE ? new VueSSRServerPlugin() : new VueSSRClientPlugin()]
        })
    },
    chainWebpack: config => {
        config.module.rule("vue").use("vue-loader").tap(options => {
            merge(options, { optimizeSSR: false })
        })
    }
};

第六步:与 src 平级,创建 server 文件夹并创建 index.js 文件

const clientManifest = require("../dist/client/vue-ssr-client-manifest.json");
const renderer = createBundleRenderer(serverBundle, {
    runInNewContext: false,
    template: fs.readFileSync("../public/index.temp.html", "utf-8"), // 宿主文件
    clientManifest
});

app.use(express.static('../dist/client', { index: false }));

app.get("*", async(req, res) => {
    try {
        const context = {
            url: req.url,
            title: 'test title'
        }

        const html = await renderer.renderToString(context);

        res.send(html)
    } catch (error) {
        console.log(error)
    }
})

app.listen(3000, () => {
    console.log(123456)
})

第七步:修改 packsge.json 文件

"scripts": {
        "serve": "cross-env WEBPACK_TARGET=dev vue-cli-service serve",
        "build:client": "vue-cli-service build",
        "build:server": "cross-env WEBPACK_TARGET=node vue-cli-service build --mode server",
        "build": "npm run build:server && npm run build:client",
        "lint": "vue-cli-service lint"
},

第八步:在 public 文件夹下创建 index.temp.html

<!DOCTYPE html>
<html lang="">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">

    <title>ssr</title>
</head>

<body>
    <!--vue-ssr-outlet-->
</body>

</html>

注意:body 里必须这么写

第九步:运行打包

npm run build 

注意: 这里打包会执行两次:客户端 和 服务端

打包后的结果:


image.png

目录总览:


image.png

到这里 SSR 就创建完成了,最后启动服务 node index.js 看下下结果吧

相关文章

网友评论

      本文标题:教你如何搭建 Vue SEO 的 SSR

      本文链接:https://www.haomeiwen.com/subject/nggmeltx.html