Я создаю Vue приложение SSR для рендеринга простой vue стороны сервера компонентов. После официального руководства по сайту vuejs я создал два файла ввода server-entry.js
и client-entry.js
, запись клиента работает нормально и без проблем отображает компонент. Однако, когда я создаю запись сервера, она собирается без проблем, давая мне js/<bundle>.js
и css/<bundle>.css
. Но когда я запускаю файл server.js
с:
node src/server.js
, терминал показывает, что он работает и прослушивает порт 8080. Но когда я захожу на localhost: 8080. У меня следующая ошибка:
TypeError: createApp is not a function
at server.get (/home/osama/projects/quran-embed/src/server.js:9:5)
at Layer.handle [as handle_request] (/home/osama/projects/quran-embed/node_modules/express/lib/router/layer.js:95:5)
at next (/home/osama/projects/quran-embed/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/osama/projects/quran-embed/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/osama/projects/quran-embed/node_modules/express/lib/router/layer.js:95:5)
at /home/osama/projects/quran-embed/node_modules/express/lib/router/index.js:281:22
at param (/home/osama/projects/quran-embed/node_modules/express/lib/router/index.js:354:14)
at param (/home/osama/projects/quran-embed/node_modules/express/lib/router/index.js:365:14)
at Function.process_params (/home/osama/projects/quran-embed/node_modules/express/lib/router/index.js:410:3)
at next (/home/osama/projects/quran-embed/node_modules/express/lib/router/index.js:275:10)
Я не понимаю, почему она говорит мне, что createApp не является функцией, хотя это так.
ПРИМЕЧАНИЕ: I Я использую Vue CLI 3.
Вот соответствующие файлы:
app. js
// https://ssr.vuejs.org/guide/structure.html#code-structure-with-webpack
// app.js the universal entry
import Vue from 'vue'
import App from './App.vue'
import {createRouter} from './router'
import {createStore} from './store'
import './assets/scss/main.scss'
Vue.config.productionTip = false
// export a factory function for creating fresh app, router and store
// instances
export function createApp() {
// create router instance
const router = createRouter()
// create store instance
const store = createStore()
// inject router into root Vue instance
const app = new Vue({
router,
store,
render: h => h(App)
})
// return both the app and the router
return {app, router}
}
entry-server. js
// entry-server.js
import {createApp} from './app.js'
export default context => {
// since there could potentially be asynchronous route hooks or components,
// we will be returning a Promise so that the server can wait until
// everything is ready before rendering.
return new Promise((resolve, reject) => {
const {app, router} = createApp()
// set server-side router's location
router.push(context.url)
// wait until router has resolved possible async components and hooks
router.onReady(() => {
const matchedComponents = router.getMatchedComponents()
// no matched routes, reject with 404
if (!matchedComponents.length) {
return reject({code: 404})
}
// the Promise should resolve to the app instance so it can be rendered
resolve(app)
}, reject)
})
}
сервер. js
// server.js
const createApp = require('../dist/js/quran-embed.js');
const renderer = require('vue-server-renderer').createRenderer();
const server = require('express')();
server.get('*', (req, res) => {
const context = {url: req.url};
createApp(context).then(app => {
renderer.renderToString(app, (err, html) => {
if (err) {
if (err.code === 404) {
res.status(404).end('Page not found')
} else {
res.status(500).end('Internal Server Error')
}
} else {
res.end(`
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>${html}</body>
</html>
`)
}
})
})
});
server.listen(8080);
vue .config. js
const webpack = require('webpack')
module.exports = {
css: {
extract: {
filename: 'css/quran-embed.css',
},
// extract: false,
},
configureWebpack: {
output: {
filename: 'js/quran-embed.js',
libraryTarget: 'commonjs2'
},
target: 'node',
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
}),
]
},
chainWebpack:
config => {
config.optimization.delete('splitChunks')
},
filenameHashing: false
}
пакет. json
{
"name": "quran-embed",
"version": "0.1.0",
"private": true,
"scripts": {
"serve-client": "vue-cli-service serve src/entry-client.js",
"build-client": "vue-cli-service build src/entry-client.js",
"build-server": "cross-env NODE_ENV=production vue-cli-service build src/entry-server.js",
"lint": "vue-cli-service lint"
},
"dependencies": {
"at-ui": "^1.3.3",
"at-ui-style": "^1.5.1",
"axios": "^0.19.2",
"bootstrap-v4-rtl": "^4.4.1-1",
"cross-env": "^7.0.0",
"document-register-element": "^1.11.0",
"express": "^4.17.1",
"jsdom": "^16.1.0",
"lodash": "^4.17.13",
"moment": "^2.22.2",
"vue": "^2.5.16",
"vue-custom-element": "^3.2.2",
"vue-router": "^3.0.1",
"vue-server-renderer": "^2.5.16",
"vuex": "^3.0.1",
"webpack": "^4.16.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.4.1",
"@vue/cli-plugin-eslint": "^3.4.1",
"@vue/cli-service": "^3.5.3",
"@vue/eslint-config-standard": "^3.0.0-rc.5",
"node-sass": "^4.11.0",
"sass-loader": "^7.0.3",
"vue-template-compiler": "^2.5.16"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"@vue/standard"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
Если вы посмотрите на файл package.json
, вы можете найти скрипт build-server
, который я использую для сборки пакета для SSR.
Я не уверен, что моя проблема с createApp не была идентифицирована как функция связана с моей настройкой или это просто ES6 / Javascript вещь.
Любая помощь по этому вопросу будет высоко ценится.