From f4d4bded139405b3b5ab8c6eaf9d100c1ab60e97 Mon Sep 17 00:00:00 2001 From: Artem Kravchenko Date: Tue, 11 Sep 2018 01:03:57 +0700 Subject: [PATCH] feat: add "HMR" on files inside web-ssr-server/src (#2) --- .../shared/resources/deployment/.env.dist | 1 + packages/web-ssr-server/package.json | 1 + packages/web-ssr-server/src/app.js | 32 ++++++++++++++++--- .../web-ssr-server/src/utils/hot-reloading.js | 29 +++++++++++++++++ packages/web-ssr-server/src/utils/watch.js | 9 ++++++ yarn.lock | 2 +- 6 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 packages/web-ssr-server/src/utils/watch.js diff --git a/packages/shared/resources/deployment/.env.dist b/packages/shared/resources/deployment/.env.dist index ac4ee42..c366891 100644 --- a/packages/shared/resources/deployment/.env.dist +++ b/packages/shared/resources/deployment/.env.dist @@ -23,6 +23,7 @@ WEBPACK_ENABLE_HMR= ################### SSR_ENABLED=1 +SSR_ENABLE_HMR= SSR_SERVER_HOSTNAME=localhost SSR_SERVER_PORT=3000 diff --git a/packages/web-ssr-server/package.json b/packages/web-ssr-server/package.json index 310b7f9..cc2d853 100644 --- a/packages/web-ssr-server/package.json +++ b/packages/web-ssr-server/package.json @@ -19,6 +19,7 @@ "babel-plugin-module-resolver": "3.1.1", "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", "babel-plugin-universal-import": "3.0.2", + "chokidar": "2.0.4", "jest": "23.4.2", "supertest": "3.1.0", "webpack": "4.12.0", diff --git a/packages/web-ssr-server/src/app.js b/packages/web-ssr-server/src/app.js index d90caa5..a4cacdd 100644 --- a/packages/web-ssr-server/src/app.js +++ b/packages/web-ssr-server/src/app.js @@ -1,9 +1,6 @@ import express from 'express'; import path from 'path'; -import { createRenderMiddleware } from './services/render'; -import { createGetAssetsCreator } from './services/render/assets/index'; - // logging // cors // errors? @@ -31,7 +28,9 @@ function createApplication() { const compiler = webpack(webpackConfig); compiler.hooks.done.tap('GetAssetsProvider', stats => { + const { createGetAssetsCreator } = require('./services/render/assets'); app.locals.getAssets = createGetAssetsCreator()(stats); + app.locals.webpackStats = stats; }); app.use( @@ -51,10 +50,35 @@ function createApplication() { ); } } else { + const { createGetAssetsCreator } = require('./services/render/assets'); app.locals.getAssets = createGetAssetsCreator()(); } - app.get('*', createRenderMiddleware()); + if (process.env.SSR_ENABLE_HMR === '1') { + const { watchServer } = require('./utils/watch'); + const { clearServerCache } = require('./utils/hot-reloading'); + + const watcher = watchServer(); + + watcher.on('ready', () => { + watcher.on('all', () => { + clearServerCache(); + + const { createGetAssetsCreator } = require('./services/render/assets'); + const getAssets = createGetAssetsCreator()(app.locals.webpackStats); + app.locals.getAssets = getAssets; + }); + }); + } + + if (process.env.SSR_ENABLE_HMR === '1') { + app.get('*', (req, res, next) => { + const render = require('./services/render').createRenderMiddleware(); + render(req, res, next); + }); + } else { + app.get('*', require('./services/render').createRenderMiddleware()); + } if (process.env.SSR_ENABLED === '1') { app.renderAsync = Promise.promisify(app.render, { context: app }); diff --git a/packages/web-ssr-server/src/utils/hot-reloading.js b/packages/web-ssr-server/src/utils/hot-reloading.js index e69de29..544f898 100644 --- a/packages/web-ssr-server/src/utils/hot-reloading.js +++ b/packages/web-ssr-server/src/utils/hot-reloading.js @@ -0,0 +1,29 @@ +function clearRequireCache(predicate) { + for ( + let i = 0, ids = Object.keys(require.cache), l = ids.length, id; + i < l; + ++i + ) { + id = ids[i]; + + if (predicate(id)) { + delete require.cache[id]; + } + } +} + +const ssrServerFilenamePattern = /web-ssr-server\/src/; + +function isServerFile(id) { + return ssrServerFilenamePattern.test(id); +} + +export function clearServerCache() { + // eslint-disable-next-line no-console + console.log('Started to clear web-ssr-server modules cache'); + + clearRequireCache(isServerFile); + + // eslint-disable-next-line no-console + console.log('Finished to clear web-ssr-server modules cache'); +} diff --git a/packages/web-ssr-server/src/utils/watch.js b/packages/web-ssr-server/src/utils/watch.js new file mode 100644 index 0000000..6512109 --- /dev/null +++ b/packages/web-ssr-server/src/utils/watch.js @@ -0,0 +1,9 @@ +import chokidar from 'chokidar'; +import path from 'path'; + +const packageSrcPath = path.join(__dirname, '..'); + +export function watchServer() { + const watcher = chokidar.watch(packageSrcPath); + return watcher; +} diff --git a/yarn.lock b/yarn.lock index 00b704c..46f8991 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1821,7 +1821,7 @@ chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" -chokidar@^2.0.2: +chokidar@2.0.4, chokidar@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" dependencies: