New 3.4-beta.12 Release, Faster Builds, Smaller Bundles and Modern Setups with the Rspack integration ⚡

This seems odd. I’m running Meteor 3.4-beta.11 . I was on a branch where everything runs as expected.

In package.json, I updated this:

"react-router-dom": "^6.23.1",

… to this:

"react-router": "^7.9.3",

I didn’t expect react-router 7 to work yet because there are a lot of other changes to make to the code to update from react router 6 to 7. I expected to get a lot of react router error.

But instead, the client wouldn’t load, due to this unexpected and seemingly unrelated error:

In module.js:

        } catch (error) {
            console.error(`Error loading route module \`${route.module}\`, reloading page...`);
            console.error(error);
            if (window.__reactRouterContext && window.__reactRouterContext.isSpaMode && // @ts-expect-error
            import.meta.hot) {
                throw error;
            }
            window.location.reload();
            return new Promise(()=>{});
        }

…on the line:

            import.meta.hot) {
                throw error;
            }

…I get the error:

Uncaught SyntaxError: Cannot use ‘import.meta’ outside a module (at modules.js?hash=81d9f1b41933efc36c207594a7a96b81aa72a01a:26920:20)

To further identify the file in which the error occurs, the first lines of the file are:

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// This is a generated file. You can view the original                  //
// source in your browser if your browser supports source maps.         //
// Source maps are supported by all recent versions of Chrome, Safari,  //
// and Firefox, and by Internet Explorer 11.                            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


Package["core-runtime"].queue("modules",function () {/* Imports */
var Meteor = Package.meteor.Meteor;
var global = Package.meteor.global;
var meteorEnv = Package.meteor.meteorEnv;
var meteorInstall = Package['modules-runtime'].meteorInstall;
var verifyErrors = Package['modules-runtime'].verifyErrors;

var require = meteorInstall({"node_modules":{"meteor":{"modules":{"client.[.....]

Does that make any sense?

I was able to create a tiny test example that shows the same anomaly.

  • Created a new app using meteor create --react
  • Updated to Meteor 3.4-beta.11
  • Added "react-router": "^7.9.3" to package.json
  • Asked a Claude agent to add a component to implement react router v7
  • Launched the app
  • The identical anomaly occurred

Here is a link to the tiny test app:

https://gitlab.com/VikR0001/react-router-7-anomaly

The initial post mentions the command to create an app with the latest beta.
You have that problem because you create the app with 3.3 which is set for CommonJS.
You might have this in your package.json - "type": "commonjs". It needs to go away with Meteor 3.4

The solution with Meteor 3 was to us a patch for the react-router package.
Add patch-package NPM to your dev dependencies and this is my patch file called react-router+7.7.0.patch in the patches folder in root.

What it does - it renames all the .mjs extensions to .js.

diff --git a/node_modules/react-router/package.json b/node_modules/react-router/package.json
index a93691a..5e5f72e 100644
--- a/node_modules/react-router/package.json
+++ b/node_modules/react-router/package.json
@@ -20,26 +20,26 @@
   "sideEffects": false,
   "types": "./dist/development/index.d.ts",
   "main": "./dist/development/index.js",
-  "module": "./dist/development/index.mjs",
+  "module": "./dist/development/index.js",
   "exports": {
     ".": {
       "react-server": {
-        "module": "./dist/development/index-react-server.mjs",
+        "module": "./dist/development/index-react-server.js",
         "default": "./dist/development/index-react-server.js"
       },
       "node": {
         "types": "./dist/development/index.d.ts",
-        "module": "./dist/development/index.mjs",
-        "module-sync": "./dist/development/index.mjs",
+        "module": "./dist/development/index.js",
+        "module-sync": "./dist/development/index.js",
         "default": "./dist/development/index.js"
       },
       "module": {
         "types": "./dist/development/index.d.mts",
-        "default": "./dist/development/index.mjs"
+        "default": "./dist/development/index.js"
       },
       "import": {
         "types": "./dist/development/index.d.mts",
-        "default": "./dist/development/index.mjs"
+        "default": "./dist/development/index.js"
       },
       "default": {
         "types": "./dist/development/index.d.ts",
@@ -49,17 +49,17 @@
     "./dom": {
       "node": {
         "types": "./dist/development/dom-export.d.ts",
-        "module": "./dist/development/dom-export.mjs",
-        "module-sync": "./dist/development/dom-export.mjs",
+        "module": "./dist/development/dom-export.js",
+        "module-sync": "./dist/development/dom-export.js",
         "default": "./dist/development/dom-export.js"
       },
       "module": {
         "types": "./dist/development/dom-export.d.mts",
-        "default": "./dist/development/dom-export.mjs"
+        "default": "./dist/development/dom-export.js"
       },
       "import": {
         "types": "./dist/development/dom-export.d.mts",
-        "default": "./dist/development/dom-export.mjs"
+        "default": "./dist/development/dom-export.js"
       },
       "default": {
         "types": "./dist/development/dom-export.d.ts",
@@ -79,22 +79,22 @@
     },
     "./internal/react-server-client": {
       "react-server": {
-        "module": "./dist/development/index-react-server-client.mjs",
+        "module": "./dist/development/index-react-server-client.js",
         "default": "./dist/development/index-react-server-client.js"
       },
       "node": {
         "types": "./dist/development/index.d.ts",
-        "module": "./dist/development/index.mjs",
-        "module-sync": "./dist/development/index.mjs",
+        "module": "./dist/development/index.js",
+        "module-sync": "./dist/development/index.js",
         "default": "./dist/development/index.js"
       },
       "module": {
         "types": "./dist/development/index.d.mts",
-        "default": "./dist/development/index.mjs"
+        "default": "./dist/development/index.js"
       },
       "import": {
         "types": "./dist/development/index.d.mts",
-        "default": "./dist/development/index.mjs"
+        "default": "./dist/development/index.js"
       },
       "default": {
         "types": "./dist/development/index.d.ts",
@@ -159,4 +159,4 @@
     "watch": "tsup --watch & tsup --config tsup.config.rsc.ts --watch",
     "typecheck": "tsc"
   }
-}
\ No newline at end of file
+}

I can’t access the repo you shared. I get a 404 error.

Do you have the Rspack package in your app? The error looks like it comes from the Meteor bundler compiling your code, which suggests Rspack isn’t running.

Rspack recognizes those export fields, so you don’t need the workaround @paulishca mentioned. That workaround fits a pure Meteor bundler setup without ESM config support, not a Rspack integration, which support it. I also have tests of react-router in the modern test suite confirming no patches required for Meteor when Rspack is integrated to recognize ESM packages.

Please grant repo access so I can check. I suspect Rspack isn’t compiling your app code yet, but if there is another reason I’d like to fix it.

I understand the cache problems happen mainly with your setup using a cloudflared tunnel, not on a normal localhost dev project, right?

I’ve found a few cache issues on the localhost dev server and I’m fixing them. They show up when changing config files and only on app restart. I’m making the cache system aware of these cases. But your issue seems specific to that remote dev setup.

It’s not recommended to add a hash to client-rspack.js. That file handles HMR updates, and a cache buster in the URL breaks that logic. For your setup you may need to disable HMR. Have you tried devServer.hot: false in your rspack.config.js? It should trigger a full reload instead automatically (liveReload: true is set by default).

If you want to keep HMR with your approach, we may need strict cache headers so that file is always fetched from the network. Can you try adding:

devServer: {
  headers: {
    "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate",
    "Pragma": "no-cache",
    "Expires": "0",
    "Surrogate-Control": "no-store"
  }
}

Meteor add rspack fixed it. :100:

I wonder if updating Meteor should give the user an alert to add rspack?

The repo link (without rspack) is now public in case anyone would like to access it.

Thanks @nachocodoner !

2 Likes

I’m working on finding an rspack config that supports rspack code-splitting.

I ran these terminal commands per request from Claude’s web app.

Vik to Claude:

ls -la .meteor/local/build/programs/web.browser/app/
returns many files.

find .meteor/local -name "*defaultVendors*.js"
returns no files

Claude generated:

Aha! That’s the problem - the chunk files aren’t being created at all. The splitChunks configuration is being ignored or overridden by Meteor’s rspack integration.

This means Meteor’s @meteorjs/rspack package might not fully support code splitting, or it’s being disabled somewhere in their integration layer.

Let me try a more explicit approach that forces chunk creation:

I tried another config Claude provided.

Me to Claude:

Now I’m getting this in the IDE during compile:

ERROR in × Conflict: Multiple assets emit different content to the same filename client-rspack.js

Claude replied:

There it is - we’re back to the original conflict! The chunks: 'all' and runtimeChunk: 'single' are causing Meteor and rspack to fight over the output filename.

Unfortunately, this confirms that Meteor’s rspack integration doesn’t properly support code splitting. The integration expects a single bundle file and conflicts when rspack tries to create multiple files.

Posting this here for reference in case Claude is correct. In the meantime, I can revert to a config without rspace code-splitting.

Hey @vikr00001. What are you trying to achieve?

Code splitting works via dynamic imports: use await import('./my-module'). It creates a chunk for that module tree, served from public/build-chunks. Learn more in the Rspack docs.

There are two other options: Entrypoints and SplitChunks. I haven’t tested these, they may not work. I’ll test them in upcoming updates and see if I can support them, along with veryfing the preloac/prefetch of modules from docs.

Please share more details on the code-splitting approach you’re trying.

Tip: give the AI more context about your config. You can get config logs by adding this to package.json:

{
  "meteor": {
    "modern": {
      "verbose": true
    }
  }
}

This shows the final config when running the app, combining defaults and your custom rspack.config.js. Sharing it helps the AI see the full setup and assist further.

1 Like

I have code-splitting through react lazy(), and that has worked for years.

I have the impression that rspack may be able to add additional code-splitting functionality. Is that correct? If so I will try any approach you recommend.

@nachocodoner

After Meteor add rspack, Meteor.loginWithPassword stopped working in my app. I was able to replicate the anomaly in an update to this tiny demo repo I used before:

Accounts.createUser works, but an error is thrown on Meteor.loginWithPassword.

I know how busy you are, so this would take precedence by far over the chunks topic. :slight_smile: Thanks very much for any thoughts!

React.lazy uses dynamic imports for code splitting. We have a working example in the modern test suite where React.lazy is used, and it works well. The repository you shared in the next post should include your React.lazy code-splitting issue, otherwise I can’t tell what the problem is, since this approach is supported.

I will check the repo you shared to see the other login issue you mentioned to me, not sure if related with bundler, I have tested login sucessfully in other apps with Rspack, but good to double check. Thanks.

My react.lazy calls do work with rspack. I will stick with that.

Thanks very much for checking into the login issue.

A note on react lazy, I will paste directly from google and save the planet from an extra search:

In summary, if you need SSR now or in the future, you need more than react lazy

@loadable/component (often referred to as Loadable Components) and React.lazy are both solutions for code splitting and lazy loading components in React applications, but they differ primarily in their support for Server-Side Rendering (SSR) and feature set.

React.lazy:

  • Client-Side Only:

React.lazy is designed for client-side rendering and relies on React.Suspense to handle the loading state. It is not compatible with Server-Side Rendering (SSR) because Suspense is not available in the server environment.

  • Simpler API:

It offers a straightforward API for dynamic imports, making it easy to implement basic lazy loading.

  • Limited Features:

React.lazy focuses on the core functionality of lazy loading and does not offer advanced features like preloading or custom loading states beyond what Suspense provides.

@loadable/component:

  • SSR Compatible:

@loadable/component provides a robust solution for Server-Side Rendering, allowing you to perform code splitting and lazy loading in SSR environments. It handles the complexities of server-side chunking and hydration.

  • Richer Feature Set:

It offers more advanced features compared to React.lazy, including:

  • Preloading: You can explicitly preload components, which can improve user experience by fetching components before they are needed.

  • Custom Loading and Error States: It provides more granular control over loading and error states, allowing for custom fallback components and error handling logic.

  • Library Splitting: It supports library splitting, enabling you to separate common libraries into their own bundles.

  • More Configuration:

While offering more features, it also involves a slightly more complex setup and configuration, especially for SSR.

In summary:

  • If your application is client-side rendered only and you need a simple solution for lazy loading, React.lazy is a suitable and easy-to-use option.
  • If your application requires Server-Side Rendering (SSR) or you need more advanced features like preloading, custom loading/error states, or library splitting, @loadable/component is the recommended choice.
1 Like

Hi, many thanks for your work on modernizing Meteor’s build infrastructure!

Does rspack provide for production builds at the moment? meteor build . (:bulb: I tried . after exhausting my options) gives me

packages/core-runtime.js:189
            throw error;
            ^

Error: Could not find rspack.config.js, rspack.config.mjs, or rspack.config.cjs. Make sure @meteorjs/rspack is installed correctly.
    at getConfigFilePath (packages/rspack/lib/processes.js:161:9)
    at runRspackBuild (packages/rspack/lib/processes.js:406:22)
    at module.wrapAsync.self (packages/rspack/rspack_plugin.js:289:9)

Further investigation with strace appears to show that the getCustomConfigFilePath() logic can’t seem to figure out where the application sources are — Here is an abridged excerpt:

[pid   581] access("/app/node_modules/@meteorjs/rspack/rspack.config.js", F_OK) = -1 ENOENT (No such file or directory)
[pid   581] access("/app/node_modules/@meteorjs/rspack/rspack.config.mjs", F_OK) = -1 ENOENT (No such file or directory)
[pid   581] access("/app/node_modules/@meteorjs/rspack/rspack.config.cjs", F_OK) = -1 ENOENT (No such file or directory)
[pid   581] access("/app/package.json", F_OK) = 0
[pid   581] openat(AT_FDCWD, "/app/package.json", O_RDONLY|O_CLOEXEC) = 383
[pid   581] read(383, "{\n  \"name\": \"phd-assess\",\n  \"ver"..., 8192) = 3391
[pid   581] read(383, "", 8192)         = 0
[pid   581] close(383)                  = 0
[pid   581] access("/app/lerna.json", F_OK) = -1 ENOENT (No such file or directory)
[pid   581] access("/app/pnpm-workspace.yaml", F_OK) = -1 ENOENT (No such file or directory)
[pid   581] access("/package.json", F_OK) = -1 ENOENT (No such file or directory)
[pid   581] access("/lerna.json", F_OK) = -1 ENOENT (No such file or directory)
[pid   581] access("/pnpm-workspace.yaml", F_OK) = -1 ENOENT (No such file or directory)
[pid   581] clock_gettime(CLOCK_MONOTONIC, {tv_sec=44783, tv_nsec=284023876}) = 0
[pid   581] clock_gettime(CLOCK_MONOTONIC, {tv_sec=44783, tv_nsec=284141876}) = 0
[pid   581] write(17, "\33[31mRspack plugin error: Could "..., 155Rspack plugin error: Could not find rspack.config.js, rspack.config.mjs, or rspack.config.cjs. Make sure @meteorjs/rspack is installed correctly.
) = 155

Thanks in advance for your help!

Nevermind — The error message was meant to be taken at face value, and the fix was to put @meteorjs/rspack in dependencies rather than devDependencies in package.json.

Leaving my previous comment up, as an offering to the search engine deities. :moyai:

2 Likes

Well, @meteorjs/rspack is listed as a devDependency in all Meteor-Rspack examples so far.

I’d like to understand why it was required in your setup. Are you using a monorepo structure? How does your project manage dependencies?

I am occasionally getting a ridiculous amount of memory in a rspack instance, I had a 80gb one that i just missed screenshotting as well.

This just happened while I was trying to build my project. I hadn’t gotten it to succeed yet.

Edit:
I have gotten it to happen every time I launch. I’m not sure how long I can keep my computer in this state, but if you have anything I should do to help debug this let me know. I’ve tried deleting the __build and most of the .meteor/local folder and still got the same result


=> Started proxy.
=> Started HMR server.
e[35m[i] Meteor Npx prefix: /Users/user/.meteor/packages/meteor-tool/.3.4.0-beta.11.1byw6heih2ak++os.osx.arm64+web.browser+web.browser.legacy+web.cordova/mt-os.osx.arm64/dev_bundle/bin/npxe[0m
e[35m[i] Meteor Npm prefix: /Users/user/.meteor/packages/meteor-tool/.3.4.0-beta.11.1byw6heih2ak++os.osx.arm64+web.browser+web.browser.legacy+web.cordova/mt-os.osx.arm64/dev_bundle/bin/npme[0m
e[35m[i] Meteor app ignores: _build/test/** _build/main-prod/** node_modules/** .DS_Store .babelrc .bash_profile .eslintrc .gitignore .gitmodules .graphqlrc.ts .mocharc.js .npmrc .oxlintignore .prettierignore .prettierrc .slugignore .watchmanconfig Dockerfile PlayPackSteps.md README.md app.json bitbucket-pipelines.yml docker-compose.yml dump.rdb environment_app_image_aws eslint-local-rules.js eslint.config.mjs heroku-postinstall.sh heroku-preinstall.sh jsconfig.json memoryIssue.txt mobile-config.js npm-shrinkwrap.json out.txt rspack.config.js sample.bin.db1.zip settings.json swc.config.js test.settings.json webpack.config.js .circleci/**/*.ts .circleci/**/*.tsx .circleci/**/*.js .circleci/**/*.jsx .circleci/**/*.mjs .circleci/**/*.cjs .circleci/**/*.json .circleci/**/*.yml .circleci/**/*.info .circleci/**/*.txt .circleci/**/*.sample .circleci/**/*.2 .circleci/**/*.0 .circleci/**/*.4 .circleci/**/*.5 .circleci/**/*.9 .circleci/**/*.7 .circleci/**/*.1 .circleci/**/*.6 .circleci/**/*.64 .circleci/**/*.3 .circleci/**/*.33 .circleci/**/*.22 .circleci/**/*.17 .circleci/**/*.18 .circleci/**/*.19 .circleci/**/*.78 .circleci/**/*.13 .circleci/**/*.20 .circleci/**/*.idx .circleci/**/*.pack .circleci/**/*.public .circleci/**/*.rev .circleci/**/*.lock .circleci/**/*.bin .circleci/**/*.properties .circleci/**/*.iml .circleci/**/*.xml .circleci/**/*.cmake .circleci/**/*.o .circleci/**/*.ninja .circleci/**/*.check_cache .circleci/**/*.a .circleci/**/*.cpp .circleci/**/*.c .circleci/**/*.verify_globs .circleci/**/*.log .circleci/**/*.bzl .circleci/**/*.gradle .circleci/**/*.bundle .circleci/**/*.java .circleci/**/*.h .circleci/**/*.png .circleci/**/*.jpg .circleci/**/*.gif .circleci/**/*.mp4 .circleci/**/*.map .circleci/**/*.ttf .circleci/**/*.meta .circleci/**/*.profm .circleci/**/*.prof .circleci/**/*.pb .circleci/**/*.jar .circleci/**/*.so .circleci/**/*.dat .circleci/**/*.dex .circleci/**/*.aab .circleci/**/*.kotlin_module .circleci/**/*.class .circleci/**/*.ap_ .circleci/**/*.flat .circleci/**/*.zip .circleci/**/*.sym .circleci/**/*.textproto .circleci/**/*.tab .circleci/**/*.tab_i .circleci/**/*.len .circleci/**/*.keystream .circleci/**/*.at .circleci/**/*.bat .circleci/**/*.keystore .circleci/**/*.pro .circleci/**/*.kt .circleci/**/*.sha .circleci/**/*.html .circleci/**/*.md .circleci/**/*.sh .circleci/**/*.plist .circleci/**/*.env .circleci/**/*.local .circleci/**/*.mm .circleci/**/*.podspec .circleci/**/*.swift .circleci/**/*.m .circleci/**/*.hpp .circleci/**/*.cc .circleci/**/*.modulemap .circleci/**/*.xcprivacy .circleci/**/*.swiftinterface .circleci/**/*.swiftdoc .circleci/**/*.strings .circleci/**/*.swiftsourceinfo .circleci/**/*.xcfilelist .circleci/**/*.windows .circleci/**/*.in .circleci/**/*.gz .circleci/**/*.svg .circleci/**/*.build .circleci/**/*.cfg .circleci/**/*.meson .circleci/**/*.yaml .circleci/**/*.s .circleci/**/*.asm .circleci/**/*.bash .circleci/**/*.manifest .circleci/**/*.rc .circleci/**/*.am .circleci/**/*.bak .circleci/**/*.pbxproj .circleci/**/*.xcscheme .circleci/**/*.pch .circleci/**/*.xcconfig .circleci/**/*.markdown .circleci/**/*.cer .circleci/**/*.ipa .circleci/**/*.storekit .circleci/**/*.xcworkspacedata .circleci/**/*.xcsettings .circleci/**/*.xcuserstate .circleci/**/*.storyboard .circleci/**/*.entitlements .circleci/**/*.command .circleci/**/*.cts .circleci/**/*.stflow .circleci/**/*.bnf .circleci/**/*.flow .circleci/**/*.aar .circleci/**/*.snap .circleci/**/*.css .circleci/**/*.mts .circleci/**/*.jst .circleci/**/*.def .circleci/**/*.ogg .circleci/**/*.jks .circleci/**/*.glsl .circleci/**/*.ttc .circleci/**/*.less .circleci/**/*.pug .circleci/**/*.proto .circleci/**/*.bsd .circleci/**/*.idl .circleci/**/*.sln .circleci/**/*.config .circleci/**/*.props .circleci/**/*.vcxproj .circleci/**/*.filters .circleci/**/*.tsbuildinfo .circleci/**/*.rb .circleci/**/*.avif .circleci/**/*.ico .circleci/**/*.probe .circleci/**/*.kts .circleci/**/*.toml .circleci/**/*.mf .circleci/**/*.node .circleci/**/*.docs .circleci/**/*.mkd .circleci/**/*.cmd .circleci/**/*.ls .circleci/**/*.wiki .circleci/**/* .... <<<VERY LONG LIST OF IGNORES>>>

 !server/*.html !server/*.csse[0m
e[35m[i] App entrypoints: {
  "mainClient": "_build/main-dev/client-meteor.js",
  "mainServer": "_build/main-dev/server-meteor.js",
  "testModule": "_build/test/test-meteor.js"
}e[0m
e[35m[i] App custom script: /__rspack__/client-rspack.jse[0m
e[35m[i] Rspack DevServer Port: 8080e[0m
e[35m[i] Rspack default config: /Users/user/my_app/node_modules/@meteorjs/rspack/rspack.config.jse[0m
e[35m[i] Rspack custom config: /Users/user/my_app/rspack.config.jse[0m
e[35m[Rspack Server] [i] Rspack mode: development
e[0m
e[35m[Rspack Server] [i] Meteor flags: {
  isDevelopment: e[33mtruee[39m,
  isProduction: e[33mfalsee[39m,
  isDebug: e[33mfalsee[39m,
  isVerbose: e[33mtruee[39m,
  isTest: e[33mfalsee[39m,
  isRun: e[33mtruee[39m,
  isBuild: e[33mfalsee[39m,
  isNative: e[33mfalsee[39m,
  isClient: e[33mfalsee[39m,
  isServer: e[33mtruee[39m,
  entryPath: e[32m'main-dev/server-entry.js'e[39m,
  outputPath: e[32m'main-dev/server-rspack.js'e[39m,
  outputFilename: e[32m'server-rspack.js'e[39m,
  runPath: e[32m'main-dev/server-meteor.js'e[39m,
  buildContext: e[32m'_build'e[39m,
  chunksContext: e[32m'build-chunks'e[39m,
  assetsContext: e[32m'build-assets'e[39m,
  devServerPort: e[32m'8080'e[39m,
  projectConfigPath: e[32m'/Users/user/my_app/rspack.config.js'e[39m,
  swcExternalHelpers: e[33mtruee[39m,
  isReactEnabled: e[33mtruee[39m,
  isTypescriptEnabled: e[33mtruee[39m,
  isTsxEnabled: e[33mtruee[39m,
  RSPACK_WATCH: e[33mtruee[39m,
  buildOutputDir: e[32m'/Users/user/my_app/_build/main-dev'e[39m,
  HtmlRspackPlugin: e[36m[Function (anonymous)]e[39m
}
e[0m
e[35m[Rspack Client] [i] Rspack mode: development
e[0m
e[35m[Rspack Client] [i] Meteor flags: {
  isDevelopment: e[33mtruee[39m,
  isProduction: e[33mfalsee[39m,
  isDebug: e[33mfalsee[39m,
  isVerbose: e[33mtruee[39m,
  isTest: e[33mfalsee[39m,
  isRun: e[33mtruee[39m,
  isBuild: e[33mfalsee[39m,
  isNative: e[33mfalsee[39m,
  isClient: e[33mtruee[39m,
  isServer: e[33mfalsee[39m,
  entryPath: e[32m'main-dev/client-entry.js'e[39m,
  outputPath: e[32m'main-dev/client-rspack.js'e[39m,
  outputFilename: e[32m'client-rspack.js'e[39m,
  runPath: e[32m'main-dev/client-meteor.js'e[39m,
  buildContext: e[32m'_build'e[39m,
  chunksContext: e[32m'build-chunks'e[39m,
  assetsContext: e[32m'build-assets'e[39m,
  devServerPort: e[32m'8080'e[39m,
  projectConfigPath: e[32m'/Users/user/my_app/rspack.config.js'e[39m,
  swcExternalHelpers: e[33mtruee[39m,
  isReactEnabled: e[33mtruee[39m,
  isTypescriptEnabled: e[33mtruee[39m,
  isTsxEnabled: e[33mtruee[39m,
  RSPACK_SERVE: e[33mtruee[39m,
  buildOutputDir: e[32m'/Users/user/my_app/_build/main-dev'e[39m,
  HtmlRspackPlugin: e[36m[Function (anonymous)]e[39m
}
e[0m
e[35m[Rspack Server] Config: {
  name: e[32m'[server-rspack]'e[39m,
  target: e[32m'node'e[39m,
  mode: e[32m'development'e[39m,
  entry: e[32m'/Users/user/my_app/_build/main-dev/server-entry.js'e[39m,
  output: {
    path: e[32m'/Users/user/my_app/private'e[39m,
    filename: e[36m[Function: filename]e[39m,
    libraryTarget: e[32m'commonjs'e[39m,
    chunkFilename: e[32m'build-chunks/[id].js'e[39m,
    assetModuleFilename: e[32m'build-assets/[hash][ext][query]'e[39m
  },
  optimization: { usedExports: e[33mtruee[39m },
  module: {
    rules: [
      {
        test: e[31m/\.(tsx|ts|mts|cts|jsx|mjs|cjs)$/ie[39m,
        exclude: e[31m/node_modules|\.meteor\/local/e[39m,
        loader: e[32m'builtin:swc-loader'e[39m,
        options: {
          jsc: {
            baseUrl: e[32m'/Users/user/my_app'e[39m,
            paths: {
              e[32m'/*'e[39m: [ e[32m'*'e[39m, e[32m'/*'e[39m ],
              e[32m'@meteorrn/core'e[39m: [ e[32m'meteor'e[39m ],
              e[32m'react-native-localization'e[39m: [ e[32m'react-localization'e[39m ],
              e[32m'@shared/*'e[39m: [ e[32m'common/*'e[39m ],
              e[32m'@client_root/*'e[39m: [ e[32m'client/*'e[39m ],
              e[32m'/imports/*'e[39m: [ e[32m'imports/*'e[39m ],
              e[32m'/server/*'e[39m: [ e[32m'server/*'e[39m ],
              e[32m'@admin-methods'e[39m: [ e[32m'server/admin/admin_includes'e[39m ],
              e[32m'@printer-server'e[39m: [ e[32m'server/printer'e[39m ],
              e[32m'@admin-router'e[39m: [ e[32m'./client/router/adminRouterEmpty'e[39m ],
              e[32m'@server-includes'e[39m: [ e[32m'./server/bundles/server_includes_user'e[39m ],
              e[32m'@main-router'e[39m: [ e[32m'./client/router/webRoutes'e[39m ]
            },
            parser: { syntax: e[32m'typescript'e[39m, tsx: e[33mtruee[39m, jsx: e[33mtruee[39m },
            target: e[32m'es2015'e[39m,
            transform: { react: { development: e[33mtruee[39m } },
            externalHelpers: e[33mtruee[39m
          }
        }
      },
      {
        test: e[31m/\.js$/e[39m,
        use: {
          loader: e[32m'builtin:swc-loader'e[39m,
          options: { jsc: { parser: { syntax: e[32m'ecmascript'e[39m, jsx: e[33mtruee[39m } } }
        }
      },
      { test: e[31m/\.node$/e[39m, type: e[32m'asset/resource'e[39m }
    ],
    parser: { javascript: { dynamicImportMode: e[32m'eager'e[39m } },
    noParse: e[31m/react-native-|react-native-gesture-handler/e[39m
  },
  resolve: {
    extensions: [
      e[32m'.web.ts'e[39m, e[32m'.web.tsx'e[39m,
      e[32m'.web.js'e[39m, e[32m'.ts'e[39m,
      e[32m'.tsx'e[39m,    e[32m'.js'e[39m,
      e[32m'.jsx'e[39m,    e[32m'.html'e[39m,
      e[32m'.mts'e[39m,    e[32m'.cts'e[39m,
      e[32m'.mjs'e[39m,    e[32m'.cjs'e[39m,
      e[32m'.json'e[39m,   e[32m'.wasm'e[39m
    ],
    alias: {
      e[32m'/'e[39m: e[32m'/Users/user/my_app'e[39m,
      e[32m'three/examples'e[39m: [ e[32m'/Users/user/my_app/node_modules/three/examples'e[39m ],
      e[32m'@react-native-async-storage/async-storage'e[39m: [
        e[32m'/Users/user/my_app/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage'e[39m
      ]
    },
    modules: [ e[32m'node_modules'e[39m, e[32m'/Users/user/my_app'e[39m ],
    conditionNames: [ e[32m'import'e[39m, e[32m'require'e[39m, e[32m'node'e[39m, e[32m'default'e[39m ],
    tsConfig: e[32m'/Users/user/my_app/tsconfig.json'e[39m,
    enforceExtension: e[33mfalsee[39m,
    fullySpecified: e[33mfalsee[39m
  },
  externals: [ e[31m/^meteor.*/e[39m, e[31m/^react$/e[39m, e[31m/^react-dom$/e[39m, e[31m/^bcrypt$/e[39m, e[31m/^bcrypt/e[39m ],
  plugins: [
    DefinePlugin {
      affectedHooks: e[32m'compilation'e[39m,
      name: e[32m'DefinePlugin'e[39m,
      _args: [
        {
          e[32m'Meteor.isClient'e[39m: e[32m'false'e[39m,
          e[32m'Meteor.isServer'e[39m: e[32m'true'e[39m,
          e[32m'Meteor.isTest'e[39m: e[32m'false'e[39m,
          e[32m'Meteor.isAppTest'e[39m: e[32m'false'e[39m,
          e[32m'Meteor.isDevelopment'e[39m: e[32m'true'e[39m,
          e[32m'Meteor.isProduction'e[39m: e[32m'false'e[39m
        }
      ]
    },
    BannerPlugin {
      affectedHooks: e[90mundefinede[39m,
      name: e[32m'BannerPlugin'e[39m,
      _args: [
        {
          banner: e[32m'/**\n'e[39m +
            e[32m'* @file server-rspack.js\n'e[39m +
            e[32m'* @description Bundled output generated by Rspack\n'e[39m +
            e[32m'* --------------------------------------------------------------------------\n'e[39m +
            e[32m'* ⚡ Rspack Server App (Development)\n'e[39m +
            e[32m'* --------------------------------------------------------------------------\n'e[39m +
            e[32m'* • [   server-entry.js ] ──▶ [■ server-rspack.js ] ──▶ [   server-meteor.js ]\n'e[39m +
            e[32m'*\n'e[39m +
            e[32m'* This file is the bundled output generated by Rspack.\n'e[39m +
            e[32m'* It contains all application code and assets combined into one build.\n'e[39m +
            e[32m'* It is not used directly, but will be imported by the Meteor main module\n'e[39m +
            e[32m'* file (`server-meteor.js`) so that Meteor runs the Rspack bundle.\n'e[39m +
            e[32m'*\n'e[39m +
            e[32m'* ⚠️ Note: This file is autogenerated. It is not meant to be modified manually.\n'e[39m +
            e[32m'* These files also act as a cache: they can be safely removed and will be\n'e[39m +
            e[32m'* regenerated on the next build. They should be ignored in IDE suggestions\n'e[39m +
            e[32m'* and version control.\n'e[39m +
            e[32m'*/\n'e[39m +
            e[32m'\n'e[39m +
            e[32m'/* Code generated */\n'e[39m,
          entryOnly: e[33mtruee[39m
        }
      ]
    },
    RequireExternalsPlugin {
      pluginName: e[32m'RequireExternalsPlugin'e[39m,
      _externals: e[1mnulle[22m,
      _externalMap: e[1mnulle[22m,
      _enableGlobalPolyfill: e[33mfalsee[39m,
      _isEagerImport: e[1mnulle[22m,
      _lastImports: e[1mnulle[22m,
      _defaultExternalPrefix: e[32m'external 'e[39m,
      filePath: e[32m'/Users/user/my_app/_build/main-dev/server-meteor.js'e[39m,
      backRoot: e[32m'../../'e[39m,
      _funcCount: e[33m1e[39m
    }
  ],
  watchOptions: {
    ignored: [
      e[32m'**/fakeServer/**'e[39m,    e[32m'**/app/android'e[39m,
      e[32m'**/app/ios'e[39m,          e[32m'**/cloudslicer/**'e[39m,
      e[32m'**/tools/**'e[39m,         e[32m'**/dataAnalyzer/**'e[39m,
      e[32m'**/app/app/**'e[39m,       e[32m'**/app/e2e/**'e[39m,
      e[32m'**/app/**tests**/**'e[39m, e[32m'**/app/Assets/**'e[39m,
      e[32m'**/app/node_modules'e[39m, e[32m'**/*.native.js'e[39m,
      e[32m'**/gen/**'e[39m,           e[32m'**/services/target'e[39m,
      e[32m'**/app/**'e[39m,           e[32m'**/.meteor/local/**'e[39m,
      e[32m'**/dist/**'e[39m
    ]
  },
  devtool: e[32m'source-map'e[39m,
  cache: e[33mtruee[39m,
  experiments: {
    cache: {
      version: e[32m'swc-development-server'e[39m,
      type: e[32m'persistent'e[39m,
      storage: {
        type: e[32m'filesystem'e[39m,
        directory: e[32m'node_modules/.cache/rspack/server'e[39m
      }
    }
  }
}
e[0m
e[35m[Rspack Client] Config: {
  name: e[32m'[client-rspack]'e[39m,
  target: e[32m'web'e[39m,
  mode: e[32m'development'e[39m,
  entry: e[32m'/Users/user/my_app/_build/main-dev/client-entry.js'e[39m,
  output: {
    path: e[32m'/Users/user/my_app/public'e[39m,
    filename: e[36m[Function: filename]e[39m,
    libraryTarget: e[32m'commonjs'e[39m,
    publicPath: e[32m'/'e[39m,
    chunkFilename: e[32m'build-chunks/[id].js'e[39m,
    assetModuleFilename: e[32m'build-assets/[hash][ext][query]'e[39m,
    cssFilename: e[32m'build-chunks/[name].css'e[39m,
    cssChunkFilename: e[32m'build-chunks/[id].css'e[39m
  },
  optimization: { usedExports: e[33mtruee[39m, splitChunks: { chunks: e[32m'async'e[39m } },
  module: {
    rules: [
      {
        test: e[31m/\.(tsx|ts|mts|cts|jsx|mjs|cjs)$/ie[39m,
        exclude: e[31m/node_modules|\.meteor\/local/e[39m,
        loader: e[32m'builtin:swc-loader'e[39m,
        options: {
          jsc: {
            baseUrl: e[32m'/Users/user/my_app'e[39m,
            paths: {
              e[32m'/*'e[39m: [ e[32m'*'e[39m, e[32m'/*'e[39m ],
              e[32m'@meteorrn/core'e[39m: [ e[32m'meteor'e[39m ],
              e[32m'react-native-localization'e[39m: [ e[32m'react-localization'e[39m ],
              e[32m'@shared/*'e[39m: [ e[32m'common/*'e[39m ],
              e[32m'@client_root/*'e[39m: [ e[32m'client/*'e[39m ],
              e[32m'/imports/*'e[39m: [ e[32m'imports/*'e[39m ],
              e[32m'/server/*'e[39m: [ e[32m'server/*'e[39m ],
              e[32m'@admin-methods'e[39m: [ e[32m'server/admin/admin_includes'e[39m ],
              e[32m'@printer-server'e[39m: [ e[32m'server/printer'e[39m ],
              e[32m'@admin-router'e[39m: [ e[32m'./client/router/adminRouterEmpty'e[39m ],
              e[32m'@server-includes'e[39m: [ e[32m'./server/bundles/server_includes_user'e[39m ],
              e[32m'@main-router'e[39m: [ e[32m'./client/router/webRoutes'e[39m ]
            },
            parser: { syntax: e[32m'typescript'e[39m, tsx: e[33mtruee[39m, jsx: e[33mtruee[39m },
            target: e[32m'es2015'e[39m,
            transform: { react: { development: e[33mtruee[39m, refresh: e[33mtruee[39m } },
            externalHelpers: e[33mtruee[39m
          }
        }
      },
      {
        test: e[31m/\.js$/e[39m,
        use: {
          loader: e[32m'builtin:swc-loader'e[39m,
          options: { jsc: { parser: { syntax: e[32m'ecmascript'e[39m, jsx: e[33mtruee[39m } } }
        }
      },
      { test: e[31m/\.node$/e[39m, type: e[32m'asset/resource'e[39m }
    ],
    noParse: e[31m/react-native-|react-native-gesture-handler/e[39m
  },
  resolve: {
    extensions: [
      e[32m'.web.ts'e[39m, e[32m'.web.tsx'e[39m,
      e[32m'.web.js'e[39m, e[32m'.ts'e[39m,
      e[32m'.tsx'e[39m,    e[32m'.js'e[39m,
      e[32m'.jsx'e[39m,    e[32m'.html'e[39m,
      e[32m'.mts'e[39m,    e[32m'.cts'e[39m,
      e[32m'.mjs'e[39m,    e[32m'.cjs'e[39m,
      e[32m'.json'e[39m,   e[32m'.wasm'e[39m
    ],
    alias: {
      e[32m'/'e[39m: e[32m'/Users/user/my_app'e[39m,
      e[32m'three/examples'e[39m: [ e[32m'/Users/user/my_app/node_modules/three/examples'e[39m ],
      e[32m'@react-native-async-storage/async-storage'e[39m: [
        e[32m'/Users/user/my_app/node_modules/@react-native-async-storage/async-storage/lib/module/AsyncStorage'e[39m
      ]
    },
    tsConfig: e[32m'/Users/user/my_app/tsconfig.json'e[39m,
    enforceExtension: e[33mfalsee[39m,
    fullySpecified: e[33mfalsee[39m
  },
  externals: [ e[31m/^meteor.*/e[39m, e[31m/^react$/e[39m, e[31m/^react-dom$/e[39m, e[31m/^bcrypt/e[39m ],
  plugins: [
    ReactRefreshRspackPlugin {
      options: {
        exclude: e[31m/node_modules/ie[39m,
        include: e[31m/\.([cm]js|[jt]sx?|flow)$/ie[39m,
        forceEnable: e[33mfalsee[39m,
        injectLoader: e[33mtruee[39m,
        injectEntry: e[33mtruee[39m,
        reloadOnRuntimeErrors: e[33mfalsee[39m,
        overlay: e[33mfalsee[39m
      }
    },
    RequireExternalsPlugin {
      pluginName: e[32m'RequireExternalsPlugin'e[39m,
      _externals: e[1mnulle[22m,
      _externalMap: e[1mnulle[22m,
      _enableGlobalPolyfill: e[33mtruee[39m,
      _isEagerImport: e[1mnulle[22m,
      _lastImports: e[1mnulle[22m,
      _defaultExternalPrefix: e[32m'external 'e[39m,
      filePath: e[32m'/Users/user/my_app/_build/main-dev/client-meteor.js'e[39m,
      backRoot: e[32m'../../'e[39m,
      _funcCount: e[33m1e[39m
    },
    DefinePlugin {
      affectedHooks: e[32m'compilation'e[39m,
      name: e[32m'DefinePlugin'e[39m,
      _args: [
        {
          e[32m'Meteor.isClient'e[39m: e[32m'true'e[39m,
          e[32m'Meteor.isServer'e[39m: e[32m'false'e[39m,
          e[32m'Meteor.isTest'e[39m: e[32m'false'e[39m,
          e[32m'Meteor.isAppTest'e[39m: e[32m'false'e[39m,
          e[32m'Meteor.isDevelopment'e[39m: e[32m'true'e[39m,
          e[32m'Meteor.isProduction'e[39m: e[32m'false'e[39m
        }
      ]
    },
    BannerPlugin {
      affectedHooks: e[90mundefinede[39m,
      name: e[32m'BannerPlugin'e[39m,
      _args: [
        {
          banner: e[32m'/**\n'e[39m +
            e[32m'* @file client-rspack.js\n'e[39m +
            e[32m'* @description Bundled output generated by Rspack\n'e[39m +
            e[32m'* --------------------------------------------------------------------------\n'e[39m +
            e[32m'* ⚡ Rspack Client App (Development)\n'e[39m +
            e[32m'* --------------------------------------------------------------------------\n'e[39m +
            e[32m'* • [   client-entry.js ] ──▶ [■ client-rspack.js ] ──▶ [   client-meteor.js ]\n'e[39m +
            e[32m'*\n'e[39m +
            e[32m'* This file is the bundled output generated by Rspack.\n'e[39m +
            e[32m'* It contains all application code and assets combined into one build.\n'e[39m +
            e[32m'* It is not used directly, but will be imported by the Meteor main module\n'e[39m +
            e[32m'* file (`client-meteor.js`) so that Meteor runs the Rspack bundle.\n'e[39m +
            e[32m'*\n'e[39m +
            e[32m'* ⚠️ Note: This file is autogenerated. It is not meant to be modified manually.\n'e[39m +
            e[32m'* These files also act as a cache: they can be safely removed and will be\n'e[39m +
            e[32m'* regenerated on the next build. They should be ignored in IDE suggestions\n'e[39m +
            e[32m'* and version control.\n'e[39m +
            e[32m'*/\n'e[39m +
            e[32m'\n'e[39m +
            e[32m'/* No code generated as served by HMR server */\n'e[39m,
          entryOnly: e[33mtruee[39m
        }
      ]
    },
    HtmlRspackPlugin {
      options: {
        inject: e[33mfalsee[39m,
        cache: e[33mtruee[39m,
        filename: e[32m'../_build/main-dev/index.html'e[39m,
        templateContent: e[32m'\n'e[39m +
          e[32m'          <head>\n'e[39m +
          e[32m'            <% for tag in htmlRspackPlugin.tags.headTags { %>\n'e[39m +
          e[32m'              <%= toHtml(tag) %>\n'e[39m +
          e[32m'            <% } %>\n'e[39m +
          e[32m'          </head>\n'e[39m +
          e[32m'          <body>\n'e[39m +
          e[32m'            <% for tag in htmlRspackPlugin.tags.bodyTags { %>\n'e[39m +
          e[32m'              <%= toHtml(tag) %>\n'e[39m +
          e[32m'            <% } %>\n'e[39m +
          e[32m'          </body>\n'e[39m +
          e[32m'        'e[39m
      }
    }
  ],
  watchOptions: {
    ignored: [
      e[32m'**/fakeServer/**'e[39m,    e[32m'**/app/android'e[39m,
      e[32m'**/app/ios'e[39m,          e[32m'**/cloudslicer/**'e[39m,
      e[32m'**/tools/**'e[39m,         e[32m'**/dataAnalyzer/**'e[39m,
      e[32m'**/app/app/**'e[39m,       e[32m'**/app/e2e/**'e[39m,
      e[32m'**/app/**tests**/**'e[39m, e[32m'**/app/Assets/**'e[39m,
      e[32m'**/app/node_modules'e[39m, e[32m'**/*.native.js'e[39m,
      e[32m'**/gen/**'e[39m,           e[32m'**/services/target'e[39m,
      e[32m'**/app/**'e[39m,           e[32m'**/.meteor/local/**'e[39m,
      e[32m'**/dist/**'e[39m
    ]
  },
  devtool: e[32m'source-map'e[39m,
  devServer: {
    static: {
      directory: e[32m'/Users/user/my_app/public'e[39m,
      publicPath: e[32m'/__rspack__/'e[39m
    },
    hot: e[33mtruee[39m,
    liveReload: e[33mtruee[39m,
    port: e[32m'8080'e[39m,
    devMiddleware: { writeToDisk: e[36m[Function: writeToDisk]e[39m }
  },
  cache: e[33mtruee[39m,
  experiments: {
    cache: {
      version: e[32m'swc-development-client'e[39m,
      type: e[32m'persistent'e[39m,
      storage: {
        type: e[32m'filesystem'e[39m,
        directory: e[32m'node_modules/.cache/rspack/client'e[39m
      }
    },
    css: e[33mtruee[39m
  }
}
e[0m
=> Started MongoDB.
e[35m[Rspack Client] <i> [webpack-dev-server] Project is running at:
e[0m
e[35m[Rspack Client] <i> [webpack-dev-server] Loopback: e[36mhttp://localhost:8080/e[39m, e[36mhttp://[::1]:8080/e[39m
<i> [webpack-dev-server] On Your Network (IPv4): e[36mhttp://192.168.0.56:8080/e[39m
<i> [webpack-dev-server] Content not from webpack is served from 'e[36m/Users/user/my_app/publice[39m' directory
e[0m
e[35m[Rspack Client] [client-rspack]:
  e[1m[client-rspack]e[39me[22m compiled e[1me[32msuccessfullye[39me[22m in 728 ms
e[0m

You have a project with performance issues that seem to come from the Rspack config. Can you reproduce this often to verify possible fixes?

I suggest you try the next options and measure the memory consumed to verify if fixed:

  • Set devtool: false → retry. Source maps can use a lot of memory on large projects. There are cheaper options, but first disable it completely to confirm.
  • If still high: set experiments.cache=false, cache=false → retry. If this helps, the cache may be corrupted or too large. You can re-enable later with a fresh cache dir.
  • If still high: set RSPACK_MAX_THREADS=1 and retry. Peak memory may come from threading. If it helps, increase slowly to 2, then 3.
  • If fixed, re-enable in this order: threads, cache, then a cheap devtool.

By the way, is your project using barrel index files? Like using the re-export pattern:

export * from './a'
export * from './b'
export * from './c'

I’m migrating a project that uses this and I’m seeing early performance issues. I haven’t confirmed it’s the cause, but research suggests this pattern can increase incremental memory use, introduce circular deps, and block some bundle optimizations. I’m analyzing it to find better patterns for performance and optimizations. I wonder if you use them, just to understand if a fix on these will also help you if I confirm it beforehand.

1 Like
    experiments: {
      cache: false,
    },

This resolves the memory issue for me

I do have a few places where I do export * from I will look at what happens if I remove those

Edit:
I tried getting rid of all export * from and it was still having the memory issue.

I tried reverting to beta 9 which is the last one I had working and got

[Rspack Client Error] Panic occurred at runtime. Please file an issue on GitHub with the backtrace below: https://github.com/web-infra-dev/rspack/issues: panicked at crates/rspack_core/src/cache/persistent/occasion/make/module_graph.rs:188:8:
should mgm exist

So that might be related?

Try always to meteor reset when changing from Meteor versions or even changes on profile. I am improving this automatically cleaning for next betas, but for existing you should consider to do this yourself more often.

I improved the cache in the newer beta.11 version so it creates separate caches for client and server contexts, since these targets need different caches. Maybe this affected on consume lots more of RAM.

Glad to see removing the cache fixes it for you. Persistent cache is experimental in Rspack and may improve in upcoming versions. Another option is to use memory cache, maybe it behaves better.

Also try:

optimization: { usedExports: Meteor.isProduction }

If we disable tree-shaking analysis in development, it might help. I’m seeing reports that this analysis can cause spikes.

1 Like