From 19d8178606ebb16db20506a2348977acc252a7df Mon Sep 17 00:00:00 2001 From: Tim Miller-Williams Date: Thu, 7 Nov 2019 20:19:54 +0000 Subject: [PATCH] Add webpack hot module reloading for development Co-Authored-By: Tim Miller-Williams --- README.md | 2 +- package.json | 6 ++++-- src/command-line/start.js | 5 +++-- src/plugins/dev-server.js | 28 +++++++++++++++++++++++++++ src/server.js | 11 ++++++++--- webpack.config.js | 2 +- yarn.lock | 40 +++++++++++++++++++++++++++++++++++++-- 7 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 src/plugins/dev-server.js diff --git a/README.md b/README.md index 4e1179d2..d965c146 100644 --- a/README.md +++ b/README.md @@ -112,4 +112,4 @@ Before submitting any change, make sure to: - Read the [Contributing instructions](https://github.com/thelounge/thelounge/blob/master/.github/CONTRIBUTING.md#contributing) - Run `yarn test` to execute linters and test suite - Run `yarn build` if you change or add anything in `client/js` or `client/views` -- `yarn dev` can be used to start The Lounge and watch for any file changes in the client folder +- `yarn dev` can be used to start The Lounge with hot module reloading diff --git a/package.json b/package.json index ee75d83c..0f88e29b 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "scripts": { "build": "webpack", "coverage": "run-s test:{client,server} && nyc --nycrc-path=test/.nycrc-report.json report", - "dev": "run-p watch start", + "dev": "node index start --dev", "format:prettier": "prettier --write \"**/*.*\"", "lint:check-eslint": "eslint --print-config .eslintrc.yml | eslint-config-prettier-check", "lint:eslint": "eslint . --ext .js,.vue --report-unused-disable-directives --color", @@ -122,7 +122,9 @@ "vue-template-compiler": "2.6.10", "vuedraggable": "2.23.2", "webpack": "4.41.2", - "webpack-cli": "3.3.10" + "webpack-cli": "3.3.10", + "webpack-dev-middleware": "3.7.2", + "webpack-hot-middleware": "2.25.0" }, "husky": { "hooks": { diff --git a/src/command-line/start.js b/src/command-line/start.js index 628ddb83..c76e1722 100644 --- a/src/command-line/start.js +++ b/src/command-line/start.js @@ -12,12 +12,13 @@ const Utils = require("./utils"); program .command("start") .description("Start the server") + .option("--dev", "Development mode with hot module reloading") .on("--help", Utils.extraHelp) - .action(function() { + .action(function(options) { initalizeConfig(); const server = require("../server"); - server(); + server(options); }); function initalizeConfig() { diff --git a/src/plugins/dev-server.js b/src/plugins/dev-server.js new file mode 100644 index 00000000..1da841e8 --- /dev/null +++ b/src/plugins/dev-server.js @@ -0,0 +1,28 @@ +"use strict"; + +module.exports = (app) => { + const log = require("../log"); + + log.debug("Starting server in development mode"); + + const webpack = require("webpack"); + const webpackConfig = require("../../webpack.config.js"); + + webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin()); + webpackConfig.entry["js/bundle.js"].push( + "webpack-hot-middleware/client?path=storage/__webpack_hmr" + ); + + const compiler = webpack(webpackConfig); + + app.use( + require("webpack-dev-middleware")(compiler, { + index: "/", + publicPath: webpackConfig.output.publicPath, + }) + ).use( + require("webpack-hot-middleware")(compiler, { + path: "/storage/__webpack_hmr", + }) + ); +}; diff --git a/src/server.js b/src/server.js index 51ea8d87..bf7191ea 100644 --- a/src/server.js +++ b/src/server.js @@ -32,7 +32,7 @@ const serverHash = Math.floor(Date.now() * Math.random()); let manager = null; -module.exports = function() { +module.exports = function(options = {}) { log.info(`The Lounge ${colors.green(Helper.getVersion())} \ (Node.js ${colors.green(process.versions.node)} on ${colors.green(process.platform)} ${ process.arch @@ -44,8 +44,13 @@ module.exports = function() { maxAge: 86400 * 1000, }; - const app = express() - .set("env", "production") + const app = express(); + + if (options.dev) { + require("./plugins/dev-server.js")(app); + } + + app.set("env", "production") .disable("x-powered-by") .use(allRequests) .get("/", indexRequest) diff --git a/webpack.config.js b/webpack.config.js index 3c062ad0..06198be6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -10,7 +10,7 @@ const Helper = require("./src/helper.js"); const config = { mode: process.env.NODE_ENV === "production" ? "production" : "development", entry: { - "js/bundle.js": path.resolve(__dirname, "client/js/lounge.js"), + "js/bundle.js": [path.resolve(__dirname, "client/js/lounge.js")], "css/style": path.resolve(__dirname, "client/css/style.css"), }, devtool: "source-map", diff --git a/yarn.lock b/yarn.lock index 03eaea7b..9411bf6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1051,6 +1051,11 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.5.2" +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -4038,6 +4043,11 @@ html-comment-regex@^1.1.0: resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== +html-entities@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + html-minifier-loader@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/html-minifier-loader/-/html-minifier-loader-1.4.1.tgz#65f05e2a5f91f6b0713cc2081ae4ebe4bfc0d696" @@ -5397,6 +5407,11 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + mimic-fn@^2.0.0, mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -7314,7 +7329,7 @@ querystring-es3@^0.2.0: resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= -querystring@0.2.0: +querystring@0.2.0, querystring@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= @@ -7339,7 +7354,7 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" -range-parser@~1.2.1: +range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== @@ -9286,6 +9301,27 @@ webpack-cli@3.3.10: v8-compile-cache "2.0.3" yargs "13.2.4" +webpack-dev-middleware@3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" + integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + +webpack-hot-middleware@2.25.0: + version "2.25.0" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz#4528a0a63ec37f8f8ef565cf9e534d57d09fe706" + integrity sha512-xs5dPOrGPCzuRXNi8F6rwhawWvQQkeli5Ro48PRuQh8pYPCPmNnltP9itiUPT4xI8oW+y0m59lyyeQk54s5VgA== + dependencies: + ansi-html "0.0.7" + html-entities "^1.2.0" + querystring "^0.2.0" + strip-ansi "^3.0.0" + webpack-log@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f"