@benjamnWill Meteor 1.3 compile Meteor packages into code that follows the CommonJS module semantics? So they just use require to get their dependencies. And they export via module.exports. This is would be very useful to use standard testing tools, like Jest with Wallaby for unit testing. Otherwise I’m forced to load all Meteor packages before I can run the tests and that’s slow.
I understand that some Meteor package code is coupled to Meteor. But that wouldn’t be a big problem, because I can mock packages.
I think right now in the beta, packages still get their dependencies via the Package global. You can see that when you look at the built files in .meteor/local/build. So the Meteor build tool does some transformation and concatenation after Babel compiling.
Packages still need to be backwards compatible, so the final linked version (try view-source on a package’s JS in 1.3) is still an IIFE with regular Meteor imports (Package global, local vars for file-level “globals”), etc.
However, if your package doesn’t use the old API - api.use()/export() - and instead relies solely on import and export, I think you’ll be ok. I never tried though It will still be inside an IIFE and you might need to stub a Package global to avoid a ReferenceError, but it uses the new meteorInstall for deps, which is based on CommonJS - each file is wrapped in a function(require,exports,module) and receives deps via this require.
This is an excellent & accurate summary, @gadicc! Thanks for making my job easier
It is definitely true that Meteor package code, though implemented using a CommonJS module system, is eagerly required before your application code has a chance to import it.
While that behavior is important for backwards compatibility, Meteor 1.3 is introducing a new package.js API, namely api.mainModule, so we might have an opportunity to allow lazy Meteor packages in a backwards compatible way. Specifically, api.mainModule could take an options object, like so:
If the main module is lazy, we would avoid emitting an eager require("/node_modules/meteor/<package name>/client.js") call at the end of the package bundle, and your application code would become responsible for importing meteor/<package name> when needed.
Of course this would mean the package might never be loaded at all, but that sounds more like a feature than a pitfall. Also, you could still define other eager entry point files using api.addFiles.