-
Notifications
You must be signed in to change notification settings - Fork 455
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
Omit dynamic imported module from require, import statement #6232
Conversation
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.
Looks great.
Left some comments.
jscomp/core/js_dump_program.ml
Outdated
@@ -73,8 +73,12 @@ let node_program ~output_dir f (x : J.deps_program) = | |||
P.newline f; | |||
let cxt = | |||
Js_dump_import_export.requires L.require Ext_pp_scope.empty f | |||
(Ext_list.map x.modules (fun x -> | |||
( x.id, | |||
(* dynamic import should not print in require statement *) |
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.
not be emitted in require statements
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.
Oh actually, it happened. Not only es6_program. I you correct my comment, haha. Got it.
It's a bit confusing, but do you mean that it's not generated in commonJS by default? In fact, we can use dynamic imports in commonJS as well. So, the changes in this PR would also apply to the node_program.
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.
Sorry I just meant to suggest an alternative phrasing of the comment
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.
Got it. 3603852
jscomp/core/js_dump_program.ml
Outdated
@@ -83,8 +87,12 @@ let node_program ~output_dir f (x : J.deps_program) = | |||
let es6_program ~output_dir fmt f (x : J.deps_program) = | |||
let cxt = | |||
Js_dump_import_export.imports Ext_pp_scope.empty f | |||
(Ext_list.map x.modules (fun x -> | |||
( x.id, | |||
(* dynamic import should not print in import statement *) |
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.
not be emitted in require statements
jscomp/core/lam_analysis.ml
Outdated
@@ -32,7 +32,7 @@ let not_zero_constant (x : Lam_constant.t) = | |||
let rec no_side_effects (lam : Lam.t) : bool = | |||
match lam with | |||
| Lvar _ | Lconst _ | Lfunction _ -> true | |||
| Lglobal_module _ -> true | |||
| Lglobal_module (_, dynamic_import) -> not dynamic_import |
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.
What is the impact of this change in practice?
Do we have tests that show what would happen with and without this change?
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.
Good catch. Now that I look at it again, Lglobal_module always being no side effect might have a different context. I'll do some testing.
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 just found there are already side_effect.res
and side_effect_free.res
in tests. I've changed my tests to import_side_effect.res
and import_side_effect_free.res
. I confirmed that the compiler correctly detects side effects when dynamically importing a value with no side effects. So, it seems that the original Lglobal_module expression without side effects is indeed correct in the existing code.
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.
See b5d8366
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.
The comment is indeed correct. https://github.com/rescript-lang/rescript-compiler/blob/master/jscomp/core/lam_analysis.ml#L35-L38
jscomp/test/import_unnecessary.res
Outdated
@@ -0,0 +1,5 @@ | |||
// Import_lazy_component is not a pure module | |||
// It is supposed not to be required by dynamic import | |||
let a = Js.import(Import_lazy_component.a) |
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.
What is tested in this example?
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.
// import_lazy_component.res
let a = Belt.Array.map([1], x => x)
import_lazy_component.res
has side effect. So, import_unnecessary.res
module's JS output also had unnecessary require("./import_lazy_component.js");
before this PR changes. See the test output before this PR changes affect: dface2b
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.
Looks like it's ready to go? When the changelog is updated.
jscomp/core/lam_convert.ml
Outdated
@@ -505,9 +505,13 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) : | |||
primitive %s" | |||
s | |||
in | |||
let args = Ext_list.map args convert_aux in | |||
let dynamic_import = match primitive with |
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 be simplified as primitive = Pimport
.
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.
Thanks! Done 3603852
45f2537
to
3603852
Compare
8cd19cf |
Fixes #6223
This PR fixes the issue of dynamic import modules being added to require or import statements. The main changes are as follows.
Lam.Lglobal_module
representation and printJ.module_id
definitionIf Lglobal_module has dynamic import=true, the module is considered to have side effects.Omit dynamic imported module from require, import statement #6232 (comment)