Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support windows paths on windows, both absolute and relative #108

Open
cspotcode opened this issue Apr 29, 2022 · 3 comments · May be fixed by #109
Open

Support windows paths on windows, both absolute and relative #108

cspotcode opened this issue Apr 29, 2022 · 3 comments · May be fixed by #109

Comments

@cspotcode
Copy link

Trying to get this working for cspotcode/node-source-map-support#38, and hitting issues where it cannot handle Windows paths on Windows.

When pulling sourcemaps from source files, I need to resolve their sourcemap URLs relative to the file's path. For example, I get C:\foo\bar.js as a path, I read the file contents and parse out the source-map comment, then use resolve-uri to resolve that source-map comment relative to the windows path.

require('resolve-uri')('foo.js.map', 'C:\\foo.js')
// Would also like to support
require('resolve-uri')('C:\\foo.js.map', 'C:\\foo.js')

// Currently, a naive replacement of \ with / also fails
require('@jridgewell/resolve-uri')('C:/foo.js.map', 'C:/foo.js')
// C:/C:/foo.js.map

Per the readme, I believe this should be supported. Is this something we can get working?

@jridgewell
Copy link
Owner

jridgewell commented Apr 29, 2022

I aim to resolve URLs, and URL-like paths (basically posix, foo/bar like you'd get out of a location.pathname). You could convert to an absolute beforehand:

function toUrl(str) {
  if (str.indexOf('\\') === -1) return str;

  str = str.replace(/\\/g, '/');
  if (/^[a-z]:/i.test(str)) str = 'file:///' + str;
  return str;
}

function toWindows(str) {
  if (str.startsWith('file:///')) str = str.slice('file:///'.length);
  return str.replace(/\//g, '\\');
}


const resolve = require('@jridgewell/resolve-uri');
const resolved = resolve(toUrl('c:\\foo.js.map'), toUrl('C:\\foo.js'));
console.log(toWindows(resolved));
// c:\foo.js.map

I could try adding helpers to the library to handle this.

@cspotcode
Copy link
Author

cspotcode commented Apr 29, 2022

The problem for this project is that the resolved output needs to match the format/style of the input. If the input is a windows path, the output should also be a windows path in that same style. For CommonJS modules on nodejs, this means backslashes, without file://.

When we rewrite a stack frame, the input we get may look like this:

Error
  at foo (D:\project\dist\path.js:1:1)

So we should mimic that style through the remapping:

Error
  at foo (D:\project\src\path.ts:1:1)

This is what you'd get from node if you really were natively executing path.ts as a CommonJS file, and it's also what you get from node's native --enable-sourcemaps flag.

@cspotcode
Copy link
Author

To achieve this, I've avoided using resolve-uri when the base is an absolute path and the URL is neither a protocol-relative nor absolute URL. In these cases I use path.resolve(path.dirname())

To do this, I copied isAbsoluteUrl and isSchemeRelativeUrl into my code since they're not exposed by resolve-uri. Would be great to have that functionality exposed in some form.

@jridgewell jridgewell linked a pull request Apr 30, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants