Skip to content
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

JsChecker: support extensionless ES6 imports #409

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

robfig
Copy link
Contributor

@robfig robfig commented Aug 15, 2019

I want to use extensionless ES6 imports, e.g.

import { foo } from '/path/to/file';

where the module is defined in //path/to/file.js

That seems to work with closure_js_binary without issue, but JsChecker complains. Copying 3 lines from NodeModuleResolver causes the right thing to happen.

If @jart could shed any light on what she had in mind for "Unify path resolution with ModuleLoader", that might be a more robust solution, but this seems to work acceptably.

@Yannic
Copy link
Contributor

Yannic commented Sep 7, 2019

Can we add a test for this?

@robfig
Copy link
Contributor Author

robfig commented Sep 11, 2019

Test added, but that reminded me of a lingering problem -- moduleLoad error always fires spuriously. Since moduleLoad seems to be redundant to strictDependencies, I suppressed it unconditionally. But probably for the real rules it should be made to work...

@robfig
Copy link
Contributor Author

robfig commented Sep 11, 2019

Hm, I see similar moduleLoad suppressions in the ES6 tests in closure/compiler/test/strict_dependency_checking/BUILD, so that makes me think that it never worked.

Perhaps the rules should just always suppress moduleLoad?

@Yannic
Copy link
Contributor

Yannic commented Oct 18, 2019

Sorry for the delay!

Yeah, the moduleLoad seems to be an existing issue in rules_closure. I'm a bit hesitant to add suppresses by default, so we should fix the root cause instead. Can you create an issue for that?

Regarding this PR, I'm deferring to @alexeagle et al. to decide whether that's something rules_closure should do or not.

@robfig
Copy link
Contributor Author

robfig commented Oct 21, 2019

Opened an issue for the moduleLoad problem

I'm not sure I understand your other comment -- perhaps rules_closure should not support extensionless imports, or perhaps the fix instead belongs somewhere else?

Thanks for taking a look

@robfig
Copy link
Contributor Author

robfig commented Dec 5, 2019

@alexeagle any thoughts on getting this in? It seems pretty small / unobjectionable to me.

@Yannic
Copy link
Contributor

Yannic commented Dec 11, 2019

Sorry for taking so long to come back to this!

The longer I think about this, the more opposed I get to allow this. I can't cite the relevant spec right now, but, IIRC, ES6 module imports are supposed to be paths to existing files (which is not true for extensionless imports). IMHO, this should be fixed in the tools producing this broken code.

OTOH, I also understand that extensionless imports aren't that uncommon. WDYT about allowing it only behind a flag --@io_bazel_rules_closure//closure:allow_extensionless_imports.

@robfig
Copy link
Contributor Author

robfig commented Dec 12, 2019

Extensionless imports are explicitly supported by Closure Compiler in NODE resolution mode, which is where I got the idea originally:
https://github.com/google/closure-compiler/wiki/JS-Modules#node-resolution-mode

I don't know the history or context behind them, but after pretty much investigation, this is by far the cleanest way I've found to enable VSCode and other IDEs to understand imports and enable showing info on hover or the ability to click into imported files, for JSX. Since this is supporting a Compiler feature, required for reasonable interop, and I don't really see a downside, I would advocate for not requiring a flag.

We can set the flag in our .bazelrc or something if necessary, of course.

@Yannic
Copy link
Contributor

Yannic commented Dec 12, 2019

Doesn't node resolution mode also allow importing folders (IIRC by loading index.js if it exists), making import statements potentially ambiguous, thus breaking incremental type-checking?

Let's say we have the following workspace:

/
  lib/
    BUILD
    foo.js
    bar.js
    BUILD
    foo/index.js
    foo/baz.js
  app/
    BUILD
    main.js

We declare one closure_js_library target per .js file, //lib:bar depends on //lib:foo, //libs/foo:baz depends on //lib/foo:index, and //app:main depends on //lib:bar and //lib/foo:baz.

  • lib/bar.js imports lib/foo.js as /lib/foo (allowed by resolution-mode node) -> Typecheks fine with this PR.
  • lib/foo/baz.js imports lib/foo/index.js as /lib/foo (allowed by resolution-mode node) -> Typecheks fine if we implement all of resolution-mode node.
  • app/main.js imports lib/bar.js and lib/foo/baz.js with their full import path. However, since we have a (transitive) dependency on lib/foo.js and lib/foo/index.js, both as /lib/foo, one will get precedence over the other (IIUC, it should be lib/foo.js) and the compilation of main.js breaks even though library-level checks were fine.

@robfig
Copy link
Contributor Author

robfig commented Mar 30, 2020

Sorry, I missed your last response.

Relevant link:
https://nodejs.org/api/modules.html#modules_all_together

I agree that your scenario is possible in theory, but it's not possible in practice because the LOAD_AS_DIRECTORY algorithm requires a package.json file, so I don't believe it's possible to trigger that case using rules_closure. Regardless, JsChecker already catches a fraction of the errors, and I think that an additional unusual case which it doesn't catch would not substantially change the developer experience.

I suggest that JsChecker supports "LOAD_AS_FILE" but not "LOAD_AS_DIRECTORY".

@gkdn
Copy link
Collaborator

gkdn commented Aug 6, 2022

There hasn't been any activity in this PR for very long time.
Please let me know if there are any intentions to pursue this change. Otherwise I will close it.
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants