Webpack compiler inside Meteor (ES6 modules, hot reload and code splitting!)

For the curious, you can now run velocity with webpack! I’ve added a few examples on the kickstart-simple and kickstart-hugeapp (they are exactly the same tests).

It runs unit and integration tests with jasmine and are packed within your modules. Pretty easy to use and so much powerful. @sam I would love to get your opinion on this when you have a few minutes :smile:.

2 Likes

Nice one!

I wonder if it’s possible to unit test the code using something simpler than Velocity, e.g. plain Jasmine/Mocha/Buster/whatever. Velocity feels like it does a lot of magic for simple unit tests…

1 Like

That’s neat!

I take it that you’re injecting the tests in at build time as you include modules?

If only it were that simple!

I tried to do this a long time ago using stubs in RTD but it was a pain to keep that stub up-to-date, despite community efforts to maintain it. We then tried again with Velocity in the meteor-stubs project. It was just too much work to do it everytime there was a new release.

Then we tried to use the automatic mocking approach that jest takes and that worked, but you still need to initially run the analysis to automock in a meteor run-time, so you still need to start Meteor. In fact, the sanjo:jasmine server unit mode uses this approach, but it has been disabled in the latest sanjo:jasmine release due to ES6 support. You can force it on if you know what you’re doing (see the docs).

The only current way to load your code and unit test it entirely outside of Meteor, is either to write your own stub, or to decouple all the parts of your app that use Meteor and use some dependency injection at run-time to insert Meteor. I don’t think that will be a pleasant from a maintenance point of view in either case and if you find a good way to do that, I (and a lot of others) would love to hear about it!

For true Unit testing that can run at blitzing speeds, we would need an up-to-date stub. Ideally this would be released with every new Meteor release.

The next couple of weeks will be interesting, I’ll say that much :wink:

Hey thanks. Their is a special require with regex that include every -test.js(x) files automatically. It’s in the entry.js file and you can adapt it to your own structure depending on how you like it.

Webpack is really awesome for having that feature :smiley:

@benoitt how are you working around the modules not being defined in the shell or tests?

I ended up creating a function that would insert the module into a Test namespace in dev then export but would just pass through and export in production.

Something like this (if i’m remembering right):
export default exposeInDev(MyModule);

Then in the shell/Velocity you could reference
Test.MyModule or even better: const {MyModule} = Test

They are not within the regular tests folder. There is only a index.js placeholder there to activate the type of tests I want. They are defined within the modules/…/tests folder (or could be anywhere). Then, entry.js is automatically including every files ending with -test. You can read the entry.js file link I’ve posted above.

This means I can import within test files :smile:

1 Like

Ah, that’s really slick! Do you have any sorcery for accessing modules in the Meteor shell? :smile:

@benoitt how would I go about including an EventSource polyfill for HMR in IE?

@benoitt My team is also looking to move towards Webpack, your approach looks promising ! How “future proof” do you think your solution is ? Is it likely to break on Meteor update ?

Hey kamek,

Meteor is not going to make any breaking change to the build API until 1.3 for sure. Then I can’t tell you. However what I can tell you is it will be actively maintained for a very long period of time. A lot of people are making the switch and I personally have my major projects using it.

I don’t think this will ever be integrated within Meteor because it is a bit complicated for a beginner. However until I use Webpack with Meteor I can’t imagine not using it anymore :smile:

1 Like

Nice !
Also, even if Meteor’s build API changes, I imagine we’ll always find a way to plug Webpack or any other build system.
Anyways, being able to go full ES6 outweights the risk, imo.
Still, it would be really nice if the MDG could support alternate build systems, just like they support Angular and React.

1 Like

It seems that both lodash (by npm packages) and underscore (by meteor-base package) are included, at least in the browser.

Perhaps add underscore in webpack conf externals? And then lodash = underscore in a custom meteor package. But there are differences between lodash and underscore and not sure what issues it might have. Any suggestions?


Edit: Looking at https://github.com/jedwards1211/meteor-webpack-react/issues/30, I think a better solution might be if we somehow avoid including meteor’s underscore in the build.

I keep getting the same error for some reason, this is my project structure, am I doing something wrong?

Webpack is really needed in our real projects. Do you have hacked webpack to support current Blaze and its packages?

It would be hard to know without your webpack.conf.js. Do you have a git repo I can take a look at?

I haven’t done it personally. I’m not sure it is a good idea. If you’re just looking for ES6 modules, they will be there with Meteor 1.3. In the mean time, it is probably possible to use Blaze with webpack but I don’t have any example nor time to build one.

I suppose an app that includes several sub-apps include React and Blaze. The main optimize is targeted on picture loading not on code. For example I just need to load pictures in main page at first then load other pictures on demand. How webpack help in this case?

I am sorry for this late answer: https://github.com/Jdruwe/webpack. I was following this tutorial: https://medium.com/@SamCorcos/meteor-webpack-from-the-ground-up-f123288c7b75#.mf5j9yrp9, but it gives me the same error as your kickstarter projects. Thanks in advance!

Hey - again an issue with Material UI. I can’t make the material ui elements react to click events. I know I’m supposed to add react-tap-event-plugin package and add the following lines:

import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

But that doesn’t work and events are not fired. Is this related to that issue?

EDIT: I made this work by adding the meteor package coniel:react-tap-event-plugin, and adding the following line to the externals in the /entry/webpack.conf.js file:

externals: {
  ...
  'react-tap-event-plugin': 'injectTapEventPlugin'
}