Vue2.x服务端渲染

自己准备一个 vue2.0 的空项目,这里不做演示,如果不会请看:创建一个 vue2 的项目

安装依赖

1、服务端渲染的核心包

npm install -------------------------- -S

2、打包客户端和服务端时需要的依赖包

npm install ---------------------------- -D

3、执行编译的包

npm install --------------- -D

4、选择一个启动 node 服务的包,使用 express、koa 都行。本示例使用的是 koa

npm install ---------- ----------------- ---------------- -S

Router

修改 src > router > index.js

import --- from "vue";
import --------- from "vue-router";

---.use(---------);

const ------ = [
    {
		path: "/home",
		name: "Home",
		component: () => import("../views/Home.vue"),
	},
	{
		path: "/about",
		name: "About",
		component: () => import("../views/About.vue"),
	}
];

export default function createRouter() {
	return new VueRouter({
		mode: "history",
		base: "/ssr/",
		------,
	});
}

Vuex

修改 src > store > index.js

import --- from "vue";
import ---- from "vuex";

---.use(----);

export default function createStore() {
	return new Vuex.Store({
		state: {},
		mutations: {},
		actions: {},
		modules: {},
	});
}

main.js

修改 src > main.js

import --- from "vue";
import --- from "./App.vue";
import ------------ from "./router";
import ----------- from "./store";

---.------.------------- = false;

export default function createApp() {
	const ------ = createRouter();
	const ----- = createStore();
	const --- = new Vue({
		------,
		-----,
		render: (h) => h(---),
	});
	return {
		---,
		------,
		-----
	};
}

main-client.js

在项目的 src 目录下新建 main-client.js

import --------- from "./main";

const { ---, ------, ----- } = createApp();

------.onReady(() => {
	---.$mount("#app");
});

main-server.js

在项目的 src 目录下新建 main-server.js

import --------- from "./main";

export default (context) => {
	return new Promise((resolve, reject) => {
		const { ---, ------, ----- } = createApp();
		------.push(-------.---);
		------.onReady(() => {
			resolve(---);
		}, ------);
	});
};

server

在项目的根目录下创建一个 server 目录

1、创建 server > index.template.html,用于渲染模板。

<!DOCTYPE html>
<html lang="en">
	<head>
		<!-- 使用三花括号(triple-mustache)进行 HTML 不转义插值(non-HTML-escaped interpolation) -->
		--- ---- ---
		<!-- 使用双花括号(double-mustache)进行 HTML 转义插值(HTML-escaped interpolation) -->
		<title>---------</title>
	</head>
	<body>
		<!--vue-ssr-outlet-->
	</body>
</html>

2、创建 server > index.js,这就是服务端渲染要的启动的 nodejs 服务。

const -- = require("fs");
const ---- = require("path");

const --- = require("koa");
const --------- = require("koa-static");
const ------ = require('koa-router');

const --- = new Koa();
const ------ = new Router();

const resolve = (file) => ----.resolve(---------, ----);
---.use(koaStatic(resolve("../dist/client")));

const { -------------------- } = require("vue-server-renderer");
const ------------ = require("../dist/server/vue-ssr-server-bundle.json");
const -------------- = require("../dist/client/vue-ssr-client-manifest.json");
const renderToString = function(context){
	return new Promise((resolve, reject) => {
		createBundleRenderer(------------, {
			runInNewContext: false,
			template: --.readFileSync(
				----.resolve(---------, "./index.template.html"),
				"utf-8"
			),
			--------------,
		}).renderToString(-------, (err, html) => {
			--- ? reject(---) : resolve(----);
		});
	});
}

------.get("/(.*)", async (ctx, next) => {
	const ------- = {
		title: "Hello vue2-SSR",
		meta: `
		    <meta charset="utf-8">
		    <meta name="viewport" content="width=device-width,initial-scale=1">
			<meta name="keywords" content="keywords" />
			<meta name="description" content="description" />
		  `,
		url: ---.-------.---.replace('/ssr', ''),
	};
	const ---- = await renderToString(-------);
	---.---- = ----;
});

---.use(------.routes());

---.listen(8888, () => {
	-------.log("server started at localhost: 8888");
});

package.json

{
	"scripts": {
		"serve:ssr": "npm run build:ssr && node ./server/index.js",
		"build:client": "cross-env RUN_ENV=client vue-cli-service build",
		"build:server": "cross-env RUN_ENV=server vue-cli-service build",
		"build:ssr": "npm run build:server && npm run build:client"
	}
}

vue.config.js

const ------------------ = require("vue-server-renderer/server-plugin");
const ------------------ = require("vue-server-renderer/client-plugin");
const ------------- = require("webpack-node-externals");
const -------- = -------.---.RUN_ENV === "server";

------.------- = {
	lintOnSave: false,
	publicPath: "./",
	outputDir: `dist/${ process.env.RUN_ENV }`,
	configureWebpack: {
		entry: `./src/main-${ process.env.RUN_ENV }.js`,
		devtool: "eval",
		target: -------- ? "node" : "web",
		output: {
			libraryTarget: -------- ? "commonjs2" : undefined,
		},
		externals: -------- ? nodeExternals({ allowlist: /\.css$/ }) : undefined,
		optimization: {
			splitChunks: -------- ? false : undefined
		},
		plugins: [-------- ? new VueSSRServerPlugin() : new VueSSRClientPlugin()]
	}
};

启动项目

运行下面命令,正常访问即可。

npm --- ---------

我宁愿犯错误,也不愿什么都不做。