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.