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

Yeah, I noticed Meteor 3.4 doesn’t jive well with any fancy caching stuff now so I disabled it too

1 Like

It does look like it might be a slightly more generic issue than just meteor.

I’m sure we could do something to mitigate, but seems like it should be coordinated with the RSPack team

Yes, it could be an Rspack issue. It’s marked experimental, so it may still need improvements.

I haven’t hit it myself. It might be due to the project sizes I’ve used for the integration. I’m now working on larger apps and still haven’t seen it. Do you have any means to reproduce it?

Would enabling the in-memory cache help? Use:

cache: true,
experiments: { cache: true }

You won’t see gains on a full app restart, but it should help incremental rebuilds in dev. This can show if the problem is with serialization/deserialization of Rspack’s persistent cache used by default in Meteor.

If you can confirm the in-memory cache behaves better, I’ll enable it by default for all apps. Otherwise, I’ll disable caching entirely so projects don’t run into these issues until it’s fixed by Rspack. I still encourage everyone to find reproducible cases so Rspack can get more data to resolve it.

Anyway, with and without cache, Rspack is faster than pure Meteor bundling of your app code. But hopefully they can make it stable.

For me, registration and login work correctly. I tried several times. Could you check after meteor reset` just in case (I don’t think is related).

I’m not sure what the issue is, it might not be related to your Rspack integration. Please provide exact steps to reproduce.

2 Likes

@nachocodoner You’re right, it’s fine. There was a repeatable error on my dev system, and after reading your post here, I tracked it down. Yet again my local mongdb for the project had been corrupted. This is the second time this has happened in the past few months. I believe it has something to do with how I’m maintaining two separate folders for the project (one with tested working code, and one with new code) as I update different node packages, etc. Each has its own separate copy of the mongodb, so I’m not quite sure how it’s happening. I tried to avoid the things that I thought may have been responsible last time.

This time I just verified that everything was good in the older folder, and finder-coped my-project/.meteor/local/db/ from the older folder to the newer folder. I ran a meteor reset, re-built, and all was well. :slight_smile:

1 Like

@nachocodoner would it be helpful to open a forum thread where people can contribute their rspack.config.js setups, or is that better handled as a github issue? I can start a thread here if that would be helpful.

Is there a way to separate out server and client unit tests?

This is something that was nice about meteor’s old test infrastructure but doesn’t work with RS pack

This is also part of what makes using the test entry point harder since there isn’t really a way to specify the 3 different possible entries (.app-test., server .test. , and client .test.)

Also on my large app even after the ignore fix I am getting memory errors pretty frequently

<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
----- Native stack trace -----

 1: 0x10473625c node::OOMErrorHandler(char const*, v8::OOMDetails const&) [/Users/zacholigschlaeger/.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/node]
 2: 0x10490c4fc v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, v8::OOMDetails const&) [/Users/zacholigschlaeger/.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/node]
 3: 0x104b1bc24 v8::internal::Heap::stack() [/Users/zacholigschlaeger/.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/node]
 4: 0x104b19fc4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/zacholigschlaeger/.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/node]
 5: 0x104b0e5ac v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/Users/zacholigschlaeger/.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/node]
 6: 0x104b0ede4 v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/Users/zacholigschlaeger/.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/node]
 7: 0x104af2104 v8::internal::Factory::NewFillerObject(int, v8::internal::AllocationAlignment, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/Users/zacholigschlaeger/.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/node]
 8: 0x104f0dbb4 v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/Users/zacholigschlaeger/.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/node]
 9: 0x1053d1af4 Builtins_CEntry_Return1_ArgvOnStack_NoBuiltinExit [/Users/zacholigschlaeger/.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/node]

I have not been able to break it down and figure out exactly what causes it, but its not happening every time
Doing this does resolve it, but thats a pretty high amount of memory
NODE_OPTIONS=“–max-old-space-size=40960”

Edit:
Figured out the memory problem was at least partially because unit tests were including the .spec. files which is not what they used to do, which was causing it to include my app test, which then includes way too much and causes it to crash

In my repo

npm run test
and
npm run test-app

both fail when by old Meteor infrastructure they would pass.

It seems that has been fixed:

I’ll check in which Rspack version it’s released, likely 1.6.0. There’s also a chance that a beta will include it for early testing.

Remember that your Meteor app can now use any specific Rspack version you define in your package.json. To use the latest version, just update it there. As long as it’s newer than the one bundled by the Meteor Rspack package, it will be preserved. Later, when an official Meteor Rspack update includes a newer version, it will become the new default automatically. But you can always adopt the latest Rspack version whenever you prefer.

New extensibility & contributions release available: 3.4-beta.12. This release ensures further Rspack support for real-world app projects, enabling new features and fixes. It also marks the start of contributions from the Meteor community.

Since the last report, I’ve been able to integrate Rspack into real-world apps like Galaxy and successfully get it running and felt all speed gains and modern build environment. I also reviewed additional feedback provided during your transitions.

  • Added Meteor.compileWithRspack, a quick helper for rspack.config.js to define npm dependencies that should be treated as modern or require transpilation through Rspack’s SWC. Useful for npm packages written in modern-only syntax.
  • Added Meteor.compileWithMeteor, a quick helper for rspack.config.js to define npm dependencies that should be skipped by Rspack and handled directly by Meteor’s bundler and Node runtime. Needed for native dependencies.
  • Added Meteor.setCache([true|false|'memory']) as a shortcut to configure Rspack cache in rspack.config.js.
  • Added support for Rspack code-splitting using splitChunks.
  • Improved dev environments where ROOT_URL points to an external server instead of localhost.
  • Ensured shared code can properly resolve modules, allowing node/server-specific modules to be processed as no-ops in client code, supporting natural code sharing.
  • Ensured cache refreshes properly when configuration files like rspack.config.js, .swcrc, .babelrc, or tsconfig.json change, keeping the persistent cache in sync.
  • Ensured externalHelpers in .swcrc is enabled only for client code, since server code already supports needed syntax features.
  • Fixed an issue with Service Workers causing infinite reloads in dev mode.

We’ll continue addressing feedback on the Rspack integration, with the focus now on ensure stability in production environments, eager tests behaving better, support additional modern setups, and other feedback we get with it.

Besides, we’ve included several community contributions that were pending for inclusion in Meteor 3.4, among them:

We still have more contributions to include in this release, especially after Hacktoberfest, during which we received the highest number of contributions in years. Some of these remaining updates will be part of the next beta and round up the final Meteor 3.4 release.

6 Likes

I updated to beta 12 via:

meteor update --release 3.4-beta.12

I’m now getting these error logs during build:

[i] Rspack DevServer Port: 8080
Rspack plugin error: Could not find rspack.config.js, rspack.config.mjs, or rspack.config.cjs. Make sure @meteorjs/rspack is installed correctly.
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 module.wrapAsync.self (packages/rspack/rspack_plugin.js:151:26)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)

Node.js v22.20.0

Have you tried to do npm install? I should add this recommendation as part of that command error message, normally it happens when @meteorjs/rspack within node_modules is not present, and npm install should fix it.

I hit this when migrating a large app. My fix was to externalize a native-style dependency so Rspack doesn’t process it, and let Meteor/Node handle it directly. You can do this with the externals field, or by using the new Meteor.compileWithMeteor helper. This usually helps when you have native deps and Rspack tries to resolve them. In general, externalizing native deps is recommended.

In my case the issue was the thread-stream lib, with this config:

module.exports = defineConfig((Meteor) => {
  return {
     // ..
    ...Meteor.compileWithMeteor([
      // ..
      "thread-stream"
    ]),
  };
});

To find which dependency needs to be externalized, open the server intermediate bundle (_build/main-dev/server-rspack.js). Search for worker.js (or join(__dirname, 'lib', 'worker.js')) and check the context around it to see which npm package it’s coming from. In my case it was thread-stream. It might be the same for you, but I’m describing the process in case others hit this with a different package.

I’ll update the docs to mention this case.

1 Like

That worked. Thanks!

@nachocodoner I just can’t make this work with JSX in a npm package.
Whatever I tried, I always end up with this:

  [client-rspack] compiled with 4 warnings in 690 ms

=> Errors prevented startup:                  
   
   While building for web.browser:
   node_modules/@act/toastr-component/index.js:17:14: This experimental syntax requires enabling one of the following parser plugin(s): "jsx", "flow", "typescript".
   (17:14)

What is on my line 17:

const getIcon = icon => {
  switch (icon) {
    case 'success':
      return (<ThumbUpTwoToneIcon color='success' fontSize='large' />) // line 17
    // case 'warning':
     //  return (<WarningTwoToneIcon color='warning' fontSize='large' />)
    // case 'info':
      // return (<InfoTwoToneIcon color='info' fontSize='large' />)
    // case 'error':
      // return (<ReportTwoToneIcon color='error' fontSize='large' />)
    // case 'link':
      // return (<ShareTwoToneIcon color='primary' fontSize='large' />)
  }
}

I have no problem outside rspack adoption.
I tried to use babel-loader, swc, include folders, exclude folders, what-not-plugins etc.
Simple reproduction: meteor create app with beta 12, add a local package with an index.js such as

const component = () => (<div>Test</div>)
export { component }

import it anywhere on the client.

I need to figure out if I can somehow migrate to this (or fix my Vite config*) because I realised somehow my (meteor-vite-compiled) client side app code is not being minified properly, and it is not a pretty bundle size :slight_smile:

(but it never was, so… I’m not really suffering so much as feeling FOMO)

*I suspect it’s because I added the swc plugin to Vite, to phase out my use of Babel, so now esbuild isn’t doing the minimisation for some reason, but I can’t quite jump to rspack because I’m using a few plugins where I’m not sure how they’ll fare with Webpack style APIs (thanks to unjs & unplugin things are a bit less fragmented these days but…)

Reporting on the positive side: I have been using Beta 11 and now Beta 12 for about a week, and everything is working well, enjoying the speed. With my M4 powered Mac and these improvements, everything is flying.

Are we close to making a full release version yet?

4 Likes

Could you share the plugins you use in the Vite setup? It would help in case someone here has ideas for Rspack equivalents.

About SWC and Vite: did you make sure you’re including @swc/helpers and enabling the externalHelpers option in the swcrc config (Compilation)?

When we integrated SWC in Meteor, either directly in core or through Rspack, we had to add that dependency or recommend adding it. We also auto-enabled externalHelpers when possible for client code, so helper functions are not inlined in every file. That avoids unnecessary repeated SWC helper code and keeps it in a single shared place, reducing back the client bundle size.

Oh, great to know this. It’s nice that not everything turns out to be an issue, and I really appreciate users sharing feedback like this, as it helps us move faster toward the official release.

Regarding that, we’re currently in the extension/contribution phase. This means we’re still covering reports to achieve full Rspack support, while also adding community contributions and starting to test them. I still have a list of setups to verify. I expect that list to grow as more people experiment with the betas, so we want to keep this period open for both positive experiences and issue reports.

The main factor for the official release will be fixing critical issues. Our top priority right now is the “Total Bundle Size”. While Rspack has significantly reduced the client and server app bundle sizes, the final build artifacts (meteor build) have grown noticeably. The reason is how Meteor packages production artifacts, it includes NPM dependencies from Atmosphere packages, even dev-only ones. We also recently added SWC and a few others that increased the total size, that are not needed for production at all. On top of that, some dev dependencies like Rspack are still being included from the app’s package.json, likely due to native dependency handling. Check this attachment. It shows how Meteor 3.3 compared to Meteor 3.4-beta.12 ended up including rspack, along with several other modules, in the final app bundle artifacts where is not needed (production).

For the first issue, we already have a fix pending testing with the new Meteor dev-only packages. For the second, I’ll be working on a fix soon. With these changes, we expect to clean up long-standing problems in Meteor builds and remove unnecessary dependencies from production, reducing drastically the bundle size.

While I keep focus on the main priorities, I also keep reviewing reports, fixes, and extension possibilities in parallel. Hopefully, once the critical parts are done, we can move toward the official release and leave further feedback for the Meteor 3.4.x series.

2 Likes

I had a similar problem you need to tell RSPack to treat .js as jsx

This package is doing something non-standard

I solved my similar problem like this:

    module: {
      rules: [
        {
          test: /react-native-reanimated|react-native-gesture-handler/,
          use: {
            loader: "builtin:swc-loader",
            options: {
              jsc: {
                parser: { syntax: "typescript", tsx: true, jsx: true },
              },
            },
          },
        },
      ],
    },

You can also just use patch-package to rename this file to a .jsx