Vue CLI和服务器端渲染

时间:2018-07-05 10:20:39

标签: javascript node.js vue.js

我正在使用Vue CLI(使用main.js来安装应用程序)与服务器端渲染(根据我遵循的here教程)一起使用app.js,entry-client.js和entry- server.js。

我试图绕过main.js,但出现错误,因为它似乎需要一些方法。

如何将main.js与app.js,entry-client.js和entry-server.js保持在一起。

这可能是一个非常基本的问题,我可能会在main.js中使用app.js的内容,因为我想做正确的事。

main.js:

import Vue from 'vue'
import bootstrap from 'bootstrap'
import App from './App.vue'
import router from './router'
import store from './store'
import VueResource from 'vue-resource'
import BootstrapVue from 'bootstrap-vue'
import './registerServiceWorker'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

Vue.config.productionTip = false
Vue.use(VueResource)
Vue.use(BootstrapVue)

new Vue({
  bootstrap,
  router,
  store,
  render: h => h(App)
}).$mount('#app')

app.js:

import Vue from 'vue'
import App from './App.vue'
import bootstrap from 'bootstrap'
import { createRouter } from './router'
import store from './store'
import VueResource from 'vue-resource'
import BootstrapVue from 'bootstrap-vue'
import './registerServiceWorker'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

Vue.config.productionTip = false
Vue.use(VueResource)
Vue.use(BootstrapVue)

export function createApp () {
    // create router instance
    const router = createRouter()

    const app = new Vue({
        bootstrap,
        router,
        store,
        render: h => h(App)
    })

    return { app, bootstrap, router, store }
}

server-client.js

import { createApp } from './app'

const { app, router } = createApp()

router.onReady(() => {
    app.$mount('#app')
})

entry-server.js

import { createApp } from './app'

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)
    })
}

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

我刚刚找到了。默认情况下,Vue CLI 3不附带vue.config.js。我必须在文件夹的根目录中创建一个,以覆盖设置为/src/main.js的条目。

我使用了在此github上找到的vue.config.js,然后将entry写入./src/entry-$ {target}

const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
const nodeExternals = require('webpack-node-externals')
const merge = require('lodash.merge')

const TARGET_NODE = process.env.WEBPACK_TARGET === 'node'

const createApiFile = TARGET_NODE 
  ? './create-api-server.js'
  : './create-api-client.js'

const target = TARGET_NODE 
  ? 'server' 
  : 'client'

module.exports = {
  configureWebpack: () => ({
    entry: `./src/entry-${target}`,
    target: TARGET_NODE ? 'node' : 'web',
    node: TARGET_NODE ? undefined : false,
    plugins: [
      TARGET_NODE 
        ? new VueSSRServerPlugin()
        : new VueSSRClientPlugin()
    ],
    externals: TARGET_NODE ? nodeExternals({
      whitelist: /\.css$/
    }) : undefined,
    output: {
      libraryTarget: TARGET_NODE 
        ? 'commonjs2' 
        : undefined
    },
    optimization: {
      splitChunks: undefined
    },
    resolve:{
      alias: {
        'create-api': createApiFile
      }
    }
  }),
  chainWebpack: config => {
    config.module
    .rule('vue')
    .use('vue-loader')
    .tap(options =>
      merge(options, {
        optimizeSSR: false
      })
    )
  }
}