Meteor-node-stubs: When is it really needed?

Just attaching +1 issue related with this package

1 Like

Hey,

Following up on @italojs’s question from august about whether to remove or refactor meteor-node-stubs.

I looked into this from a Meteor 3.x perspective and it seems like we don’t really need it anymore. Here’s what I found,

With rspack (which 3.x uses by default now), there’s already a makeWebNodeBuiltinsAlias() function that handles Node polyfills. It allows process, util, events, path, stream, and assert - everything else gets set to false. So we already have polyfill handling built in without meteor-node-stubs

The package is still using bundledDependencies which means all the node_modules get packaged inside it. That’s why we keep having to publish new versions whenever there’s a security issue in something like qs or buffer - users can’t just npm update it themselves. We’re at 1.2.26 now

Looking at the skeleton templates in the source, they all still include "meteor-node-stubs": "^1.2.12" by default. But based on @jkuester’s bundle analysis from 2021, fresh apps barely use it

So has anyone here actually tried removing it from their apps? Especially if you’re on 3.x with rspack. What broke? Or did everything just work fine?

Would be helpful to know real world impact before proposing to remove it from the default dependencies

1 Like

We never had meteor-node-stubs in our projects since Meteor 1.x (I already forgot the exact version). Every time we added an npm or meteor package that introduced that dependency, we had to put in extra effort to find alternatives or fork the package so it wouldn’t require the stubs. We are also very keen on which code is server-only or shared between client and server; we heavily use the server folders for this.

4 Likes

That’s unfortunately the biggest problem. Most of the time there’s no alternative without it.

Also tests complained a lot about it missing, so we added it back in.

How about an opt-out, then?

Can you explain a bit more?

Can you share the kind of error you get, please? We are trying to track what issues we find when we remove it before removing it completely.

As @sanki92 explained, after 3.4 handle polyfills, I would suggest we remove it for new meteor apps that uses modern:true while maintaining it for old project or modern:false, so those who use it can keep the package in the project or add it only when necessary.

It’s a warning that it’s missing together with the link to install it with --save. I’m not sure if it had any effect on failing tests as eventually I added it back in as it was annoying to get the warning and continued fixing the tests.

UPDATE:

Unable to resolve some modules:

  "timers/promises" in
/Users/andreaswest/Documents/workspace/test2/node_modules/@sinonjs/fake-timers/src/fake-timers-src.js
(web.browser.legacy)

If you notice problems related to these missing modules, consider running:

  meteor npm install --save meteor-node-stubs

Do you have a link to the documentation or any more information on this? I’ve been unable to find anything on it.

I did find documentation on polyfilling Node globals, though this only handles global (which the Meteor package already polyfills in every app), __dirname, and __filename.

@zodern sorry wasn’t clear - makeWebNodeBuiltinsAlias() is Meteor’s own helper, not a rspack built-in

it’s in meteorRspackHelpers.js (line 78)

generates a resolve.fallback config that disables most Node builtins except the browser-safe ones (process, util, events, path, stream, assert)

the point is Meteor’s rspack integration already handles polyfills, so we don’t need meteor-node-stubs for that

As @sanki92 mentioned, makeWebNodeBuiltinsAlias exists in Rspack to add a default config to ensure browser-safe execution of the client app by disabling Node built-in specifics. I needed this to keep shared code compatible across server and client.

But my question remains. I’m not sure about the full scope of meteor-node-stubs. Since Rspack handles app code, and meteor-node-stubs applies at the project root, it seems like something we could remove. Still, I’m not sure if meteor-node-stubs is also needed for Atmosphere package compilation, or for client code inside Meteor packages or Rspack externalized packages. Rspack doesn’t compile Atmosphere packages, and the Meteor bundler still processes them, so in some cases meteor-node-stubs may still be needed.

Can anybody confirm meteor-node-stubs is only needed for app code polyfilling? It might be best for teams already using Rspack to try removing meteor-node-stubs and see what breaks, especially in larger projects with lots of Meteor packages or Rspack externalized dependencies where inconsistencies are more likely to show up. If it works, we may have an opportunity to drop it for Meteor 3.4 Rspack defaults.

2 Likes

Thank you, I was able to find it now.

I was curious what node polyfills it uses. It seems makeWebNodeBuiltinsAlias just prevents loading node built-in modules that are not in the list of allowed modules, though the allowed modules still have to be imported from somewhere if app or package code uses them. That part doesn’t seem to be working yet, or I missed where it is implemented.

meteor-node-stubs simply allows any code that imports node’s built-in modules to work on the client, whether the code is from app code, npm packages, or Meteor package. When compiling client code, isobuild would change any import for node’s built-in modules to instead import from meteor-node-stubs.

This used to be a very important feature for bundlers to have, especially since before npm 3 most npm packages were designed for the server. It’s much better now that npm has been the standard place for client packages for a while. Though there are still cases where a package that would be useful on the client imports node’s built-in modules (the example of sinon is mentioned above).

In regard to rspack, meteor-node-stubs could still be useful. It depends on how you want to implement importing node built-in modules in client code. You could have rspack change the imports for the built-in modules to import from meteor-node-stubs, same as what isobuild does for client code.

Isobuild seems to show a useful error message when an app doesn’t have meteor-node-stubs, as @a4xrbj1 demonstrated above. If it isn’t normally needed, you could remove it from the defaults for apps that use isobuild and rely on the message to help developers that need it. This also works to inform developers when they or a third party dependency is trying to import a node built-in module on the client, and they have the opportunity to decide if they want to change something, or add meteor-node-stubs.

I don’t know how rspack handles this same situation. If it is able to handle these polyfills without meteor-node-stubs, or also show a good message when they are needed, then you probably could remove it from the defaults too. Though I don’t have any knowledge on how often Meteor packages use them; I do know some versions of the vue Meteor packages needed buffer in development.


One of the bigger issues though, is the maintenance caused by the bundled dependencies.

Many of the dependencies have the same name as built-in node modules. I am guessing they are bundled, so npm doesn’t hoist them and cause server code to import these dependencies instead of the built-in modules. I don’t know if there is another option to avoid this. The best option is probably to reduce maintenance by reviewing the list of pollyfilled modules, and seeing if you can remove any (for example, domain-browser is for a node module that has been deprecated for many years), or if there are modern replacements that are smaller or have had less security issues.

This actually makes a good case for having something like meteor-node-stubs instead of asking developers to install the specific dependencies they want to use as polyfills, since meteor-node-stubs can ensure they are only used on the client, and don’t affect server code or node scripts (the node: prefix also eliminates this problem, but a lot of code doesn’t use it).

2 Likes

agree 100% with zodern