-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
suggestion: internally split into separate module files to make optimised builds easier #720
Comments
PS. my |
What I'd be aiming for is being able to do something like var priorityQueue = require("async/lib/priority-queue"); |
I came here looking for this issue. I am in the same boat: I use a handful of async methods, but I don't need the whole thing. It would be great if these could be split out. I am tempted to create a PR that splits everything. Any feedback on if that would be well received or not? |
@caolan ? |
This is an often requested feature. There are advantages to having it both ways, as a single file, or a collection of files. Ease of use vs. modularity. We could author as a multiple modules, but then still publish a single file with We would still have to check that single built file in order to support people using the whole shebang with Bower. There would also be the problem of people submitting PR's to the built file, rather than the modules... There is also the lodash-cli style route. Author a single file, but create a tool to split things up and create custom builds. This is a lot of work -- the SLOC of lodash-cli rivals that of lodash itself (with more complexity). lodash-cli has only succeeded because jdalton works on lodash nearly full time. Whatever the case, don't go creating a PR with everything split out without coordination with @caolan . If you did split things up, it would invalidate a bunch of outstanding PRs waiting to be merged. |
I spent a couple hours (because I was interested, not looking to cause any bad blood) trying to break async up into smaller modules. Here's the result: https://github.com/andyburke/antisync It passes all the tests except for noConflict (I removed that in preference to simplifying to only support node/browserify since I have no real knowledge of the other package managers or what's involved in testing them). A full browserify build of this modular version is ~3k larger than an async build (due to the overhead of more files, more require statements, etc). However, in a real-life use case where I was only using series+parallel+waterfall, antisync ended up about 1/3 the size of async. After minification, antisync ended up saving about 10k on the minified bundle I am currently using async in. I'm not sure what my next steps would be. I don't really fancy maintaining a fork of async, but there are things about this approach that I really prefer to the monolithic setup that currently exists. One thing I would like to improve, but I'm not really sure there's a way is that the root of antisync is full of module files and it's a bit noisy. I did that to support sane require()s, eg: var antisync = {
series: require( 'antisync/series' ),
parallel: require( 'antisync/parallel' )
}; I'm turned off by the idea of requires that would look like this (note the /lib/ in the middle): var antisync = {
series: require( 'antisync/lib/series' )
}; ... that seems a lot less intuitive. If anyone has suggestions on how to address that, I'd be all ears. (I wasn't able to find anything in package.json docs to allow for hoisting a directory into the root include path.) Thoughts? |
Seems like you have a solution that works for you for now. There's nothing wrong with having a bunch of js files at the root. You could move some of the non-public utility methods to
|
This seems like a very useful change. We use async very heavily and having the project be more modular would be a great help on many fronts. First off, @andyburke's changes have really improved the overall health and maintainability of the asyc project as seen here (disclaimer, I work at bitHound): https://www.bithound.io/github/andyburke/antisync and here's the impact of the main refactoring commit: https://www.bithound.io/github/andyburke/antisync/commit/317a8e5a5aeda6d0374ccca59009e14e389f7a4d I think a change like this could greatly benefit the project for a few reasons:
As mentioned above, there are some negatives as well:
We love this project and would be very happy to contribute to help make this happen. We can help complete the work and would also be happy to convert any existing pull requests to fit the new project structure. Would there be interest in having @andyburke issue an initial pull request and having us help bring the pull request to a state that would be acceptable to this project? Including updating any existing pull requests that would need to be updated? I would love to hear @caolan comments and thoughts on this. |
One proposed solution (if it was important to leave lib/async.js where it is):
So existing consumers don't experience any change. |
We also would have to keep Bower users happy. We might have to bundle on a Bower pre-install (or equivalent hook). As of right now they can just use the single |
If I added a step to build lib/async.js, probably using browserify (and maybe collapser to help with size), would that make this an easier change to digest? (I won't have time to get to this until next week at the earliest, but I would welcome a PR off my branch.) I'm not sure I understand the bower issue: if I built to lib/async.js using browserify with an 'async' export, would it just work for them or is there something else to it? I am also not sure how to handle the noConflict thing (or really what the purpose of that is)... any recommendations? |
The bower stuff is because people like to use async either as a global or with AMD. It would be best to have it as a bower build step so we don't have to check in a generated file (and confuse people as to where to submit pull requests). |
I added a pull request to |
Thanks @gtanner, merged. |
@aearly Do you feel like the steps you've listed, if taken, would make my changes more palatable to merge? Specifically, it seems like you're requesting:
Do you have commit privileges or is @caolan the final arbiter? |
You don't need to have bower execute the build step if we just continue to commit the build output to this git repository. There ought to be zero impact for bower users then. |
I don't have commit privileges, I just help out with issue triage. (But it might be worth asking if he's open for more maintainers.) Those three steps sound good for a change like this. But I would still prefer this happen after the backlog of pull-requests is dealt with. |
@aearly Do you have commit privileges now? How can we move this along? It needs to happen. I'm willing to help. |
I don't want to think about this just yet -- still wrangling lots of issues and PRs. Right now I'm leaning towards the lodash-cli strategy, where we parse out the modules programmatically, leaving a lean source file people can use wholesale. There are a lot of modules that would end up being a single line, which would add a lot of overhead and make refactoring more difficult. |
Just to add my voice to the many people requesting this. I don't know if modules being a single line is so much of an issue. How much overhead would it actually add? As for refactoring and maintainability, I'll leave that up to whoever will be maintaining, but being able to require just the pieces I need would be a huge win for me. |
A lot of the async's methods are generated, especially the It also means for the browser, many modules would be a single line with a handful of I really want to go the When I have time, I'm going to make an experimental |
Closing this, we're working on this in #996. |
I just forked this project specifically so I could use
priorityQueue()
and virtually nothing else. It occurs to me that this is a long-term mistake because I'll miss out on future improvements to this function unless I manually import them.May I suggest splitting async.js into multiple files in a lib sub-directory, to facilitate delivering async's functionality to the browser whilst eschewing unnecessary bytes?
This may be of little benefit for server-side users, but every byte counts in the front-end.
Also, whilst undertaking this pruning, it occurred to me that dependencies between internal and exported methods isn't always clear unless you carefully read the source code. Modularising could assist in making these interdependencies more clear.
What do you think? Should I start a Pull Request for this, or is a bad idea / waste of time?
The text was updated successfully, but these errors were encountered: