3

I'm using Vue CLI which uses main.js to mount the app versus Server-Side Rendering (according to the tutorial I follow here) which uses app.js, entry-client.js and entry-server.js.

I tried to bypass main.js, but I'm having an error since its seems its required some how.

How can I work to keep main.js with app.js, entry-client.js and entry-server.js.

It might be a very basic question and I could maybe use the content of app.js in main.js, be I want to do things right.

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

Any help is greatly appreciated.

1 Answer 1

3

I just found how. By default, Vue CLI 3 comes with no vue.config.js. I had to create one at the root of the folder to override the entry which was set to /src/main.js.

I used the vue.config.js found on this github and onverwrittes the entry to ./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
      })
    )
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.