meteor / meteor/meteor

Rspack dev client script is injected without ROOT_URL_PATH_PREFIX, so no app code runs under a path-prefixed ROOT_URL in development

Open Beginner friendly
#14,716 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
JavaScript
Stars
44.8k
Forks
5.2k
Avg merge
3d 12h
Merged PRs (30d)
25

Description

_Problem encountered while developing an application. This issue was written and opened by Claude Code, after review by the author._

### Summary

In development, the Rspack client script is injected into the boilerplate as ``, without `ROOT_URL_PATH_PREFIX`. With a path-prefixed `ROOT_URL` (`https://example.com/app`), `webapp` answers 404 to anything outside the prefix, so that script never loads and the app's client modules never run (`client/main.js` and everything it imports). The page itself renders and Blaze templates from `.html` files still show up, which makes the app look half-alive.

Reproduced with `meteor create --blaze`. The code path is the same for any app using the `rspack` package in development (`packages/rspack/lib/config.js`, `isMeteorAppRun() && isMeteorAppDevelopment()`), so other Rspack skeletons should be affected too; only `--blaze` and the `--pwa` skeleton from #14473 were actually checked.

### Versions

- Meteor `devel` (0bbf7f33bd), run from a checkout: meteor-tool 3.5.1, `rspack` 1.2.1, `boilerplate-generator` 2.1.0, Node 24.15 dev bundle
- Linux (Ubuntu, kernel 6.8)
- Not a regression: the injection was added in d231b23f0b ("ensure a way to inject a custom script", 2025-06-05, first shipped in 3.4) and has never carried the prefix.

### Reproduction

```sh
meteor create --blaze prefixed && cd prefixed
ROOT_URL=http://localhost:3000/app meteor
```

Open `http://localhost:3000/app/`.

**Expected:** the app boots as it does without a prefix; `client/main.js` runs (the `hello` template's `counter` helper exists).

**Actual:** `GET /__rspack__/client-rspack.js` → 404. `Template.hello.__helpers.get('counter')` is undefined, i.e. `client/main.js` never ran, while the page, the `/app/packages/*.js` bundles and the "Click Me" button from the template all load, and `__meteor_runtime_config__.ROOT_URL_PATH_PREFIX` is `"/app"`. Checked from a Playwright page.

The server side already handles the prefix: `GET /app/__rspack__/client-rspack.js` on the same running app returns 200 `text/javascript`. Only the HTML points to the wrong place.

Production is not affected: checked with the app from #14473, `meteor run --production` under the same `ROOT_URL` loads the client bundle from prefixed URLs and the app boots.

### Cause

`packages/rspack/lib/config.js` builds the dev-mode custom script URL as `/__rspack__/<file>` and stores it in `METEOR_APP_CUSTOM_SCRIPT_URL`. `packages/boilerplate-generator/template-web.browser.js` injects it verbatim, while the `additionalStaticJs` entries right above are prefixed with `rootUrlPathPrefix`:

```js
...(additionalStaticJs || []).map(({ contents, pathname }) => (
...
src: rootUrlPathPrefix + pathname,
)),
process.env.METEOR_APP_CUSTOM_SCRIPT_URL ?
template(" <script type=\"text/javascript\" src=\"<%- src %>\">")({
src: process.env.METEOR_APP_CUSTOM_SCRIPT_URL // <- no prefix
})
: '',
```

### Fix

One line in `packages/boilerplate-generator/template-web.browser.js`:

```diff
- src: process.env.METEOR_APP_CUSTOM_SCRIPT_URL
+ src: rootUrlPathPrefix + process.env.METEOR_APP_CUSTOM_SCRIPT_URL
```

Applied locally on the `--blaze` reproduction above: the tag becomes ``, no 4xx, and `client/main.js` runs.

A regression test could be a prefixed `meteor run` in `tools/e2e-tests/skeleton.test.js` asserting that app client code runs; the dev case of the `PWA Skeleton / path prefix /` block in #14473 was left out for exactly this reason and would fit.

### How it was found

While adding path-prefix support to the `meteor create --pwa` skeleton (#14473, review by @italojs), the prefixed E2E case passed in production but failed in development with the service worker never registered. Narrowing it down showed the app's client code was not executing at all in dev under a prefix.

Contributor guide

Open the contributing guide

Research direction

Start in packages/boilerplate-generator/template-web.browser.js and compare the custom script injection with the prefixed additionalStaticJs entries. Run the path-prefix development case in tools/e2e-tests/skeleton.test.js, using the reproduction with ROOT_URL=http://localhost:3000/app as needed. Done means the Rspack client script loads under the prefix and client/main.js runs without a 404.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
build-system
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
88/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.