-
Notifications
You must be signed in to change notification settings - Fork 7
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
module fragment identification #5
Comments
Would this declaration be possible to make anywhere, or only at the top level of modules? |
Anyway, I really like this idea. The main thing is that I can't think of how it would extend to exported modules (maybe it would magically get the hash name?), but maybe nobody needs that. I'm OK with |
How would you import from a module in a different file with this approach? I believe that's one of the main use cases for this proposal. I think we'd need something to be added to the module specifier to reference a sub-module and fragments make the most sense IMO. If they were declared as identifiers in the source code they could be magically mapped to fragments but this feels confusing to me. I prefer the more explicit approach of using fragment strings for this. |
@devongovett yeah I'd like to avoid all the magic strings if possible... I think there are definitely solutions with the identifier form, for example |
@devsnek That's a bit difficult if you need the module specifier as a string, like in a dynamic import or Worker constructor. Arguably, for those cases, you could get this as a module block object instead (if that's exported from the module), but it feels a little complicated/mismatched. |
@littledan yeah I haven't though of something I really like yet. one thing which came to mind was that resource proposal, in the vein of a syntax which lets you specify the specifier and identifier and returns some opaque value which can be imported. still not great though. |
I guess I'm not sold on the idea that you should be able to directly name one of these modules without going through its parent: // a.mjs
module foo {}
export foo;
// b.mjs
import { foo } from 'a.mjs';
import * from foo;
// or
new Worker(foo); This also explains how to import deeply nested modules (just keep adding imports) and imo is easy to understand, but it is also quite verbose. |
In the current proposal, whether a dynamic import targets an engine-held inline module or a host-resolved external one, depends on the set-inclusion of a runtime evaluated string. I can see how this is a strange structure and cost. It makes sense to use an identifier + opaque value for inline structures, while reserving string specifiers / URLs for actual host-resolved resources. |
At this point it’d make sense to consider merging this proposal with Module Blocks (or the other way around?). One of the most-frequent questions for Module Blocks has been whether or not it tries to solve the “Bundler Problem” (putting multiple modules into one file). So far the answer has been “no”. The delta between this proposal and Module Blocks now boils down to “named” module blocks that can be used in static imports. Looking at the current README of Module Blocks, the examples would continue to work as-is, but now some could be improved to look more idiomatic (imo): - let workerBlock = module {
+ module workerBlock {
onmessage = function({data}) {
let mod = await import(data);
postMessage(mod.fn());
}
};
let worker = new Worker(workerBlock, {type: "module"});
worker.onmessage = ({data}) => alert(data);
// Anonymous inline modules continue to work and can be postMessage()’d
worker.postMessage(module { export function fn() { return "hello!" } }); The syntax is reminiscent of At the same time, this would allow the proposal to solve the bundler use-case. The counter-example from the Module Blocks README would be handled as follows: module countBlock {
let i = 0;
export function count() {
i++;
return i;
}
};
module uppercaseBlock {
export function uppercase(string) {
return string.toUpperCase();
}
};
module combinedBlock {
import {count} from countBlock;
import {uppercase} from uppercaseBlock;
console.log(count()); // 1
console.log(uppercase("daniel")); // "DANIEL"
}; I’d suggest we discuss this possible merge at the incubator call, potentially under a new-ish name to avoid confusion (“Inline Modules”?) If it makes sense, we can move forward on the change as follows:
|
I think we should go in the direction identified by this issue, with these these major changes:
We discussed this direction in an incubator call as well as a TC39 tools call, and feedback seemed generally positive. I'd like to follow up with a discussion in the July 2021 TC39 meeting. In my opinion, it's not necessary to merge this proposal with module blocks--it layers on top of module blocks cleanly already. |
The current string identification design is imo not a great ux, and it introduces a split between fragments and blocks. I think just using identifiers could be helpful:
One thing to note is that this couldn't work, and might cause confusion:
One solution would be to not have the expression form, which turns
new Worker(module {})
intoThis also touches on #4 regarding how public modules (if such a thing end up existing) should be referred to from other modules.
The text was updated successfully, but these errors were encountered: