Thank you for reporting another edge case for Blaze.
As part of Meteor 3.6, we have covered a bunch of new failure cases, and this is yet another one. We really need your help to get Blaze into a properly covered state, so thank you for showing up and reporting the problem in detail.
Thanks to that, we have been able to cover this edge case with dynamic imports in our E2E suite and fix it:
release-3.6 ← test/14803-blaze-lazy-import
opened 03:34PM - 30 Sep 26 UTC
This PR fixes lazy Blaze template imports with Rspack for `release-3.6`. When a … FlowRouter route dynamically imports its controller, the controller's paired HTML now stays lazy and is ready before the controller executes.
Fixes [#14803](https://github.com/meteor/meteor/issues/14803).
I reproduced the issue with FlowRouter's `waitOn()` importing a controller that imports `./tagged-with-page.html`. The default Meteor bundler already handles this correctly. With Rspack, the controller was lazy, but the HTML was still downloaded and registered at startup because the integration mirrored every HTML import into Meteor's eager entry.
The fix keeps Blaze compilation in Meteor and connects Meteor's existing dynamic-import loader to Rspack's chunk-loading hooks. Rspack tracks the HTML dependencies of each chunk and waits for them before evaluating the controller. The compiled templates are fetched through Meteor's dynamic-import payloads alongside the Rspack JavaScript chunk, using Meteor's existing cache. Templates used by the initial app remain eager, including those shared with a lazy route.
Also, generated imports now keep their configured order across rebuilds and upgrades, so the template module stays before the app bundle. In development, Meteor handles the page reload after recompiling the templates, including JavaScript-only changes. This avoids reloading against mismatched JavaScript and templates.
The new E2Es check the initial scripts actually downloaded by the browser, template registration before navigation, and template availability when the controller executes. They cover the default bundler and Rspack in development and production, a built Rspack app, and eager-to-lazy transitions during development rebuilds. The existing router import-order assertion follows the generated template module and still checks that templates load before the app bundle.
Validation with the local `@meteorjs/rspack` package linked:
- All 31 Blaze E2E checks passed in Chromium with retries disabled: 26 existing checks and five new dynamic-import cases.
- All three new unit checks passed, covering import order as dependencies change, upgrades of existing generated entries, and preservation of the last working entry when compilation fails.
- The E2E group audit and whitespace checks passed.
```bash
METEOR_E2E_TEST_RETRIES=0 npm run test:e2e:group -- blaze
npm run test:unit -- npm-packages/meteor-rspack/plugins/RequireExtenalsPlugin.test.js
git diff --check
```
For the local run, the skeleton suite used a temporary free port because its default port was occupied. That test-only change was restored afterward.
The package README and E2E coverage report are updated. `@meteorjs/rspack` will need a release for applications to pick up this fix.
We will likely be able to include this fix in the Meteor 3.6 or otherwise 3.6.1 patch, since we have already closed the Meteor 3.6 beta for features or critical changes . I will see if the changes above are stable enough to be added straight.
Btw, we will introduce Blaze 3.1.0 support as part of Meteor 3.7, so we really need more eyes and hands testing it on real Blaze projects.