From the previous two articles, I wrote a simple WebPack configuration that supports VUE isomorphism, but there is no Dev Server yet, it cannot be hot updated and compiled in real time, and it is still very cumbersome for development.

Vue’s official Webpack scaffolding is client-only, powerful and fully configured. Github-vuejs /vue-hackernews-2.0 has been modified to support #SSR# : Clone Built with Vue 2.0, Vue-Router & vuex, with Server side Rendering.

Vue init Wheato/VUE-SSR-boilerplate project-name Let’s talk briefly about the modification process.

Modify the code

This part is mainly to add two entrances, and the modified content is the same as the previous articles and official documents. If it is useful for vue-router, you need to modify route.js. For details, please see the official documentation. With vue-Router we can define static methods inside the component that the server calls to inject data.

// Foo.vue
<template>
  <div>
    <h2>Foo</h2>
  </div>
</template>

<script>
export default {
  preFetch(data) {
    console.log(data)
  },
  data () {
    return {}
  }
}
</script>Copy the code
// entry-server.js
import { createApp } from './app.js'
export default context => {
  return new Promise((resolve, reject) => {
    const { app, router } = createApp()
    router.push('/foo')
    router.onReady(() => {
      const matchedComponents = router.getMatchedComponents()
      matchedComponents.forEach(p => {
        p.preFetch('data')
      })
      resolve(app)
    }, reject)
  })
}Copy the code

Increased server. Js

Server.js is basically copied from vue-Hackernews-2.0, with some cuts, using Express and Koa as well.

Modify the webpack. *. Conf. Js

Changes to webpack.prod.conf.js:

  • Change webpack.prod.conf.js to webpack.server.conf.js;
  • Remove htML-webpack-plugin, use SSR, no need to automatically inject resources into HTML files;
  • Put compressed CSS and JS plug-ins in the conditional judgment, only production environment compressed files;
  • Modify entry;
  • increaseProcess. The env. VUE_ENV = 'client';
  • Added vue-server-renderer client plug-in.

Increase the webpack. Server. Conf. Js:

  • Remove CommonsChunkPlugin from client;
  • Modify import files, and output files, compile target platform;
  • – Added vue-server-renderer server plugin;
  • – Added extract-text-webpack-plugin that does not compile CSS into the server;
  • increaseProcess. The env. VUE_ENV = 'server'.

Add vue-server-renderer client plug-in to webpack.dev.conf.js and change entry to entry-client.js.

Modify the dev – server. Js

The dev-server.js section is quite large, where the client configuration uses webpack.dev.conf.js.

There are no major changes to the Client section, which requires the use of two plugins, Webpack-dev-middleware and Webpack-hot-middleware. – Added a callback to the clientCompiler Done event to save the compiled client-bundle file into the clientManifest so that when the page is refreshed the server render can be synchronized with the modified content.

// dev middleware
var clientCompiler = webpack(clientWebpackConfig)
var devMiddleware = require('webpack-dev-middleware')(clientCompiler, {
  publicPath: clientWebpackConfig.output.publicPath,
  noInfo: true
})
app.use(devMiddleware)
clientCompiler.plugin('done'. stats => { stats = stats.toJson() stats.errors.forEach(err => console.error(err)) stats.warnings.forEach(err => console.warn(err))if (stats.errors.length) return
  clientManifest = JSON.parse(readFile(
    devMiddleware.fileSystem,
    'vue-ssr-client-manifest.json'
  ))
  update()
})
// hot middleware
var hotMiddleware = require('webpack-hot-middleware')(clientCompiler, { heartbeat: 5000 })
app.use(hotMiddleware)Copy the code

In the Server section, The devMiddleware code doesn’t update the Server side, so add a Watch event to compile the Server-bundle in real time.

// watch and update server renderer
var serverCompiler = webpack(serverWebpackConfig)
var mfs = new MFS()
serverCompiler.outputFileSystem = mfs
serverCompiler.watch({}, (err, stats) => {
  if (err) throw err
  stats = stats.toJson()
  if (stats.errors.length) return
  // read bundle generated by vue-ssr-webpack-plugin
  bundle = JSON.parse(readFile(mfs, 'vue-ssr-server-bundle.json'))
  update()
})
// read template from disk and watch
template = fs.readFileSync(templatePath, 'utf-8')
chokidar.watch(templatePath).on('change', () => {
  template = fs.readFileSync(templatePath, 'utf-8')
  console.log('index.html template updated.')
  hotMiddleware.publish({ action: 'reload'})})Copy the code

Modify the build. Js

The modification point is relatively simple. After compiling on the client side, you can add compiling on the server side. Finally, modify the package.json command.

NPM run dev NPM run build NPM run server // Start the serverCopy the code

More code can be created using the scaffold template to create an empty project to run around.

Vue.js SSR Step by Step series

  • Vue.js SSR Step by Step (1) – Implement simple client-only vuE-Webpack configuration
  • Vue.js SSR Step by Step (2) – a simple isomorphic DEMO