(Note: you probably shouldn't use this in the real world, but it is totally valid and does exactly what you want.)
Here's an implementation of your print.js
:
function print_things(msg) {
console.log(msg)
}
if(0)typeof await/2//2; export default print_things
<script type=module>
// (renamed to avoid name collision)
import print_things2 from "https://12Me21.github.io/external/print.js"
print_things2("Javascript innovation")
</script>
<script src="https://12Me21.github.io/external/print.js"></script>
<script>
print_things("Hmmmmmmm.")
</script>
This syntax will "hide" the export statement from non-module scripts, because
await/2//2; ...
is parsed differently depending on context:
- In a module or async function:
await
(operator) /2/
(regexp) /
(divide) 2
(number)
- In a normal script:
await
(variable) /
(divide) 2
(number) //2 ...
(comment)
When it's parsed as a comment, the rest of the line is ignored. So, the export
statement is only visible to module scripts.
Here is the relevant part of the specification:
15.8 Async Function Definitions > Syntax > AwaitExpression > Note 1
Compatibility
As a non-module script, it should work in any browser (even ancient versions of Internet Explorer etc.), and is still valid with "use strict"
enabled
However, loading it as a module requires support for "top-level await", which was added a few years after modules themselves (~2021 vs ~2018), so keep that in mind.
(It also works with nodejs, in either mode)
I've used this trick in a library that I wrote, and it's been working fine in multiple environments for several months.
However, it has caused some problems with external tools (frameworks, compilers, minifiers, etc.)
import
in ypur code, but output it without – Safarprint_things
instead ofwindow.print
? – Keitt