Skip to content

JSC_CANNOT_CONVERT even with NO_TRANSPILE #3712

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

Closed
ctjlewis opened this issue Oct 30, 2020 · 3 comments
Closed

JSC_CANNOT_CONVERT even with NO_TRANSPILE #3712

ctjlewis opened this issue Oct 30, 2020 · 3 comments
Assignees

Comments

@ctjlewis
Copy link
Contributor

ctjlewis commented Oct 30, 2020

Related to #3707, #3708.

With the following flags, we should never see errors about ES6 or unsupported features:

-O SIMPLE
--language_in ES_NEXT
--language_out NO_TRANSPILE

Yet this does not hold for JSC_CANNOT_CONVERT error, especially as it relates to import.meta. Cannot coerce the compiler to produce output of any kind, sadly. Exits with:

ERROR - [JSC_CANNOT_CONVERT] This code cannot be converted from ES6. import.meta
@ctjlewis ctjlewis changed the title JSC_CANNOT_CONVERT even with --language_out NO_TRANSPILE JSC_CANNOT_CONVERT even with NO_TRANSPILE Oct 30, 2020
@brad4d
Copy link
Contributor

brad4d commented Nov 3, 2020

The output from closure-compiler isn't an ES module. It's a script. As such, import.meta doesn't make sense there.
If we passed it through unchanged, then it would be a syntax error.

If we transpile it, what should we put in it? It's supposed to be populated by the JS engine.
AFAIK, the only content you can really expect is the url field populated by browsers.
(Maybe there's other stuff for Node.js?) Regardless, the compiler doesn't know what should go in it. e.g. It can't know what URL was used to load the script.

What's more, the context is all wrong.

When you're authoring a JS module and refer to import.meta, you expect it to have information related to the JS module you're writing as it was loaded at runtime. But if you've compiled your JS modules with closure-compiler, the module you're writing doesn't even exist at runtime. It's just part of one big script with renaming done to keep the global variables distinct.

Suppose, for the sake of argument, that we just allowed import.meta to pass through unmolested into the compiler's output and then you could avoid it being a syntax error by loading the compiled output with <script type="module">. This this still wouldn't give you what you want. All references to import.meta in the compiled output would end up being the import.meta data for the entire output from the compiler treated as a module.

We decided that it was much better to be up-front with our users and refuse to compile code containing import.meta, so they would not trip over these many land mines.

@brad4d brad4d closed this as completed Nov 3, 2020
@ctjlewis
Copy link
Contributor Author

ctjlewis commented Nov 3, 2020

All references to import.meta in the compiled output would end up being the import.meta data for the entire output from the compiler treated as a module.

Surprising though it may seem, this is what I want. I am wanting some way to tell the compiler to trust me, that I know what I'm doing, and leave import.meta in.

In the case where all modules are being compiled to one output module, any references to "this file location" (via import.meta) in the input modules would need to refer to the import.meta of the output file since the output is what is imported.

If I have a.js, b.js, and c.js which depends on the first two, and I'm compiling to out.js, if I wanted to import out.js as an ES module, I need all previous import.metas to refer to out.js as "this file", since that will be the new location of the module source that is actually being imported. This should not be default behavior for sure, but I'm struggling to get the compiler to just leave it alone.

For context, the specific use case I am using for this is compiling an ES module to an ES module, using -O SIMPLE for basic DCE, and the only way to get a reference to the file location with an ES module is using import.meta (i.e., I need it in the output). I can hack around this by using Babel to replace all import.metas with some @external __IMPORT_META__, compile, and then rewrite -- but that's working against the compiler rather than with it.

Totally understand why this approach was taken, just explaining my use case and why I raised this issue.

@AshleyScirra
Copy link

I just stumbled across this while using the new dynamic imports support in Closure Compiler, and we need import.meta pass-through support too. Our code already understands the difference between pre-closure and post-closure transforms, so we know that import.meta.url changes after build and we already handle that. In fact we are migrating from document.currentScript.src to import.meta.url. Closure handles document.currentScript just fine even though it is the same potential footgun, but the lack of support for import.meta blocks migration to modules for code that formerly used document.currentScript. I see this issue is already closed - is there somewhere else I could file a feature request for this?

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

No branches or pull requests

3 participants