1

Vue offers a HackerNews example to demonstrate how to do server-sided rendering along with hot module reloading support.

Basically, the client and server side code are split into two files: are compiled into two json files entry-client.js and entry-server.js. Then two webpack configs are written for each and they would be compiled into JSON files.

Then, there's the server server.js which makes use of vue-server-renderer to process the two JSONs and serve the contents.

As for hot module reloading, there's a config called setup-dev-server.js inside the build folder which handles the task and stores the compiled content inside webpack-dev-middleware's file system.

This setup works perfectly as long as you only make changes to entry-client.js and entry-server.js and their associated modules. However, what I want to do is adding a new module that is used by only server.js along with hot module reloading support.

An example would be adding a RESTful API, entry-api.js:

export function apiRoutes(app) {
  app.get('/hihi', (req, res, next) => {
    res.send(JSON.stringify({ status: 'hmr hi hitest success' }));
  });
  app.get('/byebye', (req, res, next) => {
    res.send(JSON.stringify({ status: 'hmr bye byetest success' }));
  });
}

And in server.js:

const isProd = process.env.NODE_ENV === 'production'
// ...
const app = express()

// ...
if (isProd) {
  const template = fs.readFileSync(templatePath, 'utf-8')
  const bundle = require('./dist/vue-ssr-server-bundle.json')
  const clientManifest = require('./dist/vue-ssr-client-manifest.json')
    renderer = createRenderer(bundle, {
    template,
    clientManifest
  })
  apiRoutes = require('./dist/api-bundle.js')
  apiRoutes(app)
} else {
  readyPromise = require('./build/setup-dev-server')(
    app,
    templatePath,
    (bundle, api, options) => {
      renderer = createRenderer(bundle, options)
    }
  )
}
// ...
app.get('*', isProd ? render : (req, res) => {
  readyPromise.then(() => render(req, res))
})

I managed to write a webpack config for compiling entry-api.js which works perfectly for production build. As for hot module reloading, any changes to code associated with entry-api.js does trigger a recompilation but the changes never reflection in real-time. Can someone show me what changes should I make to set-dev-server.js to make it work?

Reference:

My webpack config for entry-api.js:

const webpack = require('webpack')
const merge = require('webpack-merge')
const base = require('./webpack.base.config')
const nodeExternals = require('webpack-node-externals')

module.exports = merge(base, {
  target: 'node',
  devtool: '#source-map',
  entry: './src/entry-api.ts',
  output: {
    filename: 'api-bundle.js',
    libraryTarget: 'commonjs2'
  },
  // https://webpack.js.org/configuration/externals/#externals
  // https://github.com/liady/webpack-node-externals
  externals: nodeExternals({
    // do not externalize CSS files in case we need to import it from a dep
    whitelist: /\.css$/
  }),
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
    })
  ]
})

I also opened an issue on GitHub, which I doubt would get any response.

kevguy
  • 4,328
  • 1
  • 24
  • 45

0 Answers0