Closed guybedford closed 9 years ago
Effectively baseURL is just window.href.
Can you explain what this means? How do you set the baseURL with this change?
Using paths for example - module names are URIs so changing the baseURL doesn't make sense I don't think.
It's nice being able to do System.baseURL = '../'
, can I do that with paths? I guess that would probably work...
Hm, I don't think that would be very nice to write. You'd have to take the href, check to see if it's a file path and if so remove the file name, then add '../'. I like baseURL for convenience.
System.paths['app'] = '../';
System.import('app/main');
Or even just System.import('../main');
Oh, awesome, I thought with the new sites
the value had to be the full url.
Will your paths extension support wildcards? I want to be able to do System.paths['*'] = '../';
I'd hope so, but yes this stuff is where we may hit issues later, but I'm hoping we can help flesh out suggestions to the spec on this stuff. And if not, paths
can do its own internal normalization so we have a buffer.
Paths is a wildcard, there isn't currently a wildcard proposal for paths for things like paths['*.less'] = 'less/*.less'
though.
Oh right - I was actually considering adding a single wildcard path rule like that yes, good point. But I don't want it to be more general than that specific case.
Actually I suppose though, if we did that, that would just be baseURL
though?
So maybe we shouldn't deprecate baseURL
rather? Then if the spec doesn't implement, we provide the implementation?
:+1: to not deprecating.
Yeah I guess it is all or nothing.
Ok how about this then - what's a good argument that we even need a baseURL or wildcard path?
You can't load modules from the root without a baseURL. And that's something that's common and desirable.
You mean like System.import('/x.js')
? This will be allowed.
No, I mean like System.import('foo')
where foo is at baseURL + '/foo.js'
Right, I appreciate that, but perhaps we've just got used to a simple convention that we can do without?
Why should we do without it though? What do we gain from getting rid of it? Btw, in jspm don't you have a ~/
path for this purpose as well?
Each API feature should have a good reason for being there. That pressure is the difference between bloat and streamlining. Just because a feature has become tradition doesn't give it exception, and this is the big breaking change where we can consider these things, which won't be happening again soon.
In jspm the we've changed to defining an app
path - https://github.com/jspm/jspm-cli/wiki/Getting-Started#5-in-an-html-page-include-the-downloaded-systemjs-loader-along-with-the-automatically-generated-configuration-file-configjs-then-load-the-modules.
Sorry, don't mean to drone on... just throwing these ideas out, really value the feedback.
I don't mind the debate. So what is app/
? Is that the base directory? So if your structure looks like:
one
models
components
two
models
components
three
models
views
To get to the "car" model you might do System.import('app/one/models/cart')
, is that right? Or does app mean something else here?
App would be a path the user would always define in the config file to the application code:
System.paths['app'] = '/src/';
Without a baseURL (or a wildcard path) you can't reuse a config file. The paths become worthless, they have to be redefined for each page.
Ok, agreed we need to keep baseURL
It is critically necessary for bundling, because the only way to bundle in a URL module scheme is either as absolute URIs or relative to some baseURL. Absolute URI bundles are not portable so to make them portable we need a baseURL the names are relative to.
Not happening.
@guybedford I will keep this in mind, we can revisit this later this month. I'm not fully convinced that we need baseURL, we will see.
@caridy sure that makes sense, but as long as it can be implemented in an extension (which it currently can be). As discussed here, we do need this feature after all.
@caridy I'm not sure how it's possible to reuse a config that contains paths
without baseURL. Reusing a config is very important in large applications where you have more than a single index.html. You might have separate test/demo pages for each component you are working on and need to use the same configuration file for each of these.
@matthewp this is not different from scripts, and even links in a page. The same principle should apply, including <base href="/path/to/base/">
. My main concern of introducing a configuration is that script/module tags will not, or should not, rely on that for obvious reasons, which means we will have a dual behavior, and that will be undesired.
Geez, I forgot all about base
. I remember it having a lot of gotchas in the past but maybe those have been cleared up. Can you put a relative path in the base href (relative to the current document)? If so that might work. Still have to consider non-browser environments though.
Yeah would one really want the script base and the <a href="some/path">
bases to match though? This is creating coupled concerns between navigation and script loading.
@matthewp yes
I just wanted to come back to this idea of deprecating an explicit baseURL for the loader. The baseURL "under the hood" can be the base
or window.location.origin
.
The problem we hit previously was that bundles want to be able to be baseURL-relative and control that baseURL.
But surely we just use absolute URLs for bundles then?
System.register('/first/module.js', ...)
That is, our bundle names still go through the locate
phase, but not the normalize
phase (these phases will be simulated within the new resolve hook for conceptual simplicity).
So @matthewp do you have a strong argument that bundle names need more than absolute normalization rules? Note that SystemJS will probably still expose a locate hook so that custom location functions could be written allowing custom concepts of bundleBase
and bundle portability.
In short, I'm still keen to deprecate an explicit baseURL in the loader, and just make the root the default internal baseURL which is a fixed natural reference point.
I'm not following your question, maybe it's related to how System.register bundles works (which we don't use)? I would hope that the bundle extension still normalizes (or whatever that becomes) the bundle names though, I can't think of a reason why not? I'm probably misunderstanding you though.
Regardless of the exact process, the question is simply if there are scenarios where an explicit baseURL not matching the window.location might be needed, and I'm still not convinced that there are.
Yes, I don't think so. I haven't used <base>
in recent years so if it's possible to do <base href="../../">
then I don't see a need for a SystemJS baseURL.
I think
Edit: I think baseURL
should go away. Or at least I don't see me ever using it.baseURL
isn't necessary in the browser case. For web workers it's another story as I'm not aware of an alternative.
BTW in ember apps we extensively use the base tag because the server responds to example.com
and example.com/posts/10
with the same index.html
. The ember app will look differently for both URLs of course - but that's all in the client-side code. The index.html
contains a base tag with a domain relative URL, e.g. "/", so that all resources are found.
I'd stay away from relying on <base href="...">
as other framework (e.g. Angular) seem to want to (ab)use it for their router and this will likely creating mixing of concerns that will be hard to reconciliate across the various bits that would read this tag.
In our app, we need to override the baseURL
to point to /assets
, which is the path under which our server exposes the assets from its public
local folder. If there were no baseURL
, how would we be expected to manage this in the configuration?
I'd stay away from relying on
as other framework (e.g. Angular) seem to want to (ab)use it for their router
@theefer What do you mean? I think the base tag is the optimal primitive to define what place you consider the app root in relation to the domain (or to the current resource, though that's inconvenient because the relative location usually isn't fixed). I am not aware of any downsides.
if there are scenarios where an explicit baseURL not matching the window.location might be needed
when you are loading from the cloud, not from the server that the base html sits on. My 'app' consists of a small html file that people can copy to Google Drive, Dropbox or similar, and which pulls in the code from jspm:github. I have a testing version which pulls in from localhost, and the only real difference is the baseURL. I might be able to use <base>
instead; I have used this in the past and seem to remember coming across issues, but it's so long ago I can't really remember what the issues were.
Actually I think baseURL is essential in Node. You can't reasonably expect to be able to change process.chdir()
because other parts of the program (other libraries, etc) will not be expecting it.
@MajorBreakfast For Angular, the base URL is essentially the root for the routing. For SystemJS, the base URL is the root for resolving module paths. What if the routing root (say /
) is not the same as the module path root (say /assets
or even https://cdn.example.io/app-files
)?
@guybedford I know we discussed this in previous issues and PRs, but how else than using baseURL
is one supposed to setup the server path where assets are exposed under? Can't really hack the paths
in the config as they would then no longer match local file paths on disk. I might be missing something, but this seems like a strong need for baseURL
.
I'm using baseURL
to define the path for production/development/etc based on the 'environment' that my server-side framework is using. That way I keep the same config.js regardless. So it's essential for me or am I doing that wrong?
The idea was to try and converge on absolute URLs (like /path/to/module.js
) and share that base always, but I guess it is a little too restricting to always expect.
For us the problem is that the absolute path of the URL on the server may need to differ from the local path. The common path fragment can indeed be set in the config.js
paths
, but the server prefix has to be set using System.baseURL
whereas the local filesystem prefix is set using directories.baseURL
in package.json
.
For example consider:
// config.js
System.config({
"paths": {
"app/*": "lib/*.js",
"github:*": "jspm_packages/github/*.js",
"npm:*": "jspm_packages/npm/*.js"
}
});
// SERVER
https://example.com/index.html (or https://example.com/somewhere/else/index.html)
<script src="/assets/config.js"></script>
<script>
System.baseURL = '/assets';
System.import('app/main');
</script>
loads:
https://example.com/assets/config.js
https://example.com/assets/lib/main.js
// package.json
{
"jspm": {
"directories": {
"baseURL": "public"
},
...
}
given:
dir/package.json
dir/public/config.js
dir/public/lib/main.js
In other words, for paths to resolve correctly on both the server and client, they need different baseURL
s. I think that's a fairly common pattern really...
@theefer It's possible to dynamically set the base tag just like baseURL:
<head>
<script>
if (...) { document.write('<base href="...">') }
</script>
<!-- Inserts the base tag here -->
</head>
I've done this in the past. It works as expected.
@MajorBreakfast But in my example above, it'd have to be set to /assets
for SystemJS (root of assets paths) and to /
for AngularJS (navigation). Which one is it?
Thanks everyone for letting me rehash this. It sounds like we will stick with it for practicality.
@theefer The trick is to avoid that scenario in the first place. For example:
<link rel="stylesheet" href="assets/style.css">
System.import('assets/style.css!')
It's better if these two access the same file to avoid unnecessary confusion. The baseURL
then only needs to be used in environments like node oder web workers which have no base tag.
I believe this is going out with the move to module names as URIs.
@caridy it would be good to get confirmation on this?