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

import with absolute path? #203

Closed
alinnert opened this Issue Jun 7, 2018 · 70 comments

Comments

@alinnert
Copy link

commented Jun 7, 2018

Okay, this project looks really interesting so far. While watching the talk I just noticed one thing that might be a problem for some developers. That's just allowing imports with relative path's (besides URLs). There are a lot of questions on the internet on how one can import a file in TS/Webpack/whatever relative to the project root. With relative paths people will end up with things like import { foo } from '../../../../modules/featureA/foo.ts'. Or was it just ../../../modules/...? What if I move my files around? Yes, you have to update your imports anyway. But figuring out how many directories you have to go up is a very tedious task on its own.

In the talk, you/Ryan talked about browser compatibility. I haven't tried out ES modules in the browser just yet. But I'm pretty sure it also supports absolute paths. Absolute in that context means relative to the web root. It would be really handy if we were able to just write import { foo } from '/modules/featureA/foo.ts'.

Of course, now there's the question: What is the root directory of a deno application? The only thing that makes sense to me right now is the folder that contains the entry file ‒ basically what process.cwd() is in node. But I also think it's fine to place the entry file in the most top-level directory of the project, isn't it?

Or is there any problem about absolute paths I didn't think about so far? What do you think about that?

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Jun 7, 2018

There are no absolute paths in a browser, those are called URLs which are supported. Absolute paths don't make sense in deno IMO because they would mean 100% non portable code, which makes no sense why you would generate that?

Paths are relative to the module, which means all the module needs to know is its own contained little world. Absolute paths invariably would leak local machine details and not be portable to things like a CI server, or anyone else's machine.

@nicolasparada

This comment has been minimized.

Copy link

commented Jun 7, 2018

Indeed, in the browser when you import something starting with / it is from the web root.
In my opinion, it makes sense for Deno to import from the project root.

Node imports from the OS root. Which makes the code non portable for browsers.

@nicolasparada

This comment has been minimized.

Copy link

commented Jun 7, 2018

Or have a --base flag like <base href> in the browser.

@alinnert

This comment has been minimized.

Copy link
Author

commented Jun 7, 2018

Exactly, I'm talking about <script src="index.js"> vs. <script src="/index.js">. Of course technically both is a relative path, but the starting point is different. I'm not talking about fs absolute path like /var/www/...

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Jun 7, 2018

Then what are the proposed semantics of defining the base?

@gillchristian

This comment has been minimized.

Copy link
Contributor

commented Jun 7, 2018

Then what are the proposed semantics of defining the base?

What about a flag?

deno --base=./some-path

EDIT: @nicolasparada I just realized you already said this

@nicolasparada

This comment has been minimized.

Copy link

commented Jun 7, 2018

Or don't. Just the project root.
But if you like the idea, I think it should only allow paths inside the current project for security reasons.

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Jun 7, 2018

Or don't. Just the project root.

What is the project root? There is no concept of a project with deno at the moment, and highly unlikely to be. I am still not sure what problem this would solve once you accept that even with a base all paths are relative.

@nicolasparada

This comment has been minimized.

Copy link

commented Jun 7, 2018

Now that you say it, you're right. I was confused with the browser and serving the content.
So in Deno one could do:

import { whatever } from '../../../some/os/path/file.js'

Right?

@alinnert

This comment has been minimized.

Copy link
Author

commented Jun 7, 2018

Just to write down an example:

Assume the entry file is located at (absolute path on an os level, just for clearification): /home/username/projects/my-project/main.ts

In that case the base would be /home/username/projects/my-project.

Writing import { someFunc } from '/modules/module-a.ts' would resolve to: /home/username/projects/my-project/modules/module-a.ts.

If the entry file was located at /var/www/project-a/main.ts, that line would resolve to: /var/www/project-a/modules/module-a.ts, which makes it basically portable for my understanding.

There is no concept of a project with deno at the moment, and highly unlikely to be.

Even if there's no "project" from a Deno perspective, there will always be one from another perspective. You will still check-in a project folder into version control e. g.

I am still not sure what problem this would solve once you accept that even with a base all paths are relative.

What problem does it solve? Here are some other sources that describe the problem:

In another article I just read the term "relative path hell" which describes it very well.

I understand that Deno won't support aliases as it looks right now, but my proposal is a possible workaround or alternative.


EDIT: okay, I've found a way to describe the problem in a short way:

With import { func } from '/folder/file.ts' you only have to know the location of the imported file.

With import { func } from '../folder/file.ts' you have to know the locations of both the imported file and the importing file.

Hope that makes it more clear.

@nicolasparada

This comment has been minimized.

Copy link

commented Jun 7, 2018

It's true that in JavaScript we don't enforce project structure (like Go and its main.go and main() function). In browser you just load the scripts you want. But on the server people do execute just one script that serves as entry point for a project.

cd /home/username/projects/project-name
deno main.ts

Now, imports starting with / should point to /home/username/projects/project-name/.

Deno aims to be secure and browser compatible...
I propose to don't allow imports from paths up /home/username/projects/project-name/ in this case.

For example, in that main.ts, the following shouldn't be allowed.

import { something } from '../other-project/lib.ts'
@nicolasparada

This comment has been minimized.

Copy link

commented Jun 7, 2018

cd /home/username/projects/project-name
deno some-module/main.ts

If you try to run that, now the "root" will be /home/username/projects/project-name/some-module/ and it will break if you wrote imports with the assumption root was /home/username/projects/project-name/. This is where a --base flag comes handy.

cd /home/username/projects/project-name
deno --base . some-module/main.ts
@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Jun 8, 2018

With import { func } from '/folder/file.ts' you only have to know the location of the imported file.

With import { func } from '../folder/file.ts' you have to know the locations of both the imported file and > the importing file.

Hope that makes it more clear.

In the first you still have to know where/how the base is defined and hope that is consistent across every environment it runs in and that doesn't change between invocations of deno.

@alinnert

This comment has been minimized.

Copy link
Author

commented Jun 8, 2018

In the first you still have to know where/how the base is defined...

While this is true, it is only one thing to remember. With relative paths you have to remember <number of files in your project> things. (Where am I currently? How many dirs do I have to go up? What dirs do I have to enter?)

Oh, I just noticed another problem with relative paths. Let's take this import statement as an example:

import { func } from '../folder/file.ts'

Now imagine there are several file.ts inside a folder in different places. What file.ts am I talking about? You can use this exact statement without any changes in different files across a project and every statement points to a different file on disk.

If you write import ... '/module-a/folder/file.ts' and import ... '/module-b/folder/file.ts' I know exactly what file.ts I am referencing here without having to look up what file I'm currently looking at. This makes imports also more explicit.

...and hope that is consistent across every environment it runs in...

You check-in your project into a VCS, check-out on another machine and the base is still the same because your folder structure is the same as well. If your base changes for some reason I think you do something very wrong - like changing the project structure or moving just a subfolder of your project to another system. Why would you do that, if you're not explicitly working with something like submodules? (If that was even a reason. I don't know.)

...and that doesn't change between invocations of deno.

Why would it change there? In order for a change to happen here you have to change your project structure on purpose. This doesn't happen for no reason. And if you do that it would mess up relative paths as well, or actually even more easily.

About the security concerns @nicolasparada mentions: Deno is said to have read access to the entire file system. Limiting the files a Deno app can import doesn't seem to be a goal right now. But I feel that this is still a point that is worth thinking about... maybe? But I think that may be a different topic.

@kizerkizer

This comment has been minimized.

Copy link
Contributor

commented Jun 8, 2018

What if we allowed relative imports that do not back-reference? Like, only allow relative importing of this folder and what's contained within. Or why not both, just like accessing files in a shell. Except / is the root of your project.

@kingdaro

This comment has been minimized.

Copy link

commented Jun 9, 2018

I'm of the opinion that relative imports are better in general because it's much more explicit what file you want to actually import, when compared to node-style imports. That's the core reason for deno's approach here, no?

While it is bothersome needing to update imports whenever moving a file, or having to figure out how many .. are needed to get to the file you want, we don't have to do these things manually. That's not to say everyone is using VSCode, but obviously a lot of people are, and it's certainly because of features like this. Plus, VSCode isn't the only editor to have them. Any editor using the typescript server can take advantage of them.

When met with the safer, simpler, more maintainable option (relative imports), relying on tooling to smooth out the DX seems like the next natural step forward.

@alinnert

This comment has been minimized.

Copy link
Author

commented Jun 9, 2018

@kizerkizer Yes, that would be great. (I don't know if I've been clear enough. I don't want to remove or replace the possibility to use relative paths. I just think they are not enough.)

@GSchrammel A predefined alias (that's what they are called in Webpack) could be a semantic alternative. The result is the same. Also the main question still applies: "What is the project scope? How is it defined?"

@kingdaro

it's much more explicit what file you want to actually import,...

Can you explain why? In my previous comment, I just explained the opposite.

when compared to node-style imports.

Node also only supports relative paths. Plus the module resolution thing, but that's an entire different topic. Somewhere I read also absolute paths are supported but couldn't find any information on that. I guess it's fs absolute which wouldn't be very helpful.

I'm also using VS Code and I do know about these features. But I don't know if it's a good idea to tell others to just use another editor if they don't like relative import paths. Especially those who use Atom or Vim (Is it possible to add these features there? I don't know).

When met with the safer, simpler, more maintainable option (relative imports), relying on tooling to smooth out the DX seems like the next natural step forward.

I have to admin, I do get this point. But on the other hand you could also say: "Tooling shouldn't be necessary to fix design flaws." The question is, which one applies here...

@ilpoo

This comment has been minimized.

Copy link

commented Jun 9, 2018

I like the idea of absolute paths and I think, when done right, they could make imports more readable, as described above. But, I think that implementing them in a way that they actually make sense is a little problematic, which would largely come down to external imports.

I like the idea of absolute paths being relative to the project root, which is where the entry point would always be located. However, the absolute paths for imports within external imports would have to use the imported file as their root.

So, doing deno ./myproject would make ./myproject the root of this project. Then, doing import { test } from "https://unpkg.com/deno_testing@0.0.5/testing.ts" would make https://unpkg.com/deno_testing@0.0.5/ the importee's root.

However, what happens, if you want to import a sub resource from say https://unpkg.com/deno_testing@0.0.5/subfolder/somethingelse.ts? Would https://unpkg.com/deno_testing@0.0.5/subfolder/ become the root? What if said resource relies on its root being https://unpkg.com/deno_testing@0.0.5/ with its absolute imports? How would Deno know what the intended root should be for external resources?

I don't see an obvious way to solve this problem, since Deno doesn't/won't have a package.json file or similar which could describe the project root. Unless, of course, the import statement would also support some sort of root flag -- which might make importing stuff more confusing...

@brechtcs

This comment has been minimized.

Copy link

commented Jun 9, 2018

Since on the web import { method } from '/module.ts' is basically just a shorthand for import { method } from 'http://currentdomain.com/module.ts, the question is whether we can find a single, unambigious way to resolve the same shorthand outside of the web. I don't think we can, since in this thread alone there are already a few competing resolutions: current 'project', current working directory, etc.

If project- or cwd-based resolution is desired however, we can make this explicit in the syntax, like so:

import { method } from 'project://module.ts'
import { method } from 'cwd://module.ts'

When accidentally used in the browser, this will throw a much clearer 'Invalid URL scheme' style error, instead of the likely 404 you'll get when using '/module.ts'.

@alinnert

This comment has been minimized.

Copy link
Author

commented Jun 9, 2018

So, doing deno ./myproject would make ./myproject the root of this project. Then, doing import { test } from "https://unpkg.com/deno_testing@0.0.5/testing.ts" would make https://unpkg.com/deno_testing@0.0.5/ the importee's root.

Oh, wait. If you import a file via a URL this file is the only one that gets imported. There are no other files at that location that could be imported. Because of that, you should only import bundled files from external sources. But bundling is a planned feature of Deno. So I don't see a problem there. But importing external .ts files that also import other files with a relative path might be a problem - unless Deno is able to resolve those references correctly. But as you said, this is not possible for absolute paths. But there are no details in the presentation on this topic.

But to be honest I'm also not really sold on the "package.json-less structure" part. Every development environment has some kind of project concept. Node has npm, PHP has Composer, Java has Maven and Gradle, Rust has Cargo, .Net has NuGet, Go... seems to have a whole list of solutions. And all of them need to be configured in one or another way.

If Deno has an equivalent it could contain instructions on how to bundle your code (of course not too much). But the finished product could still be a single code file (is it supposed to be a .ts file or something different?) that can be referenced by other projects and you don't end up with the same problem node_modules has.

Also updating a library is another problem. If the URL contains the imported version and the URL is used all over your project you'll have a hard time updating the version numbers without missing a spot. Otherwise, you'll end up shipping your code with two or more versions of a dependency. (And relying on tooling could be more difficult here)

I just fear if Deno doesn't tackle these problems someone else will. Wasn't npm developed independently at first and got integrated with Node.js later on? Now we have npm, Yarn, bower, etc. Java has a similar problem (see above). Cargo has been part of Rust from the very beginning and everyone seems to be happy with it (= I don't know of any alternatives).

I just realized something: You could still use npm with Deno: init an npm project, install your dependencies, write a global importNpmModule function and voila. My fear is: if Deno doesn't provide some project related tools, someone else will, and that can get out of control very quickly (see npm, see Maven and Gradle, see PHP's PSR-0 and PSR-4, ...).

@alinnert

This comment has been minimized.

Copy link
Author

commented Jun 9, 2018

@brechtcs For browsers the scope gets defined by the HTTP server. Via an apache or nginx config. (But when I started developing in Node, I've realized that a mapping between a URL path and a file system path is just a "feature" of the server. The URL path is technically just a string and you can do with it whatever you want.)

If this should be supported by Deno as well there of course also needs to be that kind of configuration. And there we are at a package.json equivalent. I don't really see another way here. I don't think a flag is a good idea since you have to remember it and you can change it too easily.

cwd relative imports are actually not a bad idea. Use cases would be CLI tools written in Deno. But then again, you need to configure some things: What commands should be available in the terminal, what files should be executed? And you need a way to register them. (If that's a planned feature at all.)

@brechtcs

This comment has been minimized.

Copy link

commented Jun 9, 2018

@alinnert I don't necessarily disagree with you. My point was just that, since it's difficult to pin down the exact user expectation of what import '/module.ts should mean on the server, it might be better to add an explicit protocol identifier to resolve it.

@alinnert

This comment has been minimized.

Copy link
Author

commented Jun 9, 2018

@brechtcs Yes, I understand. I just took your idea and developed it a little further. If we use protocols we just have to be careful not to introduce protocol clashes. Custom protocols are in heavy use recently. VSCode uses vscode: for instance.

@kingdaro

This comment has been minimized.

Copy link

commented Jun 9, 2018

@alinnert

Can you explain why? In my previous comment, I just explained the opposite.

You mean this?

Oh, I just noticed another problem with relative paths. Let's take this import statement as an example:

Now imagine there are several file.ts inside a folder in different places. What file.ts am I talking about? You can use this exact statement without any changes in different files across a project and every statement points to a different file on disk.

We'll just have to agree to disagree on this one. If I have a file in a project referencing another file, there can only be one possible file to import in that specific context. If you mean that there could be multiple ../folder/file.ts's between projects, I'll know what project I'm working in when I'm working on it, and I'll know what file that is, so I can't ever see that being a problem. "Go to definition" on the import itself will bring me to the file either way, no?

@alinnert

This comment has been minimized.

Copy link
Author

commented Jun 9, 2018

@kingdaro Technically this, but mentally I was inside one project. You know of course if you're inside a different project. It's difficult to come up with a more specific example...

my-project/
  feature-a/
    fetchData.ts
    main.ts
  feature-b/
    fetchData.ts
    main.ts

Both main.ts contain import { foo } from './fetchData.ts'. If you switch between files a lot (maybe because you're new and you're trying to figure out what this project does and how it works) you can easily lose track of what file you're currently looking at and what fetchData.ts gets imported right now.

import { foo } from '/feature-a/fetchData.ts' is more explicit because it explicitly says which fetchData.ts it is importing right there.

@kingdaro

This comment has been minimized.

Copy link

commented Jun 9, 2018

I get what you mean, and I can agree that it's clearer from a human readability standpoint, but from a technical standpoint, I don't think "explicit" is the most accurate word to use here.

If we look at things from the perspective of the module resolution algorithm:

  • ./fetchData.ts is explicit because it can only mean one thing and can only point to one file.
  • /feature-a/fetchData.ts is ambiguous, and could mean: some file in my project, some third-party module, some file from the root of my file-system, and so on. On top of that, what if there's a feature-a folder in another project? We'd run into the same human readability problem here, no? And even more trouble for the module resolver.

Though this can be remedied with some sort of prefix system (as I think was mentioned before). Respectively, module:feature-a, project:feature-a, or absolute:feature-a. After we figure out what "project" means, anyway.

While that could bring about the complexity in module resolution this project was most likely trying to avoid, it feels like a reasonable enough compromise.

EDIT: Actually, after some thought:

  • Importing from system root seems like an anti-pattern and probably a security hole, so never mind that
  • The module thing would be done through something like /deno-modules/some-module/index.ts
  • Then project imports would be /src/whatever/feature.ts

And the project root could be configured using something like the --base flag that was mentioned before, so... Maybe it could work ¯\_(ツ)_/¯

I'd still prefer to just use relatives, though.

@alinnert

This comment has been minimized.

Copy link
Author

commented Jun 9, 2018

Ah, now we're on the same level. I was missing the "technical standpoint" information bit.

I agree that /feature-a/fetchData.ts could mean both "start from the project root" and "start from the fs root". But a module feature-a would be resolved with import { ... } from 'feature-a/fetchData.ts'. Without the leading slash. Just like Node does it. I don't see any connection to other modules in /foo/bar. At least this kind of resolution would be new to me.

But I'm just asking for the pure existence of this feature, the semantics were just a first thought or idea. It doesn't really matter how it gets implemented. I'm fine with any solution: prefix, protocols, pre-defined alias...

@yordis

This comment has been minimized.

Copy link

commented Jun 9, 2018

I didn't read the whole detail of what you are talking about but on the web /... means the root so I would just push for / pointing to the cwd folder.

@Androbin

This comment has been minimized.

Copy link

commented Jun 11, 2018

There seem to be two major concerns:

  • Unambiguity: Don't imply basepaths (project, domain, cwd, ...)
  • Conciseness: Don't duplicate exact paths to dependencies (CDN path, versioning, ...)

Maybe some syntactic sugar can help make the most of both?

base <basepath> { // absolute or relative
  from <relativepath> import <symbols>,
  ...
}

You could have multiple basepaths but group / deduplicate as appropiate to e.g.:

  • "the project root" or deepmost required submodule
  • URLs to some version of a group of components
@l0gicgate

This comment has been minimized.

Copy link

commented Jun 12, 2018

It’s time that real namespacing is introduced to the JS world.

namespace MyNamespace:

use My\Awesome\Lib;

Please for the love of god make this happen. Relative imports are another can of worms.

@MasterJames

This comment has been minimized.

Copy link

commented Aug 29, 2018

Just something I wanted people to be cognizant about. If it's not relative don't worry about it, sorry to complicate the issue.

@stack-wuh

This comment has been minimized.

Copy link

commented Sep 4, 2018

likes url-loader pakage

@dmayerdesign

This comment has been minimized.

Copy link

commented Oct 6, 2018

There are no absolute paths in a browser, those are called URLs which are supported. Absolute paths don't make sense in deno IMO because they would mean 100% non portable code, which makes no sense why you would generate that?

Paths are relative to the module, which means all the module needs to know is its own contained little world. Absolute paths invariably would leak local machine details and not be portable to things like a CI server, or anyone else's machine.

Wouldn't portability just be a matter of transforming all the import paths in a project? Could it somehow be snuck into the default process of porting to browser-compatible JS?

@chrisdothtml

This comment has been minimized.

Copy link

commented Dec 19, 2018

Worth mentioning package name maps https://github.com/domenic/package-name-maps are a thing

+1 for this as it would solve not only the issue of relative-path-hell, but also dependency management (a.k.a not having urls scattered around your project). The only thing I would be curious about is where the map file is located.

Others in this thread have brought up the concern of importing third party modules that have their own mapping. Making the location of the config file implicit (e.g. the root of the package) becomes a nightmare quickly (e.g. having to walk up the directory tree looking for a map file; e.g. the node_modules problem).

What if this was handled like sourcemaps? Every file that wants to use the mapping needs an explicit annotation. e.g.

map.json

{
  "imports": {
    "test": "https://deno.land/x/testing/testing.ts"
  }
}

module.js

//# importMapURL=./map.json
import { test } from 'test'

//...

some/nested/module

//# importMapURL=../../map.json
import { test } from 'test'

//...

It would be slightly inconvenient having to maintain the path to the map file, but I feel like this addresses the concerns mentioned so far in this thread and limits the logic deno has to worry about

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Dec 20, 2018

@chrisdothtml this can simply be solved within the existing capabilities of ES Modules. Essentially your suggestion is something like what I have done with oak:

export { serve } from "https://deno.land/x/net/http.ts";
export { Status } from "https://deno.land/x/net/http_status.ts";

and then:

import { serve } from "./deps";

No need for anything specific in Deno. I don't see why something like this wouldn't be viable. It is a convention that I would hope would become standard within the Deno community.

@chrisdothtml

This comment has been minimized.

Copy link

commented Dec 20, 2018

@kitsonk does that scale to a project with something like 20+ dependencies though? That solution either


A. reduces all of a library's exports down to a single export:

export * as lodash from 'https://some/path/lodash'

which eliminates any possibility of importing one individual export; or


B. combines all of a library's exports with all your other dependency's exports in one single file:

export { get, map } from 'https://some/path/lodash'

So, in the context of a module using the deps, it would end up being very ambiguous:

// what is get?
import { get } from './deps.js'

Not to mention modules like https://deno.land/x/testing/testing.ts or https://deno.land/x/dotenv/load.ts which are self-initializing, so are just incompatible with the deps file format

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Dec 20, 2018

@chrisdothtml in my opinion it is as scalable as an external meta data file.

export * as is currently not valid ES syntax. See: https://github.com/tc39/proposal-export-ns-from
It would have to be something like this currently:

import * as lodashNS from "https://some/path/loadash";
export const http = lodash;

As far as B, that is currently solvable:

export { get as lodashGet } from "https://some/path/loadash";

Considering that Option A is generally equivalent to an external imports JSON file, again, we should try to avoid any external meta data requirements however possible. That is a foundational design goal of the project.

@chrisdothtml

This comment has been minimized.

Copy link

commented Dec 20, 2018

I can definitely appreciate keeping it simple; the speed of directly linking to third party modules in deno is very refreshing.

Most of my professional experience is on large teams that maintain many apps, so my head always goes to abstraction right away. I still believe a more official solution to this problem is inevitable, but it's probably best to not hard-wire any particular solution until the ecosystem matures more

@benjamingr

This comment has been minimized.

Copy link

commented Dec 20, 2018

The rational of import maps isn't that it's easier than a deps.ts file - it's for web and browser compatibility and in order to get bare names.

@thgh

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

Here is an overview of the current behaviour. The last one surprised me.

import↓   context → /path/mod.ts http://example.org/sub/mod.ts
import './a.ts' /path/a.ts http://example.org/sub/a.ts
import '../a.ts' /a.ts http://example.org/a.ts
import '../../../../a.ts' /a.ts http://example.org/a.ts
import '/a.ts /a.ts /a.ts 🤷‍♂️

🤷‍♂️ is the only browser deviation.

JSPM also expects absolute paths to resolve like browsers do. Unless they change it.

@ry

This comment has been minimized.

Copy link
Collaborator

commented Feb 7, 2019

@thgh We should be able to support absolute path resolution. It's a little odd for local development tho because deno won't know where the root will be in a file system...

@jedahan

This comment has been minimized.

Copy link

commented Feb 7, 2019

How do browsers find http://example.org? Is it simply window.location.origin? What about looking for window.location.origin or global.location.origin for wherever the global context object is defined?

@ry

This comment has been minimized.

Copy link
Collaborator

commented Feb 7, 2019

@jedahan Yes - let's do window.location.origin - that's the proper solution.

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

Browsers don't use that. Items like AMD use XHR, and the internals of the browser know the current location when the URL is absolute. window.location.origin won't work, because that is different based on what module you are calling it from.

Also module resolution doesn't happen in the runtime. It is Rust that needs to know that and it does, because the request contains the referencing URL. To support it, you just need to change the module resolution logic in Rust, but I still don't think it will do what people are expecting (Or be useful). Likely someone will need/want to configure the loader, and the WHATWG has repeatedly dodged making the ability to configure the ESM loader.

@ry

This comment has been minimized.

Copy link
Collaborator

commented Feb 7, 2019

Let's just assume that on the file system, the "root" is the current working directory. If we resolve absolute paths and set window.location.origin to a file:// URL pointing to cwd, I think this solves the problem of working locally.

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

@ry to be clear...

If you run deno foo.ts then:

  • foo.ts requesting module /bar.ts will resolve to $cwd/bar.ts
  • foo.ts requests https://example.com/bar.ts and https://example.com/bar.ts requests /baz.ts it will resolve to https://example.com/baz.ts
  • window.location.origin will be set to file://$cwd globally no matter who loads what.

My question is if you run deno https://example.com/foo.ts the resolution can be the same, but what is window.location.origin?

@ry

This comment has been minimized.

Copy link
Collaborator

commented Feb 7, 2019

@kitsonk I agree with those itemized examples.

My question is if you run deno https://example.com/foo.ts the resolution can be the same, but what is window.location.origin?

I guess in that case it should be set to https://example.com like the browser would.

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Feb 8, 2019

Cool... so to be clear:

  • window.location.origin will be set to cwd if the arg module is local, and host if the arg module is remote.
@ry

This comment has been minimized.

Copy link
Collaborator

commented Feb 8, 2019

window.location.origin will be set to cwd if the arg module is local, and host if the arg module is remote.

s/arg module/main module/

@Ciantic

This comment has been minimized.

Copy link

commented Feb 8, 2019

What is the origin in this case:

deno https://unpkg.com/mysuperpackage@1.0.0/somefile.ts

If somefile.ts has:

import { something } from "/otherfile.ts"

Will it use https://unpkg.com/otherfile.ts or https://unpkg.com/mysuperpackage@1.0.0/otherfile.ts ?

If I understood correctly, if deno sets it to just host then the answer is first one. In case it sets it to the host and path, it's the second.

@thgh

This comment has been minimized.

Copy link
Contributor

commented Feb 8, 2019

file://$cwd

If I write /Users/thomas/ in the Chrome address bar, then open console, I get:
screenshot 2019-02-08 at 15 55 07

I'm not sure which program is rendering the page, the page says Chromium.

Following the logic above, window.location.origin should be:
deno https://unpkg.com/mysuperpackage@1.0.0/somefile.ts => https://unpkg.com
deno somefile.ts => file://

@ry

This comment has been minimized.

Copy link
Collaborator

commented Feb 8, 2019

I think we've reached consensus here on behavior. I will now accept implementations for abs path resolution and window.location. Let's remember to update the documentation when doing this.

(I believe @kitsonk is working on this as part of his continuing compiler refactors?)

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Feb 8, 2019

@ry yup... probably easier taking care of it that way.

@kitsonk

This comment has been minimized.

Copy link
Contributor

commented Mar 12, 2019

I forgot this... I will take a look at it. We have window.location but we need the absolute module resolution logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.