├── .vscode
└── settings.json
├── SSR-3
├── .vscode
│ └── settings.json
├── build
│ ├── utils.js
│ ├── webpack.base.js
│ ├── webpack.client.js
│ └── webpack.server.js
├── babel.config.json
├── public
│ ├── index.html
│ └── index.ssr.html
├── dist
│ ├── client.bundle.js.LICENSE.txt
│ ├── server.bundle.js.LICENSE.txt
│ ├── index.html
│ └── index.ssr.html
├── src
│ ├── client-entry.js
│ ├── components
│ │ ├── Foo.vue
│ │ └── Bar.vue
│ ├── main.js
│ ├── router.js
│ ├── App.vue
│ ├── store.js
│ └── server.entry.js
├── package.json
├── server.js
└── 笔记
├── .gitignore
├── SSR-1
├── build
│ ├── utils.js
│ ├── webpack.base.js
│ ├── webpack.client.js
│ └── webpack.server.js
├── src
│ ├── client-entry.js
│ ├── server.entry.js
│ ├── main.js
│ ├── components
│ │ ├── Foo.vue
│ │ └── Bar.vue
│ └── App.vue
├── dist
│ ├── client.bundle.js.LICENSE.txt
│ ├── server.bundle.js.LICENSE.txt
│ ├── index.html
│ ├── index.ssr.html
│ └── server.bundle.js
├── babel.config.json
├── public
│ ├── index.html
│ └── index.ssr.html
├── 笔记
├── package.json
└── server.js
├── SSR-2-ERR
├── build
│ ├── utils.js
│ ├── webpack.base.js
│ ├── webpack.client.js
│ └── webpack.server.js
├── src
│ ├── client-entry.js
│ ├── server.entry.js
│ ├── main.js
│ ├── components
│ │ ├── Foo.vue
│ │ └── Bar.vue
│ └── App.vue
├── dist
│ ├── client.bundle.js.LICENSE.txt
│ ├── server.bundle.js.LICENSE.txt
│ ├── index.ssr.html
│ ├── index.html
│ └── vue-ssr-client-manifest.json
├── babel.config.json
├── public
│ ├── index.html
│ └── index.ssr.html
├── package.json
├── 笔记
└── server.js
├── 单页面配置
├── dist
│ ├── bundle.js.LICENSE.txt
│ ├── index.html
│ └── bundle.js
├── babel.config.json
├── src
│ ├── main.js
│ ├── components
│ │ ├── Bar.vue
│ │ └── Foo.vue
│ └── App.vue
├── public
│ └── index.html
├── template.html
├── 笔记
├── server.js
├── package.json
└── webpack.config.js
├── 基本的服务端渲染
├── template.html
├── package.json
├── server.js
└── package-lock.json
└── README.md
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "git.ignoreLimitWarning": true
3 | }
--------------------------------------------------------------------------------
/SSR-3/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "git.ignoreLimitWarning": true
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .vscode
3 | /单页面配置/node_modules
4 | /SSR-2-ERR/node_modules/
5 | /SSR-3/node_modules/
6 |
--------------------------------------------------------------------------------
/SSR-1/build/utils.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | exports.resolve = dir => {
3 | return path.resolve(__dirname, dir);
4 | };
5 |
--------------------------------------------------------------------------------
/SSR-3/build/utils.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | exports.resolve = dir => {
3 | return path.resolve(__dirname, dir);
4 | };
5 |
--------------------------------------------------------------------------------
/SSR-1/src/client-entry.js:
--------------------------------------------------------------------------------
1 | // 客户端打包
2 | import createApp from "./main";
3 | const { app } = createApp(); //执行导出的函数
4 | app.$mount("#app");
5 |
--------------------------------------------------------------------------------
/SSR-2-ERR/build/utils.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | exports.resolve = dir => {
3 | return path.resolve(__dirname, dir);
4 | };
5 |
--------------------------------------------------------------------------------
/单页面配置/dist/bundle.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vue.js v2.6.12
3 | * (c) 2014-2020 Evan You
4 | * Released under the MIT License.
5 | */
6 |
--------------------------------------------------------------------------------
/SSR-1/dist/client.bundle.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vue.js v2.6.12
3 | * (c) 2014-2020 Evan You
4 | * Released under the MIT License.
5 | */
6 |
--------------------------------------------------------------------------------
/SSR-1/dist/server.bundle.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vue.js v2.6.12
3 | * (c) 2014-2020 Evan You
4 | * Released under the MIT License.
5 | */
6 |
--------------------------------------------------------------------------------
/SSR-2-ERR/src/client-entry.js:
--------------------------------------------------------------------------------
1 | // 客户端打包
2 | import createApp from "./main";
3 | const { app } = createApp(); //执行导出的函数
4 | app.$mount("#app");
5 |
--------------------------------------------------------------------------------
/SSR-2-ERR/dist/client.bundle.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vue.js v2.6.12
3 | * (c) 2014-2020 Evan You
4 | * Released under the MIT License.
5 | */
6 |
--------------------------------------------------------------------------------
/SSR-2-ERR/dist/server.bundle.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * Vue.js v2.6.12
3 | * (c) 2014-2020 Evan You
4 | * Released under the MIT License.
5 | */
6 |
--------------------------------------------------------------------------------
/SSR-1/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "@babel/plugin-transform-runtime"
4 | ],
5 | "presets": [
6 | "@babel/preset-env"
7 | ]
8 | }
--------------------------------------------------------------------------------
/SSR-3/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "@babel/plugin-transform-runtime"
4 | ],
5 | "presets": [
6 | "@babel/preset-env"
7 | ]
8 | }
--------------------------------------------------------------------------------
/单页面配置/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "@babel/plugin-transform-runtime"
4 | ],
5 | "presets": [
6 | "@babel/preset-env"
7 | ]
8 | }
--------------------------------------------------------------------------------
/SSR-2-ERR/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "@babel/plugin-transform-runtime"
4 | ],
5 | "presets": [
6 | "@babel/preset-env"
7 | ]
8 | }
--------------------------------------------------------------------------------
/单页面配置/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App";
3 | const vm = new Vue({
4 | el: "#app",
5 | data: {},
6 | render: h => h(App)
7 | });
8 |
--------------------------------------------------------------------------------
/SSR-2-ERR/dist/index.ssr.html:
--------------------------------------------------------------------------------
1 |
{{title}}
--------------------------------------------------------------------------------
/SSR-1/src/server.entry.js:
--------------------------------------------------------------------------------
1 | // 服务端打包
2 | import createApp from "./main";
3 | export default () => {
4 | // 服务端需要调用当前这个文件 去产生一个vue实例
5 | const { app } = createApp();
6 | return app; //拿这个实例去服务端渲染结果
7 | };
8 | // 服务端配置好后 【打包后】给node来使用
--------------------------------------------------------------------------------
/SSR-2-ERR/src/server.entry.js:
--------------------------------------------------------------------------------
1 | // 服务端打包
2 | import createApp from "./main";
3 | export default () => {
4 | // 服务端需要调用当前这个文件 去产生一个vue实例
5 | const { app } = createApp();
6 | return app; //拿这个实例去服务端渲染结果
7 | };
8 | // 服务端配置好后 【打包后】给node来使用
--------------------------------------------------------------------------------
/SSR-1/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App";
3 | // 客户端和服务端需要区分开 服务端渲染 每个人都应该有一个自己的vue实例
4 | export default () => {
5 | const app = new Vue({
6 | render: h => h(App)
7 | });
8 | return { app };
9 | };
10 |
--------------------------------------------------------------------------------
/SSR-1/dist/index.html:
--------------------------------------------------------------------------------
1 | index
--------------------------------------------------------------------------------
/SSR-2-ERR/dist/index.html:
--------------------------------------------------------------------------------
1 | index
--------------------------------------------------------------------------------
/SSR-2-ERR/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App";
3 | // 客户端和服务端需要区分开 服务端渲染 每个人都应该有一个自己的vue实例
4 | export default () => {
5 | const app = new Vue({
6 | router,
7 | render: h => h(App)
8 | });
9 | return { app };
10 | };
11 |
--------------------------------------------------------------------------------
/单页面配置/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/单页面配置/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{title}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/基本的服务端渲染/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{title}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/SSR-1/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= htmlWebpackPlugin.options.title %>
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SSR-2-ERR/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= htmlWebpackPlugin.options.title %>
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SSR-3/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= htmlWebpackPlugin.options.title %>
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SSR-3/dist/client.bundle.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * vue-router v3.4.7
3 | * (c) 2020 Evan You
4 | * @license MIT
5 | */
6 |
7 | /*!
8 | * Vue.js v2.6.12
9 | * (c) 2014-2020 Evan You
10 | * Released under the MIT License.
11 | */
12 |
13 | /*!
14 | * vuex v3.5.1
15 | * (c) 2020 Evan You
16 | * @license MIT
17 | */
18 |
--------------------------------------------------------------------------------
/SSR-3/dist/server.bundle.js.LICENSE.txt:
--------------------------------------------------------------------------------
1 | /*!
2 | * vue-router v3.4.7
3 | * (c) 2020 Evan You
4 | * @license MIT
5 | */
6 |
7 | /*!
8 | * Vue.js v2.6.12
9 | * (c) 2014-2020 Evan You
10 | * Released under the MIT License.
11 | */
12 |
13 | /*!
14 | * vuex v3.5.1
15 | * (c) 2020 Evan You
16 | * @license MIT
17 | */
18 |
--------------------------------------------------------------------------------
/SSR-1/public/index.ssr.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%= htmlWebpackPlugin.options.title %>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/SSR-3/public/index.ssr.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%= htmlWebpackPlugin.options.title %>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/SSR-2-ERR/public/index.ssr.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%= htmlWebpackPlugin.options.title %>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/单页面配置/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SSR-3/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | index
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/单页面配置/src/components/Bar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
20 |
--------------------------------------------------------------------------------
/单页面配置/src/components/Foo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
20 |
--------------------------------------------------------------------------------
/SSR-1/dist/index.ssr.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{title}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SSR-3/dist/index.ssr.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{title}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SSR-1/src/components/Foo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
26 |
--------------------------------------------------------------------------------
/SSR-3/src/client-entry.js:
--------------------------------------------------------------------------------
1 | // 客户端打包
2 | import createApp from "./main";
3 | const { app, store } = createApp(); //执行导出的函数
4 |
5 | // 浏览器执行的时候需要将服务端设置的最新状态,替换掉客户端的状态。
6 | if (typeof window !== "undefined" && window.__INITIAL_STATE__) {
7 | // 用服务端的数据替换 变成当前最新的状态
8 | // 浏览器中的状态就会变成服务器最新的状态(因为客户端也注入了store 目的就是让页面能取到值this.$store.state)
9 | store.replaceState(window.__INITIAL_STATE__);
10 | }
11 |
12 | app.$mount("#app");
13 |
--------------------------------------------------------------------------------
/SSR-3/src/components/Foo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
26 |
--------------------------------------------------------------------------------
/SSR-2-ERR/src/components/Foo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
17 |
18 |
26 |
--------------------------------------------------------------------------------
/SSR-3/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App";
3 | import createRouter from "./router";
4 | import createStore from "./store";
5 | // 客户端和服务端需要区分开 服务端渲染 每个人都应该有一个自己的vue实例
6 | export default () => {
7 | const router = createRouter(); //创建新的router实例
8 | const store = createStore();
9 | const app = new Vue({
10 | router,
11 | store,
12 | render: h => h(App)
13 | });
14 | return { app, router, store };
15 | };
16 |
--------------------------------------------------------------------------------
/单页面配置/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
26 |
27 |
--------------------------------------------------------------------------------
/SSR-1/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
26 |
27 |
--------------------------------------------------------------------------------
/SSR-2-ERR/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
26 |
27 |
--------------------------------------------------------------------------------
/SSR-2-ERR/build/webpack.base.js:
--------------------------------------------------------------------------------
1 | // 基础的webapck配置 服务端和客户端打包都基于它
2 | const VueLoaderPlugin = require("vue-loader/lib/plugin");
3 | const utils = require("./utils");
4 | module.exports = {
5 | output: {
6 | filename: "[name].bundle.js",
7 | path: utils.resolve("../dist")
8 | },
9 | resolve: {
10 | extensions: [".vue", ".js"]
11 | },
12 | devServer: {
13 | port: Math.floor(Math.random().toFixed(2) * 10000)
14 | },
15 |
16 | plugins: [new VueLoaderPlugin()]
17 | };
18 |
--------------------------------------------------------------------------------
/SSR-3/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Router from "vue-router";
3 | import Foo from "./components/Foo";
4 | import Bar from "./components/Bar";
5 | // 每个服务器创建应用,都应该有一个自己的路由。所以路由也需要写成一个函数
6 | // 每次调用都产生一个路由系统
7 |
8 | Vue.use(Router);
9 |
10 | export default () => {
11 | const router = new Router({
12 | mode: "history",
13 | // 动态路由必须返回一个promise函数
14 | routes: [{ path: "/", component: Foo }, { path: "/Bar", component: Bar }]
15 | });
16 | return router;
17 | };
18 |
--------------------------------------------------------------------------------
/SSR-1/src/components/Bar.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
24 |
25 |
30 |
--------------------------------------------------------------------------------
/SSR-2-ERR/src/components/Bar.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
24 |
25 |
30 |
--------------------------------------------------------------------------------
/基本的服务端渲染/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "base-ssr",
3 | "version": "1.0.0",
4 | "description": "base-ssr",
5 | "main": "main.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "wensiyuan",
10 | "license": "ISC",
11 | "dependencies": {
12 | "koa": "^2.13.0",
13 | "koa-router": "^9.4.0",
14 | "koa-static": "^5.0.0",
15 | "vue": "^2.6.12",
16 | "vue-router": "^3.4.7",
17 | "vue-server-renderer": "^2.6.12",
18 | "vuex": "^3.5.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SSR-1/build/webpack.base.js:
--------------------------------------------------------------------------------
1 | // 基础的webapck配置 服务端和客户端打包都基于它
2 | const VueLoaderPlugin = require("vue-loader/lib/plugin");
3 | const utils = require("./utils");
4 | module.exports = {
5 | output: {
6 | filename: "[name].bundle.js",
7 | path: utils.resolve("../dist")
8 | },
9 | resolve: {
10 | extensions: [".vue", ".js"]
11 | },
12 | devServer: {
13 | port: Math.floor(Math.random().toFixed(2) * 10000)
14 | },
15 |
16 | plugins: [new VueLoaderPlugin()]
17 | // devtool: "source-map" // 输出 source-map 方便直接调试 ES6 源码
18 | };
19 |
--------------------------------------------------------------------------------
/SSR-3/build/webpack.base.js:
--------------------------------------------------------------------------------
1 | // 基础的webapck配置 服务端和客户端打包都基于它
2 | const VueLoaderPlugin = require("vue-loader/lib/plugin");
3 | const utils = require("./utils");
4 | module.exports = {
5 | output: {
6 | filename: "[name].bundle.js",
7 | path: utils.resolve("../dist")
8 | },
9 | resolve: {
10 | extensions: [".vue", ".js"]
11 | },
12 | devServer: {
13 | port: Math.floor(Math.random().toFixed(2) * 10000)
14 | },
15 |
16 | plugins: [new VueLoaderPlugin()]
17 | // devtool: "source-map" // 输出 source-map 方便直接调试 ES6 源码
18 | };
19 |
--------------------------------------------------------------------------------
/SSR-3/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 我是App哈哈哈
4 | Foo
5 | Bar
6 |
7 |
8 |
9 |
10 |
27 |
28 |
--------------------------------------------------------------------------------
/SSR-2-ERR/dist/vue-ssr-client-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "publicPath": "auto",
3 | "all": [
4 | "client.bundle.js"
5 | ],
6 | "initial": [
7 | "client.bundle.js"
8 | ],
9 | "async": [
10 | "client.bundle.js"
11 | ],
12 | "modules": {
13 | "3b8cad02": [
14 | 0
15 | ],
16 | "4a526035": [
17 | 0
18 | ],
19 | "247d24e8": [
20 | 0
21 | ],
22 | "51a1d93f": [
23 | 0
24 | ],
25 | "d7e9791e": [
26 | 0
27 | ],
28 | "326c9dc8": [
29 | 0
30 | ],
31 | "8da141ea": [
32 | 0
33 | ],
34 | "6fbc4fdc": [
35 | 0
36 | ],
37 | "35b75c20": [
38 | 0
39 | ]
40 | }
41 | }
--------------------------------------------------------------------------------
/单页面配置/笔记:
--------------------------------------------------------------------------------
1 | 一些包
2 | webpack相关
3 | webpack
4 | webpack-cli //命令行解析工具 4.0之前是一起的 4.0之后拆开了 需要安装
5 | webpack-dev-server
6 |
7 | es6转es5
8 | babel-loader //es6=>es5 webpack中接入babel
9 | @babel/core // babel-loader依赖
10 | @babel/preset-env //加入新的语法特性 比如2015年加入的新特性 Env包括所有的新特性
11 | @babel/plugin-transform-runtime 减少冗余代码 默认的polifill属性已经被废除掉了
12 | @babel/runtime @babel/plugin-transform-runtime依赖
13 |
14 | 解析css的包
15 | vue-style-loader //支持服务端渲染 和style-loader功能一样
16 | css-loader
17 |
18 | 处理vue
19 | vue-loader 处理.vue文件
20 | vue-template-loader //处理模板编译
21 |
22 | html-webpack-plugin
23 | webpack-merge
24 |
25 |
26 | ----------------------------
27 | npx webpack === node_modules/bin/webpack // 这是打包
28 |
29 |
30 |
31 | 关于babel的配置
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/SSR-3/src/components/Bar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bar
5 |
7 | {{ this.$store.state}}
8 |
9 |
10 |
11 |
37 |
38 |
43 |
--------------------------------------------------------------------------------
/基本的服务端渲染/server.js:
--------------------------------------------------------------------------------
1 | const Koa = require("koa");
2 | const Router = require("koa-router");
3 | const Vue = require("Vue");
4 | const vueServerRender = require("vue-server-renderer");
5 | const app = new Koa();
6 | const router = new Router();
7 | const vm = new Vue({
8 | data: {
9 | msg: "hello,ssr"
10 | },
11 | template: `{{msg}}
`
12 | });
13 |
14 | // 创建一个渲染器 为了把vue渲染成字符串
15 | // vueServerRender身上有两个方法 renderToString ,renderToStream 把生成的字符串插入到body中
16 | const render = vueServerRender.createRenderer({
17 | template: require("fs").readFileSync("./template.html", "utf-8") //把渲染出来的字符串塞到html模板的body中,再由服务端吐出来 模板中必须带有
18 | });
19 | router.get("/", async ctx => {
20 | // ctx.body='hello,ssr'
21 | ctx.body = await render.renderToString(vm, { title: "base-ssr" }); //返回promise 结果为 'hello,ssr
' 会把结果塞给template
22 | });
23 |
24 | app.use(router.routes());
25 |
26 | app.listen(3004, () => {
27 | console.log("服务器开启成功");
28 | });
29 |
--------------------------------------------------------------------------------
/单页面配置/server.js:
--------------------------------------------------------------------------------
1 | const Koa = require("koa");
2 | const Router = require("koa-router");
3 | const Vue = require("Vue");
4 | const vueServerRender = require("vue-server-renderer");
5 |
6 | const app = new Koa();
7 | const router = new Router();
8 | const vm = new Vue({
9 | data: {
10 | msg: "hello,ssr"
11 | },
12 | template: `{{msg}}
`
13 | });
14 |
15 | // 创建一个渲染器 为了把vue渲染成字符串
16 | // vueServerRender身上有两个方法 renderToString ,renderToStream 把生成的字符串插入到body中
17 | const render = vueServerRender.createRenderer({
18 | template: require("fs").readFileSync("./template.html", "utf-8") //把渲染出来的字符串塞到html模板的body中,再由服务端吐出来 模板中必须带有
19 | });
20 | router.get("/", async ctx => {
21 | // ctx.body='hello,ssr'
22 | ctx.body = await render.renderToString(vm, { title: "base-ssr" }); //返回promise 结果为 'hello,ssr
' 会把结果塞给template
23 | });
24 |
25 | app.use(router.routes());
26 |
27 | app.listen(300, () => {
28 | console.log("服务器开启成功");
29 | });
30 |
--------------------------------------------------------------------------------
/SSR-1/build/webpack.client.js:
--------------------------------------------------------------------------------
1 | const Merge = require("webpack-merge");
2 | const base = require("./webpack.base");
3 | const HtmlWebpackPlugin = require("html-webpack-plugin");
4 | const utils = require("./utils");
5 | module.exports = Merge.merge(base, {
6 | entry: {
7 | client: utils.resolve("./../src/client-entry.js")
8 | },
9 | module: {
10 | rules: [
11 | {
12 | test: /\.js$/,
13 | use: {
14 | loader: "babel-loader",
15 | options: {
16 | presets: ["@babel/preset-env"] //新的语法特性 如果需要生效还需要再。babelsrc中配置
17 | }
18 | },
19 | exclude: /node_modules/
20 | },
21 | {
22 | test: /.vue$/,
23 | use: "vue-loader"
24 | },
25 | {
26 | test: /\.css$/,
27 | use: ["style-loader", "css-loader"]
28 | }
29 | ]
30 | },
31 | plugins: [
32 | new HtmlWebpackPlugin({
33 | title: "index",
34 | filename: "index.html",
35 | template: utils.resolve("./../public/index.html")
36 | })
37 | ]
38 | });
39 |
--------------------------------------------------------------------------------
/SSR-3/build/webpack.client.js:
--------------------------------------------------------------------------------
1 | const Merge = require("webpack-merge");
2 | const base = require("./webpack.base");
3 | const HtmlWebpackPlugin = require("html-webpack-plugin");
4 | const utils = require("./utils");
5 | module.exports = Merge.merge(base, {
6 | entry: {
7 | client: utils.resolve("./../src/client-entry.js")
8 | },
9 | module: {
10 | rules: [
11 | {
12 | test: /\.js$/,
13 | use: {
14 | loader: "babel-loader",
15 | options: {
16 | presets: ["@babel/preset-env"] //新的语法特性 如果需要生效还需要再。babelsrc中配置
17 | }
18 | },
19 | exclude: /node_modules/
20 | },
21 | {
22 | test: /.vue$/,
23 | use: "vue-loader"
24 | },
25 | {
26 | test: /\.css$/,
27 | use: ["style-loader", "css-loader"]
28 | }
29 | ]
30 | },
31 | plugins: [
32 | new HtmlWebpackPlugin({
33 | title: "index",
34 | filename: "index.html",
35 | template: utils.resolve("./../public/index.html")
36 | })
37 | ]
38 | });
39 |
--------------------------------------------------------------------------------
/单页面配置/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-ssr-example",
3 | "version": "1.0.0",
4 | "description": "base-ssr",
5 | "main": "main.js",
6 | "scripts": {
7 | "start": "webpack serve ",
8 | "watch": "webpack --watch"
9 | },
10 | "author": "wensiyuan",
11 | "license": "ISC",
12 | "dependencies": {
13 | "@babel/runtime": "^7.12.1",
14 | "koa": "^2.13.0",
15 | "koa-router": "^9.4.0",
16 | "koa-static": "^5.0.0",
17 | "vue": "^2.6.12",
18 | "vue-router": "^3.4.7",
19 | "vue-server-renderer": "^2.6.12",
20 | "vuex": "^3.5.1"
21 | },
22 | "devDependencies": {
23 | "@babel/core": "^7.12.3",
24 | "@babel/plugin-transform-runtime": "^7.12.1",
25 | "@babel/preset-env": "^7.12.1",
26 | "babel-loader": "^8.1.0",
27 | "css-loader": "^5.0.0",
28 | "html-webpack-plugin": "^4.5.0",
29 | "vue-loader": "^15.9.3",
30 | "vue-style-loader": "^4.1.2",
31 | "vue-template-compiler": "^2.6.12",
32 | "vue-template-loader": "^1.1.0",
33 | "webpack": "^5.2.0",
34 | "webpack-cli": "^4.1.0",
35 | "webpack-dev-server": "^3.11.0",
36 | "webpack-merge": "^5.2.0"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/SSR-2-ERR/build/webpack.client.js:
--------------------------------------------------------------------------------
1 | const Merge = require("webpack-merge");
2 | const base = require("./webpack.base");
3 | const HtmlWebpackPlugin = require("html-webpack-plugin");
4 | const utils = require("./utils");
5 | // 生成一个目录映射
6 | const ClientRenderPlugin = require("vue-server-renderer/client-plugin");
7 | module.exports = Merge.merge(base, {
8 | entry: {
9 | client: utils.resolve("./../src/client-entry.js")
10 | },
11 | module: {
12 | rules: [
13 | {
14 | test: /\.js$/,
15 | use: {
16 | loader: "babel-loader",
17 | options: {
18 | presets: ["@babel/preset-env"] //新的语法特性 如果需要生效还需要再。babelsrc中配置
19 | }
20 | },
21 | exclude: /node_modules/
22 | },
23 | {
24 | test: /.vue$/,
25 | use: "vue-loader"
26 | },
27 | {
28 | test: /\.css$/,
29 | use: ["style-loader", "css-loader"]
30 | }
31 | ]
32 | },
33 | plugins: [
34 | new ClientRenderPlugin(),
35 | new HtmlWebpackPlugin({
36 | title: "index",
37 | filename: "index.html",
38 | template: utils.resolve("./../public/index.html")
39 | })
40 | ]
41 | });
42 |
--------------------------------------------------------------------------------
/SSR-1/笔记:
--------------------------------------------------------------------------------
1 | 一些包
2 | webpack相关
3 | webpack
4 | webpack-cli //命令行解析工具 4.0之前是一起的 4.0之后拆开了 需要安装
5 | webpack-dev-server
6 |
7 | es6转es5
8 | babel-loader //es6=>es5 webpack中接入babel
9 | @babel/core // babel-loader依赖
10 | @babel/preset-env //加入新的语法特性 比如2015年加入的新特性 Env包括所有的新特性
11 | @babel/plugin-transform-runtime 减少冗余代码 默认的polifill属性已经被废除掉了
12 | @babel/runtime @babel/plugin-transform-runtime依赖
13 |
14 | 解析css的包
15 | vue-style-loader //支持服务端渲染 和style-loader功能一样
16 | css-loader
17 |
18 | 处理vue
19 | vue-loader 处理.vue文件
20 | vue-template-loader //处理模板编译
21 |
22 | html-webpack-plugin
23 | webpack-merge
24 |
25 |
26 | ----------------------------
27 | npx webpack === node_modules/bin/webpack // 这是打包
28 |
29 |
30 |
31 | webpack5.0 bug记录
32 |
33 | webpack5.0与webpack-dev-server不兼容
34 |
35 | npm script 需把 "run":"webpack-dev-server --open"改成
36 | "run":"webpack serve"
37 |
38 |
39 | vue-style-loader与css-loader 在服务端打包时style样式不生效问题解决方案
40 |
41 | {
42 | test: /\.css$/,
43 | use: [
44 | "vue-style-loader",
45 | {
46 | loader: "css-loader",
47 | options: {
48 | esModule: false //默认为true 需要设置为false
49 | }
50 | }
51 | ]
52 | }
53 |
54 |
55 | npm run client:build -- --watch 文件变动执行打包编译
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/单页面配置/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const HtmlWebpackPlugin = require("html-webpack-plugin");
3 | const VueLoaderPlugin = require("vue-loader/lib/plugin");
4 | const resolve = dir => {
5 | return path.resolve(__dirname, dir);
6 | };
7 | module.exports = {
8 | entry: resolve("./src/main.js"),
9 | output: {
10 | filename: "bundle.js",
11 | path: resolve("dist")
12 | },
13 | resolve: {
14 | extensions: [".vue", ".js"]
15 | },
16 | devServer: {
17 | contentBase: "./dist"
18 | },
19 | module: {
20 | rules: [
21 | {
22 | test: /\.css$/,
23 | use: ["vue-style-loader", "css-loader"]
24 | },
25 | {
26 | test: /\.js$/,
27 | use: {
28 | loader: "babel-loader",
29 | options: {
30 | presets: ["@babel/preset-env"] //新的语法特性 如果需要生效还需要再。babelsrc中配置
31 | }
32 | },
33 | exclude: /node_modules/
34 | },
35 | {
36 | test: /.vue$/,
37 | use: "vue-loader"
38 | }
39 | ]
40 | },
41 | plugins: [
42 | new VueLoaderPlugin(),
43 | new HtmlWebpackPlugin({
44 | filename: "index.html",
45 | template: resolve("./public/index.html")
46 | })
47 | ],
48 | devtool: "source-map" // 输出 source-map 方便直接调试 ES6 源码
49 | };
50 |
--------------------------------------------------------------------------------
/SSR-3/src/store.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import Vuex from "vuex";
3 | Vue.use(Vuex);
4 | //服务端和客户端都会走此逻辑 服务端先走 客户端再走
5 | export default () => {
6 | let store = new Vuex.Store({
7 | state: {
8 | username: "song",
9 | email: "123456"
10 | },
11 | mutations: {
12 | changeName(state) {
13 | state.username = "hello";
14 | },
15 | changeEmail(state) {
16 | state.email = "178382039@qq.com";
17 | }
18 | },
19 | actions: {
20 | // 此处如果是服务端调用必须返回 promise 否则不生效 因为在service.entry.js的逻辑是Promise.all()
21 | // 自己有里面的所有数据都获取完之后才会渲染app.vue 所以会等待三秒才渲染数据
22 | // 只写setTimeout 不生效 因为setTimeout是异步的,在vuex实例渲染完成后才被调用,此时页面已经被当成字符串渲染到浏览器上了。
23 | changeName({ commit }) {
24 | return new Promise((resolve, reject) => {
25 | setTimeout(() => {
26 | commit("changeName");
27 | resolve();
28 | }, 3000);
29 | });
30 | },
31 | changeEmail({ commit }) {
32 | setTimeout(() => {
33 | commit("changeEmail");
34 | }, 2000);
35 | }
36 | }
37 | });
38 | return store;
39 | };
40 |
41 | // 解释流程
42 |
43 | // 刷新页面--先执行服务端渲染-执行vuex-把state挂载到window上
44 | // 客户端(client.bundle.js)执行时,通过store.replaceState()把执行的结果替换掉, 客户端也就是指引入的js逻辑比如 mounted(){}
45 | // 那么此时拿到的我就是最新状态 此时我们再去取值那就是设置好的状态了
46 |
--------------------------------------------------------------------------------
/SSR-1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-ssr-example",
3 | "version": "1.0.0",
4 | "description": "base-ssr",
5 | "main": "main.js",
6 | "scripts": {
7 | "dev": "webpack serve --config ./build/webpack.client.js --mode development",
8 | "client:build": "webpack --config ./build/webpack.client.js --mode production",
9 | "server:build": "webpack --config ./build/webpack.server.js --mode production"
10 | },
11 | "author": "wensiyuan",
12 | "license": "ISC",
13 | "dependencies": {
14 | "@babel/runtime": "^7.12.1",
15 | "koa": "^2.13.0",
16 | "koa-router": "^9.4.0",
17 | "koa-static": "^5.0.0",
18 | "vue": "^2.6.12",
19 | "vue-router": "^3.4.7",
20 | "vue-server-renderer": "^2.6.12",
21 | "vuex": "^3.5.1"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.12.3",
25 | "@babel/plugin-transform-runtime": "^7.12.1",
26 | "@babel/preset-env": "^7.12.1",
27 | "babel-loader": "^8.1.0",
28 | "css-loader": "^5.0.0",
29 | "html-webpack-plugin": "^4.5.0",
30 | "style-loader": "^2.0.0",
31 | "vue-loader": "^15.9.3",
32 | "vue-style-loader": "^4.1.2",
33 | "vue-template-compiler": "^2.6.12",
34 | "vue-template-loader": "^1.1.0",
35 | "webpack": "^5.2.0",
36 | "webpack-cli": "^4.1.0",
37 | "webpack-dev-server": "^3.11.0",
38 | "webpack-merge": "^5.2.0"
39 | }
40 | }
--------------------------------------------------------------------------------
/SSR-3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-ssr-example",
3 | "version": "1.0.0",
4 | "description": "base-ssr",
5 | "main": "main.js",
6 | "scripts": {
7 | "dev": "webpack serve --config ./build/webpack.client.js --mode development",
8 | "client:build": "webpack --config ./build/webpack.client.js --mode production",
9 | "server:build": "webpack --config ./build/webpack.server.js --mode production"
10 | },
11 | "author": "wensiyuan",
12 | "license": "ISC",
13 | "dependencies": {
14 | "@babel/runtime": "^7.12.1",
15 | "koa": "^2.13.0",
16 | "koa-router": "^9.4.0",
17 | "koa-static": "^5.0.0",
18 | "vue": "^2.6.12",
19 | "vue-router": "^3.4.7",
20 | "vue-server-renderer": "^2.6.12",
21 | "vuex": "^3.5.1"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.12.3",
25 | "@babel/plugin-transform-runtime": "^7.12.1",
26 | "@babel/preset-env": "^7.12.1",
27 | "babel-loader": "^8.1.0",
28 | "css-loader": "^5.0.0",
29 | "html-webpack-plugin": "^4.5.0",
30 | "style-loader": "^2.0.0",
31 | "vue-loader": "^15.9.3",
32 | "vue-style-loader": "^4.1.2",
33 | "vue-template-compiler": "^2.6.12",
34 | "vue-template-loader": "^1.1.0",
35 | "webpack": "^5.2.0",
36 | "webpack-cli": "^4.1.0",
37 | "webpack-dev-server": "^3.11.0",
38 | "webpack-merge": "^5.2.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/SSR-2-ERR/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-ssr-example",
3 | "version": "1.0.0",
4 | "description": "base-ssr",
5 | "main": "main.js",
6 | "scripts": {
7 | "dev": "webpack serve --config ./build/webpack.client.js --mode development",
8 | "client:build": "webpack --config ./build/webpack.client.js --mode production",
9 | "server:build": "webpack --config ./build/webpack.server.js --mode production"
10 | },
11 | "author": "wensiyuan",
12 | "license": "ISC",
13 | "dependencies": {
14 | "@babel/runtime": "^7.12.1",
15 | "koa": "^2.13.0",
16 | "koa-router": "^9.4.0",
17 | "koa-static": "^5.0.0",
18 | "vue": "^2.6.12",
19 | "vue-router": "^3.4.7",
20 | "vue-server-renderer": "^2.6.12",
21 | "vuex": "^3.5.1"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.12.3",
25 | "@babel/plugin-transform-runtime": "^7.12.1",
26 | "@babel/preset-env": "^7.12.1",
27 | "babel-loader": "^8.1.0",
28 | "css-loader": "^5.0.0",
29 | "html-webpack-plugin": "^4.5.0",
30 | "style-loader": "^2.0.0",
31 | "vue-loader": "^15.9.3",
32 | "vue-style-loader": "^4.1.2",
33 | "vue-template-compiler": "^2.6.12",
34 | "vue-template-loader": "^1.1.0",
35 | "webpack": "^5.2.0",
36 | "webpack-cli": "^4.1.0",
37 | "webpack-dev-server": "^3.11.0",
38 | "webpack-merge": "^5.2.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/SSR-1/server.js:
--------------------------------------------------------------------------------
1 | const Koa = require("koa");
2 | const Router = require("koa-router");
3 | const static = require("koa-static");
4 | const vueServerRender = require("vue-server-renderer");
5 | const fs = require("fs");
6 | const { pathToFileURL } = require("url");
7 | const app = new Koa();
8 | const router = new Router();
9 | const path = require("path");
10 | const serverBundle = fs.readFileSync("./dist/server.bundle.js", "utf8");
11 | const template = fs.readFileSync("./dist/index.ssr.html", "utf8");
12 | // 渲染打包后的结果
13 | const render = vueServerRender.createBundleRenderer(serverBundle, {
14 | template
15 | });
16 |
17 | // koa只能用promise
18 | router.get("/", async ctx => {
19 | // 此时打包之后的结果全是字符串,字符串没有任何的事件功能 所以js逻辑不生效(打包之后vue-server-render也会丢弃js逻辑,所以页面中只有css(vue-style-loader的功劳)和html逻辑)
20 | // 所以需要把客户端打包后的结果挂载到模板上,因为客户端代码包含事件逻辑
21 | // 此时需要三个个步骤 1.在模板(dist目录)中先手动引入客户端打包后的结果 (因为js中的事件逻辑不需要被怕成爬取)
22 | // 2.但此时服务器并没有读取此文件,所以需要koa-static静态服务中间件 去dist查找此文件
23 | // 3.需要在App.vue中指定id='app' ,客户端激活
24 | // 这种方法比较笨
25 |
26 | ctx.body = await new Promise((resolve, reject) => {
27 | // 必须写成回调函数的形式否则css样式不生效
28 | render.renderToString(
29 | {
30 | title: "服务"
31 | },
32 | (err, data) => {
33 | if (err) reject(err);
34 | resolve(data);
35 | }
36 | );
37 | }); // 返回promise 结果为 'hello,ssr
' 会把结果塞给template
38 | });
39 |
40 | app.use(router.routes());
41 | // koa静态服务中间件 会去dist目录插查找看是否有client.bundle.js 如果有就从服务器中返回此文件
42 | app.use(static(path.resolve(__dirname, "dist")));
43 | let port = 8003;
44 | app.listen(port, () => {
45 | console.log("服务器开启成功");
46 | });
47 |
--------------------------------------------------------------------------------
/SSR-2-ERR/笔记:
--------------------------------------------------------------------------------
1 | 一些包
2 | webpack相关
3 | webpack
4 | webpack-cli //命令行解析工具 4.0之前是一起的 4.0之后拆开了 需要安装
5 | webpack-dev-server
6 |
7 | es6转es5
8 | babel-loader //es6=>es5 webpack中接入babel
9 | @babel/core // babel-loader依赖
10 | @babel/preset-env //加入新的语法特性 比如2015年加入的新特性 Env包括所有的新特性
11 | @babel/plugin-transform-runtime 减少冗余代码 默认的polifill属性已经被废除掉了
12 | @babel/runtime @babel/plugin-transform-runtime依赖
13 |
14 | 解析css的包
15 | vue-style-loader //支持服务端渲染 和style-loader功能一样
16 | css-loader
17 |
18 | 处理vue
19 | vue-loader 处理.vue文件
20 | vue-template-loader //处理模板编译
21 |
22 | html-webpack-plugin
23 | webpack-merge
24 |
25 |
26 | ----------------------------
27 | npx webpack === node_modules/bin/webpack // 这是打包
28 |
29 |
30 |
31 | webpack5.0 bug记录
32 |
33 | 问题一
34 |
35 | webpack5.0与webpack-dev-server不兼容
36 |
37 | npm script 需把 "run":"webpack-dev-server --open"改成
38 | "run":"webpack serve"
39 |
40 | 问题2
41 |
42 | vue-style-loader与css-loader 在服务端打包时style样式不生效问题解决方案
43 |
44 | {
45 | test: /\.css$/,
46 | use: [
47 | "vue-style-loader",
48 | {
49 | loader: "css-loader",
50 | options: {
51 | esModule: false //默认为true 需要设置为false
52 | }
53 | }
54 | ]
55 | }
56 |
57 |
58 | 问题三
59 | build目录中 webpack.server.js
60 | const ServerRenderPlugin = require("vue-server-renderer/server-plugin") 报错
61 |
62 | 解决方案 修改vue-server-renderer包中的代码
63 |
64 | https://github.com/vuejs/vue/issues/11718#issuecomment-717786088
65 |
66 |
67 |
68 | 问题四
69 |
70 | 使用 const ClientRenderPlugin = require("vue-server-renderer/client-plugin");
71 | const ServerRenderPlugin = require("vue-server-renderer/server-plugin");
72 | 自动引入js文件时服务端会报错 展示没有解决办法 需要手动引入js文件
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/SSR-3/src/server.entry.js:
--------------------------------------------------------------------------------
1 | // 服务端打包
2 | import createApp from "./main";
3 | // 通过server.js文件中的toString传进来的参数
4 | // 服务端会执行此方法
5 |
6 | export default context => {
7 | // // 服务端需要调用当前这个文件 去产生一个vue实例
8 | // const { app, router } = createApp();
9 | // // context.url 服务端要把对应的路由和此url相匹配
10 | // router.push(context.url); //渲染当前页面对应的路由
11 | // return app; //拿这个实例去服务端渲染结果
12 |
13 | // 为了异步渲染 建议使用promise 服务端renderToString会等待promise执行完成再执行
14 | return new Promise((resolve, reject) => {
15 | // 服务端需要调用当前这个文件 去产生一个vue实例
16 | const { app, router, store } = createApp();
17 | // context.url 服务端要把对应的路由和此url相匹配
18 | router.push(context.url); //渲染当前页面对应的路由
19 | // 页面跳转成功之后,所有异步组件加载完毕再执行
20 | router.onReady(() => {
21 | // 获取当前跳转匹配到的所有组件,整个都在服务端执行
22 | const match = router.getMatchedComponents();
23 | if (match.length === 0) {
24 | //会走到renderToString的err中
25 | reject({ code: 404 });
26 | }
27 | // 有可能匹配多个组件
28 | Promise.all(
29 | match.map(component => {
30 | // 只是在服务端渲染好之后返回出去的
31 | if (component.asyncData) {
32 | // 如果服务端没有asyncData更改状态 是不需要等待的
33 | //asyncData是在服务端调用的。如果当前的路由组件有asyncData函数 就执行此函数。
34 | return component.asyncData(store);
35 | }
36 | })
37 | ).then(() => {
38 | // Parmise.all()中的方法会改变store中的state 此时数据已经被改变
39 | // 服务器执行完成之后把状态改变了 会在window上生成一个变量
40 | // __INITIAL_STATE__是固定的名字
41 | context.state = store.state; //名字必须为state(规定) 把vuex的状态挂载到上下文中,会将状态挂载到window上
42 | // {
43 | // title: "服务",
44 | // url: ctx.url,
45 | // context:store.state
46 | // },
47 | resolve(app);
48 | });
49 | }, reject);
50 | });
51 | };
52 | // 服务端配置好后 【打包后】给node来使用
53 |
--------------------------------------------------------------------------------
/SSR-1/build/webpack.server.js:
--------------------------------------------------------------------------------
1 | const Merge = require("webpack-merge");
2 | const base = require("./webpack.base");
3 | const HtmlWebpackPlugin = require("html-webpack-plugin");
4 | const utils = require("./utils");
5 | const { node } = require("webpack");
6 | module.exports = Merge.merge(base, {
7 | entry: {
8 | server: utils.resolve("./../src/server.entry.js")
9 | },
10 | target: "node", //打包后的结果给node来使用 node中会使用const path=require('path') 如果不指定为node环境 打包后的结果会包含path模块
11 | output: {
12 | libraryTarget: "commonjs2" //打包后的结果给node来使用 把最终执行的结果放到module.exports上
13 | /** node执行原理
14 | (function(){
15 | //自己的代码
16 | function(){}
17 | })()
18 | */
19 | },
20 | module: {
21 | rules: [
22 | {
23 | test: /.vue$/,
24 | use: "vue-loader"
25 | // options: {
26 | // // enable CSS extraction
27 | // extractCSS: true
28 | // }
29 | },
30 | {
31 | test: /\.js$/,
32 | use: {
33 | loader: "babel-loader",
34 | options: {
35 | presets: ["@babel/preset-env"] //新的语法特性 如果需要生效还需要再。babelsrc中配置
36 | }
37 | },
38 | exclude: /node_modules/
39 | },
40 | {
41 | test: /\.css$/,
42 | use: [
43 | "vue-style-loader",
44 | {
45 | loader: "css-loader",
46 | options: {
47 | esModule: false
48 | }
49 | }
50 | ]
51 | }
52 | ]
53 | },
54 | plugins: [
55 | new HtmlWebpackPlugin({
56 | title: "{{title}}",
57 | minify: {
58 | collapseWhitespace: true, //压缩代码
59 | removeComments: false //不移除注释
60 | },
61 | filename: "index.ssr.html",
62 | template: utils.resolve("./../public/index.ssr.html"),
63 | excludeChunks: ["server"] //排除在模板中引用打包之后的server.js
64 | })
65 | ]
66 | });
67 |
--------------------------------------------------------------------------------
/SSR-3/build/webpack.server.js:
--------------------------------------------------------------------------------
1 | const Merge = require("webpack-merge");
2 | const base = require("./webpack.base");
3 | const HtmlWebpackPlugin = require("html-webpack-plugin");
4 | const utils = require("./utils");
5 | const { node } = require("webpack");
6 | module.exports = Merge.merge(base, {
7 | entry: {
8 | server: utils.resolve("./../src/server.entry.js")
9 | },
10 | target: "node", //打包后的结果给node来使用 node中会使用const path=require('path') 如果不指定为node环境 打包后的结果会包含path模块
11 | output: {
12 | libraryTarget: "commonjs2" // 打包后的结果给node来使用 把最终执行的结果放到module.exports上
13 | /** node执行原理
14 | (function(){
15 | //自己的代码
16 | function(){}
17 | })()
18 | */
19 | },
20 | module: {
21 | rules: [
22 | {
23 | test: /.vue$/,
24 | use: "vue-loader"
25 | // options: {
26 | // // enable CSS extraction
27 | // extractCSS: true
28 | // }
29 | },
30 | {
31 | test: /\.js$/,
32 | use: {
33 | loader: "babel-loader",
34 | options: {
35 | presets: ["@babel/preset-env"] //新的语法特性 如果需要生效还需要再。babelsrc中配置
36 | }
37 | },
38 | exclude: /node_modules/
39 | },
40 | {
41 | test: /\.css$/,
42 | use: [
43 | "vue-style-loader",
44 | {
45 | loader: "css-loader",
46 | options: {
47 | esModule: false
48 | }
49 | }
50 | ]
51 | }
52 | ]
53 | },
54 | plugins: [
55 | new HtmlWebpackPlugin({
56 | title: "{{title}}",
57 | minify: {
58 | collapseWhitespace: true, //压缩代码
59 | removeComments: false //不移除注释
60 | },
61 | filename: "index.ssr.html",
62 | template: utils.resolve("./../public/index.ssr.html"),
63 | excludeChunks: ["server"] //排除在模板中引用打包之后的server.js
64 | })
65 | ]
66 | });
67 |
--------------------------------------------------------------------------------
/SSR-2-ERR/build/webpack.server.js:
--------------------------------------------------------------------------------
1 | const Merge = require("webpack-merge");
2 | const base = require("./webpack.base");
3 | const HtmlWebpackPlugin = require("html-webpack-plugin");
4 | const utils = require("./utils");
5 | // 打包出一个文件 指向server.bundle.js
6 | const ServerRenderPlugin = require("vue-server-renderer/server-plugin");
7 | module.exports = Merge.merge(base, {
8 | entry: {
9 | server: utils.resolve("./../src/server.entry.js")
10 | },
11 | target: "node", //打包后的结果给node来使用 node中会使用const path=require('path') 如果不指定为node环境 打包后的结果会包含path模块
12 | output: {
13 | libraryTarget: "commonjs2" // 打包后的结果给node来使用 把最终执行的结果放到 module.exports上
14 | /** node执行原理
15 | (function(){
16 | //自己的代码
17 | function(){}
18 | })()
19 | */
20 | },
21 | module: {
22 | rules: [
23 | {
24 | test: /.vue$/,
25 | use: "vue-loader"
26 | // options: {
27 | // // enable CSS extraction
28 | // extractCSS: true
29 | // }
30 | },
31 | {
32 | test: /\.js$/,
33 | use: {
34 | loader: "babel-loader",
35 | options: {
36 | presets: ["@babel/preset-env"] //新的语法特性 如果需要生效还需要再。babelsrc中配置
37 | }
38 | },
39 | exclude: /node_modules/
40 | },
41 | {
42 | test: /\.css$/,
43 | use: [
44 | "vue-style-loader",
45 | {
46 | loader: "css-loader",
47 | options: {
48 | esModule: false
49 | }
50 | }
51 | ]
52 | }
53 | ]
54 | },
55 | plugins: [
56 | new ServerRenderPlugin(),
57 | new HtmlWebpackPlugin({
58 | title: "{{title}}",
59 | minify: {
60 | collapseWhitespace: true, //压缩代码
61 | removeComments: false //不移除注释
62 | },
63 | filename: "index.ssr.html",
64 | template: utils.resolve("./../public/index.ssr.html"),
65 | excludeChunks: ["server"] // 排除在模板中引用打包之后的server.js
66 | })
67 | ]
68 | });
69 |
--------------------------------------------------------------------------------
/SSR-2-ERR/server.js:
--------------------------------------------------------------------------------
1 | const Koa = require("koa");
2 | const Router = require("koa-router");
3 | const static = require("koa-static");
4 | const vueServerRender = require("vue-server-renderer");
5 | const fs = require("fs");
6 | const { pathToFileURL } = require("url");
7 | const app = new Koa();
8 | const router = new Router();
9 | const path = require("path");
10 | // 不读取它 而是引入映射文件 交给vue-server-renderer自动出路
11 | // const serverBundle = fs.readFileSync("./dist/server.bundle.js", "utf8");
12 | // 需要在build目录中配置好webpack plugin
13 | const serverBundle = require("./dist/vue-ssr-server-bundle.json"); // 引入服务端映射文件
14 | const clientManifest = require("./dist/vue-ssr-client-manifest.json"); // 引入客户端映射文件
15 | const template = fs.readFileSync("./dist/index.ssr.html", "utf8");
16 | // 渲染打包后的结果 让客户端与服务端文件相互关联
17 | // 相当于告诉webpack 服务端打包的时候需要用到manifest.json(客户端的映射文件),然后根据这个映射文件在template模板中自动注入客户端js文件(client.bundle.js)
18 | // 这样就不需要主动去引入客户端打包好的js文件了
19 | const render = vueServerRender.createBundleRenderer(serverBundle, {
20 | template,
21 | clientManifest
22 | });
23 |
24 | // koa只能用promise
25 | router.get("/", async ctx => {
26 | // 此时打包之后的结果全是字符串,字符串没有任何的事件功能 所以js逻辑不生效(打包之后vue-server-render也会丢弃js逻辑,所以页面中只有css(vue-style-loader的功劳)和html逻辑)
27 | // 所以需要把客户端打包后的结果挂载到模板上,因为客户端代码包含事件逻辑
28 | // 此时需要三个个步骤 1.在模板(dist目录)中先手动引入客户端打包后的结果 (因为js中的事件逻辑不需要被爬虫爬取)
29 | // 2.但此时服务器并没有读取此文件,所以需要 koa-static 静态服务中间件 去dist查找此文件
30 | // 3.需要在App.vue中指定id='app' ,客户端激活
31 | // 这种方法比较笨
32 |
33 | ctx.body = await new Promise((resolve, reject) => {
34 | // 必须写成回调函数的形式否则css样式不生效
35 | render.renderToString(
36 | {
37 | title: "服务"
38 | },
39 | (err, data) => {
40 | if (err) reject(err);
41 | resolve(data);
42 | }
43 | );
44 | }); // 返回promise 结果为 'hello,ssr
' 会把结果塞给 template
45 | });
46 |
47 | app.use(router.routes());
48 | // koa静态服务中间件 会去dist目录插查找看是否有client.bundle.js 如果有就从服务器中返回此文件
49 | app.use(static(path.resolve(__dirname, "dist")));
50 | let port = 8020;
51 | app.listen(port, () => {
52 | console.log("服务器开启成功", `http://localhost:${port}/`);
53 | });
54 |
--------------------------------------------------------------------------------
/SSR-3/server.js:
--------------------------------------------------------------------------------
1 | let port = 8059;
2 | const Koa = require("koa");
3 | const Router = require("koa-router");
4 | const static = require("koa-static");
5 | const vueServerRender = require("vue-server-renderer");
6 | const fs = require("fs");
7 | const { pathToFileURL } = require("url");
8 | const app = new Koa();
9 | const router = new Router();
10 | const path = require("path");
11 | const serverBundle = fs.readFileSync("./dist/server.bundle.js", "utf8");
12 | const template = fs.readFileSync("./dist/index.ssr.html", "utf8");
13 | // 渲染打包后的结果
14 | // 此方法会自动去调用client.service.js文件中导出的函数 供rendertostring传参使用
15 | const render = vueServerRender.createBundleRenderer(serverBundle, {
16 | template
17 | });
18 |
19 | // koa只能用promise
20 | router.get("/", async ctx => {
21 | // 此时打包之后的结果全是字符串,字符串没有任何的事件功能 所以js逻辑不生效(打包之后vue-server-render也会丢弃js逻辑,所以页面中只有css(vue-style-loader的功劳)和html逻辑)
22 | // 所以需要把客户端打包后的结果挂载到模板上,因为客户端代码包含事件逻辑
23 | // 此时需要三个个步骤 1.在模板(dist目录)中先手动引入客户端打包后的结果 (因为js中的事件逻辑不需要被怕成爬取)
24 | // 2.但此时服务器并没有读取此文件,所以需要koa-static静态服务中间件 去dist查找此文件
25 | // 3.需要在App.vue中指定id='app' ,客户端激活
26 | // 这种方法比较笨
27 |
28 | ctx.body = await new Promise((resolve, reject) => {
29 | // 必须写成回调函数的形式否则css样式不生效
30 | render.renderToString(
31 | {
32 | title: "服务",
33 | url: "/"
34 | },
35 | (err, data) => {
36 | if (err) reject(err);
37 | resolve(data);
38 | }
39 | );
40 | }); // 返回promise 结果为 'hello,ssr
' 会把结果塞给template
41 | });
42 | // 中间件
43 | app.use(router.routes());
44 |
45 | // koa静态服务中间件 会去dist目录插查找看是否有client.bundle.js 如果有就从服务器中返回此文件
46 | app.use(static(path.resolve(__dirname, "dist")));
47 | // 中间件 当找不到路由时会走此逻辑
48 | // 如果匹配不到路由就会走此逻辑(当路由不是/时,要跳转到对应的路径,渲染对应的页面)
49 | // 如果服务器没有此路径,会渲染当前的app.vue(首页)文件,在渲染时中又会重新指向/bar路径对应的页面
50 | // 此中间件需要放到最后
51 | app.use(async ctx => {
52 | // 获取到server.entry.js中配置404逻辑
53 | try {
54 | ctx.body = await new Promise((resolve, reject) => {
55 | // 必须写成回调函数的形式否则css样式不生效
56 | render.renderToString(
57 | {
58 | title: "服务",
59 | url: ctx.url //比如当前请求的时/bar 那就把/bar传到server.entry.js中的content
60 | },
61 | (err, data) => {
62 | if (err) reject(err);
63 | resolve(data);
64 | }
65 | );
66 | });
67 | } catch (error) {
68 | ctx.body = "404";
69 | }
70 | });
71 | app.listen(port, () => {
72 | console.log("服务器开启成功", `http://localhost:${port}/`);
73 | });
74 |
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## 使用
3 |
4 | - 在SSR-3目录中 npm install 安装依赖
5 | - 打包服务端 npm run server:build
6 | - 打包客户端 npm run client:build
7 |
8 | - 在dist目录index.ssr.html中引入客户端代码``
9 |
10 | - 执行服务端脚本 `node server.js`
11 |
12 | # webpack5.0尝鲜 SSR+Vue+Koa+vue-router+vuex【排坑记录】
13 |
14 | 
15 |
16 | ## 一些包
17 |
18 | ### webpack相关
19 |
20 | - webpack
21 | - webpack-cli 命令行解析工具 4.0之前是一起的 4.0之后拆开了 需要安装
22 | - webpack-dev-server
23 | - html-webpack-plugin
24 | - webpack-merge
25 |
26 | ### es6转es5
27 |
28 | - babel-loader es6=>es5 webpack中接入babel
29 | - @babel/core babel-loader依赖
30 | - @babel/preset-env 加入新的语法特性 比如2015年加入的新特性 Env包括所有的新特性
31 | - @babel/plugin-transform-runtime 减少冗余代码 默认的polifill属性已经被废除掉了
32 | - @babel/runtime @babel/plugin-transform-runtime依赖
33 |
34 | ### 解析css的包
35 |
36 | - vue-style-loader 支持服务端渲染 和style-loader功能一样
37 | - css-loader
38 |
39 | ### vue相关
40 |
41 | - vue-loader 处理.vue文件
42 | - vue-template-loader 处理模板编译
43 |
44 | ----------------------------
45 | npx webpack === node_modules/bin/webpack 打包
46 |
47 | ## webpack5.0 bug记录
48 |
49 | ### 问题一
50 |
51 | webpack5.0与webpack-dev-server不兼容
52 |
53 | npm script 需把 "run":"webpack-dev-server --open"改成
54 | "run":"webpack serve"
55 |
56 | ### 问题2
57 |
58 | vue-style-loader与css-loader 在服务端打包时style样式不生效问题解决方案
59 |
60 | {
61 | test: /\.css$/,
62 | use: [
63 | "vue-style-loader",
64 | {
65 | loader: "css-loader",
66 | options: {
67 | esModule: false //默认为true 需要设置为false
68 | }
69 | }
70 | ]
71 | }
72 |
73 | ### 问题三
74 |
75 | build目录中 webpack.server.js
76 | const ServerRenderPlugin = require("vue-server-renderer/server-plugin") 报错
77 |
78 | 解决方案 修改vue-server-renderer包中的代码
79 |
80 |
81 |
82 | ### 问题四
83 |
84 | 使用 const ClientRenderPlugin = require("vue-server-renderer/client-plugin");
85 | const ServerRenderPlugin = require("vue-server-renderer/server-plugin");
86 | 自动引入js文件时服务端会报错 展示没有解决办法 需要手动引入js文件
87 |
88 | npm run client:build -- --watch 文件变动执行打包编译
89 |
90 | 为什么服务端vue vuex vueRouter 都需要调用一个函数,从函数中获取实例?
91 |
92 | 因为Node.js 服务器是一个长期运行的进程 当代码进入进程时,它将进行一次取值并留存在内存中。也就是会把vue实例保存到内存中
93 | 假如说不用函数返回新的实例,那么每个人访问同一个页面时都会共用同一个实例,那么就会造成数据的污染。
94 |
95 |
96 |
97 | ## 路由集成
98 |
99 | 首屏只渲染一个路由,但是其他路由的逻辑混淆再js文件中。如果需要分开 可以使用路由懒加载。
100 | 每个路由需要返回一个函数 每个服务器都要返回一个路由实例
101 |
102 | 此时的问题
103 | 此时在服务器中执行构建,
104 | 访问localhose:3000/ 应该渲染出对应的组件Foo 但是没有渲染出来
105 | 并且控制台会报错 Failed to execute 'appendChild' on 'Node': This node type does not support this method.at Object.appendChild
106 |
107 | 解造成此问题的原因:
108 | 服务器访问根目录时 router.get("/") 渲染出来的时字符串 它并不知道哪个页面对应哪个路由 所以只会渲染app.vue
109 |
110 | 解决方案:
111 |
112 | server.js中
113 | `render.renderToString({url:'/' })`
114 |
115 | server.enter.js中
116 |
117 | ```js
118 | export default context => {
119 | // 服务端需要调用当前这个文件 去产生一个vue实例
120 | const { app, router } = createApp();
121 | // context.url 服务端要把对应的路由和此url相匹配
122 | router.push(context.url); // 渲染当前页面对应的路由
123 | return app; //拿这个实例去服务端查找渲染结果
124 | };
125 | ```
126 |
127 | 切换到其他路由localhose:3000/bar然后刷新浏览器会报404错误 Not Fount
128 |
129 | **重点**:如果此时是点击切换 那就只是客户端切换 并不是服务端切换。并不会造成服务端重新渲染。
130 | 也可以理解为服务端不认识router-link,解析不出对应的组件, localhose:3000/bar 只有刷新页面时才会走服务端渲染。
131 | 但是此时会报404 因为器服务器根本没有此路径。
132 | 解决方法:
133 | 所以在服务器中还得再配其他路径,使用中间件,使得每个路径渲染对应的页面
134 |
135 | **中间件**
136 | 当找不到路由时会走此逻辑
137 | 如果匹配不到路由就会走此逻辑(当路由不是跟路径时,要跳转到对应的路径,渲染对应的页面)
138 | 如果服务器没有此路径,会渲染当前的app.vue(首页)文件,在渲染时又会重新指向/bar路径对应的页面
139 | 然后 server.entry.js 中router.push(context.url)找对应的组件
140 |
141 | ```js
142 | app.use(async ctx => {
143 | ctx.body = await new Promise((resolve, reject) => {
144 | // 必须写成回调函数的形式否则css样式不生效
145 | render.renderToString(
146 | {
147 | title: "服务",
148 | url: ctx.url //比如当前请求的/bar 那就把/bar传到server.entry.js中的content
149 | },
150 | (err, data) => {
151 | if (err) reject(err);
152 | resolve(data);
153 | }
154 | );
155 | });
156 | });
157 | ```
158 |
159 | 也就是先渲染app.vue---->找其他路由对应的组件
160 |
161 | 这也是history模式需要后端支持的原理
162 |
163 | ## Vuex集成
164 |
165 | 为什么vuex需要此判断?
166 |
167 | ```js
168 | if (typeof window !== "undefined" && window.__INITIAL_STATE__) {
169 | store.replaceState(window.__INITIAL_STATE__);
170 | }
171 | ```
172 |
173 | 因为客户端和服务端各自生成一个vuex实例 而他们两个需要共用一个状态,因此需要服务端状态改变之后传给客户端
174 |
175 | 服务端与客户端各自的用处?
176 |
177 | 服务端用于渲染html 有利于seo
178 | 客户端用于处理js逻辑比如 点击事件 client.bundle.js
179 |
180 | 服务端调用在组件中调用asyncDate() vuex必须返回promise才能生效,并且只有等resolve()执行完成之后才会返回结果
181 |
182 | 如果是服务端调用必须返回 promise 否则不生效 因为在service.entry.js的逻辑是Promise.all()
183 | 自己有里面的所有数据都获取完之后才会渲染app.vue 所以会等待三秒才渲染数据
184 | 只写setTimeout 不生效 因为setTimeout是异步的,在vuex实例渲染完成后才被调用,此时页面已经被当成字符串渲染到浏览器上了。
185 |
186 | 哪些请求放在ajax哪些放在服务端请求?
187 |
188 | 被爬虫爬取,比如新闻列表的数据 由服务端返回
189 |
190 | ## 流程大致总结
191 |
192 | 主入口文件
193 |
194 | - 服务端入口文件
195 | - 客户端入口文件
196 |
197 | webpack
198 |
199 | - base.js
200 | - 服务端配置
201 | - 客户端配置
202 | - merge-webpack
203 |
204 | vue-server-renderer
205 |
206 | - createRender() createBundleRender()
207 |
208 | - renderTostring() renderToStream()
209 |
210 | ### 主流程
211 |
212 | - webpack.server.js -> 入口文件 server.entry.js(函数生成每个实例)-> npm run server:build->服务端文件打包到dist目录
213 |
214 | - webpack.client.js->入口文件 server.entry.js ->npm run client:build->客户端打包到dist目录
215 |
216 | - Koa-> vue-server-renderer->render.createBundleRender()引入打包好的服务端文件和模板->render.renderToStream()配置模板属性+生成html字符串->koa中间件监听dist目录->在模板中手动引入客户端打包好的bundle.js文件->挂载#app激活事件->返回给客户端。
217 |
218 | css->vue-style-loader
219 |
220 | -配置meta标签
221 |
222 | - 在option中设置title
223 | - 客户端:document.title=this.$options.title
224 | - 服务端:this.$ssrContext=title
225 |
226 | ### 配置路由
227 |
228 | 引入路由->每个路由都已函数的形式返回->koa中间件捕获到history路径->把url传给render.renderToString->server.entry.js接受到路径
229 | router.push(context.url)渲染当前页面对应的路由
230 |
231 | router.onReady() router.getMatchedComponents()
232 |
233 | ### 配置vuex
234 |
235 | 引入vuex->每个路由都已函数的形式返回->在匹配到的每个组件中调用asyncData方法动态传入store->
236 | 改变store的状态->更新(此时会等待promise执行完成再渲染页面)->
237 | 再拿到状态->context.state = store.state->把vuex的状态挂载到上下文中,会将状态挂载到window上->
238 | 当客户端执行vuex时把状态替换掉store.replaceState(window.__INITIAL_STATE__);
239 |
--------------------------------------------------------------------------------
/SSR-3/笔记:
--------------------------------------------------------------------------------
1 | # webpack5.0+Vue+SSR+vue-router+vuex
2 | 
3 | ## 一些包
4 | ### webpack相关
5 | - webpack
6 | - webpack-cli 命令行解析工具 4.0之前是一起的 4.0之后拆开了 需要安装
7 | - webpack-dev-server
8 | - html-webpack-plugin
9 | - webpack-merge
10 |
11 | ### es6转es5
12 | - babel-loader es6=>es5 webpack中接入babel
13 | - @babel/core babel-loader依赖
14 | - @babel/preset-env 加入新的语法特性 比如2015年加入的新特性 Env包括所有的新特性
15 | - @babel/plugin-transform-runtime 减少冗余代码 默认的polifill属性已经被废除掉了
16 | - @babel/runtime @babel/plugin-transform-runtime依赖
17 |
18 | ### 解析css的包
19 | - vue-style-loader 支持服务端渲染 和style-loader功能一样
20 | - css-loader
21 |
22 | ### vue相关
23 | - vue-loader 处理.vue文件
24 | - vue-template-loader 处理模板编译
25 |
26 |
27 |
28 | ----------------------------
29 | npx webpack === node_modules/bin/webpack 打包
30 |
31 |
32 |
33 | ## webpack5.0 bug记录
34 |
35 | ### 问题一
36 | webpack5.0与webpack-dev-server不兼容
37 |
38 | npm script 需把 "run":"webpack-dev-server --open"改成
39 | "run":"webpack serve"
40 |
41 |
42 | ### 问题2
43 | vue-style-loader与css-loader 在服务端打包时style样式不生效问题解决方案
44 |
45 | ```js
46 | {
47 | test: /\.css$/,
48 | use: [
49 | "vue-style-loader",
50 | {
51 | loader: "css-loader",
52 | options: {
53 | esModule: false //默认为true 需要设置为false
54 | }
55 | }
56 | ]
57 | }
58 | ```
59 |
60 |
61 | ### 问题三
62 | build目录中 webpack.server.js
63 | const ServerRenderPlugin = require("vue-server-renderer/server-plugin") 报错
64 |
65 | 解决方案 修改vue-server-renderer包中的代码
66 |
67 | https://github.com/vuejs/vue/issues/11718#issuecomment-717786088
68 |
69 |
70 | ### 问题四
71 | 使用
72 | ```js
73 | const ClientRenderPlugin = require("vue-server-renderer/client-plugin");
74 | const ServerRenderPlugin = require("vue-server-renderer/server-plugin");
75 | ```
76 | 自动引入js文件时服务端会报错 暂时没有解决办法 需要手动引入js文件
77 |
78 |
79 |
80 |
81 | npm run client:build -- --watch 文件变动执行打包编译
82 |
83 | 为什么服务端vue vuex vueRouter 都需要调用一个函数,从函数中获取实例?
84 |
85 | 因为Node.js 服务器是一个长期运行的进程 当代码进入进程时,它将进行一次取值并留存在内存中。也就是会把vue实例保存到内存中
86 | 假如说不用函数返回新的实例,那么每个人访问同一个页面时都会共用同一个实例,那么就会造成数据的污染。
87 |
88 | https://ssr.vuejs.org/zh/guide/structure.html
89 |
90 |
91 | ## 路由集成
92 | 首屏只渲染一个路由,但是其他路由的逻辑混淆再js文件中。如果需要分开 可以使用路由懒加载。
93 | 每个路由需要返回一个函数 每个服务器都要返回一个路由实例
94 |
95 |
96 | 此时的问题
97 |
98 | 此时在服务器中执行构建,
99 | 访问localhose:3000/ 应该渲染出对应的组件Foo 但是没有渲染出来
100 | 并且控制台会报错 Failed to execute 'appendChild' on 'Node': This node type does not support this method.at Object.appendChild
101 |
102 | 解造成此问题的原因:
103 | 服务器访问根目录时 router.get("/") 渲染出来的时字符串 它并不知道哪个页面对应哪个路由 所以只会渲染app.vue
104 |
105 | 解决方案:
106 |
107 | server.js中
108 | `render.renderToString({url:'/' })`
109 |
110 | server.enter.js中
111 |
112 | ```js
113 | export default context => {
114 | // 服务端需要调用当前这个文件 去产生一个vue实例
115 | const { app, router } = createApp();
116 | // context.url 服务端要把对应的路由和此url相匹配
117 | router.push(context.url); // 渲染当前页面对应的路由
118 | return app; //拿这个实例去服务端查找渲染结果
119 | };
120 | ```
121 |
122 | 切换到其他路由localhose:3000/bar然后刷新浏览器会报404错误 Not Fount
123 |
124 | **重点**:如果此时是点击切换 那就只是客户端切换 并不是服务端切换。并不会造成服务端重新渲染。
125 | 也可以理解为服务端不认识router-link,解析不出对应的组件, localhose:3000/bar 只有刷新页面时才会走服务端渲染。
126 | 但是此时会报404 因为器服务器根本没有此路径。
127 | 解决方法:
128 | 所以在服务器中还得再配其他路径,使用中间件,使得每个路径渲染对应的页面
129 |
130 | **中间件**
131 | 当找不到路由时会走此逻辑
132 | 如果匹配不到路由就会走此逻辑(当路由不是根路径时,要跳转到对应的路径,渲染对应的页面)
133 | 如果服务器没有此路径,会渲染当前的app.vue(首页)文件,在渲染时又会重新指向/bar路径对应的页面
134 | 然后 server.entry.js 中router.push(context.url)找对应的组件
135 |
136 | app.use(async ctx => {
137 | ctx.body = await new Promise((resolve, reject) => {
138 | // 必须写成回调函数的形式否则css样式不生效
139 | render.renderToString(
140 | {
141 | title: "服务",
142 | url: ctx.url //比如当前请求的/bar 那就把/bar传到server.entry.js中的content
143 | },
144 | (err, data) => {
145 | if (err) reject(err);
146 | resolve(data);
147 | }
148 | );
149 | });
150 | });
151 |
152 | 也就是先渲染app.vue---->找其他路由对应的组件
153 | 如果是单页面 koa中间件会去监听生成的bundle.js文件(中间件回去监听dist目录下的所有文件)
154 | 这也是history模式需要后端支持的原理
155 |
156 | ## Vuex集成
157 |
158 | Vuex中为什么需要此判断?
159 |
160 | if (typeof window !== "undefined" && window.__INITIAL_STATE__) {
161 | store.replaceState(window.__INITIAL_STATE__);
162 | }
163 |
164 |
165 | 因为客户端和服务端各自生成一个vuex实例 而他们两个需要共用一个状态,因此需要服务端状态改变之后传给客户端
166 |
167 |
168 | 服务端与客户端各自的用处?
169 |
170 | 服务端用于渲染html 有利于seo
171 | 客户端用于处理js逻辑比如 点击事件 client.bundle.js
172 |
173 | 服务端调用在组件中调用asyncDate() vuex必须返回promise才能生效,并且只有等resolve()执行完成之后才会返回结果
174 |
175 | 如果是服务端调用必须返回 promise 否则不生效 因为在service.entry.js的逻辑是Promise.all()
176 | 自己有里面的所有数据都获取完之后才会渲染app.vue 所以会等待三秒才渲染数据
177 | 只写setTimeout 不生效 因为setTimeout是异步的,在vuex实例渲染完成后才被调用,此时页面已经被当成字符串渲染到浏览器上了。
178 |
179 | 哪些请求放在ajax哪些放在服务端请求?
180 |
181 | 被爬虫爬取,比如新闻列表的数据 由服务端返回
182 |
183 |
184 | ## 使用
185 | - 在SSR-3目录中 npm install 安装依赖
186 | - 打包服务端 npm run server:build
187 | - 打包客户端 npm run client:build
188 |
189 | - 在dist目录index.ssr.html中引入客户端代码``
190 |
191 | - 执行服务端脚本 `node server.js`
192 |
193 | ## 项目地址
194 |
195 | https://github.com/wensiyuanseven/Vue-SSR
196 |
197 |
198 |
199 | 流程大致总结
200 |
201 | 主入口文件 - 服务端入口文件
202 | - 客户端入口文件
203 | webpack - base.js
204 | - 服务端配置
205 | - 客户端配置
206 | - merge-webpack
207 | vue-server-renderer 两个方法 createRender() createBundleRender()
208 | renderTostring() renderToStream()
209 |
210 | 流程
211 | webpack.server.js -> 入口文件 server.entry.js(函数生成每个实例)-> npm run server:build->服务端文件打包到dist目录
212 |
213 | webpack.client.js->入口文件 server.entry.js ->npm run client:build->客户端打包到dist目录
214 |
215 | Koa-> vue-server-renderer->render.createBundleRender()引入打包好的服务端文件和模板->render.renderToStream()配置模板属性+生成html字符串
216 | ->koa中间件监听dist目录->在模板中手动引入客户端打包好的bundle.js文件->挂载#app激活事件->返回给客户端。
217 |
218 | css->vue-style-loader
219 |
220 | 配置meta标签->在option中设置title
221 | 客户端:document.title=this.$options.title
222 | 服务端:this.$ssrContext=title
223 |
224 | 配置路由
225 |
226 | 引入路由->每个路由都已函数的形式返回->koa中间件捕获到history路径->把url传给render.renderToString->server.entry.js接受到路径
227 | router.push(context.url)渲染当前页面对应的路由
228 |
229 | router.onReady() router.getMatchedComponents()
230 |
231 |
232 | 配置vuex
233 |
234 | 引入vuex->每个路由都已函数的形式返回->在匹配到的每个组件中调用asyncData方法动态传入store->
235 | 改变store的状态->更新(此时会等待promise执行完成再渲染页面)->
236 | 再拿到状态->context.state = store.state->把vuex的状态挂载到上下文中,会将状态挂载到window上->
237 | 当客户端执行vuex时把状态替换掉 store.replaceState(window.__INITIAL_STATE__);
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
--------------------------------------------------------------------------------
/基本的服务端渲染/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "base-ssr",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npm.taobao.org/accepts/download/accepts-1.3.7.tgz",
10 | "integrity": "sha1-UxvHJlF6OytB+FACHGzBXqq1B80=",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "ansi-regex": {
17 | "version": "2.1.1",
18 | "resolved": "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-2.1.1.tgz",
19 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
20 | },
21 | "ansi-styles": {
22 | "version": "2.2.1",
23 | "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-2.2.1.tgz",
24 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
25 | },
26 | "any-promise": {
27 | "version": "1.3.0",
28 | "resolved": "https://registry.npm.taobao.org/any-promise/download/any-promise-1.3.0.tgz",
29 | "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
30 | },
31 | "cache-content-type": {
32 | "version": "1.0.1",
33 | "resolved": "https://registry.npm.taobao.org/cache-content-type/download/cache-content-type-1.0.1.tgz",
34 | "integrity": "sha1-A1zeKwjuISn0qDFeqPAKANuhRTw=",
35 | "requires": {
36 | "mime-types": "^2.1.18",
37 | "ylru": "^1.2.0"
38 | }
39 | },
40 | "chalk": {
41 | "version": "1.1.3",
42 | "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-1.1.3.tgz",
43 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
44 | "requires": {
45 | "ansi-styles": "^2.2.1",
46 | "escape-string-regexp": "^1.0.2",
47 | "has-ansi": "^2.0.0",
48 | "strip-ansi": "^3.0.0",
49 | "supports-color": "^2.0.0"
50 | }
51 | },
52 | "co": {
53 | "version": "4.6.0",
54 | "resolved": "https://registry.npm.taobao.org/co/download/co-4.6.0.tgz",
55 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
56 | },
57 | "content-disposition": {
58 | "version": "0.5.3",
59 | "resolved": "https://registry.npm.taobao.org/content-disposition/download/content-disposition-0.5.3.tgz",
60 | "integrity": "sha1-4TDK9+cnkIfFYWwgB9BIVpiYT70=",
61 | "requires": {
62 | "safe-buffer": "5.1.2"
63 | }
64 | },
65 | "content-type": {
66 | "version": "1.0.4",
67 | "resolved": "https://registry.npm.taobao.org/content-type/download/content-type-1.0.4.tgz",
68 | "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js="
69 | },
70 | "cookies": {
71 | "version": "0.8.0",
72 | "resolved": "https://registry.npm.taobao.org/cookies/download/cookies-0.8.0.tgz?cache=0&sync_timestamp=1570851324736&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcookies%2Fdownload%2Fcookies-0.8.0.tgz",
73 | "integrity": "sha1-EpPOSzkXQKhAbjyYcOgoxLVPP5A=",
74 | "requires": {
75 | "depd": "~2.0.0",
76 | "keygrip": "~1.1.0"
77 | },
78 | "dependencies": {
79 | "depd": {
80 | "version": "2.0.0",
81 | "resolved": "https://registry.npm.taobao.org/depd/download/depd-2.0.0.tgz",
82 | "integrity": "sha1-tpYWPMdXVg0JzyLMj60Vcbeedt8="
83 | }
84 | }
85 | },
86 | "debug": {
87 | "version": "3.1.0",
88 | "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz?cache=0&sync_timestamp=1600502873540&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.1.0.tgz",
89 | "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=",
90 | "requires": {
91 | "ms": "2.0.0"
92 | }
93 | },
94 | "deep-equal": {
95 | "version": "1.0.1",
96 | "resolved": "https://registry.npm.taobao.org/deep-equal/download/deep-equal-1.0.1.tgz",
97 | "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
98 | },
99 | "delegates": {
100 | "version": "1.0.0",
101 | "resolved": "https://registry.npm.taobao.org/delegates/download/delegates-1.0.0.tgz",
102 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
103 | },
104 | "depd": {
105 | "version": "1.1.2",
106 | "resolved": "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz",
107 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
108 | },
109 | "destroy": {
110 | "version": "1.0.4",
111 | "resolved": "https://registry.npm.taobao.org/destroy/download/destroy-1.0.4.tgz",
112 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
113 | },
114 | "ee-first": {
115 | "version": "1.1.1",
116 | "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
117 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
118 | },
119 | "encodeurl": {
120 | "version": "1.0.2",
121 | "resolved": "https://registry.npm.taobao.org/encodeurl/download/encodeurl-1.0.2.tgz",
122 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
123 | },
124 | "escape-html": {
125 | "version": "1.0.3",
126 | "resolved": "https://registry.npm.taobao.org/escape-html/download/escape-html-1.0.3.tgz",
127 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
128 | },
129 | "escape-string-regexp": {
130 | "version": "1.0.5",
131 | "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz",
132 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
133 | },
134 | "fresh": {
135 | "version": "0.5.2",
136 | "resolved": "https://registry.npm.taobao.org/fresh/download/fresh-0.5.2.tgz",
137 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
138 | },
139 | "function-bind": {
140 | "version": "1.1.1",
141 | "resolved": "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz",
142 | "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0="
143 | },
144 | "has": {
145 | "version": "1.0.3",
146 | "resolved": "https://registry.npm.taobao.org/has/download/has-1.0.3.tgz",
147 | "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=",
148 | "requires": {
149 | "function-bind": "^1.1.1"
150 | }
151 | },
152 | "has-ansi": {
153 | "version": "2.0.0",
154 | "resolved": "https://registry.npm.taobao.org/has-ansi/download/has-ansi-2.0.0.tgz",
155 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
156 | "requires": {
157 | "ansi-regex": "^2.0.0"
158 | }
159 | },
160 | "hash-sum": {
161 | "version": "1.0.2",
162 | "resolved": "https://registry.npm.taobao.org/hash-sum/download/hash-sum-1.0.2.tgz",
163 | "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ="
164 | },
165 | "he": {
166 | "version": "1.2.0",
167 | "resolved": "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz",
168 | "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8="
169 | },
170 | "http-assert": {
171 | "version": "1.4.1",
172 | "resolved": "https://registry.npm.taobao.org/http-assert/download/http-assert-1.4.1.tgz",
173 | "integrity": "sha1-xfcl1neqfoc+9zYZm4lobM6zeHg=",
174 | "requires": {
175 | "deep-equal": "~1.0.1",
176 | "http-errors": "~1.7.2"
177 | },
178 | "dependencies": {
179 | "http-errors": {
180 | "version": "1.7.3",
181 | "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.7.3.tgz?cache=0&sync_timestamp=1593407611415&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.7.3.tgz",
182 | "integrity": "sha1-bGGeT5xgMIw4UZSYwU+7EKrOuwY=",
183 | "requires": {
184 | "depd": "~1.1.2",
185 | "inherits": "2.0.4",
186 | "setprototypeof": "1.1.1",
187 | "statuses": ">= 1.5.0 < 2",
188 | "toidentifier": "1.0.0"
189 | }
190 | }
191 | }
192 | },
193 | "http-errors": {
194 | "version": "1.8.0",
195 | "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.8.0.tgz?cache=0&sync_timestamp=1593407611415&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.8.0.tgz",
196 | "integrity": "sha1-ddG75JfhBE9R5O6ecEpi8o0zZQc=",
197 | "requires": {
198 | "depd": "~1.1.2",
199 | "inherits": "2.0.4",
200 | "setprototypeof": "1.2.0",
201 | "statuses": ">= 1.5.0 < 2",
202 | "toidentifier": "1.0.0"
203 | },
204 | "dependencies": {
205 | "setprototypeof": {
206 | "version": "1.2.0",
207 | "resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.2.0.tgz",
208 | "integrity": "sha1-ZsmiSnP5/CjL5msJ/tPTPcrxtCQ="
209 | }
210 | }
211 | },
212 | "inherits": {
213 | "version": "2.0.4",
214 | "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz",
215 | "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w="
216 | },
217 | "is-core-module": {
218 | "version": "2.0.0",
219 | "resolved": "https://registry.npm.taobao.org/is-core-module/download/is-core-module-2.0.0.tgz",
220 | "integrity": "sha1-WFMbcK7R23wOjU6xoKLR3dZL0S0=",
221 | "requires": {
222 | "has": "^1.0.3"
223 | }
224 | },
225 | "is-generator-function": {
226 | "version": "1.0.7",
227 | "resolved": "https://registry.npm.taobao.org/is-generator-function/download/is-generator-function-1.0.7.tgz",
228 | "integrity": "sha1-0hMuUpuwAAp/gHlNS99c1eWBNSI="
229 | },
230 | "keygrip": {
231 | "version": "1.1.0",
232 | "resolved": "https://registry.npm.taobao.org/keygrip/download/keygrip-1.1.0.tgz",
233 | "integrity": "sha1-hxsWgdXhWcYqRFsMdLYV4JF+ciY=",
234 | "requires": {
235 | "tsscmp": "1.0.6"
236 | }
237 | },
238 | "koa": {
239 | "version": "2.13.0",
240 | "resolved": "https://registry.npm.taobao.org/koa/download/koa-2.13.0.tgz?cache=0&sync_timestamp=1592754966586&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fkoa%2Fdownload%2Fkoa-2.13.0.tgz",
241 | "integrity": "sha1-JSF+Be/TNYp+Xd7ADwo4DJtxtQE=",
242 | "requires": {
243 | "accepts": "^1.3.5",
244 | "cache-content-type": "^1.0.0",
245 | "content-disposition": "~0.5.2",
246 | "content-type": "^1.0.4",
247 | "cookies": "~0.8.0",
248 | "debug": "~3.1.0",
249 | "delegates": "^1.0.0",
250 | "depd": "^1.1.2",
251 | "destroy": "^1.0.4",
252 | "encodeurl": "^1.0.2",
253 | "escape-html": "^1.0.3",
254 | "fresh": "~0.5.2",
255 | "http-assert": "^1.3.0",
256 | "http-errors": "^1.6.3",
257 | "is-generator-function": "^1.0.7",
258 | "koa-compose": "^4.1.0",
259 | "koa-convert": "^1.2.0",
260 | "on-finished": "^2.3.0",
261 | "only": "~0.0.2",
262 | "parseurl": "^1.3.2",
263 | "statuses": "^1.5.0",
264 | "type-is": "^1.6.16",
265 | "vary": "^1.1.2"
266 | }
267 | },
268 | "koa-compose": {
269 | "version": "4.1.0",
270 | "resolved": "https://registry.npm.taobao.org/koa-compose/download/koa-compose-4.1.0.tgz",
271 | "integrity": "sha1-UHMGuTcZAdtBEhyBLpI9DWfT6Hc="
272 | },
273 | "koa-convert": {
274 | "version": "1.2.0",
275 | "resolved": "https://registry.npm.taobao.org/koa-convert/download/koa-convert-1.2.0.tgz",
276 | "integrity": "sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=",
277 | "requires": {
278 | "co": "^4.6.0",
279 | "koa-compose": "^3.0.0"
280 | },
281 | "dependencies": {
282 | "koa-compose": {
283 | "version": "3.2.1",
284 | "resolved": "https://registry.npm.taobao.org/koa-compose/download/koa-compose-3.2.1.tgz",
285 | "integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=",
286 | "requires": {
287 | "any-promise": "^1.1.0"
288 | }
289 | }
290 | }
291 | },
292 | "koa-router": {
293 | "version": "9.4.0",
294 | "resolved": "https://registry.npm.taobao.org/koa-router/download/koa-router-9.4.0.tgz?cache=0&sync_timestamp=1597368200163&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fkoa-router%2Fdownload%2Fkoa-router-9.4.0.tgz",
295 | "integrity": "sha1-e9PNT2JHJW5LVvuyIDveOFGswVo=",
296 | "requires": {
297 | "debug": "^4.1.1",
298 | "http-errors": "^1.7.3",
299 | "koa-compose": "^4.1.0",
300 | "methods": "^1.1.2",
301 | "path-to-regexp": "^6.1.0"
302 | },
303 | "dependencies": {
304 | "debug": {
305 | "version": "4.2.0",
306 | "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502873540&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz",
307 | "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=",
308 | "requires": {
309 | "ms": "2.1.2"
310 | }
311 | },
312 | "ms": {
313 | "version": "2.1.2",
314 | "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz",
315 | "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk="
316 | }
317 | }
318 | },
319 | "koa-send": {
320 | "version": "5.0.1",
321 | "resolved": "https://registry.npm.taobao.org/koa-send/download/koa-send-5.0.1.tgz",
322 | "integrity": "sha1-Odzuv6+zldDWC+r/ujpwtPVD/nk=",
323 | "requires": {
324 | "debug": "^4.1.1",
325 | "http-errors": "^1.7.3",
326 | "resolve-path": "^1.4.0"
327 | },
328 | "dependencies": {
329 | "debug": {
330 | "version": "4.2.0",
331 | "resolved": "https://registry.npm.taobao.org/debug/download/debug-4.2.0.tgz?cache=0&sync_timestamp=1600502873540&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.2.0.tgz",
332 | "integrity": "sha1-fxUPk5IOlMWPVXTC/QGjEQ7/5/E=",
333 | "requires": {
334 | "ms": "2.1.2"
335 | }
336 | },
337 | "ms": {
338 | "version": "2.1.2",
339 | "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz",
340 | "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk="
341 | }
342 | }
343 | },
344 | "koa-static": {
345 | "version": "5.0.0",
346 | "resolved": "https://registry.npm.taobao.org/koa-static/download/koa-static-5.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fkoa-static%2Fdownload%2Fkoa-static-5.0.0.tgz",
347 | "integrity": "sha1-XpL8lrU3rVIZ9CUxnJW2R3J3aUM=",
348 | "requires": {
349 | "debug": "^3.1.0",
350 | "koa-send": "^5.0.0"
351 | }
352 | },
353 | "lodash._reinterpolate": {
354 | "version": "3.0.0",
355 | "resolved": "https://registry.npm.taobao.org/lodash._reinterpolate/download/lodash._reinterpolate-3.0.0.tgz",
356 | "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
357 | },
358 | "lodash.template": {
359 | "version": "4.5.0",
360 | "resolved": "https://registry.npm.taobao.org/lodash.template/download/lodash.template-4.5.0.tgz",
361 | "integrity": "sha1-+XYZXPPzR9DV9SSDVp/oAxzM6Ks=",
362 | "requires": {
363 | "lodash._reinterpolate": "^3.0.0",
364 | "lodash.templatesettings": "^4.0.0"
365 | }
366 | },
367 | "lodash.templatesettings": {
368 | "version": "4.2.0",
369 | "resolved": "https://registry.npm.taobao.org/lodash.templatesettings/download/lodash.templatesettings-4.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash.templatesettings%2Fdownload%2Flodash.templatesettings-4.2.0.tgz",
370 | "integrity": "sha1-5IExDwSdPPbUfpEq0JMTsVTw+zM=",
371 | "requires": {
372 | "lodash._reinterpolate": "^3.0.0"
373 | }
374 | },
375 | "lodash.uniq": {
376 | "version": "4.5.0",
377 | "resolved": "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz",
378 | "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
379 | },
380 | "media-typer": {
381 | "version": "0.3.0",
382 | "resolved": "https://registry.npm.taobao.org/media-typer/download/media-typer-0.3.0.tgz",
383 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
384 | },
385 | "methods": {
386 | "version": "1.1.2",
387 | "resolved": "https://registry.npm.taobao.org/methods/download/methods-1.1.2.tgz",
388 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
389 | },
390 | "mime-db": {
391 | "version": "1.44.0",
392 | "resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.44.0.tgz?cache=0&sync_timestamp=1600831212519&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmime-db%2Fdownload%2Fmime-db-1.44.0.tgz",
393 | "integrity": "sha1-+hHF6wrKEzS0Izy01S8QxaYnL5I="
394 | },
395 | "mime-types": {
396 | "version": "2.1.27",
397 | "resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.27.tgz",
398 | "integrity": "sha1-R5SfmOJ56lMRn1ci4PNOUpvsAJ8=",
399 | "requires": {
400 | "mime-db": "1.44.0"
401 | }
402 | },
403 | "ms": {
404 | "version": "2.0.0",
405 | "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz",
406 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
407 | },
408 | "negotiator": {
409 | "version": "0.6.2",
410 | "resolved": "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz",
411 | "integrity": "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs="
412 | },
413 | "on-finished": {
414 | "version": "2.3.0",
415 | "resolved": "https://registry.npm.taobao.org/on-finished/download/on-finished-2.3.0.tgz",
416 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
417 | "requires": {
418 | "ee-first": "1.1.1"
419 | }
420 | },
421 | "only": {
422 | "version": "0.0.2",
423 | "resolved": "https://registry.npm.taobao.org/only/download/only-0.0.2.tgz",
424 | "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q="
425 | },
426 | "parseurl": {
427 | "version": "1.3.3",
428 | "resolved": "https://registry.npm.taobao.org/parseurl/download/parseurl-1.3.3.tgz",
429 | "integrity": "sha1-naGee+6NEt/wUT7Vt2lXeTvC6NQ="
430 | },
431 | "path-is-absolute": {
432 | "version": "1.0.1",
433 | "resolved": "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz",
434 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
435 | },
436 | "path-parse": {
437 | "version": "1.0.6",
438 | "resolved": "https://registry.npm.taobao.org/path-parse/download/path-parse-1.0.6.tgz",
439 | "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw="
440 | },
441 | "path-to-regexp": {
442 | "version": "6.2.0",
443 | "resolved": "https://registry.npm.taobao.org/path-to-regexp/download/path-to-regexp-6.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-to-regexp%2Fdownload%2Fpath-to-regexp-6.2.0.tgz",
444 | "integrity": "sha1-97OAMzYQTDRoia3s5hRmkjBkXzg="
445 | },
446 | "randombytes": {
447 | "version": "2.1.0",
448 | "resolved": "https://registry.npm.taobao.org/randombytes/download/randombytes-2.1.0.tgz",
449 | "integrity": "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=",
450 | "requires": {
451 | "safe-buffer": "^5.1.0"
452 | }
453 | },
454 | "resolve": {
455 | "version": "1.18.1",
456 | "resolved": "https://registry.npm.taobao.org/resolve/download/resolve-1.18.1.tgz?cache=0&sync_timestamp=1603313534612&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fresolve%2Fdownload%2Fresolve-1.18.1.tgz",
457 | "integrity": "sha1-AY/LLFsgfSpkJK7jYcWiZtqPQTA=",
458 | "requires": {
459 | "is-core-module": "^2.0.0",
460 | "path-parse": "^1.0.6"
461 | }
462 | },
463 | "resolve-path": {
464 | "version": "1.4.0",
465 | "resolved": "https://registry.npm.taobao.org/resolve-path/download/resolve-path-1.4.0.tgz",
466 | "integrity": "sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=",
467 | "requires": {
468 | "http-errors": "~1.6.2",
469 | "path-is-absolute": "1.0.1"
470 | },
471 | "dependencies": {
472 | "http-errors": {
473 | "version": "1.6.3",
474 | "resolved": "https://registry.npm.taobao.org/http-errors/download/http-errors-1.6.3.tgz?cache=0&sync_timestamp=1593407611415&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhttp-errors%2Fdownload%2Fhttp-errors-1.6.3.tgz",
475 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
476 | "requires": {
477 | "depd": "~1.1.2",
478 | "inherits": "2.0.3",
479 | "setprototypeof": "1.1.0",
480 | "statuses": ">= 1.4.0 < 2"
481 | }
482 | },
483 | "inherits": {
484 | "version": "2.0.3",
485 | "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz",
486 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
487 | },
488 | "setprototypeof": {
489 | "version": "1.1.0",
490 | "resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.0.tgz",
491 | "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY="
492 | }
493 | }
494 | },
495 | "safe-buffer": {
496 | "version": "5.1.2",
497 | "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz",
498 | "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0="
499 | },
500 | "serialize-javascript": {
501 | "version": "3.1.0",
502 | "resolved": "https://registry.npm.taobao.org/serialize-javascript/download/serialize-javascript-3.1.0.tgz?cache=0&sync_timestamp=1599740666792&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fserialize-javascript%2Fdownload%2Fserialize-javascript-3.1.0.tgz",
503 | "integrity": "sha1-i/OpFwcSZk7yVhtEtpHq/jmSFOo=",
504 | "requires": {
505 | "randombytes": "^2.1.0"
506 | }
507 | },
508 | "setprototypeof": {
509 | "version": "1.1.1",
510 | "resolved": "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz",
511 | "integrity": "sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM="
512 | },
513 | "source-map": {
514 | "version": "0.5.6",
515 | "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.5.6.tgz",
516 | "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
517 | },
518 | "statuses": {
519 | "version": "1.5.0",
520 | "resolved": "https://registry.npm.taobao.org/statuses/download/statuses-1.5.0.tgz?cache=0&sync_timestamp=1587355518192&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstatuses%2Fdownload%2Fstatuses-1.5.0.tgz",
521 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
522 | },
523 | "strip-ansi": {
524 | "version": "3.0.1",
525 | "resolved": "https://registry.npm.taobao.org/strip-ansi/download/strip-ansi-3.0.1.tgz",
526 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
527 | "requires": {
528 | "ansi-regex": "^2.0.0"
529 | }
530 | },
531 | "supports-color": {
532 | "version": "2.0.0",
533 | "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-2.0.0.tgz?cache=0&sync_timestamp=1598611719015&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-2.0.0.tgz",
534 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
535 | },
536 | "toidentifier": {
537 | "version": "1.0.0",
538 | "resolved": "https://registry.npm.taobao.org/toidentifier/download/toidentifier-1.0.0.tgz",
539 | "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM="
540 | },
541 | "tsscmp": {
542 | "version": "1.0.6",
543 | "resolved": "https://registry.npm.taobao.org/tsscmp/download/tsscmp-1.0.6.tgz",
544 | "integrity": "sha1-hbmVg6w1iexL/vgltQAKqRHWBes="
545 | },
546 | "type-is": {
547 | "version": "1.6.18",
548 | "resolved": "https://registry.npm.taobao.org/type-is/download/type-is-1.6.18.tgz",
549 | "integrity": "sha1-TlUs0F3wlGfcvE73Od6J8s83wTE=",
550 | "requires": {
551 | "media-typer": "0.3.0",
552 | "mime-types": "~2.1.24"
553 | }
554 | },
555 | "vary": {
556 | "version": "1.1.2",
557 | "resolved": "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz",
558 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
559 | },
560 | "vue": {
561 | "version": "2.6.12",
562 | "resolved": "https://registry.npm.taobao.org/vue/download/vue-2.6.12.tgz",
563 | "integrity": "sha1-9evU+mvShpQD4pqJau1JBEVskSM="
564 | },
565 | "vue-router": {
566 | "version": "3.4.7",
567 | "resolved": "https://registry.npm.taobao.org/vue-router/download/vue-router-3.4.7.tgz?cache=0&sync_timestamp=1603457247867&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-router%2Fdownload%2Fvue-router-3.4.7.tgz",
568 | "integrity": "sha1-vxibr9FvTk73g8SmJQowkPLB+hs="
569 | },
570 | "vue-server-renderer": {
571 | "version": "2.6.12",
572 | "resolved": "https://registry.npm.taobao.org/vue-server-renderer/download/vue-server-renderer-2.6.12.tgz",
573 | "integrity": "sha1-qMucSUOe8gUpPLQcNdDSsFQWU6U=",
574 | "requires": {
575 | "chalk": "^1.1.3",
576 | "hash-sum": "^1.0.2",
577 | "he": "^1.1.0",
578 | "lodash.template": "^4.5.0",
579 | "lodash.uniq": "^4.5.0",
580 | "resolve": "^1.2.0",
581 | "serialize-javascript": "^3.1.0",
582 | "source-map": "0.5.6"
583 | }
584 | },
585 | "vuex": {
586 | "version": "3.5.1",
587 | "resolved": "https://registry.npm.taobao.org/vuex/download/vuex-3.5.1.tgz",
588 | "integrity": "sha1-8bjc6mSbwlJUz09DWAgdv12hiz0="
589 | },
590 | "ylru": {
591 | "version": "1.2.1",
592 | "resolved": "https://registry.npm.taobao.org/ylru/download/ylru-1.2.1.tgz",
593 | "integrity": "sha1-9Xa2M0FUeYnB3nuiiHYJI7J/6E8="
594 | }
595 | }
596 | }
597 |
--------------------------------------------------------------------------------
/单页面配置/dist/bundle.js:
--------------------------------------------------------------------------------
1 | /*! For license information please see bundle.js.LICENSE.txt */
2 | (()=>{"use strict";var t={};t.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}();var e=Object.freeze({});function n(t){return null==t}function r(t){return null!=t}function o(t){return!0===t}function i(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function a(t){return null!==t&&"object"==typeof t}var s=Object.prototype.toString;function c(t){return"[object Object]"===s.call(t)}function u(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function l(t){return r(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function f(t){return null==t?"":Array.isArray(t)||c(t)&&t.toString===s?JSON.stringify(t,null,2):String(t)}function p(t){var e=parseFloat(t);return isNaN(e)?t:e}function d(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(n,1)}}var m=Object.prototype.hasOwnProperty;function y(t,e){return m.call(t,e)}function _(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var g=/-(\w)/g,b=_((function(t){return t.replace(g,(function(t,e){return e?e.toUpperCase():""}))})),C=_((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),w=/\B([A-Z])/g,$=_((function(t){return t.replace(w,"-$1").toLowerCase()})),A=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function x(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function O(t,e){for(var n in e)t[n]=e[n];return t}function k(t){for(var e={},n=0;n0,X=W&&W.indexOf("edge/")>0,G=(W&&W.indexOf("android"),W&&/iphone|ipad|ipod|ios/.test(W)||"ios"===z),Z=(W&&/chrome\/\d+/.test(W),W&&/phantomjs/.test(W),W&&W.match(/firefox\/(\d+)/)),J={}.watch,Q=!1;if(V)try{var Y={};Object.defineProperty(Y,"passive",{get:function(){Q=!0}}),window.addEventListener("test-passive",null,Y)}catch(t){}var tt=function(){return void 0===R&&(R=!V&&!H&&void 0!==t.g&&t.g.process&&"server"===t.g.process.env.VUE_ENV),R},et=V&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function nt(t){return"function"==typeof t&&/native code/.test(t.toString())}var rt,ot="undefined"!=typeof Symbol&&nt(Symbol)&&"undefined"!=typeof Reflect&&nt(Reflect.ownKeys);rt="undefined"!=typeof Set&&nt(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var it=S,at=0,st=function(){this.id=at++,this.subs=[]};st.prototype.addSub=function(t){this.subs.push(t)},st.prototype.removeSub=function(t){h(this.subs,t)},st.prototype.depend=function(){st.target&&st.target.addDep(this)},st.prototype.notify=function(){for(var t=this.subs.slice(),e=0,n=t.length;e-1)if(i&&!y(o,"default"))a=!1;else if(""===a||a===$(t)){var c=Mt(String,o.type);(c<0||s0&&(ce((s=ue(s,(e||"")+"_"+a))[0])&&ce(u)&&(l[c]=vt(u.text+s[0].text),s.shift()),l.push.apply(l,s)):i(s)?ce(u)?l[c]=vt(u.text+s):""!==s&&l.push(vt(s)):ce(s)&&ce(u)?l[c]=vt(u.text+s.text):(o(t._isVList)&&r(s.tag)&&n(s.key)&&r(e)&&(s.key="__vlist"+e+"_"+a+"__"),l.push(s)));return l}function le(t,e){if(t){for(var n=Object.create(null),r=ot?Reflect.ownKeys(t):Object.keys(t),o=0;o0,a=t?!!t.$stable:!i,s=t&&t.$key;if(t){if(t._normalized)return t._normalized;if(a&&r&&r!==e&&s===r.$key&&!i&&!r.$hasNormal)return r;for(var c in o={},t)t[c]&&"$"!==c[0]&&(o[c]=ve(n,c,t[c]))}else o={};for(var u in n)u in o||(o[u]=he(n,u));return t&&Object.isExtensible(t)&&(t._normalized=o),M(o,"$stable",a),M(o,"$key",s),M(o,"$hasNormal",i),o}function ve(t,e,n){var r=function(){var t=arguments.length?n.apply(null,arguments):n({});return(t=t&&"object"==typeof t&&!Array.isArray(t)?[t]:se(t))&&(0===t.length||1===t.length&&t[0].isComment)?void 0:t};return n.proxy&&Object.defineProperty(t,e,{get:r,enumerable:!0,configurable:!0}),r}function he(t,e){return function(){return t[e]}}function me(t,e){var n,o,i,s,c;if(Array.isArray(t)||"string"==typeof t)for(n=new Array(t.length),o=0,i=t.length;odocument.createEvent("Event").timeStamp&&(un=function(){return ln.now()})}function fn(){var t,e;for(cn=un(),an=!0,en.sort((function(t,e){return t.id-e.id})),sn=0;snsn&&en[n].id>t.id;)n--;en.splice(n+1,0,t)}else en.push(t);on||(on=!0,Qt(fn))}}(this)},dn.prototype.run=function(){if(this.active){var t=this.get();if(t!==this.value||a(t)||this.deep){var e=this.value;if(this.value=t,this.user)try{this.cb.call(this.vm,t,e)}catch(t){Rt(t,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,t,e)}}},dn.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},dn.prototype.depend=function(){for(var t=this.deps.length;t--;)this.deps[t].depend()},dn.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||h(this.vm._watchers,this);for(var t=this.deps.length;t--;)this.deps[t].removeSub(this);this.active=!1}};var vn={enumerable:!0,configurable:!0,get:S,set:S};function hn(t,e,n){vn.get=function(){return this[e][n]},vn.set=function(t){this[e][n]=t},Object.defineProperty(t,n,vn)}var mn={lazy:!0};function yn(t,e,n){var r=!tt();"function"==typeof n?(vn.get=r?_n(e):gn(n),vn.set=S):(vn.get=n.get?r&&!1!==n.cache?_n(e):gn(n.get):S,vn.set=n.set||S),Object.defineProperty(t,e,vn)}function _n(t){return function(){var e=this._computedWatchers&&this._computedWatchers[t];if(e)return e.dirty&&e.evaluate(),st.target&&e.depend(),e.value}}function gn(t){return function(){return t.call(this,this)}}function bn(t,e,n,r){return c(n)&&(r=n,n=n.handler),"string"==typeof n&&(n=t[n]),t.$watch(e,n,r)}var Cn=0;function wn(t){var e=t.options;if(t.super){var n=wn(t.super);if(n!==t.superOptions){t.superOptions=n;var r=function(t){var e,n=t.options,r=t.sealedOptions;for(var o in n)n[o]!==r[o]&&(e||(e={}),e[o]=n[o]);return e}(t);r&&O(t.extendOptions,r),(e=t.options=Dt(n,t.extendOptions)).name&&(e.components[e.name]=t)}}return e}function $n(t){this._init(t)}function An(t){return t&&(t.Ctor.options.name||t.tag)}function xn(t,e){return Array.isArray(t)?t.indexOf(e)>-1:"string"==typeof t?t.split(",").indexOf(e)>-1:(n=t,!("[object RegExp]"!==s.call(n))&&t.test(e));var n}function On(t,e){var n=t.cache,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var s=An(a.componentOptions);s&&!e(s)&&kn(n,i,r,o)}}}function kn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,h(n,e)}!function(t){t.prototype._init=function(t){var n=this;n._uid=Cn++,n._isVue=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(n,t):n.$options=Dt(wn(n.constructor),t||{},n),n._renderProxy=n,n._self=n,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(n),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Xe(t,e)}(n),function(t){t._vnode=null,t._staticTrees=null;var n=t.$options,r=t.$vnode=n._parentVnode,o=r&&r.context;t.$slots=fe(n._renderChildren,o),t.$scopedSlots=e,t._c=function(e,n,r,o){return Me(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return Me(t,e,n,r,o,!0)};var i=r&&r.data;$t(t,"$attrs",i&&i.attrs||e,null,!0),$t(t,"$listeners",n._parentListeners||e,null,!0)}(n),tn(n,"beforeCreate"),function(t){var e=le(t.$options.inject,t);e&&(bt(!1),Object.keys(e).forEach((function(n){$t(t,n,e[n])})),bt(!0))}(n),function(t){t._watchers=[];var e=t.$options;e.props&&function(t,e){var n=t.$options.propsData||{},r=t._props={},o=t.$options._propKeys=[];t.$parent&&bt(!1);var i=function(i){o.push(i);var a=Pt(i,e,n,t);$t(r,i,a),i in t||hn(t,"_props",i)};for(var a in e)i(a);bt(!0)}(t,e.props),e.methods&&function(t,e){for(var n in t.$options.props,e)t[n]="function"!=typeof e[n]?S:A(e[n],t)}(t,e.methods),e.data?function(t){var e=t.$options.data;c(e=t._data="function"==typeof e?function(t,e){ut();try{return t.call(e,e)}catch(t){return Rt(t,e,"data()"),{}}finally{lt()}}(e,t):e||{})||(e={});for(var n,r=Object.keys(e),o=t.$options.props,i=(t.$options.methods,r.length);i--;){var a=r[i];o&&y(o,a)||(n=void 0,36===(n=(a+"").charCodeAt(0))||95===n)||hn(t,"_data",a)}wt(e,!0)}(t):wt(t._data={},!0),e.computed&&function(t,e){var n=t._computedWatchers=Object.create(null),r=tt();for(var o in e){var i=e[o],a="function"==typeof i?i:i.get;r||(n[o]=new dn(t,a||S,S,mn)),o in t||yn(t,o,i)}}(t,e.computed),e.watch&&e.watch!==J&&function(t,e){for(var n in e){var r=e[n];if(Array.isArray(r))for(var o=0;o1?x(n):n;for(var r=x(arguments,1),o='event handler for "'+t+'"',i=0,a=n.length;iparseInt(this.max)&&kn(a,s[0],s,this._vnode)),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return F}};Object.defineProperty(t,"config",e),t.util={warn:it,extend:O,mergeOptions:Dt,defineReactive:$t},t.set=At,t.delete=xt,t.nextTick=Qt,t.observable=function(t){return wt(t),t},t.options=Object.create(null),P.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,O(t.options.components,En),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=x(arguments,1);return n.unshift(this),"function"==typeof t.install?t.install.apply(t,n):"function"==typeof t&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=Dt(this.options,t),this}}(t),function(t){t.cid=0;var e=1;t.extend=function(t){t=t||{};var n=this,r=n.cid,o=t._Ctor||(t._Ctor={});if(o[r])return o[r];var i=t.name||n.options.name,a=function(t){this._init(t)};return(a.prototype=Object.create(n.prototype)).constructor=a,a.cid=e++,a.options=Dt(n.options,t),a.super=n,a.options.props&&function(t){var e=t.options.props;for(var n in e)hn(t.prototype,"_props",n)}(a),a.options.computed&&function(t){var e=t.options.computed;for(var n in e)yn(t.prototype,n,e[n])}(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,P.forEach((function(t){a[t]=n[t]})),i&&(a.options.components[i]=a),a.superOptions=n.options,a.extendOptions=t,a.sealedOptions=O({},a.options),o[r]=a,a}}(t),function(t){P.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&c(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&"function"==typeof n&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}($n),Object.defineProperty($n.prototype,"$isServer",{get:tt}),Object.defineProperty($n.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty($n,"FunctionalRenderContext",{value:Te}),$n.version="2.6.12";var jn=d("style,class"),Tn=d("input,textarea,option,select,progress"),In=d("contenteditable,draggable,spellcheck"),Dn=d("events,caret,typing,plaintext-only"),Nn=d("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),Pn="http://www.w3.org/1999/xlink",Ln=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},Fn=function(t){return Ln(t)?t.slice(6,t.length):""},Mn=function(t){return null==t||!1===t};function Rn(t,e){return{staticClass:Bn(t.staticClass,e.staticClass),class:r(t.class)?[t.class,e.class]:e.class}}function Bn(t,e){return t?e?t+" "+e:t:e||""}function Un(t){return Array.isArray(t)?function(t){for(var e,n="",o=0,i=t.length;o-1?lr(t,e,n):Nn(e)?Mn(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):In(e)?t.setAttribute(e,function(t,e){return Mn(e)||"false"===e?"false":"contenteditable"===t&&Dn(e)?e:"true"}(e,n)):Ln(e)?Mn(n)?t.removeAttributeNS(Pn,Fn(e)):t.setAttributeNS(Pn,e,n):lr(t,e,n)}function lr(t,e,n){if(Mn(n))t.removeAttribute(e);else{if(q&&!K&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var fr={create:cr,update:cr};function pr(t,e){var o=e.elm,i=e.data,a=t.data;if(!(n(i.staticClass)&&n(i.class)&&(n(a)||n(a.staticClass)&&n(a.class)))){var s=function(t){for(var e=t.data,n=t,o=t;r(o.componentInstance);)(o=o.componentInstance._vnode)&&o.data&&(e=Rn(o.data,e));for(;r(n=n.parent);)n&&n.data&&(e=Rn(e,n.data));return i=e.staticClass,a=e.class,r(i)||r(a)?Bn(i,Un(a)):"";var i,a}(e),c=o._transitionClasses;r(c)&&(s=Bn(s,Un(c))),s!==o._prevClass&&(o.setAttribute("class",s),o._prevClass=s)}}var dr,vr={create:pr,update:pr};function hr(t,e,n){var r=dr;return function o(){var i=e.apply(null,arguments);null!==i&&_r(t,o,n,r)}}var mr=zt&&!(Z&&Number(Z[1])<=53);function yr(t,e,n,r){if(mr){var o=cn,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}dr.addEventListener(t,e,Q?{capture:n,passive:r}:n)}function _r(t,e,n,r){(r||dr).removeEventListener(t,e._wrapper||e,n)}function gr(t,e){if(!n(t.data.on)||!n(e.data.on)){var o=e.data.on||{},i=t.data.on||{};dr=e.elm,function(t){if(r(t.__r)){var e=q?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}r(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(o),oe(o,i,yr,_r,hr,e.context),dr=void 0}}var br,Cr={create:gr,update:gr};function wr(t,e){if(!n(t.data.domProps)||!n(e.data.domProps)){var o,i,a=e.elm,s=t.data.domProps||{},c=e.data.domProps||{};for(o in r(c.__ob__)&&(c=e.data.domProps=O({},c)),s)o in c||(a[o]="");for(o in c){if(i=c[o],"textContent"===o||"innerHTML"===o){if(e.children&&(e.children.length=0),i===s[o])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===o&&"PROGRESS"!==a.tagName){a._value=i;var u=n(i)?"":String(i);$r(a,u)&&(a.value=u)}else if("innerHTML"===o&&zn(a.tagName)&&n(a.innerHTML)){(br=br||document.createElement("div")).innerHTML="";for(var l=br.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;l.firstChild;)a.appendChild(l.firstChild)}else if(i!==s[o])try{a[o]=i}catch(t){}}}}function $r(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,o=t._vModifiers;if(r(o)){if(o.number)return p(n)!==p(e);if(o.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Ar={create:wr,update:wr},xr=_((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Or(t){var e=kr(t.style);return t.staticStyle?O(t.staticStyle,e):e}function kr(t){return Array.isArray(t)?k(t):"string"==typeof t?xr(t):t}var Sr,Er=/^--/,jr=/\s*!important$/,Tr=function(t,e,n){if(Er.test(e))t.style.setProperty(e,n);else if(jr.test(n))t.style.setProperty($(e),n.replace(jr,""),"important");else{var r=Dr(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(Lr).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" "+(t.getAttribute("class")||"")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Mr(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(Lr).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" "+(t.getAttribute("class")||"")+" ",r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function Rr(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&O(e,Br(t.name||"v")),O(e,t),e}return"string"==typeof t?Br(t):void 0}}var Br=_((function(t){return{enterClass:t+"-enter",enterToClass:t+"-enter-to",enterActiveClass:t+"-enter-active",leaveClass:t+"-leave",leaveToClass:t+"-leave-to",leaveActiveClass:t+"-leave-active"}})),Ur=V&&!K,Vr="transition",Hr="animation",zr="transition",Wr="transitionend",qr="animation",Kr="animationend";Ur&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(zr="WebkitTransition",Wr="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(qr="WebkitAnimation",Kr="webkitAnimationEnd"));var Xr=V?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function Gr(t){Xr((function(){Xr(t)}))}function Zr(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),Fr(t,e))}function Jr(t,e){t._transitionClasses&&h(t._transitionClasses,e),Mr(t,e)}function Qr(t,e,n){var r=to(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s=o===Vr?Wr:Kr,c=0,u=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++c>=a&&u()};setTimeout((function(){c0&&(n=Vr,l=a,f=i.length):e===Hr?u>0&&(n=Hr,l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?Vr:Hr:null)?n===Vr?i.length:c.length:0,{type:n,timeout:l,propCount:f,hasTransform:n===Vr&&Yr.test(r[zr+"Property"])}}function eo(t,e){for(;t.length1}function so(t,e){!0!==e.data.show&&ro(e)}var co=function(t){var e,a,s={},c=t.modules,u=t.nodeOps;for(e=0;ev?g(t,n(o[y+1])?null:o[y+1].elm,o,d,y,i):d>y&&C(e,p,v)}(p,h,y,i,l):r(y)?(r(t.text)&&u.setTextContent(p,""),g(p,null,y,0,y.length-1,i)):r(h)?C(h,0,h.length-1):r(t.text)&&u.setTextContent(p,""):t.text!==e.text&&u.setTextContent(p,e.text),r(v)&&r(d=v.hook)&&r(d=d.postpatch)&&d(t,e)}}}function x(t,e,n){if(o(n)&&r(t.parent))t.parent.data.pendingInsert=e;else for(var i=0;i-1,a.selected!==i&&(a.selected=i);else if(T(vo(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));o||(t.selectedIndex=-1)}}function po(t,e){return e.every((function(e){return!T(e,t)}))}function vo(t){return"_value"in t?t._value:t.value}function ho(t){t.target.composing=!0}function mo(t){t.target.composing&&(t.target.composing=!1,yo(t.target,"input"))}function yo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function _o(t){return!t.componentInstance||t.data&&t.data.transition?t:_o(t.componentInstance._vnode)}var go={model:uo,show:{bind:function(t,e,n){var r=e.value,o=(n=_o(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,ro(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=_o(n)).data&&n.data.transition?(n.data.show=!0,r?ro(n,(function(){t.style.display=t.__vOriginalDisplay})):oo(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},bo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Co(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Co(ze(e.children)):t}function wo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var i in o)e[b(i)]=o[i];return e}function $o(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Ao=function(t){return t.tag||He(t)},xo=function(t){return"show"===t.name},Oo={name:"transition",props:bo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Ao)).length){var r=this.mode,o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var a=Co(o);if(!a)return o;if(this._leaving)return $o(t,o);var s="__transition-"+this._uid+"-";a.key=null==a.key?a.isComment?s+"comment":s+a.tag:i(a.key)?0===String(a.key).indexOf(s)?a.key:s+a.key:a.key;var c=(a.data||(a.data={})).transition=wo(this),u=this._vnode,l=Co(u);if(a.data.directives&&a.data.directives.some(xo)&&(a.data.show=!0),l&&l.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(a,l)&&!He(l)&&(!l.componentInstance||!l.componentInstance._vnode.isComment)){var f=l.data.transition=O({},c);if("out-in"===r)return this._leaving=!0,ie(f,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),$o(t,o);if("in-out"===r){if(He(a))return u;var p,d=function(){p()};ie(c,"afterEnter",d),ie(c,"enterCancelled",d),ie(f,"delayLeave",(function(t){p=t}))}}return o}}},ko=O({tag:String,moveClass:String},bo);function So(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Eo(t){t.data.newPos=t.elm.getBoundingClientRect()}function jo(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate("+r+"px,"+o+"px)",i.transitionDuration="0s"}}delete ko.mode;var To={Transition:Oo,TransitionGroup:{props:ko,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Ze(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=wo(this),s=0;s-1?qn[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:qn[t]=/HTMLUnknownElement/.test(e.toString())},O($n.options.directives,go),O($n.options.components,To),$n.prototype.__patch__=V?co:S,$n.prototype.$mount=function(t,e){return function(t,e,n){var r;return t.$el=e,t.$options.render||(t.$options.render=dt),tn(t,"beforeMount"),r=function(){t._update(t._render(),n)},new dn(t,r,S,{before:function(){t._isMounted&&!t._isDestroyed&&tn(t,"beforeUpdate")}},!0),n=!1,null==t.$vnode&&(t._isMounted=!0,tn(t,"mounted")),t}(this,t=t&&V?function(t){return"string"==typeof t?document.querySelector(t)||document.createElement("div"):t}(t):void 0,e)},V&&setTimeout((function(){F.devtools&&et&&et.emit("init",$n)}),0);const Io=$n;var Do=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("section",{attrs:{id:"app"}},[n("h1",[t._v("我去")]),t._v(" "),n("Foo"),t._v(" "),n("Bar")],1)};Do._withStripped=!0;var No=function(){var t=this;t.$createElement;return t._self._c,t._m(0)};function Po(t,e,n,r,o,i,a,s){var c,u="function"==typeof t?t.options:t;if(e&&(u.render=e,u.staticRenderFns=n,u._compiled=!0),r&&(u.functional=!0),i&&(u._scopeId="data-v-"+i),a?(c=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),o&&o.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(a)},u._ssrRegister=c):o&&(c=s?function(){o.call(this,(u.functional?this.parent:this).$root.$options.shadowRoot)}:o),c)if(u.functional){u._injectStyles=c;var l=u.render;u.render=function(t,e){return c.call(e),l(t,e)}}else{var f=u.beforeCreate;u.beforeCreate=f?[].concat(f,c):[c]}return{exports:t,options:u}}No._withStripped=!0;var Lo=Po({name:"bar",data:function(){return{}},components:{},watch:{},mounted:function(){},methods:{}},No,[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("section",{staticClass:"bar"},[n("h1",[t._v("Bar")])])}],!1,null,"2aa73eda",null);Lo.options.__file="src/components/Bar.vue";const Fo=Lo.exports;var Mo=function(){var t=this;t.$createElement;return t._self._c,t._m(0)};Mo._withStripped=!0;var Ro=Po({name:"Foo",data:function(){return{}},components:{},watch:{},mounted:function(){},methods:{}},Mo,[function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("section",{staticClass:"foo"},[n("h1",[t._v("Foo")])])}],!1,null,"54024074",null);Ro.options.__file="src/components/Foo.vue";var Bo=Po({name:"app",data:function(){return{}},components:{Foo:Ro.exports,Bar:Fo},watch:{},mounted:function(){},methods:{}},Do,[],!1,null,null,null);Bo.options.__file="src/App.vue";const Uo=Bo.exports;new Io({el:"#app",data:{},render:function(t){return t(Uo)}})})();
3 | //# sourceMappingURL=bundle.js.map
--------------------------------------------------------------------------------
/SSR-1/dist/server.bundle.js:
--------------------------------------------------------------------------------
1 | /*! For license information please see server.bundle.js.LICENSE.txt */
2 | module.exports=(()=>{var t={241:(t,e,n)=>{"use strict";n.r(e),n.d(e,{default:()=>zo});var r=Object.freeze({});function o(t){return null==t}function i(t){return null!=t}function a(t){return!0===t}function s(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function c(t){return null!==t&&"object"==typeof t}var u=Object.prototype.toString;function l(t){return"[object Object]"===u.call(t)}function f(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function d(t){return i(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function p(t){return null==t?"":Array.isArray(t)||l(t)&&t.toString===u?JSON.stringify(t,null,2):String(t)}function v(t){var e=parseFloat(t);return isNaN(e)?t:e}function h(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(n,1)}}var _=Object.prototype.hasOwnProperty;function g(t,e){return _.call(t,e)}function b(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var C=/-(\w)/g,w=b((function(t){return t.replace(C,(function(t,e){return e?e.toUpperCase():""}))})),$=b((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),x=/\B([A-Z])/g,A=b((function(t){return t.replace(x,"-$1").toLowerCase()})),O=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function k(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function S(t,e){for(var n in e)t[n]=e[n];return t}function j(t){for(var e={},n=0;n0,G=X&&X.indexOf("edge/")>0,J=(X&&X.indexOf("android"),X&&/iphone|ipad|ipod|ios/.test(X)||"ios"===q),Q=(X&&/chrome\/\d+/.test(X),X&&/phantomjs/.test(X),X&&X.match(/firefox\/(\d+)/)),Y={}.watch,tt=!1;if(z)try{var et={};Object.defineProperty(et,"passive",{get:function(){tt=!0}}),window.addEventListener("test-passive",null,et)}catch(t){}var nt=function(){return void 0===B&&(B=!z&&!W&&"undefined"!=typeof global&&global.process&&"server"===global.process.env.VUE_ENV),B},rt=z&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function ot(t){return"function"==typeof t&&/native code/.test(t.toString())}var it,at="undefined"!=typeof Symbol&&ot(Symbol)&&"undefined"!=typeof Reflect&&ot(Reflect.ownKeys);it="undefined"!=typeof Set&&ot(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var st=E,ct=0,ut=function(){this.id=ct++,this.subs=[]};ut.prototype.addSub=function(t){this.subs.push(t)},ut.prototype.removeSub=function(t){y(this.subs,t)},ut.prototype.depend=function(){ut.target&&ut.target.addDep(this)},ut.prototype.notify=function(){for(var t=this.subs.slice(),e=0,n=t.length;e-1)if(i&&!g(o,"default"))a=!1;else if(""===a||a===A(t)){var c=Ut(String,o.type);(c<0||s0&&(le((r=fe(r,(e||"")+"_"+n))[0])&&le(u)&&(l[c]=mt(u.text+r[0].text),r.shift()),l.push.apply(l,r)):s(r)?le(u)?l[c]=mt(u.text+r):""!==r&&l.push(mt(r)):le(r)&&le(u)?l[c]=mt(u.text+r.text):(a(t._isVList)&&i(r.tag)&&o(r.key)&&i(e)&&(r.key="__vlist"+e+"_"+n+"__"),l.push(r)));return l}function de(t,e){if(t){for(var n=Object.create(null),r=at?Reflect.ownKeys(t):Object.keys(t),o=0;o0,a=t?!!t.$stable:!i,s=t&&t.$key;if(t){if(t._normalized)return t._normalized;if(a&&n&&n!==r&&s===n.$key&&!i&&!n.$hasNormal)return n;for(var c in o={},t)t[c]&&"$"!==c[0]&&(o[c]=me(e,c,t[c]))}else o={};for(var u in e)u in o||(o[u]=ye(e,u));return t&&Object.isExtensible(t)&&(t._normalized=o),U(o,"$stable",a),U(o,"$key",s),U(o,"$hasNormal",i),o}function me(t,e,n){var r=function(){var t=arguments.length?n.apply(null,arguments):n({});return(t=t&&"object"==typeof t&&!Array.isArray(t)?[t]:ue(t))&&(0===t.length||1===t.length&&t[0].isComment)?void 0:t};return n.proxy&&Object.defineProperty(t,e,{get:r,enumerable:!0,configurable:!0}),r}function ye(t,e){return function(){return t[e]}}function _e(t,e){var n,r,o,a,s;if(Array.isArray(t)||"string"==typeof t)for(n=new Array(t.length),r=0,o=t.length;rdocument.createEvent("Event").timeStamp&&(fn=function(){return dn.now()})}function pn(){var t,e;for(ln=fn(),cn=!0,rn.sort((function(t,e){return t.id-e.id})),un=0;unun&&rn[n].id>t.id;)n--;rn.splice(n+1,0,t)}else rn.push(t);sn||(sn=!0,te(pn))}}(this)},hn.prototype.run=function(){if(this.active){var t=this.get();if(t!==this.value||c(t)||this.deep){var e=this.value;if(this.value=t,this.user)try{this.cb.call(this.vm,t,e)}catch(t){Bt(t,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,t,e)}}},hn.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},hn.prototype.depend=function(){for(var t=this.deps.length;t--;)this.deps[t].depend()},hn.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||y(this.vm._watchers,this);for(var t=this.deps.length;t--;)this.deps[t].removeSub(this);this.active=!1}};var mn={enumerable:!0,configurable:!0,get:E,set:E};function yn(t,e,n){mn.get=function(){return this[e][n]},mn.set=function(t){this[e][n]=t},Object.defineProperty(t,n,mn)}var _n={lazy:!0};function gn(t,e,n){var r=!nt();"function"==typeof n?(mn.get=r?bn(e):Cn(n),mn.set=E):(mn.get=n.get?r&&!1!==n.cache?bn(e):Cn(n.get):E,mn.set=n.set||E),Object.defineProperty(t,e,mn)}function bn(t){return function(){var e=this._computedWatchers&&this._computedWatchers[t];if(e)return e.dirty&&e.evaluate(),ut.target&&e.depend(),e.value}}function Cn(t){return function(){return t.call(this,this)}}function wn(t,e,n,r){return l(n)&&(r=n,n=n.handler),"string"==typeof n&&(n=t[n]),t.$watch(e,n,r)}var $n=0;function xn(t){var e=t.options;if(t.super){var n=xn(t.super);if(n!==t.superOptions){t.superOptions=n;var r=function(t){var e,n=t.options,r=t.sealedOptions;for(var o in n)n[o]!==r[o]&&(e||(e={}),e[o]=n[o]);return e}(t);r&&S(t.extendOptions,r),(e=t.options=Pt(n,t.extendOptions)).name&&(e.components[e.name]=t)}}return e}function An(t){this._init(t)}function On(t){return t&&(t.Ctor.options.name||t.tag)}function kn(t,e){return Array.isArray(t)?t.indexOf(e)>-1:"string"==typeof t?t.split(",").indexOf(e)>-1:(n=t,!("[object RegExp]"!==u.call(n))&&t.test(e));var n}function Sn(t,e){var n=t.cache,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var s=On(a.componentOptions);s&&!e(s)&&jn(n,i,r,o)}}}function jn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,y(n,e)}!function(t){t.prototype._init=function(t){var e=this;e._uid=$n++,e._isVue=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=Pt(xn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ge(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,o=n&&n.context;t.$slots=pe(e._renderChildren,o),t.$scopedSlots=r,t._c=function(e,n,r,o){return Ue(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return Ue(t,e,n,r,o,!0)};var i=n&&n.data;At(t,"$attrs",i&&i.attrs||r,null,!0),At(t,"$listeners",e._parentListeners||r,null,!0)}(e),nn(e,"beforeCreate"),function(t){var e=de(t.$options.inject,t);e&&(wt(!1),Object.keys(e).forEach((function(n){At(t,n,e[n])})),wt(!0))}(e),function(t){t._watchers=[];var e=t.$options;e.props&&function(t,e){var n=t.$options.propsData||{},r=t._props={},o=t.$options._propKeys=[];t.$parent&&wt(!1);var i=function(i){o.push(i);var a=Lt(i,e,n,t);At(r,i,a),i in t||yn(t,"_props",i)};for(var a in e)i(a);wt(!0)}(t,e.props),e.methods&&function(t,e){for(var n in t.$options.props,e)t[n]="function"!=typeof e[n]?E:O(e[n],t)}(t,e.methods),e.data?function(t){var e=t.$options.data;l(e=t._data="function"==typeof e?function(t,e){ft();try{return t.call(e,e)}catch(t){return Bt(t,e,"data()"),{}}finally{dt()}}(e,t):e||{})||(e={});for(var n,r=Object.keys(e),o=t.$options.props,i=(t.$options.methods,r.length);i--;){var a=r[i];o&&g(o,a)||(n=void 0,36===(n=(a+"").charCodeAt(0))||95===n)||yn(t,"_data",a)}xt(e,!0)}(t):xt(t._data={},!0),e.computed&&function(t,e){var n=t._computedWatchers=Object.create(null),r=nt();for(var o in e){var i=e[o],a="function"==typeof i?i:i.get;r||(n[o]=new hn(t,a||E,E,_n)),o in t||gn(t,o,i)}}(t,e.computed),e.watch&&e.watch!==Y&&function(t,e){for(var n in e){var r=e[n];if(Array.isArray(r))for(var o=0;o1?k(n):n;for(var r=k(arguments,1),o='event handler for "'+t+'"',i=0,a=n.length;iparseInt(this.max)&&jn(a,s[0],s,this._vnode)),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return R}};Object.defineProperty(t,"config",e),t.util={warn:st,extend:S,mergeOptions:Pt,defineReactive:At},t.set=Ot,t.delete=kt,t.nextTick=te,t.observable=function(t){return xt(t),t},t.options=Object.create(null),L.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,S(t.options.components,Tn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=k(arguments,1);return n.unshift(this),"function"==typeof t.install?t.install.apply(t,n):"function"==typeof t&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=Pt(this.options,t),this}}(t),function(t){t.cid=0;var e=1;t.extend=function(t){t=t||{};var n=this,r=n.cid,o=t._Ctor||(t._Ctor={});if(o[r])return o[r];var i=t.name||n.options.name,a=function(t){this._init(t)};return(a.prototype=Object.create(n.prototype)).constructor=a,a.cid=e++,a.options=Pt(n.options,t),a.super=n,a.options.props&&function(t){var e=t.options.props;for(var n in e)yn(t.prototype,"_props",n)}(a),a.options.computed&&function(t){var e=t.options.computed;for(var n in e)gn(t.prototype,n,e[n])}(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,L.forEach((function(t){a[t]=n[t]})),i&&(a.options.components[i]=a),a.superOptions=n.options,a.extendOptions=t,a.sealedOptions=S({},a.options),o[r]=a,a}}(t),function(t){L.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&l(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&"function"==typeof n&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(An),Object.defineProperty(An.prototype,"$isServer",{get:nt}),Object.defineProperty(An.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(An,"FunctionalRenderContext",{value:De}),An.version="2.6.12";var In=h("style,class"),Dn=h("input,textarea,option,select,progress"),Nn=h("contenteditable,draggable,spellcheck"),Pn=h("events,caret,typing,plaintext-only"),Mn=h("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),Ln="http://www.w3.org/1999/xlink",Fn=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},Rn=function(t){return Fn(t)?t.slice(6,t.length):""},Un=function(t){return null==t||!1===t};function Bn(t,e){return{staticClass:Vn(t.staticClass,e.staticClass),class:i(t.class)?[t.class,e.class]:e.class}}function Vn(t,e){return t?e?t+" "+e:t:e||""}function Hn(t){return Array.isArray(t)?function(t){for(var e,n="",r=0,o=t.length;r-1?dr(t,e,n):Mn(e)?Un(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):Nn(e)?t.setAttribute(e,function(t,e){return Un(e)||"false"===e?"false":"contenteditable"===t&&Pn(e)?e:"true"}(e,n)):Fn(e)?Un(n)?t.removeAttributeNS(Ln,Rn(e)):t.setAttributeNS(Ln,e,n):dr(t,e,n)}function dr(t,e,n){if(Un(n))t.removeAttribute(e);else{if(K&&!Z&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var pr={create:lr,update:lr};function vr(t,e){var n=e.elm,r=e.data,a=t.data;if(!(o(r.staticClass)&&o(r.class)&&(o(a)||o(a.staticClass)&&o(a.class)))){var s=function(t){for(var e=t.data,n=t,r=t;i(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(e=Bn(r.data,e));for(;i(n=n.parent);)n&&n.data&&(e=Bn(e,n.data));return o=e.staticClass,a=e.class,i(o)||i(a)?Vn(o,Hn(a)):"";var o,a}(e),c=n._transitionClasses;i(c)&&(s=Vn(s,Hn(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var hr,mr={create:vr,update:vr};function yr(t,e,n){var r=hr;return function o(){var i=e.apply(null,arguments);null!==i&&br(t,o,n,r)}}var _r=qt&&!(Q&&Number(Q[1])<=53);function gr(t,e,n,r){if(_r){var o=ln,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}hr.addEventListener(t,e,tt?{capture:n,passive:r}:n)}function br(t,e,n,r){(r||hr).removeEventListener(t,e._wrapper||e,n)}function Cr(t,e){if(!o(t.data.on)||!o(e.data.on)){var n=e.data.on||{},r=t.data.on||{};hr=e.elm,function(t){if(i(t.__r)){var e=K?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}i(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),ae(n,r,gr,br,yr,e.context),hr=void 0}}var wr,$r={create:Cr,update:Cr};function xr(t,e){if(!o(t.data.domProps)||!o(e.data.domProps)){var n,r,a=e.elm,s=t.data.domProps||{},c=e.data.domProps||{};for(n in i(c.__ob__)&&(c=e.data.domProps=S({},c)),s)n in c||(a[n]="");for(n in c){if(r=c[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),r===s[n])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===n&&"PROGRESS"!==a.tagName){a._value=r;var u=o(r)?"":String(r);Ar(a,u)&&(a.value=u)}else if("innerHTML"===n&&qn(a.tagName)&&o(a.innerHTML)){(wr=wr||document.createElement("div")).innerHTML="";for(var l=wr.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;l.firstChild;)a.appendChild(l.firstChild)}else if(r!==s[n])try{a[n]=r}catch(t){}}}}function Ar(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,r=t._vModifiers;if(i(r)){if(r.number)return v(n)!==v(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Or={create:xr,update:xr},kr=b((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Sr(t){var e=jr(t.style);return t.staticStyle?S(t.staticStyle,e):e}function jr(t){return Array.isArray(t)?j(t):"string"==typeof t?kr(t):t}var Er,Tr=/^--/,Ir=/\s*!important$/,Dr=function(t,e,n){if(Tr.test(e))t.style.setProperty(e,n);else if(Ir.test(n))t.style.setProperty(A(e),n.replace(Ir,""),"important");else{var r=Pr(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(Fr).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" "+(t.getAttribute("class")||"")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Ur(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(Fr).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" "+(t.getAttribute("class")||"")+" ",r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function Br(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&S(e,Vr(t.name||"v")),S(e,t),e}return"string"==typeof t?Vr(t):void 0}}var Vr=b((function(t){return{enterClass:t+"-enter",enterToClass:t+"-enter-to",enterActiveClass:t+"-enter-active",leaveClass:t+"-leave",leaveToClass:t+"-leave-to",leaveActiveClass:t+"-leave-active"}})),Hr=z&&!Z,zr="transition",Wr="animation",qr="transition",Xr="transitionend",Kr="animation",Zr="animationend";Hr&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(qr="WebkitTransition",Xr="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Kr="WebkitAnimation",Zr="webkitAnimationEnd"));var Gr=z?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function Jr(t){Gr((function(){Gr(t)}))}function Qr(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),Rr(t,e))}function Yr(t,e){t._transitionClasses&&y(t._transitionClasses,e),Ur(t,e)}function to(t,e,n){var r=no(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s=o===zr?Xr:Zr,c=0,u=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++c>=a&&u()};setTimeout((function(){c0&&(n=zr,l=a,f=i.length):e===Wr?u>0&&(n=Wr,l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?zr:Wr:null)?n===zr?i.length:c.length:0,{type:n,timeout:l,propCount:f,hasTransform:n===zr&&eo.test(r[qr+"Property"])}}function ro(t,e){for(;t.length1}function uo(t,e){!0!==e.data.show&&io(e)}var lo=function(t){var e,n,r={},c=t.modules,u=t.nodeOps;for(e=0;ev?g(t,o(n[y+1])?null:n[y+1].elm,n,p,y,r):p>y&&C(e,d,v)}(d,h,y,n,l):i(y)?(i(t.text)&&u.setTextContent(d,""),g(d,null,y,0,y.length-1,n)):i(h)?C(h,0,h.length-1):i(t.text)&&u.setTextContent(d,""):t.text!==e.text&&u.setTextContent(d,e.text),i(v)&&i(p=v.hook)&&i(p=p.postpatch)&&p(t,e)}}}function A(t,e,n){if(a(n)&&i(t.parent))t.parent.data.pendingInsert=e;else for(var r=0;r-1,a.selected!==i&&(a.selected=i);else if(D(mo(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));o||(t.selectedIndex=-1)}}function ho(t,e){return e.every((function(e){return!D(e,t)}))}function mo(t){return"_value"in t?t._value:t.value}function yo(t){t.target.composing=!0}function _o(t){t.target.composing&&(t.target.composing=!1,go(t.target,"input"))}function go(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function bo(t){return!t.componentInstance||t.data&&t.data.transition?t:bo(t.componentInstance._vnode)}var Co={model:fo,show:{bind:function(t,e,n){var r=e.value,o=(n=bo(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,io(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=bo(n)).data&&n.data.transition?(n.data.show=!0,r?io(n,(function(){t.style.display=t.__vOriginalDisplay})):ao(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},wo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function $o(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?$o(qe(e.children)):t}function xo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var i in o)e[w(i)]=o[i];return e}function Ao(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Oo=function(t){return t.tag||We(t)},ko=function(t){return"show"===t.name},So={name:"transition",props:wo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Oo)).length){var r=this.mode,o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var i=$o(o);if(!i)return o;if(this._leaving)return Ao(t,o);var a="__transition-"+this._uid+"-";i.key=null==i.key?i.isComment?a+"comment":a+i.tag:s(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var c=(i.data||(i.data={})).transition=xo(this),u=this._vnode,l=$o(u);if(i.data.directives&&i.data.directives.some(ko)&&(i.data.show=!0),l&&l.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(i,l)&&!We(l)&&(!l.componentInstance||!l.componentInstance._vnode.isComment)){var f=l.data.transition=S({},c);if("out-in"===r)return this._leaving=!0,se(f,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Ao(t,o);if("in-out"===r){if(We(i))return u;var d,p=function(){d()};se(c,"afterEnter",p),se(c,"enterCancelled",p),se(f,"delayLeave",(function(t){d=t}))}}return o}}},jo=S({tag:String,moveClass:String},wo);function Eo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function To(t){t.data.newPos=t.elm.getBoundingClientRect()}function Io(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate("+r+"px,"+o+"px)",i.transitionDuration="0s"}}delete jo.mode;var Do={Transition:So,TransitionGroup:{props:jo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Qe(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=xo(this),s=0;s-1?Kn[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:Kn[t]=/HTMLUnknownElement/.test(e.toString())},S(An.options.directives,Co),S(An.options.components,Do),An.prototype.__patch__=z?lo:E,An.prototype.$mount=function(t,e){return function(t,e,n){var r;return t.$el=e,t.$options.render||(t.$options.render=ht),nn(t,"beforeMount"),r=function(){t._update(t._render(),n)},new hn(t,r,E,{before:function(){t._isMounted&&!t._isDestroyed&&nn(t,"beforeUpdate")}},!0),n=!1,null==t.$vnode&&(t._isMounted=!0,nn(t,"mounted")),t}(this,t=t&&z?function(t){return"string"==typeof t?document.querySelector(t)||document.createElement("div"):t}(t):void 0,e)},z&&setTimeout((function(){R.devtools&&rt&&rt.emit("init",An)}),0);const No=An;var Po=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("section",{attrs:{id:"app"}},[t._ssrNode("我是App哈哈哈
"),n("Foo"),t._ssrNode(" "),n("Bar")],2)};Po._withStripped=!0;var Mo=function(){var t=this,e=t.$createElement;return(t._self._c||e)("section",{staticClass:"bar"},[t._ssrNode(" Bar
")])};function Lo(t,e,n,r,o,i,a,s){var c,u="function"==typeof t?t.options:t;if(e&&(u.render=e,u.staticRenderFns=n,u._compiled=!0),r&&(u.functional=!0),i&&(u._scopeId="data-v-"+i),a?(c=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),o&&o.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(a)},u._ssrRegister=c):o&&(c=s?function(){o.call(this,(u.functional?this.parent:this).$root.$options.shadowRoot)}:o),c)if(u.functional){u._injectStyles=c;var l=u.render;u.render=function(t,e){return c.call(e),l(t,e)}}else{var f=u.beforeCreate;u.beforeCreate=f?[].concat(f,c):[c]}return{exports:t,options:u}}Mo._withStripped=!0;var Fo=Lo({name:"bar",data:function(){return{}},components:{},watch:{},mounted:function(){},methods:{click:function(){alert("click")}}},Mo,[],!1,(function(t){var e=n(415);e.__inject__&&e.__inject__(t)}),"2aa73eda","5c87ab7e");Fo.options.__file="src/components/Bar.vue";const Ro=Fo.exports;var Uo=function(){var t=this,e=t.$createElement;return(t._self._c||e)("section",{staticClass:"foo"},[t._ssrNode("Fooqqq
")])};Uo._withStripped=!0;var Bo=Lo({name:"Foo",data:function(){return{}},components:{},watch:{},mounted:function(){},methods:{}},Uo,[],!1,(function(t){var e=n(107);e.__inject__&&e.__inject__(t)}),"54024074","47da2ab1");Bo.options.__file="src/components/Foo.vue";var Vo=Lo({name:"app",data:function(){return{}},components:{Foo:Bo.exports,Bar:Ro},watch:{},mounted:function(){},methods:{}},Po,[],!1,null,null,"64137b2d");Vo.options.__file="src/App.vue";const Ho=Vo.exports,zo=function(){return new No({render:function(t){return t(Ho)}})}},152:(t,e,n)=>{var r=n(645)((function(t){return t[1]}));r.push([t.id,"\nh1[data-v-2aa73eda] {\n color: yellow;\n}\n",""]),t.exports=r},652:(t,e,n)=>{var r=n(645)((function(t){return t[1]}));r.push([t.id,"\n.foo[data-v-54024074] {\n color: red;\n}\nh1[data-v-54024074] {\n color: red;\n}\n",""]),t.exports=r},645:t=>{"use strict";t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var n=t(e);return e[2]?"@media ".concat(e[2]," {").concat(n,"}"):n})).join("")},e.i=function(t,n,r){"string"==typeof t&&(t=[[null,t,""]]);var o={};if(r)for(var i=0;i{"use strict";n.r(e),n.d(e,{default:()=>a});var r=n(564),o=n.n(r),i={};for(const t in r)"default"!==t&&(i[t]=()=>r[t]);n.d(e,i);const a=o()},107:(t,e,n)=>{"use strict";n.r(e),n.d(e,{default:()=>a});var r=n(441),o=n.n(r),i={};for(const t in r)"default"!==t&&(i[t]=()=>r[t]);n.d(e,i);const a=o()},564:(t,e,n)=>{var r=n(152);"string"==typeof r&&(r=[[t.id,r,""]]),r.locals&&(t.exports=r.locals);var o=n(703).Z;t.exports.__inject__=function(t){o("18786287",r,!1,t)}},441:(t,e,n)=>{var r=n(652);"string"==typeof r&&(r=[[t.id,r,""]]),r.locals&&(t.exports=r.locals);var o=n(703).Z;t.exports.__inject__=function(t){o("506256e7",r,!1,t)}},703:(t,e,n)=>{"use strict";function r(t,e,n,r){if(r||"undefined"==typeof __VUE_SSR_CONTEXT__||(r=__VUE_SSR_CONTEXT__),r){r.hasOwnProperty("styles")||(Object.defineProperty(r,"styles",{enumerable:!0,get:function(){return o(r._styles)}}),r._renderStyles=o);var i=r._styles||(r._styles={});e=function(t,e){for(var n=[],r={},o=0;o"+r.css+""}return e}n.d(e,{Z:()=>r})}},e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={id:r,exports:{}};return t[r](o,o.exports,n),o.exports}return n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n(241)})();
--------------------------------------------------------------------------------