Doesn’t look like anyone mentioned this, so I’ll add on!
I think that Meteor’s modules
and ecmascript
system is fairly out of date now, and quite a source of complexity that keeps Meteor in legacy, especially as time moves on. It was built during a time when a revolutionary set of language features were introduced but before engines supported the new features. It was necessary in that time.
Today, the language churn has slowed down compared to the ES2015 transformation of JavaScript. The majority of the revolutionary and transformational language features used today are supported in all engines, especially the features that modules
+ecmascript
were originally designed to support, ES Modules being one particularly huge feature.
I believe the best way forward for Meteor would be to entirely scrap the current module system, and start anew with a system designed specifically for today’s ES Module reality.
The current system takes ES Modules, and compiles them into a Meteor’s custom CommonJS-like module format, going against the grains we have today.
This was necessary back in early 2016, when no engines supported ES Modules. But if we were starting anew today, we’d rather build on top of ES Modules natively, allow people to write native ES Modules, and optionally allow a bundling step with tools like Rollup or ESBuild, and optionally allow enabling down-leveling (transpiling) newer language features to lower targets, both options exclusive of each other instead of coupled together like currently (where currently we handle language transpilation on top of the module system).
Right now the system (by default) compiles modern syntax into an ancient format. This is not very necessary today because most language features today are small increments compared to ES2015, and most code today can be comfortably written without transformation for all modern browsers. And IE is done for (), so we’re free from some shackles we previously had.
This isn’t to say we don’t need transpilation, but in many cases it is not needed. Having a simple and clean setup that would allow people to choose their targets in a way in which they can avoid as much transpilation as possible, without the complexity of the current module system, would be great. This new system would be opt-in, instead of opt-out like current system. Modules and bundling would be a totally separate option from language transpilation, both optional and serving only for optimization and support of older browsers.
To make this happen, we may want to take advantage (as an opt-in) of newer tools like Vite, or Astro on top of Vite, in order to provide an ES-Module-oriented system in which we also get hot module reloading and bundling (Vite uses hot-reloading ES Modules in dev mode, and Rollup for production bundling).
In fact! Maybe the baseline should just be vanilla ES Modules out of the box (with isobuild still around for back compat (i wish it weren’t)), and any tools built on top of that would need to handle vanilla ES Module code intelligently. This is the future that is currently being explored by tools, and it would be nice to be on this path starting with vanilla ES Modules.
Whatever steps we take, all the optimizations should be opt-in. The reason for this is because if we can write in vanilla ES Modules and our apps work, and then do we choose to apply optimizations, we can rest assured that our code will work for a long time without having to upgrade build systems, etc, in the future. When things work with the new vanilla standards, they will be supported for a very very long time (JS engines are not likely to remove ES Modules any time soon, browser engines not likely to remove established ways of loading assets, etc). Vanilla ESM web apps will keep running forever with very little dependency maintenance, if at all.
By starting from a fresh ES Module foundation, we’ll eliminate a bunch of complexity that I assume no one here actually wants to maintain, and we’ll then be set up for longevity and compatibility with the wider JS and web ecosystems.
The only problem is the work needed to take a step back. There may need to be sacrifices made in backwards compatibility in order to be aligned with the future of JavaScript. Various packages, including vite:bundler
, edemaine:solid
, svelte:compiler
, barbatus:typescript
, etc, rely on the modules
package, but modules
needs to be gone for Meteor be following a JavaScript-standards-aligned future path, so this change will not be a simple upgrade.
However, without this change, Meteor is going to be stuck in legacy.