-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
feat(compile): Enable multiple roots for a standalone module graph #17663
feat(compile): Enable multiple roots for a standalone module graph #17663
Conversation
15e8c12
to
4d8e192
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nitpicks and bikesheddings aside, looks good to me and really useful.
Statically analysable dynamic imports being picked up into the module graph automatically would be a really good feature to get working, as it would make both deno compile
and Deno Deploy users quite happy indeed. For Workers I don't think it would work though, since it's possible to override the Worker
name can be overridden both by local shadowing and globally by overriding globalThis.Worker
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be able to do it without needing --extra-side-modules
.
Edit: let's wait on denoland/eszip#115
Some flag would still be needed for non-analyzable dynamic imports, and for workers. |
Sorry, I read too fast and missed about workers. I think that's reasonable for workers and in that case maybe we can just merge this without the analyzing of statically analyzable dynamic imports. For some reason, all our walking/traversing of the graph in the CLI skips over statically analyzable dynamic imports, but they're in the |
I agree with @andreubotella that the flag would be useful for non-analysable imports but... It's actually also possible to do that without the flag: const EXTRA_SIDE_MODULES = [
() => import("./side-module-1.ts"),
() => import("../root-side-module.ts"),
]; It's probably a matter of taste which is more elegant: Use the existing language features that we have, or add a configuration flag or option. |
Thanks. You should review commit 4d8e192, since the previous ones come from #17657. I built this PR off of that one not because the actual code changes need to be based on that PR, but because that way I can add to one of the worker tests from that PR.
This seems like a hard-to-explain non-obvious hack, if you're reading the code. It feels a lot cleaner to me to say " |
Not sure if you're talking about somewhere specific, but the logic of skipping over (even statically analyzable) dynamic imports exists for example in startup graph validation because we don't want to elevate dynamic module slot errors until the runtime import of that module happens. |
Yeah, why is that done? I was thinking that maybe someone would be downloading code on the fly, but that wouldn't work. It seems to shift an error that could be spotted at startup to being surfaced later on. Anyway, in this case we can make it work by updating eszip to not skip over dynamic imports: denoland/eszip#115 |
d91c285
to
7db57ef
Compare
Because the import might not happen, and even be conditioned on whether or not it would error: if (fs.exists("plugin.ts")) {
await import("./plugin.ts")
} Yeah the eszip patch should be sufficient for the |
@nayeemrmn that makes sense. Thanks for the background! |
Re flag name, the term 'side module' in this context seems too colloquial doesn't it? |
55cde30
to
0df193a
Compare
I would vote for |
Potentially related and weird errors in in WPT tests for workers:
First one doesn't fail but it's a bit suspicious. Coming from the 99_main.js file: // Add a callback for "error" event - it will be dispatched
// if error is thrown during dispatch of "unhandledrejection"
// event.
globalThis_.addEventListener("error", errorEventCb); |
denoland/eszip#115 added support for statically-analyzed dynamic imports in eszip, which made `deno compile` support dynamic imports starting from #17858. This PR adds a test for it. ---- This test is adapted from PR #17663. Closes #17908
The |
denoland/eszip#115 added support for statically-analyzed dynamic imports in eszip, which made `deno compile` support dynamic imports starting from #17858. This PR adds a test for it. ---- This test is adapted from PR #17663. Closes #17908
Discussed during CLI team meeting, we are in favor of landing this PR and going with a flag appears to be a better solution - it's easier to explain and document than requiring statically analyzable dynamic imports. I'm sure we'll bike shed on the flag name a bit. Additional benefit is that it gives a clear way to move this option to the configuration file in the future. |
This change will enable dynamic imports and web workers to use modules not reachable from the main module, by passing a list of extra side module roots as options to `deno compile`.
c731dfd
to
1a4d647
Compare
Rebased to not depend or sit on top of on #17657 anymore. |
This change enables the use of web workers in binaries produced by `deno compile`. This requires the main module to be present in the compiled module graph, which is why if it is not already, it must be explicitly added as an additional root (see denoland#17663).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add a help comment to the command line argument, otherwise looks ready for merge.
cli/tests/testdata/compile/dynamic_imports/main_unanalyzable.ts
Outdated
Show resolved
Hide resolved
"Includes an additional module in the compiled executable's module \ | ||
graph. Use this flag if a dynamically imported module or a web worker main \ | ||
module fails to load in the executable. This flag can be passed multiple \ | ||
times, to include multiple additional modules.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can I do comma separated list of urls like: --side-module=https://deno.land/std/flags/mod.ts,https://deno.land/std/version.ts
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commas are valid in URLs and filenames.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I thought we already supported comma separated lists in other flags, but maybe I'm wrong here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested it locally with a bunch of dynamic imports and while having to specify --side-module=
multiple times is not super nice it does the job very well. I'm sure this functionality will unblock many new use cases for users and I'm strongly in favor of landing it. We can try to further iterate on the flag name and potentially making it more ergonomic, but it seems worth landing as is already.
Awesome work as always @andreubotella, LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
cli/tests/testdata/compile/dynamic_imports/main_unanalyzable.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM too once the timeout is lowered. Thanks for contributing this and the other worker PR! Will be nice to have.
cli/args/flags.rs
Outdated
@@ -908,6 +909,20 @@ fn compile_subcommand<'a>() -> Command<'a> { | |||
runtime_args(Command::new("compile"), true, false) | |||
.trailing_var_arg(true) | |||
.arg(script_arg().required(true)) | |||
.arg( | |||
Arg::new("side-module") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was flag name settled? Me and @aapoalas suggested --import
which is less colloquial than --side-module
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No - it's still up to debate/bike-shedding, but I'm fine changing the name in a follow up. I'm not sure I like --import
better than --side-module
, seems more ambigious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--include
? Shorter is better here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with --include
too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah --include
was our next one #17663 (comment), sounds perfect if it might include assets as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok let's switch to --include
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I'm aware, including assets in the binary is a very different thing than including a module in the module graph. Though I guess you could reconstruct the original TS file from the source map.
In any case, if you agree that the flag name should be --include
, I'm fine with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tangential: the flag could potentially be reused to define file system assets (ffi dylib / game assets / worker source) to be included in the compiled binary? It is a very useful feature to have IMO.
I'm not sure
@andreubotella let's go with |
Flag renamed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you @andreubotella!
This change will enable dynamic imports and web workers to use modules not reachable from the main module, by passing a list of extra side module roots as options to
deno compile
.This PR builds on top of #17657, which adds support for web workers to
deno compile
.The option name
--extra-side-modules
is up for bikeshedding, as well as the exact way to specify such list of modules. I suspect this list could be added todeno.json
.Closes #17908