Last active
August 12, 2019 11:48
-
-
Save prasanthmj/7b2e27a2e9236b161726af3c367255a6 to your computer and use it in GitHub Desktop.
Simple Vue SSR without Vuex and Router.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vue from 'vue'; | |
import { createApp } from './main.js'; | |
const app = createApp(); | |
app.$mount('#app'); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {createApp } from './main.js'; | |
const isDev = process.env.NODE_ENV !== 'production' | |
// This exported function will be called by `bundleRenderer`. | |
// This is where we perform data-prefetching to determine the | |
// state of our application before actually rendering it. | |
// Since data fetching is async, this function is expected to | |
// return a Promise that resolves to the app instance. | |
export default (context) => | |
{ | |
return new Promise((resolve, reject) => | |
{ | |
const app = createApp(); | |
// After all preFetch hooks are resolved, our store is now | |
// filled with the state needed to render the app. | |
// Expose the state on the render context, and let the request handler | |
// inline the state in the HTML response. This allows the client-side | |
// store to pick-up the server-side state without having to duplicate | |
// the initial data fetching on the client. | |
context.state = {}; //store.state | |
resolve(app); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vue from 'vue'; | |
import App from './App.vue'; | |
//Create the vue instance | |
export function createApp () | |
{ | |
const app = new Vue({ | |
render: h => h(App) | |
}); | |
return app; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "simple_vue_templ", | |
"version": "1.0.0", | |
"private": true, | |
"scripts": { | |
"start": "node ./bin/www", | |
"build": "yarn build:client && yarn build:server", | |
"build:client": "cross-env NODE_ENV=production node_modules/.bin/webpack --config ./build/webpack.client.config.js --progress --hide-modules", | |
"build:server": "cross-env NODE_ENV=production node_modules/.bin/webpack --config ./build/webpack.server.config.js --progress --hide-modules" | |
}, | |
"dependencies": { | |
"cookie-parser": "~1.4.4", | |
"cross-env": "^5.2.0", | |
"debug": "~2.6.9", | |
"dotenv": "^8.0.0", | |
"express": "~4.16.1", | |
"http-errors": "~1.6.3", | |
"jade": "~1.11.0", | |
"morgan": "~1.9.1", | |
"pg": "^7.12.0", | |
"pg-hstore": "^2.3.3", | |
"sequelize": "^5.13.0", | |
"sequelize-cli": "^5.5.0", | |
"vue": "^2.6.10", | |
"vue-server-renderer": "^2.6.10" | |
}, | |
"devDependencies": { | |
"@babel/core": "^7.5.5", | |
"babel-core": "^6.26.3", | |
"babel-loader": "^8.0.6", | |
"babel-preset-env": "^1.7.0", | |
"css-loader": "^3.2.0", | |
"node-sass": "^4.12.0", | |
"vue-loader": "^15.7.1", | |
"vue-style-loader": "^4.1.2", | |
"vue-template-compiler": "^2.6.10", | |
"webpack": "^4.39.1", | |
"webpack-cli": "^3.3.6", | |
"webpack-merge": "^4.2.1", | |
"webpack-node-externals": "^1.7.2" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Vue = require('vue'); | |
var express = require('express'); | |
const fs = require('fs'); | |
const path = require('path'); | |
const resolve = file => path.resolve(__dirname, file) | |
var router = express.Router(); | |
const { createBundleRenderer } = require('vue-server-renderer'); | |
function createRenderer (bundle, options) | |
{ | |
const template = fs.readFileSync(resolve('../src/index.template.html'), 'utf-8') | |
// https://github.com/vuejs/vue/blob/dev/packages/vue-server-renderer/README.md#why-use-bundlerenderer | |
return createBundleRenderer(bundle, Object.assign(options, { | |
template, | |
// this is only needed when vue-server-renderer is npm-linked | |
basedir: resolve('../dist') | |
})) | |
} | |
router.get('/app', function(req, res, next) | |
{ | |
const bundle = require('../dist/vue-ssr-server-bundle.json'); | |
const clientManifest = require('../dist/vue-ssr-client-manifest.json'); | |
let renderer = createRenderer(bundle, { clientManifest}); | |
const context = { | |
url: req.url | |
}; | |
renderer.renderToString(context, (err, html) => | |
{ | |
if (err) | |
{ | |
console.log("Error!", err); | |
res.status(500).end('500 | Internal Server Error'); | |
} | |
res.end(html); | |
}); | |
}); | |
module.exports = router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const path = require('path'); | |
const VueLoaderPlugin = require('vue-loader/lib/plugin'); | |
const isProd = process.env.NODE_ENV === 'production'; | |
module.exports = { | |
mode: 'production', | |
output: | |
{ | |
path: path.resolve(__dirname, '../dist'), | |
publicPath: '/dist/', | |
filename: '[name].[chunkhash].js' | |
}, | |
resolve: | |
{ | |
extensions: ['.js', '.vue', '.json'] | |
}, | |
module: | |
{ | |
rules: | |
[ | |
{ | |
test: /\.vue$/, | |
loader: 'vue-loader' | |
}, | |
{ | |
test: /\.js$/, | |
loader: 'babel-loader', | |
exclude: /node_modules/ | |
}, | |
{ | |
test: /\.(png|jpg|gif|svg)$/, | |
loader: 'url-loader', | |
options: { | |
limit: 10000, | |
name: '[name].[ext]?[hash]' | |
} | |
}, | |
{ | |
test: /\.css$/, | |
use: ['vue-style-loader', 'css-loader'] | |
} | |
] | |
}, | |
plugins: [ | |
// make sure to include the plugin! | |
new VueLoaderPlugin() | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const merge = require('webpack-merge'); | |
const base = require('./webpack.base.config'); | |
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin'); | |
const config = merge(base, | |
{ | |
entry: | |
{ | |
app: './src/entry-client.js' | |
}, | |
plugins: | |
[ | |
new VueSSRClientPlugin() | |
] | |
}); | |
module.exports = config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const merge = require('webpack-merge'); | |
const base = require('./webpack.base.config'); | |
const nodeExternals = require('webpack-node-externals'); | |
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin'); | |
module.exports = merge(base, { | |
target: 'node', | |
devtool: '#source-map', | |
entry: './src/entry-server.js', | |
output: { | |
filename: 'server-bundle.js', | |
libraryTarget: 'commonjs2' | |
}, | |
// https://webpack.js.org/configuration/externals/#externals | |
// https://github.com/liady/webpack-node-externals | |
externals: nodeExternals({ | |
// do not externalize CSS files in case we need to import it from a dep | |
whitelist: /\.css$/ | |
}), | |
plugins: [ | |
new VueSSRServerPlugin() | |
] | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment