How to deal with non-meteor packages that rely on require() and exports?

I’m trying to add http://material-ui.com/ which tells me to use browserify for installation. I’ve never had to use it before since we have Meteor packages for almost everything already.

Material-UI is available as an npm package. Use browserify and reactify for dependency management and JSX transformation.

I’m using the meteor-react package for react and it’s going well, but there is no package for material-ui. I tried using meteorhacks:npm but can’t figure out how to get the api available on the client instead of just the server. Is this not possible?

Any help in the right direction would be awesome!

3 Likes

Anyone? I figured this would be super easy to answer, I just don’t know what I need to do to compile it down and use it on the client side…

I’ve been reaching out in several more places, and it seems other people are running into the issue as well.


And there seems to be no answer for any of us.

I’ve tried creating a custom package as described here, but that either leads to NPM undefined on client or JSX errors on the server…

I’ve also tried just using browserify on the src files for that library but without gulp there seems to be additional problems. If I take the bundle.js file from the gulp build command on an example project, it includes all the source for the project too, which I don’t want, I just need the exported JSX components…

1 Like

Have you had any success with this? I am looking to implement the same package, looks nice.

Nope, I have not. I’m not sure how to get any non-meteor based libraries that use a client side dependency management setup like browserify to work on top of meteor.

It’s really a shame, I’m starting to think the best way to use meteor for what I want is getting rid of meteor all together and moving to something like Asteroid instead. There are a bunch of things I’d like to use but the larger js community is building tools with the assumption we will be browserifying / webpacking / gulping things up.

1 Like

That’s a bummer, I was able to get it kind of working by packaging it up and making global variables, but was getting errors with react being included twice, and didn’t feel it was worth it, so gave up. Hopefully it’s on the roadmap for the future.

I saw someone mention this package, which seems to be handling the client-side requires in an interesting way:

Also found this which names Meteor, not sure if it would be helpful:

I’ve been wondering about this as well. Definitely need to figure this out…

Check out this project:

And specifically their build script:

I’ve got a theory, but I haven’t tested it yet. The idea would be to use something like browserify, webpack, or jspm, whichever you prefer. Write your source code in a .hidden folder so Meteor doesn’t load it automatically, then use browserify, webpack, or jspm to compile a self-executing bundle (self-executing meaning you’ve made an entry point that will run in the global scope of the browser). Place the compile bundle somewhere in a non-hidden location where it will load last after all other Meteor files (possibly put it in Meteor.startup()). In your modules (CJS, ES6, or AMD) you can take advantage of the fact that all the Meteor global objects will be available.

It should work out. And it will all get much nicer and easier to handle once ES6 Modules are supported natively by browsers because then you’ll be able to place all your files in the public folder or serve them from secure server-side routes, and the client will be able to import them and take advantage of Meteor’s globals. It should work really well.

Alright, so for the browserify route, here’s something to help you out: https://github.com/qunxyz/meteor-browserify/. It will load browserify-loader for you, which will load a specified main file for you. In that main.js file, you can have require()ed anything you want, and use all Meteor APIs!

I still haven’t tried it, but I see that it will clearly work.

Here’s a hack how you would do it with browersify https://github.com/lourd/meteor-browserify/

I ended up doing this with webpack: https://github.com/trusktr/meteor-with-webpack (it shows a blank page since famous isn’t working yet, but you’ll get the the idea)

The downside of using webpack/etc is that if your bundle’s code depends on a library from npm, and your app depends on a package that depends on the same library but wrapped in an atmosphere package, then you might end up with duplicate libraries loaded into your app.

1 Like

Please try my Meteor package which integrates browserify into Meteor: cosmos:browserify.

It will create variables which are package scoped or global for the app.

2 Likes

@elidoran I saw that! Awesome work! :smiley: That’s where I’ve gotten some inspiration for rocket:module (still work in progress). The idea with mine is initially the same: it will compile entry points by handling the entry points with a plugin registered with Package.registerBuildPlugin. But I wanted to use Webpack because I felt it was more flexible and customizable. So that idea is essentially the same as yours, but I’m adding onto it the ability for the package to detect all the packages that depend on my package, then do code splitting (one of Webpack’s features) to split common dependencies out of all bundles so they can be shared app-wide. Then next other difference will be that I’ll let the user specify NPM dependencies of the form ^X.X.X or ~X.X.X, etc. I’m making progress! The first bottle neck I encountered is that Webpack doesn’t have an in-program way of handling source codes, so I’ve had to deal with the filesystem. I’m making temporary folders in /tmp where all the compiling happens, then I finally get the compiled result from the filesystem to give to Plugin.registerSourceHandler. The current challenge I’m working on is code splitting. I was going to let packages use Npm.depends initially, but that won’t work well because it accepts only absolute versions ( :frowning: ), which means that there can easily be multiple versions of libs in the resulting splitted/shared bundle. So I’m currently detecting packages in the filesystem, then next I’ll probably write something that allows users to store dependencies, maybe just a package.json and use vanilla npm with that and in the docs I’ll explain about using the config file instead of Npm.depends.

The main concept is that packages relying on rocket:module will be able to specify npm dependencies, then those dependencies will get handled across the whole app, in all packages that depend on rocket:module. I wonder if there’s some way to resolve the dependencies. Maybe I can scan all the packages depending on rocket:module, then instead of using each config files (e.g. package.json) I will add each package location (somehow) for npm to pick up, and at compile time I’ll create a master config file that specified each Meteor package as a dependency, then I simply npm install with that config, and npm will step in and use it’s dependency resolution. Hmmmm.

I can’t wait to get that far. Thanks for the inspiration! What do you think? Any thoughts or ideas?

1 Like

mistake reply …

browserify creates a global variable. How would one use this library? https://github.com/moroshko/react-autosuggest since it seems a bit different… using ‘import’ rather than 'require… (amateur here)

Use Meteor 1.3 (currently in beta):

meteor update --release METEOR@1.3-modules-beta.6

then in your code, import as it says:

import Autosuggest from 'react-autosuggest';
1 Like