4

I'm working with a javascript system built (I think?) on ES6 compatible javascript that's compiled/transpiled down to browser compatible javascript (Wordpress Calypo, if it matters)

Does modern javascript have a way to reflect into the calling context? Put another way, if I have a javascript module foo

#File: foo/index.js
//...lots of code...
export default () => {
    //...more code...
}

Is there a way to tell, at runtime, which other javascript module and/or file has imported my "foo" module? If this isn't possible, is there a common way to do this with static analysis. If my question doesn't make any sense because I'm made an incorrect assumption (the most likely scenario) , I'd love that assumption corrected.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Alana Storm
  • 164,128
  • 91
  • 395
  • 599
  • I believe in runtime there is no such thing as "module" or "file" existing. – zerkms Aug 29 '16 at 23:54
  • 1
    This is totally impossible because one module can be imported in multiple other modules which might be loaded at arbitrary times. – Bergi Aug 30 '16 at 02:45
  • Sounds a bit like an X / Y problem - can you describe in some more detail what you're trying to do? There may be another way to go about it. – Sean Vieira Aug 30 '16 at 02:51
  • 1
    Thanks for your attention @SeanVieira -- I'm not trying to accomplish any particular task — or put another way, my task is literally to determine if ES6 has a specific reflection feature that's common in other languages, and if it does not determine what sort of reflection features it does have, or how I can use non-standard in browser reflection features to determine something. – Alana Storm Aug 30 '16 at 02:58
  • @AlanStorm: FWIW, that's not a feature common in other languages. It may exist in one or two languages but that's not common. Static analysis is common but doing I personally don't know any language that can do this at runtime. – slebetman Aug 30 '16 at 03:30
  • @siebetman I suspect we're talking about different things -- but grabbing a stack-trace and inferring code/class/module loading exists in a lot of languages/runtimes (I suspect where we differ is a "what exists at the language level" and "what exists at the runtime level") – Alana Storm Aug 30 '16 at 15:13

1 Answers1

4

tl;dr: No and no.

There's no way for a particular chunk of ES6 Javascript to determine how it was loaded. About the best you can do is have the loading Javascript tell the loaded Javascript how the loader went about it.

Static analysis can't actually tell you 100% of the time if a particular bit of code will run and therefore can't tell you 100% of the time if a particular file will be loaded. (This is related to the halting problem.) That said, 100% detection is rarely necessary given that file requests are rarely obscured to the degree necessary to hide them. However, I don't know that there is a static analysis tool capable of unwinding the more complex versions of common Javascript loading techniques as usually the code creators already know the circumstances under which they made the code in question load.

Ouroborus
  • 16,237
  • 4
  • 39
  • 62
  • Thank you! If this is transpiled/compiled down to browser javascript, are there ES 5 or below constructs that would be able reflect into this? Browser specific things to read into a callstack and interpret to reverse engineer the importing module? – Alana Storm Aug 30 '16 at 00:11
  • @AlanStorm About the best you get is `argument.callee` in ES5 (but not in `strict` mode). Though you might be able to do something with stack traces. Theoretically you could throw/catch an exception and then programmatically delve into the calls that are listed in it. – Ouroborus Aug 30 '16 at 00:12
  • @zerkms I don't see a means by which the imported module can detect how/where it was imported via `import`. The imported module may possibly be able to detect that it was imported versus loaded, but I don't think it can get further than that. In any case, it's possible to build an `eval` that imports a module in such a way as to obscure from static analysis whether or not the import actually happens (either in a reasonable time or at all). – Ouroborus Aug 30 '16 at 00:21
  • If the file was "read + eval'd" then it's not `import`ed, by definition. My point was more about exactly `export` and `import`, that are statically analysable (and that was the initial idea) – zerkms Aug 30 '16 at 00:31
  • @zerkms I believe it's possible to perform an `import` from within an `eval`. Since `eval`s are performed on strings which can contain further `eval`s, it would be possible to obscure things such that determining whether or not the `import` happens (or even exists) would be beyond the grasp of static analysis. – Ouroborus Aug 30 '16 at 00:37
  • I don't see how `eval` is relevant to the question, but whatever. – zerkms Aug 30 '16 at 00:54
  • 1
    Are you confusing P-vs-NP with the halting problem? I can't see how the former is relevant for static analysis. – Bergi Aug 30 '16 at 02:46
  • @Bergi Indeed I am. Fixed. – Ouroborus Aug 30 '16 at 14:12
  • Thanks all. FWIW I'm working around the lack of reflection by peeking at the stack of an error in the exported methods/functions (http://stackoverflow.com/a/31921381/4668) and inferring things from the compiled ES5 code. – Alana Storm Aug 30 '16 at 15:12