2

I have a JS web component that needs to load in other resources (specifically a src for an iframe it adds to the DOM, but this would be a problem for any resource with a relative path).

This resource needs to be specified relative to the calling page, which I can get easily enough from window.location.

However, the file that it needs to point the src at is relative to the JS file that's executing, and as that's a component I can't be sure where it will be.

So:

example.com/index.html 
  |__> {unknown path}/web-component.js
  |__> {unknown path}/resource.html <-- I want to get this

That component might be in node_modules or bower_components or webpackOutput or wherever, but the DOM it creates needs to point to the same location that it has been served from, not the page that's executing it.

As this code is in a web component document.currentScript is null and document.getElementsByTagName('script') might not include the component.

Keith
  • 150,284
  • 78
  • 298
  • 434
  • This answer may help: https://stackoverflow.com/questions/3133243/how-do-i-get-the-path-to-the-current-script-with-node-js – admcfajn Nov 22 '17 at 15:09
  • @admcfajn Cheers, but that applies to node.js, I'm in a web environment. I could use node.js server side to edit the file to have a hard-coded path, but that's really a last resort. – Keith Nov 22 '17 at 15:10
  • Yeah, I don't think there's a one-size-fits-all for this situation. Great idea below. This one might also help: https://stackoverflow.com/questions/39410541/how-to-get-original-file-path-in-the-script-with-webpack you're in a web-environment, but you're precompiling with node, correct? – admcfajn Nov 22 '17 at 22:01
  • @admcfajn not myself - this project is a web component, I'm using TS, but I want the output to be usable without a complex build chain (source: https://github.com/EvolutionJobs/html-editor/blob/master/html-editor.ts) – Keith Nov 22 '17 at 22:44

1 Answers1

0

I have a potential solution, but it has both potential browser compatibility and performance issues.

The idea is new Error().stack includes the path to the file executing.

So...

// Get stack string
const stack = new Error().stack.split('at');

// Get the last entry
const scriptPath = stack[stack.length - 1].trim();

// The component will share the path up to the last slash
const componentPath = scriptPath.substring(0, scriptPath.lastIndexOf('/'));

It relies on the format of the stack, the contents of the stack, and new Error() not causing any performance issues as it loads, so answers with a better method are welcome!

Keith
  • 150,284
  • 78
  • 298
  • 434