Closed kitsonk closed 4 years ago
Is hardcoding okay? I'm not sure about the way to implement it.
@bartlomieju @nayeemrmn thoughts/opinions?
I don't know how hard it is, but if there was a way to supply it during the loader, and it would be up to the loader to supply the value? Like the whole of import.meta
, since it is specifically designed to be platform specific?
For the behaviour of deno bundle
, I think we want import.meta.url
to always be hardcoded, import.meta.main
to be preserved in the "entrypoint" module (the one whose exports are passed on) of the bundle, and hardcoded to false
in others.
I agree that swc should structure a way to call back to the loader for import.meta
references so the above is all implementable in Deno. It shouldn't itself handle any concrete import.meta.*
field since that's beyond tc39.
I think we want
import.meta.url
to always be hardcoded,import.meta.main
to be preserved in the "entrypoint" module (the one whose exports are passed on) of the bundle, and hardcoded to false in others.
Yes, we would be able to do that in Deno if at bundle time we had a way to supply their values.
(For clarification, though we can certainly talk about it over in Deno, import.meta.main
should be true for the "root" module when import.meta.main
is true for the bundled module at runtime, otherwise it should be false
and always false
for all other modules. And with import.meta.url
, for remote modules, we can hard code it, but for local modules, we will want to change the value to something that does not leak local system information, so we would want to find the common root for all local files and change it to something like bundle:///a/b/mod.ts
)
I'm not really sure how we could handle import.meta
in bundles - IIRC they will be plain, old scripts and import.meta
is only set for modules. And even then there's only a single file, so the import.meta
object provided by the runtime couldn't differentiate between different parts of bundle.
@bartlomieju Do you mean it should be handled at compile (bundle) time?
For the behaviour of
deno bundle
, I think we wantimport.meta.url
to always be hardcoded,import.meta.main
to be preserved in the "entrypoint" module (the one whose exports are passed on) of the bundle, and hardcoded tofalse
in others.I agree that swc should structure a way to call back to the loader for
import.meta
references so the above is all implementable in Deno. It shouldn't itself handle any concreteimport.meta.*
field since that's beyond tc39.
I was thinking for a while to make the api clean. I have some questions.
I'm considering creating each api for each meta property. This is mainly because ecmascript spec may add some meta properties, and information required to handle them may differ. How do you think about this?
Also, which information is required to import.meta.url
? Only swc_common::FileName
?
Finally, is it okay for bundler to handle import.meta.main
without hook?
Do you mean it should be handled at compile (bundle) time?
What I'm saying is that it's most likely not possible to handle import.meta
during runtime for bundles, because V8's callback for import.meta
is only invoked in modules. Even if it is possible there would be only a single callback since SWC outputs a single bundle file.
Also, which information is required to import.meta.url? Only swc_common::FileName?
Correct, in Deno we might want to do some mangling for local URLs as pointed by https://github.com/swc-project/swc/issues/1115#issuecomment-700420312.
Finally, is it okay for bundler to handle import.meta.main without hook?
So it would be handled by SWC itself without need for intervention from the runtime?
@bartlomieju
So it would be handled by SWC itself without need for intervention from the runtime?
Yes. I think it makes sense, and more importantly, import.meta.main
cannot be implemented by runtime if it's bundled. It's a kind of information stripped out by a bundler (just like compiler's job).
I'm not really sure how we could handle
import.meta
in bundles - IIRC they will be plain, old scripts andimport.meta
is only set for modules.
@bartlomieju Right now our bundles are valid ES modules which re-export the symbols exported in the entrypoint module. Are you saying we will no longer have that?
And even then there's only a single file, so the
import.meta
object provided by the runtime couldn't differentiate between different parts of bundle.
I specified the behaviour above. In most cases it would be hardcoded, in other cases it would preserved literally as import.meta
(this is what we mean by letting the behaviour change at runtime).
Right now our bundles are valid ES modules which re-export the symbols exported in the entrypoint module. Are you saying we will no longer have that?
The entry modules symbols will be re-exported.
I'm considering creating each api for each meta property. This is mainly because ecmascript spec may add some meta properties, and information required to handle them may differ.
I think having either an API for any access to import.meta
or dealing with each individually would be fine, as long as it is determinable what property needs a value for. Thinking more about it, I would expect we would want the Deno behaviour to be something like this:
import.meta.url
to be replaced with a static string value, which would be determined by the source module.import.meta.main
we would want to have some runtime code, if the module was not an entry point module, we would always replace it with false
. If it were the entry point module, we would want to replace it with something like this:
import?.meta?.main ?? false
This would ensure that if it were run under Deno, and was the main module, its value would reflect the correct runtime value, but would not be true when running in other places.
@bartlomieju Right now our bundles are valid ES modules which re-export the symbols exported in the entrypoint module. Are you saying we will no longer have that?
I think I misunderstood something in discussion with @kdy1, bundles should be ES modules after all.
I think having either an API for any access to import.meta or dealing with each individually would be fine, as long as it is determinable what property needs a value for. Thinking more about it, I would expect we would want the Deno behaviour to be something like this:
Can import.meta
be shimmed in user code? If not we'd have to add special handling for those bundles in deno_core
which seems undesirable.
Will deno support runtime detection of import.meta.main
?
Adn even if it will be supported, I think it's ok to compile it as false
on imported modules, correct?
If it were the entry point module, we would want to replace it with something like this:
import?.meta?.main ?? false
This would ensure that if it were run under Deno, and was the main module, its value would reflect the correct runtime value, but would not be true when running in other places.
@kitsonk The current idea behind import.meta.main
is that it resolves to undefined in browsers which will normally just work as false. It's already compatible in that way. We can just preserve it as import.meta.main
for the entrypoint module.
Only whole import.meta
references can be statically analysed correctly (import.meta["url"]
). Substituting it with a host-provided object would be proper. This means we can't vary the "hardcode vs preserve" for individual properties...
Here's how we would have to do it -- always hardcode import.meta
by a host-provided object:
import.meta
-> ({ url: "<source module>": main: false })
.import.meta
-> ({ url: "<source module>": main: import.meta.main })
.That would work perfectly.
Is this released yet?
I am getting this error:
error: Expected (, got .
--> index.js:68:33
|
68 | const url = new URL(import.meta.url);
| ^
I am using these versions:
"devDependencies": {
"@swc/cli": "^0.1.27",
"@swc/core": "^1.2.37"
}
This is my config:
{
"env": {
"targets": {
"chrome": "79"
},
"mode": "entry",
"coreJs": 3
},
"jsc": {
"parser": {
"syntax": "ecmascript",
"dynamicImport": true
}
}
}
@TomasHubelbauer
You should set jsc.parser.importMeta
to true like
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"importMeta": true
}
}
}
Thanks, I missed that there was a flag for this. It works now!
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.
Describe the bug
swc_bundler does not appear to handle
import.meta
well.Input code
example7.ts
f.ts
Expected behavior
I am not actually sure what is possible here, but it is something that we struggled with in Deno with the existing bundling, how to deal with these things. The down-emit to SystemJS did allow is to support setting these and our "loader" could provide them.
When you do
deno run example7.ts
at the moment you get:But bundling outputs:
Which results in this:
Version
Version: swc_bundler 0.8.1 (#1005 branch)
Additional context
Working to integrate swc_bundler into Deno.