Repository navigation
Feature: NodeJS contextual pathing use cases #121
Description
Activity
What are the alternatives?
We could either accept
import.meta.urlto those APIs (which was mostly rejected from core APIs IIRC?) or expose another/more meta properties which would break compatibility with the web.Another thing to consider is exposing a helper function for the conversion.
For reference re the rejections of getting file:// URL string support in Node core directly to support eg
fs.readFile(import.meta.url)- nodejs/node#20944, nodejs/node#20950 were both blocked by security concerns.@benjamingr I don't believe locking
import.metadown to only APIs available in the browser is set in stone. In the pastimport.metahas been brought up as a possible place for other Node specific APIs. And talk was that as long as a path of interop between Node and browser (however narrow or not) existed then Node specific things would be OK.Reacted by Jordan HarbandCould we perhaps only allow URLs that include a particular symbol on the proto? We can then auto add that to import.meta.url... likely reduces the security concern since it is opt in
I think it would be good to try and explore carefully how __filename and __dirname are used in web-workflows so we can consider exactly what the universal use cases are here.
If anyone knows of good examples of libraries using __filename and __dirname on that web that would be a huge help.
As far as I recall, both __filename and __dirname are built into absolute URLs in the standard browserify workflow to support things like
fetch(path.resolve(__dirname, 'resource'))but will have to double-check this again.I don't believe locking import.meta down to only APIs available in the browser is set in stone.
Oh definitely. I was under the impression
import.meta.urlaims to do one of those "non Node specific API"s that work across the browser and Node.I'm personally fine with things like
import.meta.requirefor interop.Could we perhaps only allow URLs that include a particular symbol on the proto? We can then auto add that to import.meta.url... likely reduces the security concern since it is opt in
This is an interesting idea, we'd have to very carefully check that it doesn't violate user expectations though since
new Worker(import.meta.url)would work butnew Worker(import.meta.url + '')won't.Is there any reason why
import.meta.urlcan't be an actual URL by the way?On the web,
import.meta.urlis definitely being defined as a string, so that really does mean we have to stick with that in Node if we want to align with the browser.On the web, import.meta.url is definitely being defined as a string,
I realize that this is the situation - but wouldn't making it a URL make our lives much easier?
I recall @iarna and @isaacs making a compelling argument
file://urls inside - would allowing passing aURLimport.meta.url help at all with those concerns?Do we have a comparison for the cases that are outside of what the
fscompatibility for URLs supports?Right now you can do some things like:
import fs from 'fs'; const files = fs.readdirSync(new URL('./', import.meta.url)); console.log(files);
Which don't actually require getting a raw path. I suspect most of the time this will affect child processes, but think that allowing
child_processmethods to take URLs (not url strings) might alleviate that as well. It would not solve the argv of child processes though, but we could also provide a genericfileURL -> stringutility method somewhere that would solve any time people need to do this conversion manually.I think it would be good to try and explore carefully how __filename and __dirname are used in web-workflows so we can consider exactly what the universal use cases are here.
As far as I recall, both __filename and __dirname are built into absolute URLs in the standard browserify workflow to support things likefetch(path.resolve(__dirname, 'resource'))but will have to double-check this again.the only way to really make
__dirnameand__filenameuseful with browserify is by adding a transform like brfs that can handle things likefs.readFile(path.join(__dirname, 'resource'))at compile time. browserify itself replaces__dirnameand__filenamewith the absolute file paths on disk, so you can't use them to fetch() things. I'm not aware of any web libraries using those variables, except for ones that require brfs.Maybe this is a little late, but
import.metais an object, ifimport.metadoes not throw, thenimport.meta.filenamewill simply be undefined in browsers, ie do what browser people do.Is there a problem with including the
filenameanddirnamein the InitializeImportMeta context for the implementer to decide if they want to throw them in?At the same time, I think a very good performance metric to introduce would be the time spent in the
URL.constructorvs. the number of calls toimport.meta.url, we don't even need to worry about filtering constructor calls because statisticallynew URLin node is negligible imho.I wonder if as cross env solution this would work too:
const { pathname, filename = decodeURI(pathname.replace(/^\/([^:/]+:\/)/, '$1')), dirname = filename.replace(/\/[^/]*$/, '') } = new URL(import.meta.url);
There are a number of workflows in NodeJS today that use
__filenameand__dirnameto handle contextual paths relative to the current module itself.Currently we are looking at exposing a
import.meta.urlwhich will be a file URL of the current module.To use this contextual URL in NodeJS APIs requires a rather unwieldy conversion process along the lines of:
It would be great if we could allow a much more polished workflow here for users.