3

How to resolve relative path to absolute url in ES6 module (in browser)?

For example :

base-url.com/
    |-resolve
    |   |-resolveUrl.js
    |-dir
        |-dir1
            |-module1.js
        |-dir2
            |-module2.js

module1.js

import resolveUrl from "../../../resolve/resolveUrl.js"
resolveUrl("../dir2/module2.js") // return 'base-url.com/dir/dir2/module2.js'

What would be the resolveUrl implementation?

base-url.com/ may not be the web-site's domain. It can be a repo where only sources are stored.

Yairopro
  • 9,084
  • 6
  • 44
  • 51
  • Is the intention to run this code in a browser or NodeJS environment? – bsinky Feb 07 '18 at 22:29
  • @bsinky In a browser. =) – Yairopro Feb 07 '18 at 22:33
  • @PatrickRoberts Quotes? ...? – Yairopro Feb 07 '18 at 23:26
  • @jfriend00 that's not a duplicate, your link assumes there is an explicit reference to an absolute path to start from, that is not the case here. – Patrick Roberts Feb 07 '18 at 23:30
  • @PatrickRoberts - In a browser, the absolute reference is the path of the page. There is no file access from Javascript so if you're really asking about browser, you must be talking about relative URLs, right? If not, then please clarify your question. And, for URLs in a browser, look at the 2nd answer and the `URL()` object. The question, btw, seems identical to yours. You may be reacting to the accepted answer which asks you to pass a base path (which was not part of the question), but there are other answers that don't require you to pass a base path. Looks like a pure dup to me. – jfriend00 Feb 07 '18 at 23:32
  • @jfriend00 this question is about resolving a URL relative to the path of the experimental module that calls the function. I suspect there might be a solution involving `document.currentScript.src`, though I cannot confirm this as I don't have an easy way to test. But it's definitely not a duplicate. – Patrick Roberts Feb 07 '18 at 23:35
  • 1
    @PatrickRoberts - The question sure isn't very clear to me in that regard. Anyway, I reopened. – jfriend00 Feb 07 '18 at 23:37
  • @Yairopro I tried to make a test but I can't because of CORS. I think a more promising approach involves a hack creating an error object within `ResolveUrl()` and inspecting its `stack` property for a reference to the base URL of the calling module. I hope that helps. – Patrick Roberts Feb 07 '18 at 23:53
  • I also found [this](https://www.npmjs.com/package/error-polyfill) which might make this approach more robust by using `Error.captureStackTrace()`. – Patrick Roberts Feb 07 '18 at 23:58
  • @PatrickRoberts Thanks a lot for helping me keeping this question opened. Using `document.currentScript.src` doesn't help because when executing from module js files, `document.currentScript` is `undefined` (known from test). Furthermore I really like your approach user the call stack. Concerning the `error-polyfill` library, I didn't find any way to execute it in a browser. It says it's possible in the read-me, but I didn't manage to, since it uses `require` function.. – Yairopro Feb 08 '18 at 00:25
  • @Yairopro you need to transform it using something like webpack or browserify. It's very involved, but far from impossible. – Patrick Roberts Feb 08 '18 at 00:59
  • @PatrickRoberts solved. Thanks for your advice. I prefered to use [stacktrace.js](https://www.stacktracejs.com/) since it's [the recomended library from MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/Stack#See_also) – Yairopro Feb 08 '18 at 14:35

2 Answers2

1

You can now use to-absolute-url.

It uses stacktrace.js under the hoods to get the caller function's absolute path file:

Thanks to @PatrickRoberts for his idea to use stacktrace, and @jfriend00 for his tip to use URL object.

Yairopro
  • 9,084
  • 6
  • 44
  • 51
1

How about

const a = document.createElement('a')

function resolveUrl(path) {
  a.href = path
  return a.href // magic happens
}
troy
  • 387
  • 1
  • 9