When doing web development, we use relative URIs from time to time so that modular components can be created and the site can be more easily deployed. However, using relative URIs in HTML, CSS and JavaScript has different rules in different scenarios.

HTML

Using relative URIs in HTML is easy, everything relative is relative to the HTML page.

For example,

  • <link href="...">
  • <a href="..."></a>
  • <script src="..."></script>
  • <img src="...">
  • and so on…

CSS

Using relative URIs in CSS is easy as well.

For CSS style sheets, it's relative to the style sheet itself, not relative to the styled source document.

For style sheets embedded within a document, it's relative to the containing document.

Reference: 3.4.1. Relative URLs

Web Workers

The Worker() constructor

When spawning a web worker, Worker() constructor is called, with the only parameter passed to it representing the URL of the worker script.

The URL parameter passed to Worker() constructor is relative to the containing HTML page, rather than the containing JavaScript code.

Assuming we have the following file structure:

project
├── index.html
├── js
│   ├── main.js
│   └── workers
│       ├── worker.js
│       └── worker-helpers.js
└── lib
    └── lib-a.js

And main.js is referenced as a <script> element in index.html, if we are going to spawn a worker with worker.js as its script, we need to write new Worker('js/workers/worker.js'); rather than new Worker('workers/worker.js').

If you're using RequireJS and want the worker URL to be relative to the containing JavaScript file, you can use require.toUrl(). For example,

new Worker(require.toUrl('workers/worker.js'));
// or
new Worker(require.toUrl('./workers/worker.js'));
// or
new Worker(require.toUrl('../js/workers/worker.js'));

The importScripts() method

importScripts() is a method of WorkerGlobalScope interface for synchronously imports one or more scripts into the worker's scope. It accepts a comma-separated list of URLs of the scripts to be imported.

The URL parameters for importScripts() is relative to the address of the calling worker.

Assuming the same file structure mentioned above, if a worker needs to import lib-a.js and worker-helpers.js, we need to write:

importScripts('../../lib/lib-a.js', 'worker-helpers.js');

Source Mapping

The transformerd source file

In files with source mapping, usually on the last line, there is a link to the map file, for example:

//# sourceMappingURL=main.js.map

The sourceMappingURL is relative to the containing script.

The map file

In a map file (in JSON format),

  • The file property points to the transformerd source file, which has a sourceMappingURL line pointing to this file.

    This property is relative to the map file itself.

  • The sourceRoot property points to the root folder containing source files.

    Its relativity is browser dependent, so better to use an absolute URL like http://localhost:8080/a/b/c for easier cross-browser debugging, or use a URL beginning with ...

    • In form: ../a/b/c:

      Works across all browsers. Relative to the map file itself.

    • In form: a/b/c or ./a/b/c:

      Chrome, IE, Edge, Safari, Firefox (Nightly / Developer Edition) >= 52:
      Relative to the map file itself.
      Firefox:
      Relative to the HTML page.
    • In form: /a/b/c:

      Chrome, Firefox, IE, Edge, Safari:
      Relative to location.host.
      Firefox (Nightly / Developer Edition):
      Relative to the map file itself.
    • In form: //localhost:8080/a/b/c:

      Chrome, Firefox, Safari:
      Relative to the specified host using location.protocol.
      IE, Edge:
      Relative to location.host, with the specified host treated as a dir name.
      Firefox (Nightly / Developer Edition):
      Relative to the map file itself, with the specified host treated as a dir name.
  • The sources property contains all original source files which is mapped to the transformerd source files by the map file.

    This properte is relative to the sourceRoot property.

Update (): If you have difficulties to make source mapping work, try using Firefox, as it logs source map related errors. See Source map errors - Firefox Developer Tools | MDN.

The original source file

The original source file does not need to contain any informamtion about source mapping.

More Reading