@tjmonsi Maybe that’s a workaround for now . We should be able to use import/export though. I think @ngochenbang is right, maybe they just aren’t enabled in the transpiler. I submitted an issue here: https://github.com/meteor/meteor/issues/5795
My bad. I tried removing the jsx package but it didn’t work. The jsx files were not transpiled to js even when using just the ecmascript from Meteor 1.3
Has anyone got this set up with their React project and noticed faster page refresh times?
Outstanding improvements! Eagerly waiting for stable release.
Can I import from specific files in other packages, like:
`import {Posts} from “my-modular-package/collections” ?
I think the interface should be:
-
autoimport
package likeinsecure
andautopublish
as suggested by @luisherranz:
- when
autoimport
is removed, amain.server.js
file is generated which solves the following problem mentioned by @benjamn:
It would include ddp
etc and be the equivalent of the following extremely familiar code:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
});
This would bridge the gap to the Node world. The end goal would be that the app could run on NPM without using the meteor
command. I don’t know all the implications and implementation challenges if any, but even if it couldn’t currently run on NPM, it would pave the way in that direction. It would be a good marketing move to blend in with the rest of NPM. I think it’s important for non-meteor developers to be able to look at Meteor and immediately see something that gives the semblance of something they are familiar with. It would also give advanced developers the opportunity to customize something they couldn’t before. And of course it would solve the problem of having all the standard packages loaded in the correct order on startup. Many frameworks generate this sort of entry script for you to modify, so it’s hardly irregular.
Lastly, if the autoimport
package was added back, this would automatically be commented out or ignored.
- Included packages behave like this:
LEGACY ATMOSPHERE PACKAGES:
-
without
autoimport
package: are given a chance to run files in specified sequence without exporting any variables into global scope. The purpose here is to make sure things like the override of built-ins still occur, but without forcing anything new into global scope. However, the interaction between one package to another would continue with the same contract its always had. -
/w
autoimport
package: like they currently do.
NPM PACKAGES:
-
without
autoimport
package: just as you would expect, no special behavior. -
/w
autoimport
package: if ameteor-onstartup
script is specified inpackage.json
it will run any special code that needs to happen on startup such as built-in overrides, global exports, adding blaze templates, etc.api.export
would need to exist in this script, but the whole thing would run in the regular package scope so built-in overrides could be applied to any used sub-packages. There would be ameteor-ontest-startup
possibility as well. Meteor-specificpackage.js
files would obviously not be needed anymore–we are now a pure NPM package! The main idea here is A) to solve redundancy: if you import and export all your code properly from the files themselves, you shouldn’t have to export anything frompackage.js
or set the file load order; while preserving something Meteor package already rely on: B) running code on startup that does things like override built-ins (but in an NPM-idiomatic way via scripts).
This will delegate the non-standard stuff we allow to seep through the current package system to happen in an optional smaller confined place than before, and without requiring developers to make packages the old Atmosphere way. Like, if you really wanna do that fancy automated/implicit stuff within an NPM package, you can, but besides the special script you will have to make your package look and behave like a regular NPM package. We are now “guiding” developers into the “pit of NPM package success.”
Ideally, the meteor-onstartup
script wouldn’t need to exist (just as if autoimport
wasn’t included), and package developers instruct application developers in what to do to get their code running (the choice will be theirs), but obviously it’s of the utmost importance we are backwards compatible, especially as package developers migrate to the NPM style while application developers remain in the Atmosphere style–that’s the problem we are trying to solve here; and I also think it remains extremely important that things are as easy and automated as possible for novice developers; even advanced ones–if we can continue to provide the option that, for example, the meteor collection hooks package automatically makes some overrides to your collections, we should. I personally don’t like to be told what needs to be implicit and what needs to be explicit, the decision should be mine–we need to add the explicit option, not simultaneously get rid of the implicit option we are already the best in the business at offering.
Interestingly, I suspect this to be the most important and most common use case, as most application developers will likely stick with the implicit package loading option for a long time to come, while package developers (likely more advanced developers) will want to switch to the more advanced pure NPM import/export approach. That’s why it’s so important we consider and get this use case right.
Another important thing to note is this: the same NPM package can be used with autoimport
on as we all as off. Without autoimport
, application developers must follow the directions to import the file and call the code that will run onStartup
routines, whereas application developers with autoimport
included will have the meteor-onstartup
script for the given package handle that for them. In that way, the new NPM packages we are guiding package developers to create will service both use cases while otherwise looking like a standard NPM package. Slam dunk!
- THE CLINCHER: a solution for partial lazy-loading should be a first class priority so developers can migrate/upgrade their app incrementally or simply be able to take advantage of file-order-control where they need:
to accomplish this, rather than having an imports
folder, statically detect which files are ever imported, and automatically remove them from the list of files “eagerly” loaded. This would only be a behavior that occurs when the autoimport
package is still included. It would greatly ease the path towards removing the autoimport
package altogether, i.e. after you manually imported all files ever used.
In addition, this would nicely solve the confusion discussed by @serkandurusoy and @SkinnyGeek1010 above:
-
Without the
autoimport
package, developers manually add any assets, templates, css files, etc contained within packages. There’s just gonna have to be some sort of Meteor configuration file at the application level that starts to become common practice to use:meteor.config.js
. In it you can specify which assets from which packages are sent to the client. Ultimately this should evolve 2 directions: A) Webpack’s feature to include assets within js files which become part of chunks, and B) the following idea where Meteor provides a router in the core, which efficiently doubles as a way to specify how code splitting occurs across multiple entry points: -
FUTURE: I know webpack and code-splitting is for a post 1.3 release, but it seems to me that if MDG brought a router into core and coupled the router with custom webpack-like code-splitting features, we could greatly simplify the Webpack interface and make it feel more natural.
Why/How? Description of chunks emitted would live in the same location as the route definition, no config file other than route definitions needed. As for require.ensure
, we’d implement that separately (and again on our own, not using Webpack under the hood). When you rely less on routes in single-page apps, code splitting becomes all about require.ensure
anyway.
How/Why? The common code is loaded based on what’s in main.client.js
and only a second request is needed wherever you wish (e.g. a route, or upon routeless action) to ensure you have anything else you need, while of course achieving the goal of never loading more than you need until you need it.
If we simply had require.ensure
without even “lazy entry point routes” we’d have already done 90% of the job. I personally am a lot less interested in defining entry points than just being able to load a batch of code/chunks manually when I need it, but I also assume lots of people would prefer the route-based approach as well since it would allow for a single request on page load. Starting with just require.ensure
could be a great feature to do in a 1.3.1 to phase the development of all this.
Perhaps, we never need a code splitting config file (i hate that F#!ing file), and all our chunking is done within code using require.ensure
, as well as including any assets (yes, via javascript) that need to be sent to the client within that chunk. This implicit automated approach would mean one less concept Meteor developers have to learn (for the most part). It’s a lot easier to explain just use require.ensure
. In addition, what I think might make a lot of sense is instead of specifying your code in the callback to ensure
, utilize something like a decorator (almost like “use strict”) at the top of a function to annotate specific exported functions as being the starting point of a given chunk:*
FlowRouter.route('/blog/:postId', {
action: function(params, queryParams) {
@chunk(['additional', 'dependencies'])
import {post, comment} from "lib/model";
//etc
}
});
That would create a chunk according to similar rules as Webpack containing “additional” and “dependencies” chunks, and the “lib/model” module. The transpilation result would be the contents of action
function being passed as the callback to ensure
. This would save us the unnatural nesting that comes along with ensure
— it’s a seemingly small thing, but would give code-splitting a magically harmless feel, and because of that frictionless would lead to an explosion in its usage. If we could find a standards-based way to achieve something like that decorator instead of having to use a callback, I think we’d be on to something. It would be a very simple and special interface to be sure.
Up until that route, Meteor would have only loaded the common chunks/modules. If it’s the first route, Meteor could just make requests for 2 files. I’d be fine with that. If the router was added to the core by MDG, well it could likely figure out how to make that first request load only one javascript file. In either case, unlike webpack, we wouldn’t need complicated “webpack.config.js” files. Transpilation and building would be a totally separate affair in our case, currently handled by build plugins. The biggest concern MDG has had with Webpack’s interface is all the extra advanced work it expects of developers to configure. It’s too much boilerplate. That’s not the Meteor way, and I wholeheartedly agree that’s a good decision. I hate all that boilerplate config. Yuck! Lastly, I’d like to reiterate that by not having to pass all your code in a callback to ensure
we haven’t disrupted the hierarchy of your code — we have let it remain flat, which is awesome! Otherwise, importing and exporting is business as usual, not caring if you are doing it asynchronously in chunks.
As for arguments against duplicating what Webpack does and rolling our own, my response would be: code splitting is the best of Webpack, their interface is poor, and we already have other ways to perform the duties of loaders, i.e. the Build Plugin API–so let’s focus on just getting code-splitting right. Introducing the webpack configuration into Meteor or any app is a lot of extra boilerplate; and since Webpack does a lot more than just code splitting is too advanced and cumbersome for even intermediate developers. My hunch is that a way better automated interface could be developed, definitely if only code-splitting was addressed. I also feel like building for the client is so important it should be something part of ES7 or ES8. I know that’s farther outside the realm of typical language currently features being tacked on (since it deals both with the server and the client), but code-splitting is only going to become a bigger and bigger problem as the web progresses and our apps get even bigger. As I was saying above, wouldn’t it be a lot simpler if entry point bundle configuration happened in the router–there seems like there are options to implicitly do this and keep transpilation of various file types separate.
Meteor, being the only true option in town when it comes to reactive universal apps, might be the perfect guys to pioneer a format/interface for code-splitting and the other isomorphic package implementations for NPM discussed above. I.e. a set of tools for NPM that exist outside of Meteor. Unlike Blaze, which was barely supported outside of Meteor, I think in this particular case–given Meteor being a longtime pioneer of the isomorphic web and knowing it better than anyone–we may be able to offer something to the greater NPM community that they actually wanna use, especially if we promote it properly (like we never did with Blaze).
It seems we are at a place–thanks to @benjamn 's amazing work–where the foundation import/export functionality is done, and now we need to flush out the interface. I know all of it won’t get done in 1.3, but hopefully we can have a nice roadmap of how we’d like to evolve the interface here. WE NEED TO THINK ABOUT THE END GAME HERE TO GET THE NEXT STEPS RIGHT. That’s my main message.
What I’ve presented here is one possible end game. I’m sure I’ve missed some things and misunderstood some things–let it be a template for thinking of the bigger picture we want for Meteor. To sum it up, from my perspective, we don’t want only explicit (and certainly not only implicit, or we wouldn’t be having this conversation today). We would like both implicit, explicit, and more importantly a way to gracefully upgrade from implicit to explicit or simply maintain partial implicit + explicit apps. To do this we need to tackle the resulting matrix of adding the fact that packages may also be developed along this spectrum. And to top it off, we need to at least know our “webpack strategy”, which I’m voting should be a custom version all our own focusing just on code-splitting (I’m pretty sure I read somewhere that @benjamn is thinking the same).
That’s all she wrote. …@benjamn , curious what you think about the idea of removing any lazily loaded packages from the set of eagerly loaded packages via automatic static detection of whether one its modules is imported??
@faceyspacey Are you a real person or a Discourse post length edge case test function gone wild?
In that case it would have been Jeff’ed a long time ago.
In the doc you gave an example of importing a package by NOT using a relative syntax. So what is your search order in that case (given that you have to search packages and node modules…)?
@tarmes this ASCII-art directory tree illustrates how Meteor packages are installed in bundles. In short, Meteor packages are treated much like “global” node_modules
, in the sense that they can be imported without relative paths from anywhere in app code, and they can also be shadowed/overridden if the app installs Node modules locally (in /app/node_modules
or /app/client/node_modules
or wherever). Given this directory structure, the lookup rules are the same as the ones used by Node.
In the not-too-distant future, I foresee more and more Meteor packages simply becoming npm packages that apps can install locally, so treating them like npm packages now is a step in the right direction, not just an implementation trick.
@benjamn in your presentation: http://benjamn.github.io/empirenode-2015 , last slide mention http://rollupjs.org/ Is any plan to integrate this bundler beside webpack on meteor ??
I made a small github repo that shows some basics of using this new import/require syntax with npm react components. Might come in handy for somone so here it is.
This app uses the react component formsy
and integrates decently with aldeed:simple-schema
.
I feel the same way. Webpack is hard to configure and could be easily made simplier. However, where I disagree with you is: we should re-code the entire thing in the Meteor build process. It’s a though I was entertaining too until I decided to check how this can be done.
Be ready for days and days of headache just to understand how Webpack is working behind the scene. If you think Webpack config are complex, this is a very complex engineering problem that has been solved very well. I think it would be an incredibly big job (and quite frankly a waste of time) to try to do EXACTLY the same thing just to get a simplier way of using it.
Instead, why not making Webpack easier to use? Why not find a better API Meteor users could use to simplify the integration of Webpack with their projects?
What if integrating Webpack was not a matter of writing a “complex” config file (quite frankly it’s not when you’re use to). What if all you needed was to add the few packages that you needed? Example:
meteor add webpack:webpack
meteor add webpack:jsx-loader
meteor add webpack:sass-loader
And use the exact same structure than Meteor 1.3.
When the gap between Meteor and Webpack is that small, what’s the point of reinventing the wheel?
Beginners don’t need to opt-in as soon as they learn but they could just by adding a few packages. What do you think?
Hey @faceyspacey I challenge you to put a max 100 Words/600 Characters tl;dr at the beginning of your posts.
FYI: That post has 2528 words & 15170 characters. At avg. tech reading wpm that is 15-20 min. Without replying.
So: I love your posts (they are full of great ideas ) but often there’s no time to read it all (esp. on mobile) and I believe many people, incl. MDG Employees, feel the same way. A gist is great to navigate… I already feel bad not to be able to read it all due to work, real life, projects etc. Don’t have your contributions fall under the table because it is too hard to stay on-top.
// off-topic over
This sounds amazing @benoitt ! I think this coupled with whatever folder structure MDG settles on (in their guides) for 1.3 would make for a killer setup. Having a default config with easy loader support solved 80% of use cases.
How would you handle builds?
@jeremybyu I think you should post the “gotchas” over at the meteor issue tracker so that they reach the right audience and get resolved.
@benjamn Is there (or will there be) some API we can use to load modules over HTTP (or HTTP/2) at will? SystemJS has this so that it’s possible to load an entry point when you say so (and the entry point can use any of AMD, CJS, or ES2015 module formats). SystemJS will then know how to fetch all dependencies for that entry point (they can be separate files, all stuffed through a single HTTP/2 connection).
Yes, I’m also interested in that to create a plugin platform for Wekan. These plugins would be loaded dynamically at runtime depending on the current board.
they’ve gone out of their way to make sure they’re not just supporting straight up ES6 modules but also all backwards compatibility by supporting the old globals and load order, it sounds like you don’t have anything to worry about
they specifically say “lazy evaluation” to avoid that mishap. when I first read that I thought the same and almost jumped with excitement until I realized it’s just evaluation