meteor / meteor

Meteor, the JavaScript App Platform

Home Page:https://meteor.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Meteor 3] Calling WebApp.addRuntimeConfigHook breaks __meteor_runtime_config__

zarvox opened this issue · comments

Affected versions: 3.0-beta.0 is impacted (and presumably the other 3.0 alphas are all impacted too). Meteor 2.14 is not.

OS: all (verified on macOS 14.2.1 and Fedora Linux 39)

Reproduction repository: https://github.com/zarvox/meteor-trivial-runtime-config-hook

Steps to reproduce:

  1. Use a meteor-3.0 alpha or beta
  2. Make any call to WebApp.addRuntimeConfigHook() in server code. The hook can be an empty function; it doesn't matter what it is.
  3. Run the app (meteor)
  4. attempt to load the page at http://localhost:3000
  5. observe a blank white page and errors on the JS console

I believe what's happening is that packages/webapp/webapp_server.js calls runtimeConfig.hooks.forEach, and Hook defaults to binding the Meteor environment, which results in wrapping whatever callback the user provided in Meteor.bindEnvironment which seems to return a Promise under meteor 3. Then, when rendered as a string, we get [object Promise] rather than the intended result of running the hook function, which gets propagated into the line

  <script type="text/javascript">__meteor_runtime_config__ = JSON.parse(decodeURIComponent([object Promise]))</script>

which is a syntax error. Later, other parts of the meteor runtime expect that variable to be defined, and those error out too.

I'm not particularly familiar with the expected/intended behavior of bindEnvironment in the fiberless world, but if that's behaving as designed, then we probably want something like the following patch in packages/webapp/webapp_server.js to actually await each hook's completion:

diff --git a/packages/webapp/webapp_server.js b/packages/webapp/webapp_server.js
index 1245207519..3e79976618 100644
--- a/packages/webapp/webapp_server.js
+++ b/packages/webapp/webapp_server.js
@@ -425,10 +425,10 @@ WebApp.addRuntimeConfigHook = function(callback) {
   return runtimeConfig.hooks.register(callback);
 };
 
-function getBoilerplateAsync(request, arch) {
+async function getBoilerplateAsync(request, arch) {
   let boilerplate = boilerplateByArch[arch];
-  runtimeConfig.hooks.forEach(hook => {
-    const meteorRuntimeConfig = hook({
+  await runtimeConfig.hooks.forEachAsync(async hook => {
+    const meteorRuntimeConfig = await hook({
       arch,
       request,
       encodedCurrentConfig: boilerplate.baseData.meteorRuntimeConfig,

This remains unfixed as of 3.0-rc.0.

Taking a note, we will consider to fix on next RC. Thank you