Meteor is trying to open itself to NPM with Meteor 1.3, which is great. But somehow Meteor is always behind. Hacks are needed to work with the best tools, like the ecmascript package, the webpack:webpack project or Meteor 1.3 itself. There are a lot of bugs, delays and non-compatibilities.
Why not give us the opportunity to use the Meteor client side as a set of NPM packages as well:
We will still code the server side using meteor create and then connect to that meteor server with our clients using DDP. This would be compatible with your business model, because we would still want to host our meteor servers using Galaxy.
Some things like hot-code-push won’t be possible, yes, but at least give us the opportunity to choose:
It would save a lot of headaches to those of us trying to make complex apps with Meteor.
It would save us from moving away from Meteor because the current bundling and tools are not enough.
It would attract more JS/React people to Meteor.
It would work on other projects like ReactNative for example.
You already took this decision with Apollo and it is going to be a NPM package from the beginning. Make it happen for the Meteor we know and love as well.
Moving the Meteor core packages to NPM is our main focus after releasing 1.3. Also see this existing thread from someone asking essentially the same question just yesterday.
There has been some discussion on this issue as part of the meteor/blaze split-off, but opening a forum thread to get feedback seems like a good idea once we have a more concrete proposal.
One of the challenges is that the current codebase depends on Meteor’s scoping rules and specifying exports in a package.js. So the first step is probably to convert the core packages to ES2015 modules. That should also make it possible to use other build tools, although you’d still need to provide an alternative to build plugins like the ecmascript package (by manually including Babel in your build pipeline for instance, with the right configuration).
Then there is the question of what the output should look like. Ideally, I think we’d want to publish NPM packages with both CommonJS output and a jsnext:main entry for ES2015 compatible build tools (such as rollup).
I was taken a look yesterday and I tried to convert Meteor packages in modules using Webpack import and export loaders (https://webpack.github.io/docs/shimming-modules.html). I am sure you can get them working as modules without modifying your current system, but I bet it’s better if you convert them to ES2015.
Sure, I am sure we can give you good feedback. For example, there’s no need to choose between module systems, with tools like webpack is really easy to make libraries compliant with all the module systems (commonjs, commonjs2, amd) and jsnext is just another option in your build script, without transpilation to es5, if I am not mistaken.
Wow. It looks like I got this working quite easily.
I have a server folder with the meteor project.
I have a client folder with the entry point of Webpack and the app code. Normal webpack app.
I have a meteor.js file which reads from programs.js and requires all the Meteor packages from server/.meteor/local/build/programs/web.browser/packages one by one. Thanks to Webpack I can inject this and Package. Inside meteor.js I end up with a Package variable with all the Meteor modules. Then meteor.js exports all the Package properties just like Meteor exports all those to globals.
Finally (what is important) you can do this in your app files:
import { Meteor, Mongo, Tracker ...} from 'meteor';
And they work
If you want another Meteor package, just go to the server folder and do meteor add packageName. It gets added as well, and it’s globals exported to Package.
Your normal server files go in the server folder as well.
I don’t have more time today but I will publish a demo repository tomorrow
I think this approach may be more interesting for some type of projects than importing Meteor from NPM itself. In the end, you still need a real Meteor project (for the server) and this method is compatible with any Meteor package, out of the box. You just meteor add packageName and get the “global” using import from ‘meteor’ which is the important part. And the code is not duplicated or you don’t have to maintain anything, you get the meteor packages right out from your own build.
That’s good to hear; but is Meteor still going to require us to run our code through isobuild and its server though, or allow us to create e.g. an Express server and just add Meteor middleware to it?
Many Meteor core packages can be easily moved to NPM without affecting functionality: it’s simply a matter of converting package.js to package.json and listing dependencies along with using import from instead of api.use, thanks to the 1.3 modules system. Those packages moved to NPM can import APIs from other meteor packages on NPM or from any Meteor core packages that remain only on Atmosphere (for example, build-plugin stuff?).
Even the meteor CLI could be moved to NPM and still work as expected without too much work, changing the install process from curl install.meteor.com | sh to npm install -g meteor, without affecting how Meteor apps work. The only problem is that Meteor needs to depend on a specific version of Node. For that, maybe nvm can be used. That might also allow users to configure which version of Node to use (if they wish to deviate from the default at their own risk).
Idea: It might be interesting to make Atmosphere show meteor-specific NPM packages, and recommend npm install <package-name> for those, instead of meteor install <package-name>. Maybe packages that ultimately have meteor core packages as a (possibly indirect) dependency can be automatically listed on Atmosphere. I mean, if a package doesn’t depend (ultimately) on a meteor core package, then it’s probably not meteor-specific anyways.