Hey guys, I wrote rocket:module. I think the direction that Meteor 1.3 is going in is awesome.
Out-of-the-box might the new modules package might not include all the features we have in Webpack (such as loading image files, loading SVG files, etc), but, the cool thing about modules is that we can still write standard Meteor buildplugins and publish them on Atmosphere. Those build plugins can take the place of what we know as “loaders” in Webpack. For example, we can write plugins to transform images, SVG files, etc, into JavaScript CommonJS modules, which we can then import into your project thanks to the moduels package, so we’ll be able to do things like meteor installsomebody:png-modules` and then write
import image from './path/to/image.png' // is actually importing `./path/to/image.png.js`, which was compiled by a build plugin
document.querySelector('img').src = image.url // `image.url` might be a `data:` URL, or a Blob URL, for example.
The build plugin would rename image.png file to image.png.js behind the scenes (it doesn’t actually rename your original source files).
I feel this will be a great alternative to Webpack. It’ll just be a matter of time before relevant build plugins are created by the community in order to compete with all the loaders that Webpack has (or transforms that Browserify has, etc). I think @benjamn’s implementation is a good direction to go in.
@joe this will be totally possible via compiler plugins in Meteor 1.3: all you have to do is write a plugin that handles .png files and calls inputFile.addJavaScript at some point. Then, importing or requiring ./path/to/image.png will simply evaluate that javascript as a module, with whatever exports and side effects you like.
The best part is that the compiler plugin gets to decide how the image gets turned into a JS module, not the code that imports the image. Webpack’s module identifier string extensions (where the importing code picks a loader by adding extra syntax to the identifier string) get that relationship backwards, in my opinion.
Another serious problem with Webpack is that it assumes we’re going to be using CommonJS forever. Two of Webpack’s shiniest features, code splitting (require.ensure) and hot module reloading (module.hot) depend on CommonJS-isms (require and module) that will and should cease to exist in a fully ES2015 world of import and export, and Webpack has no plan to adapt those techniques to work with a purely native module system.
The more popular Webpack gets, the more it contributes to the entrenchment of CommonJS. Webpack is very much a tool for today, when what we really need is a tool that embraces the future of the language. I gave a talk recently about why it’s so important that we move on from CommonJS to a truly native module system (import and export), in case you’re not yet sold on that vision of the future.
By the same logic, adopting Webpack as a core concept in Meteor would hold the platform back in the long term—and probably in the short term, too, if you read that post of mine.
When Meteor finds a way to support code splitting and hot module reloading, those features will be designed to work with import and export syntax, without any dependencies on CommonJS. Unfortunately, Webpack has no insight to contribute to that still-open design problem. If you have ideas, we’d love to hear them!
I genuinely look forward to see how using ES2015+ imports and exports meets the goals. Recognises webpacks importance and eases its integration until a viable alternative that’s supported by the wider community, not just meteor. Provides for one central place to configure the entire build system with full transparency. Makes it possible to opt-out of costly backwards compatibility.
@benjamn Carry on, I love your involvement and the direction you are taking to lead meteor into the node npm eco system and the ES2015+ modules and standardisation. Thanks. merry Xmas.
Just wanted to say I tried out @benoitt’s Webpack boilerplate, and hot module reloading is pretty amazing. It’s really hard to go back to a regular Meteor app (and waiting ~5-10 seconds in between every code change) once you get used to it.
Same thing with code splitting, it’s a really cool feature. To be honest it’s something I thought would come to Meteor much sooner, because it’s pretty much impossible to build large performant apps without it.
Personally, my ideal solution would be some kind of Meteor wrapper of Webpack (or similar) that configures sensible defaults for you. Basically what @benoitt did in his boilerplate, but transparent to the end user.
And at the end of the day, I think most Meteor users don’t care that much about the technologies, and care a lot more about the features they enable. So that’s why Webpack is so attractive right now, no matter how it’s implemented behind the scenes.
Exactly. While there are more and more hard core programmers joining us, I believe most of us (at least early adopters) came to Meteor because of the cool technology that enabled us to (rapidly) build our cool apps, and not necessarily to learn so much of technologies beforehand in order to do so. Of course, as our cool apps grow, we should dive deeper into technologies, but I’d like it to happen later than sooner, when we’ll (hopefully) have enough money to hire smarter people than us to do the “real” job (no pun intended
So just to clarify, are you saying the next version will allow us to use Meteor’s new 1.3 npm functionalities (imports/exports) as well as all the awesome webpack stuff (hot-reload, .babelrc for ES7 decorators, code splitting, etc…) together? If so,
Regarding compiler plugins, what about if we wish to do some extra handling of JavaScript files besides what (for example) the ecmascript package provides? For example, suppose we’d like to have a file called foo.blob.js that is imported as a new Blob so that we can run it in a web worker. The problem I don’t see a workaround for yet is that if foo.blob.js has ES6+ syntax and imports NPM modules, then the compiler plugin to handle it will need to handle ES6 (f.e. with Babel) instead of letting the ecmascript package do it, which means duplicated efforts.
Are there any plans yet to support multiple plugins somehow acting on a single file? This feature would be to Meteor packages as what loader chaining is to Webpack.
Note that the ecmascriptplugin is very handily designed to import everything from the babel-compiler package, so this wouldn’t be too hard to re-use in this case.
Re hot module replacement (or more specifically, react hot loading). It sounds like a proper solution in Meteor that covers all cases will take a lot of time, but for those who want something now for a subset of cases, I’m progressing nicely with a workaround until something official is available.
+1.
When Meteor first came out, it did a lot of magic. Isomorphic code was unheard of, reactivity was unheard of. Heck, they even did Mongo on client-side! But they did it. When I think about it, how hard can it be to provide an abstraction layer on top of webpack so its as simple to use as meteor add webpack. It might sound like a lot of work, but building HMR and code-splitting from scratch sounds even more difficult. Why re-invent the wheel, MDG could’ve focused on creating a native webpack package which works without tons of configuration.
Blaze was pretty tightly integrated with Meteor, or so it looked, but React came along and MDG started supporting react. So now people can slowly migrate away from blaze to react. Why not something similar for webpack? It’s hard to believe that it’s undoable.
I don’t see evidence that it supports hot reloading with ES6 syntax, but then again, what does? Eventually a standard syntax for hot reloading will come out, and if bundling isn’t an obsolete concept by that time, I’m sure Webpack will support it.