Ich habe daran gearbeitet, meine Vuejs App funktioniert gut mit SSR, aber alle meine Versuche gescheitert. Ich brauche wirklich Hilfe dabei.Vuejs 2 Server-Side-Rendering - funktioniert nicht
Bitte beachten Sie, dass ich normale js-Dateien nicht .vue-Dateien mit es6 verwenden und die HTML-Vorlagen mit Webpack erfordern Funktion benötigen.
Die App arbeitet im Entwicklungsmodus in Ordnung, aber wenn ich es starten ausführen 'vue-Server-Renderer' mit und gehen Sie zu jeder Route, wird dieser Fehler ausgelöst:
Error: render function or template not defined in component: anonymous at normalizeRender (/Users/salaahassi/dev/vue/magicum/node_modules/vue-server-renderer/build.js:6015:13) at renderComponent (/Users/salaahassi/dev/vue/magicum/node_modules/vue-server-renderer/build.js:6081:3) at renderNode (/Users/salaahassi/dev/vue/magicum/node_modules/vue-server-renderer/build.js:6065:7) at render (/Users/salaahassi/dev/vue/magicum/node_modules/vue-server-renderer/build.js:6257:5) at RenderStream.render (/Users/salaahassi/dev/vue/magicum/node_modules/vue-server-renderer/build.js:6312:9) at RenderStream.tryRender (/Users/salaahassi/dev/vue/magicum/node_modules/vue-server-renderer/build.js:96:12) at RenderStream._read (/Users/salaahassi/dev/vue/magicum/node_modules/vue-server-renderer/build.js:125:12) at RenderStream.Readable.read (_stream_readable.js:348:10) at resume_ (_stream_readable.js:737:12) at _combinedTickCallback (internal/process/next_tick.js:74:11)
Auch wenn Ich deaktiviere Javascript in meinem Browser, sogar die Homepage wird verschwinden (das ist natürlich, weil es nicht vom SSR funktioniert).
Hier ist mein webpack:
var path = require('path')
var webpack = require('webpack')
var HTMLPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var extractCSS = new ExtractTextPlugin('styles.css');
var options = {
// entry: './entry.client.js',
entry: {
app: './entry.client.js',
vendor: [
'vue',
'vue-router',
'vuex',
'vuex-router-sync',
'moment',
'axios'
]
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/',
filename: '[name].[hash].js',
},
module: {
noParse: /es6-promise\.js$/, // avoid webpack shimming process
rules: [
{
test: /\.html$/,
loader: 'raw-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json-loader'
},
{
test: /\.(png|jpg|gif|svg|woff|woff2|eot|ttf)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
},
{
test: /\.scss$/,
loader: extractCSS.extract('css-loader!sass-loader')
}
]
},
plugins: [
extractCSS,
new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en|zh-tw)$/),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(process.env.NODE_ENV) || 'development',
'VUE_ENV': JSON.stringify(process.env.VUE_ENV) || 'client',
}
})
],
resolve: {
alias: {
'vue$': 'vue/dist/vue'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
devtool: '#eval-source-map'
}
console.log("xxxxx ---node env---- xxxx", process.env.NODE_ENV);
console.log("xxxxx ---vue env---- xxxx", process.env.VUE_ENV);
if (process.env.NODE_ENV != 'development') {
options.entry = './entry.server.js';
options.target = 'node';
options.output.filename = 'bundle-server.js';
options.output.libraryTarget = 'commonjs2';
options.externals = Object.keys(require('./package.json').dependencies);
}
if (process.env.NODE_ENV == 'development') {
options.plugins = (options.plugins || []).concat([
new HTMLPlugin({
template: './index.html'
}),
// extract vendor chunks for better caching
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor'
})
]);
}
if (process.env.VUE_ENV == 'server') {
options.devtool = '#source-map'
options.plugins = (options.plugins || []).concat([
new webpack.optimize.UglifyJsPlugin({
//sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
}),
new CopyWebpackPlugin([
{from: './assets', to: 'assets'},
{from: './index.html'}
])
])
}
module.exports = options;
Und hier ist meine Server-Eintrag Datei:
'use strict'
const fs = require('fs')
const path = require('path')
const resolve = file => path.resolve(__dirname, file)
const express = require('express')
// const favicon = require('serve-favicon')
const serialize = require('serialize-javascript')
const createBundleRenderer = require('vue-server-renderer').createBundleRenderer
const app = express()
// parse index.html template
const template = fs.readFileSync(resolve('./dist/index.html'), 'utf-8')
// create server renderer from real fs
const bundlePath = resolve('./dist/bundle-server.js')
let renderer = createRenderer(fs.readFileSync(bundlePath, 'utf-8'))
console.log(renderer);
function createRenderer (bundle) {
return createBundleRenderer(bundle, {
cache: require('lru-cache')({
max: 1000,
maxAge: 1000 * 60 * 15
})
})
}
var options = {
maxAge: '60d',
setHeaders: function(res, path, stat) {
// Webfonts need to have CORS * set in order to work.
if (path.match(/ttf|woff|woff2|eot|svg/ig)) {
res.set('Access-Control-Allow-Origin', '*');
}
}
};
var dist_path = '/dist/';
app.use(express.static(path.join(__dirname, dist_path), options));
console.log("............");
app.get('*', (req, res) => {
console.log(".....ROUTE.......", req.url);
console.log('renderer', renderer);
if (!renderer) {
return res.end('waiting for compilation... refresh in a moment.')
}
var s = Date.now()
const context = { url: req.url }
const renderStream = renderer.renderToStream(context)
let firstChunk = true
// console.log(html.head);
// res.write(html.head)
renderStream.on('data', chunk => {
if (firstChunk) {
// embed initial store state
if (context.initialState) {
res.write(
`<script>window.__INITIAL_STATE__=${
serialize(context.initialState, { isJSON: true })
}</script>`
)
}
firstChunk = false
}
res.write(chunk)
})
renderStream.on('end',() => {
res.end(template)
console.log(`whole request: ${Date.now() - s}ms`)
})
renderStream.on('error', err => {
throw err
})
})
const port = process.env.PORT || 3000
app.listen(port,() => {
console.log(`server started at http://localhost:${port}`)
})
Haben Sie versuchen, diese config von webpack zu entfernen: '' ' resolve: { alias: { 'vue $': 'vue/dist/vue' } }, ' '' – imcvampire