-
Notifications
You must be signed in to change notification settings - Fork 43
Have presentation on loaders. #135
Comments
Btw if you're looking for example, I made a WASM loader here: https://github.com/wasm-tool/node-loader Note that wasm instantiation can block some time due to executin the start function or memory initialization. |
@bmeck again I disagree with this approach. I believe it will create a lot of headache in the future since we are about to call all loaders for every import instead of calling the loader only if it's necessary
|
What would be your suggestion @viktor-ku? (I've might missed it from previous discussions). I can imagine a fixed list of extension or regexep but that won't be as generic as currently.
We don't expect to have many loaders? (20 would already be a lot to me). |
@xtuc updated comment above |
@viktor-ku one of my question was how do you call only the necessary loaders?
|
@xtuc I guess you're right. It's slow. And I don't have any other ideas |
You could also decide to allow only one loader in node and write loaders in userland that can compose multiple loaders together. |
@Janpot the problem with doing that is how composition works. If I have only a single loader how do I add to it. Imagine: node --loader jspm index.mjs And now I want to run my application with code coverage: NODE_OPTIONS='--loader code-coverage'
node --loader jspm index.mjs Use cases where you need loaders to coordinate are easy enough to show that we can't just have a single uncomposable loader. We could defer the composition to userland but that comes at the cost of not solving use cases with our default solution. |
Maybe you add the
But I see your point. |
@Janpot possible, but that just devolves into everyone needing to use |
Yes, I agree. I just remember seeing a comment somewhere that they wanted to do in core only what can't be done performantly in userland. But this would indeed take that a bit too far. edit: The main benefit I see in doing the Then again, you could treat the whole implementation this way and push forward a lot of use-cases in this repo. Personally it would be the approach I'd go for, but I understand people want a complete implementation with sane defaults from the get go. (I don't want to create more noise in this issue as I'm not a member so you can safely ignore this philosophical side-track.) |
@Janpot I too was very eager for the next iteration of @bmeck please chime in on the following, would be interested to hear from your own perspective since you obviously explored this far more deeply than most. Unlike userland loaders, you will not be able to simply replace the system if your requirements cannot be met. Lastly, not to forget hard learned lessons, efforts for standards (or widely accepted loaders) have shown that people agree to disagree, and Node.js is not a framework, we all need it to play nice with everyone. Don't get me wrong, I am all for multi-loaders, but, I think that choreography cannot be in the form of decree. So I am growing more favourable to Such a loader would use an express-like mechanism because it is very likely that the platform (including v8) has evolved to optimize this kind of chained calls. But, someone else might have a better infrastructure to chain loaders... at the end of the day this cannot be prescribed, but surely it can be facilitated and enhanced through native optimizations as they evolve. Here is a very rough chaining algorithm which takes an array of functions, and the position where the /// The usual things that Node could help facilitate ///
const base = (options.base = `file://${options.cwd || ''}`);
/**
* How you locate and import things in preload
* is where I think Node's facilitation is highly
* mandated to promote stability and prevent wasted
* performance that popular things almost always
* suffer from as they age (kind of like people).
*/
export const resolvers = new Set();
/// The following is highly opinionated ////
// Chain to be created once on first resolve
let chain;
// Must be constant (internally assigned not directly referenced)
export const resolve = async (specifier, referrer = base, resolve) =>
(chain ||
(resolve && (chain = new Chain([...resolvers, resolve], 2))))(
specifier,
referrer,
);
function Chain(ƒs, position, thisArg) {
return (...args) => {
const p = position >= 0 ? position : args.length;
const i = ƒs[Symbol.iterator]();
const n = (...args) =>
n.ƒ.apply(
thisArg,
((args[p] = ((n.ƒ = i.next().value) && n) || undefined), args),
);
n.ƒ = i.next().value;
return n(...args);
};
} |
@SMotaal for reference, here's the current design for "chaining" nodejs/node#18914 |
We have a fair number of features being related to loader hooks. I'd like to add an agenda item to either an upcoming meeting or to schedule a time to present about what loaders are/can do. Right now they seem to lack concrete definition or explanation and it is possible that this will lead to confusion as we move forward.
I've prepared some slides explaining the terms to the best of my ability: a small review of requirements, review of current loader hooks, and some thoughts on a part to refactor them based upon some research I am currently doing. I will be continuing research and nothing should be seen as a hard path forward.
Feel free to comment on the slide deck I have as we are mostly trying to reach some sort of consensus and am happy to rephrase or add content as desirable. I think the important thing in this is to discuss the what of Loaders with relation to ESM so that we get a clear distinction of what is and is not a Loader. We pass around the phrase "it just works" but we should go into depth about how it works and should be careful to not allow that phrase to be a means to ignore details as we move towards and beyond feature discussions.
The text was updated successfully, but these errors were encountered: