From ec89d00bf92e62c989b116f635871c5ec41f7f23 Mon Sep 17 00:00:00 2001 From: Francois Wouts Date: Sat, 26 May 2018 19:04:35 +1000 Subject: [PATCH] Fix hot module reloading, ensuring that it works for multiple reloads and detects CSS changes This required removing postcss-loader, and I'm not sure why. For now, this seems fine. --- internal/package.json | 2 +- internal/web_bundle/create_webpack_config.js | 20 ++----- internal/web_bundle/rule.bzl | 51 ++++++++++++----- internal/yarn.lock | 58 ++------------------ 4 files changed, 49 insertions(+), 82 deletions(-) diff --git a/internal/package.json b/internal/package.json index b31dd6c..5c31e1e 100644 --- a/internal/package.json +++ b/internal/package.json @@ -2,12 +2,12 @@ "dependencies": { "babel-cli": "^6.26.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", + "chokidar": "^2.0.3", "css-loader": "^0.28.11", "file-loader": "^1.1.11", "fs-extra": "^5.0.0", "html-webpack-plugin": "^3.2.0", "node-sass": "^4.9.0", - "postcss-loader": "^2.1.5", "sass-loader": "^7.0.1", "style-loader": "^0.21.0", "typescript": "^2.8.3", diff --git a/internal/web_bundle/create_webpack_config.js b/internal/web_bundle/create_webpack_config.js index 192bf13..32fbe36 100644 --- a/internal/web_bundle/create_webpack_config.js +++ b/internal/web_bundle/create_webpack_config.js @@ -27,7 +27,7 @@ module.exports = ( loadersNpmPackagesDir, htmlTemplatePath, ) => ({ - entry: (sourceDir.startsWith("/tmp/") ? "" : "./") + path.join( + entry: (sourceDir.startsWith("/") ? "" : "./") + path.join( sourceDir, path.dirname("${libBuildfilePath}"), "${entry}", @@ -57,12 +57,10 @@ module.exports = ( { loader: "css-loader", options: { - importLoaders: 1, modules: true, camelCase: true } - }, - "postcss-loader" + } ] }, { @@ -72,12 +70,11 @@ module.exports = ( { loader: "css-loader", options: { - importLoaders: 2, + importLoaders: 1, modules: true, camelCase: true } }, - "postcss-loader", "sass-loader" ] }, @@ -85,13 +82,7 @@ module.exports = ( test: /\\.css$/, use: [ "style-loader", - { - loader: "css-loader", - options: { - importLoaders: 1 - } - }, - "postcss-loader" + "css-loader" ] }, { @@ -101,10 +92,9 @@ module.exports = ( { loader: "css-loader", options: { - importLoaders: 2 + importLoaders: 1 } }, - "postcss-loader", "sass-loader" ] }, diff --git a/internal/web_bundle/rule.bzl b/internal/web_bundle/rule.bzl index 62a7fbb..9f6d460 100644 --- a/internal/web_bundle/rule.bzl +++ b/internal/web_bundle/rule.bzl @@ -79,34 +79,59 @@ def _web_bundle_impl(ctx): const fs = require("fs-extra"); const path = require("path"); const serve = require("webpack-serve"); +const chokidar = require("chokidar"); + +// We cannot build directly from the source directory as Webpack struggles to +// watch it correctly. Instead, we watch the source directory ourselves with +// chokidar (below), and copy it whenever it changes. +const bazelSrcDir = "{source_dir}"; +const srcDir = "devserver-src"; + +// copySrcSoon() will ensures that copySrc() is only called at most once per +// second. +let copySoonTimeout = null; +function copySrcSoon() {{ + if (copySoonTimeout) {{ + clearTimeout(copySoonTimeout); + }} + copySoonTimeout = setTimeout(copySrc, 1000); +}} + +// copySrc() copies files from Bazel's source to our source, which will be +// picked up by Webpack. +function copySrc() {{ + fs.copySync(bazelSrcDir, srcDir, {{ + dereference: true, + overwrite: true, + }}); +}} + +// Note: path.dirname() is essential here. Watching the directory directly +// does not work, probably because of the symlinks that Bazel shuffles around. +chokidar.watch(path.dirname(bazelSrcDir), {{ + ignoreInitial: true, + followSymlinks: true, +}}).on("all", copySrcSoon); +copySrc(); const configGenerator = require(path.resolve("{webpack_config}")); const config = configGenerator( - "{source_dir}", + srcDir, "{output_bundle_dir}", - "{dependencies_packages_dir}", + path.resolve("{dependencies_packages_dir}"), "{internal_packages_dir}", "{html_template}", ); - serve({{ config, -}}).then(server => {{ - server.on("build-started", ({{ compiler }}) => {{ - compiler.hooks.watchRun.tapPromise("check-entry-exists", async () => {{ - while (!fs.existsSync(config.entry[0])) {{ - console.log("Waiting for config.entry[0] to be compiled..."); - await new Promise(resolve => setTimeout(resolve, 1000)); - }} - }}) - }}); + hot: true, }}); """.format( webpack_config = webpack_config.short_path, # Directory containing the compiled source code of the js_library. source_dir = ctx.attr.lib[JsLibraryInfo].full_src_dir.short_path, # Directory in which to place the compiled JavaScript. - output_bundle_dir = ctx.outputs.bundle_dir.path, + output_bundle_dir = ctx.outputs.bundle_dir.short_path, # Directory containing external NPM dependencies the code depends on. dependencies_packages_dir = ctx.attr.lib[JsLibraryInfo].npm_packages_installed_dir.short_path, # Directory containing internal NPM dependencies (for build tools). diff --git a/internal/yarn.lock b/internal/yarn.lock index ce529b9..f47e991 100644 --- a/internal/yarn.lock +++ b/internal/yarn.lock @@ -751,7 +751,7 @@ chokidar@^1.6.1: optionalDependencies: fsevents "^1.0.0" -chokidar@^2.0.2: +chokidar@^2.0.2, chokidar@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.3.tgz#dcbd4f6cbb2a55b4799ba8a840ac527e5f4b1176" dependencies: @@ -1000,18 +1000,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.2.2.tgz#6173cebd56fac042c1f4390edf7af6c07c7cb892" - dependencies: - is-directory "^0.3.1" - js-yaml "^3.4.3" - minimist "^1.2.0" - object-assign "^4.1.0" - os-homedir "^1.0.1" - parse-json "^2.2.0" - require-from-string "^1.1.0" - cosmiconfig@^5.0.2: version "5.0.3" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.3.tgz#299c08ebce9d2df8a2c9ec3f11e55b1c2e897bf3" @@ -2565,7 +2553,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.4.3, js-yaml@^3.9.0: +js-yaml@^3.9.0: version "3.11.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" dependencies: @@ -3417,7 +3405,7 @@ os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" -os-homedir@^1.0.0, os-homedir@^1.0.1: +os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -3684,38 +3672,6 @@ postcss-filter-plugins@^2.0.0: postcss "^5.0.4" uniqid "^4.0.0" -postcss-load-config@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-1.2.0.tgz#539e9afc9ddc8620121ebf9d8c3673e0ce50d28a" - dependencies: - cosmiconfig "^2.1.0" - object-assign "^4.1.0" - postcss-load-options "^1.2.0" - postcss-load-plugins "^2.3.0" - -postcss-load-options@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-load-options/-/postcss-load-options-1.2.0.tgz#b098b1559ddac2df04bc0bb375f99a5cfe2b6d8c" - dependencies: - cosmiconfig "^2.1.0" - object-assign "^4.1.0" - -postcss-load-plugins@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz#745768116599aca2f009fad426b00175049d8d92" - dependencies: - cosmiconfig "^2.1.1" - object-assign "^4.1.0" - -postcss-loader@^2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.1.5.tgz#3c6336ee641c8f95138172533ae461a83595e788" - dependencies: - loader-utils "^1.1.0" - postcss "^6.0.0" - postcss-load-config "^1.2.0" - schema-utils "^0.4.0" - postcss-merge-idents@^2.1.5: version "2.1.7" resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" @@ -3893,7 +3849,7 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 source-map "^0.5.6" supports-color "^3.2.3" -postcss@^6.0.0, postcss@^6.0.1: +postcss@^6.0.1: version "6.0.22" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.22.tgz#e23b78314905c3b90cbd61702121e7a78848f2a3" dependencies: @@ -4276,10 +4232,6 @@ require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" -require-from-string@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" - require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" @@ -4371,7 +4323,7 @@ sax@^1.2.4, sax@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -schema-utils@^0.4.0, schema-utils@^0.4.4, schema-utils@^0.4.5: +schema-utils@^0.4.4, schema-utils@^0.4.5: version "0.4.5" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" dependencies: