vuejs/vue-hackernews-2.0

HMR for new module

Opened this issue · 0 comments

Let's say I want to add a new module to server.js and also want hot module reloading, the purpose maybe to a bunch of app.get() and app.post() to to the application, you can picture it as adding a RESTful API (to replace Firebase maybe), I think a simple approach would be adding a new file called entry-api.js with contents like this:

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

And inside server.js:

const app = express()
// ... 
apiRoutes(app)

Here's the webpack config for entry-api.js that works for production (which is almost identical to entry-client.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')
    })
  ]
})

And inside setup-dev-server, I tried to write something like this and it actually compiles whenever I make changes to entry-api.js, but the changes never reflect:

const apiConfig = require('./webpack.api.config')
// ...
module.exports = function setupDevServer (app, templatePath, cb) {
  // ...

  const apiCompiler = webpack(apiConfig)
  const apiMiddleware = require('webpack-dev-middleware')(apiCompiler, {
    publicPath: apiConfig.output.publicPath,
    noInfo: true,
  })
  app.use(apiMiddleware)
  apiCompiler.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
    update()
  })

  // hot middleware
  app.use(require('webpack-hot-middleware')(apiCompiler, { heartbeat: 5000 }))

  return readyPromise
}

How should I write make changes to the webpack configs to enable HMR for entry-api? I'm just laying out RESTful API as an example, and I think there're a lot of similar scenarios (for instance, adding Mongoose for database access or implementing JWT for sign up/login, which are probably better to be implemented elsewhere rather inside entry-client.js or entry-server.js) so the the question should be answered.