Skip to content

Commit e75a7b9

Browse files
committed
progress to real hapi-vue-ssr
1 parent 869c12e commit e75a7b9

16 files changed

+429
-21
lines changed

examples/hapi-vue-ssr/base/App.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<template>
2+
<div id="app">
3+
<header class="header">
4+
<nav class="inner">
5+
<router-link to="/top">Top</router-link>
6+
<router-link to="/new">New</router-link>
7+
<router-link to="/show">Show</router-link>
8+
<router-link to="/ask">Ask</router-link>
9+
<router-link to="/job">Jobs</router-link>
10+
<a class="github" href="https://github.com/vuejs/vue-hackernews-2.0" target="_blank" rel="noopener">
11+
Built with Vue.js
12+
</a>
13+
</nav>
14+
</header>
15+
<transition name="fade" mode="out-in">
16+
<router-view class="view"></router-view>
17+
</transition>
18+
</div>
19+
</template>

examples/hapi-vue-ssr/base/app.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Vue from 'vue'
2+
import App from './App.vue'
3+
4+
// Expose a factory function that creates a fresh set of store, router,
5+
// app instances on each call (which is called for each SSR request)
6+
export function createApp () {
7+
// create the app instance.
8+
// here we inject the router, store and ssr context to all child components,
9+
// making them available everywhere as `this.$router` and `this.$store`.
10+
const app = new Vue({
11+
render: h => h(App)
12+
})
13+
14+
// expose the app, the router and the store.
15+
// note we are not mounting the app here, since bootstrapping will be
16+
// different depending on whether we are in a browser or on the server.
17+
return { app }
18+
}

examples/hapi-vue-ssr/base/handler.js

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,53 @@ const Fs = require('fs')
44
const Vue = require('vue')
55
const Boom = require('boom')
66
const Path = require('path')
7+
const { createBundleRenderer } = require('vue-server-renderer')
78

89
// initialize Renderer with default template layout
910
const LayoutPath = Path.resolve(__dirname, '..', 'views', 'layout.html')
10-
const Renderer = require('vue-server-renderer').createRenderer({
11-
template: Fs.readFileSync(LayoutPath, 'utf-8'),
12-
data: {
13-
title: 'Welcome to hapi-vue-ssr'
14-
}
11+
const bundle = require(Path.resolve(__dirname, '..', 'dist', 'vue-ssr-bundle.json'))
12+
13+
const Renderer = createBundleRenderer(bundle, {
14+
// I know, readFileSync is bad practice
15+
// It's just shorter to read here.
16+
template: Fs.readFileSync(LayoutPath, 'utf-8')
1517
})
1618

17-
function renderAndReply (template, context, reply) {
19+
function render (template, context, reply) {
1820
const TemplatePath = Path.resolve(__dirname, '..', 'views', `${template}.html`)
1921
const app = new Vue({
2022
data: context,
2123
template: Fs.readFileSync(TemplatePath, 'utf-8')
2224
})
2325

24-
return Renderer.renderToString(app, (err, html) => {
26+
console.log(app)
27+
28+
return Renderer.renderToString(context, (err, html) => {
2529
if (err) {
2630
console.log(err)
2731
return reply(Boom.boomify(err, { statusCode: 500 }))
2832
}
2933

30-
return reply(html)
34+
return reply(html).type('text/html')
3135
})
3236
}
3337

3438
const Handler = {
3539
index: {
3640
handler: (request, reply) => {
37-
renderAndReply('index', null, reply)
41+
render('index', { title: 'Welcome to hapi-vue-ssr' }, reply)
42+
}
43+
},
44+
45+
assets: {
46+
handler: {
47+
directory: { path: Path.resolve(__dirname, '..', 'dist') }
3848
}
3949
},
4050

4151
missing: {
4252
handler: (request, reply) => {
43-
renderAndReply('about', { url: request.url.path }, reply)
53+
render('about', { title: 'About', url: request.url.path }, reply)
4454
}
4555
}
4656
}

examples/hapi-vue-ssr/base/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
const Routes = require('./routes')
44

55
exports.register = (server, options, next) => {
6+
server.dependency([ 'inert' ])
7+
68
server.route(Routes)
7-
server.log('info', 'Plugin registered: 404 handler')
9+
server.log('info', 'Plugin registered: hapi-vue-ssr base')
810

911
next()
1012
}
1113

1214
exports.register.attributes = {
13-
name: '404-handler',
15+
name: 'hapi-vue-ssr-base',
1416
version: '1.0.0'
1517
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import Vue from 'vue'
2+
import App from './App.vue'
3+
4+
new Vue({
5+
el: '#app',
6+
render: h => {
7+
h(App)
8+
}
9+
})
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Vue from 'vue'
2+
import App from './App.vue'
3+
4+
// Receives the context of the render call, returning a Promise resolution to the root Vue instance.
5+
export default context => {
6+
return Promise.resolve(
7+
new Vue({
8+
render: h => {
9+
return h(App)
10+
}
11+
})
12+
)
13+
}

examples/hapi-vue-ssr/base/routes.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ const Routes = [
88
path: '/',
99
config: Handler.index
1010
},
11+
{
12+
method: 'GET',
13+
path: '/dist/{path*}',
14+
config: Handler.assets
15+
},
1116
{
1217
method: [ 'GET', 'POST' ],
1318
path: '/{path*}',

examples/hapi-vue-ssr/dist/build.js

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/hapi-vue-ssr/dist/build.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/hapi-vue-ssr/dist/vue-ssr-bundle.json

Lines changed: 120 additions & 0 deletions
Large diffs are not rendered by default.

examples/hapi-vue-ssr/package.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "nodejs-tutorials-hapi-vue-ssr",
3+
"description": "Example code related to an extensive hapi series on Future Studio (https://futurestud.io)",
4+
"version": "1.0.0",
5+
"author": "Future Studio <info@futurestud.io>",
6+
"bugs": "https://github.com/fs-opensource/nodejs-tutorials-hapi/issues",
7+
"contributors": [
8+
{
9+
"name": "Marcus Poehls",
10+
"email": "marcus@futurestud.io"
11+
}
12+
],
13+
"dependencies": {
14+
"vue": "~2.5.2"
15+
},
16+
"devDependencies": {
17+
"babel-core": "~6.26.0",
18+
"babel-loader": "^7.1.2",
19+
"babel-preset-env": "~1.6.0",
20+
"babel-preset-es2015": "~6.24.1",
21+
"cross-env": "^5.0.5",
22+
"css-loader": "~0.28.7",
23+
"file-loader": "^1.1.4",
24+
"vue-loader": "^13.0.5",
25+
"vue-server-renderer": "~2.5.2",
26+
"vue-ssr-webpack-plugin": "~3.0.0",
27+
"vue-template-compiler": "~2.5.2",
28+
"vuex": "~3.0.0",
29+
"webpack": "^3.6.0",
30+
"webpack-dev-server": "~2.9.2"
31+
},
32+
"engines": {
33+
"node": ">=4.0.0"
34+
},
35+
"homepage": "https://futurestud.io/tutorials/hapi-get-your-server-up-and-running",
36+
"keywords": [
37+
"hapi",
38+
"node.js",
39+
"tutorials"
40+
],
41+
"license": "MIT",
42+
"repository": "https://github.com/fs-opensource/nodejs-tutorials-hapi",
43+
"scripts": {
44+
"build": "npm run build:server && npm run build:client",
45+
"build:client": "cross-env NODE_ENV=production webpack --config webpack.client.config.js --progress --hide-modules",
46+
"build:server": "cross-env NODE_ENV=production webpack --config webpack.server.config.js --progress --hide-modules",
47+
"test": "echo \"Error: no test specified\" && exit 1"
48+
}
49+
}

examples/hapi-vue-ssr/views/about.html

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
<br>
44
<h2>Hey there 😘</h2>
55
<p>
6-
Future Studio is helping 5,000+ users daily to solve
7-
Android and Node.js problems with 350+ written tutorials
8-
and videos. We’re on a mission to provide new in-depth
9-
content every week.
6+
Future Studio is helping 5,000+ users daily to solve Android and Node.js problems with 350+ written tutorials and videos.
7+
We’re on a mission to provide new in-depth content every week.
108
</p>
119

1210
<hr>
@@ -22,4 +20,4 @@ <h2>Hey there 😘</h2>
2220
You’re here: {{ url }}
2321
</p>
2422
</div>
25-
</div>
23+
</div>

examples/hapi-vue-ssr/views/layout.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<!DOCTYPE html>
22
<html>
3+
34
<head>
4-
<title>hapi & Vue SSR</title>
5+
<title>{{title}}</title>
56

67
<link rel="stylesheet" href="//cdn.rawgit.com/necolas/normalize.css/master/normalize.css">
78
<link rel="stylesheet" href="//cdn.rawgit.com/milligram/milligram/master/dist/milligram.min.css">
@@ -15,13 +16,20 @@
1516
}
1617
</style>
1718
</head>
19+
1820
<body>
21+
<div id="skip">
22+
<a href="#app">skip to content</a>
23+
</div>
1924

2025
<div class="container">
2126

2227
<!--vue-ssr-outlet-->
2328

2429
</div>
2530

31+
<script src="/dist/build.js"></script>
32+
2633
</body>
34+
2735
</html>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const path = require('path')
2+
const webpack = require('webpack')
3+
4+
module.exports = {
5+
entry: './base/main.client.js',
6+
output: {
7+
path: path.resolve(__dirname, './dist'),
8+
publicPath: '/dist/',
9+
filename: 'build.js'
10+
},
11+
module: {
12+
rules: [
13+
{
14+
test: /\.vue$/,
15+
loader: 'vue-loader',
16+
options: {
17+
loaders: {
18+
}
19+
// other vue-loader options go here
20+
}
21+
},
22+
{
23+
test: /\.js$/,
24+
loader: 'babel-loader',
25+
exclude: /node_modules/,
26+
query: {
27+
presets: ['es2015']
28+
}
29+
},
30+
{
31+
test: /\.(png|jpg|gif|svg)$/,
32+
loader: 'file-loader',
33+
options: {
34+
name: '[name].[ext]?[hash]'
35+
}
36+
}
37+
]
38+
},
39+
resolve: {
40+
alias: {
41+
'vue$': 'vue/dist/vue.esm.js'
42+
}
43+
},
44+
devServer: {
45+
historyApiFallback: true,
46+
noInfo: true
47+
},
48+
performance: {
49+
hints: false
50+
},
51+
devtool: '#eval-source-map'
52+
}
53+
54+
if (process.env.NODE_ENV === 'production') {
55+
module.exports.devtool = '#source-map'
56+
// http://vue-loader.vuejs.org/en/workflow/production.html
57+
module.exports.plugins = (module.exports.plugins || []).concat([
58+
new webpack.DefinePlugin({
59+
'process.env': {
60+
NODE_ENV: '"production"'
61+
}
62+
}),
63+
new webpack.optimize.UglifyJsPlugin({
64+
sourceMap: true,
65+
compress: {
66+
warnings: false
67+
}
68+
}),
69+
new webpack.LoaderOptionsPlugin({
70+
minimize: true
71+
})
72+
])
73+
}

0 commit comments

Comments
 (0)