- @Charles can we make seedjs compatible with Kris's proposal ? Cause one issue I think of is illustrated below
mappings: {'foo:': 'http://myhost.com/lib/'} // to require http://myhost.com/lib/bar.js
seed will expect require('foo:bar) while other platforms will expect require('foo:/bar)
Is there any other open questions ?
KrisZ Mind writing proposal since you're an author (Sorry if you already did so, can't find it on a wiki) ?
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/
Phone: +31 614 205275
Address: Taksteeg 3 - 4, 1012PB Amsterdam, Netherlands--
You received this message because you are subscribed to the Google Groups "CommonJS" group.
To post to this group, send email to comm...@googlegroups.com.
To unsubscribe from this group, send email to commonjs+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/commonjs?hl=en.
Hi
I thought I'll try to push this topic once again, since we are pretty close to an agreement (I think), since all the existing suggestions are more or less compatible with mapping proposal from KrisZ.
- Is there any point of keeping package dependency listings in package.json? Mapping expresses dependencies explicitly I believe.
- Can mapping be used for providing an overlays as well for example
mappings: {'foo/bar': 'http://myhost.com/lib/bar.js'} // where require('foo/bar') requires http://myhost.com/lib/bar.js
- @Charles can we make seedjs compatible with Kris's proposal ? Cause one issue I think of is illustrated below
mappings: {'foo:': 'http://myhost.com/lib/'} // to require http://myhost.com/lib/bar.js
seed will expect require('foo:bar) while other platforms will expect require('foo:/bar)
Is there any other open questions ?
KrisZ Mind writing proposal since you're an author (Sorry if you already did so, can't find it on a wiki) ?
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/
Phone: +31 614 205275
Address: Taksteeg 3 - 4, 1012PB Amsterdam, Netherlands
--
You received this message because you are subscribed to the Google Groups "CommonJS" group.
To post to this group, send email to comm...@googlegroups.com.
To unsubscribe from this group, send email to commonjs+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/commonjs?hl=en.
-- Thanks, Kris
- @Charles can we make seedjs compatible with Kris's proposal ? Cause one issue I think of is illustrated below
mappings: {'foo:': 'http://myhost.com/lib/'} // to require http://myhost.com/lib/bar.js
seed will expect require('foo:bar) while other platforms will expect require('foo:/bar)
I don't mind making seed compatible, but I have some concern still about using / as the package separator. The problem is:
require('foo/bar/baz')
Is ambiguous. This could be:
'foo/bar/baz' module from the current package'baz' module from the 'foo/bar' package'bar/baz' from the 'foo' package'foo/bar/baz' from the underlying system (i.e. to remain compatible with node for example, you have to fallback to looking for a simple module outside of packages)
Even the mappings as proposed by Kris doesn't solve this. What if I have defined:
mappings: {"foo": "...","foo/bar": "..."}
We basically end up back where we started - looking at a require() statement it is not clear what should be loaded (and any rules we come up with in the spec are going to be complex enough that implementors could easily screw them up).
On the other hand:
require('foo:bar/baz');require('foo/bar:baz');require('foo/bar/baz');
is far less ambiguous. The last one is technically still ambiguous but less likely to be so since package cases are removed.
How would you address this ambiguous scenario with mappings?
-- Thanks, Kris
Suppose we limit the package aliases to the first term:
"require('foo/bar/baz') will get the bar/baz module from the package mapped to 'foo'"
We can map packages with:
"mappings": {
"foo": { // alias
"uri": "http://github.com/foo/...",
"version": "0.2"
}
}
To map to a specific module you could now do:
"mappings": {
"foo": { // alias
"uri": "http://github.com/foo/...",
"version": "0.2",
"module": "specific-foo"
}
}
require("foo")
This could be used to overwrite system modules as well.
I too have found the need to map to a module in package.json and think it is a necessary feature.
I am adamant about needing a clear separation between the package component and module component in a module ID. To achieve this for one-arg require the package must *always* be prefixed even for system modules.
require("system/system")
require("commonjs/system")
require("foo/bar")
require("foo") -> special case (mapped to module as described above)
This would necessitate the platform providing some default packages such as "system" or "commonjs" or the package.json needs to map *all* packages.
The reason I like the two-arg require is that it provides in my mind more flexibility.
require("system") -> the "system" module from the system namespace
require("system", "commonjs") -> the "system" module from the "commonjs" package
*Any* package can install modules into the system namespace by declaring them in the "dependencies" package.json property while "packages" get defined in the "packages" property.
Mappings in this case would be used to map modules in the system namespace. This can be used to organize modules for transport to the browser with a browser loader that re-maps them to the two-arg require when they arrive at the client. I have not had a chance to play with that but believe it is possible and fairly trivial.
I see the module system at several levels:
Level 0: bootstrapping
Level 1: 1 arg require global namespace module system
Level 2: 2 arg require or other aliased package-based module systems
Level 3: package spaces with dependencies mapped in package.json
Level 0 and 1 would be platform specific while level 2 and 3 would be interoperable across all platforms.
I presume we all have the goal of writing programs split into packages that run on a variety of platforms. I am also observing that implementors have their own ideas of how they believe packages should operate on their platforms.
Maybe our focus should remain at level 1 with the exception of specifying a common package.json format that works for all package managers and loaders. I think we are close in that regard. In my mind this should suffice to achieve interoperability because when a package loads it can load a module loader to load its own dependencies from whatever package ecosystem it desires. I see this as no different to a website running prototype, jquery and dojo in parallel each with their own plugin/module systems.
-- Thanks, Kris
b. ':'
c. Something else, '!' or ';' anyone?
--
Thanks,
Kris
--
You received this message because you are subscribed to the Google Groups "CommonJS" group.
To post to this group, send email to comm...@googlegroups.com.
To unsubscribe from this group, send email to commonjs+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/commonjs?hl=en.
KrisZ I believe seedjs has one more thing which I personally won't miss much, but some might. From your mapping example seedjs would:
require("json"); // gets http://example.com/json-package/lib/index.js
-- Thanks, Kris
+1 for this algorithm:1. check package.json for main property2. check for index.js3. check for package-name.js4. throw error
-- Thanks, Kris
The package mappings has been carefully designed to *never* introduce multiple lookups. This greatly simplifies implementation and improves performance. Introducing multiple looks can easily permutate to a numerous lookups with big performance penalties, and is particularly unacceptable in the browser.
On 5/13/2010 10:03 AM, Zachary Carter wrote:+1 for this algorithm:1. check package.json for main property2. check for index.js3. check for package-name.js4. throw error
I would look to continue to avoid multiple lookups. Does the main module only apply to the package root, or does it apply to every folder in a package?
With the latter, even with a known main module name, this seems to create situation where you have to go to the disk first to check to see if a directory exists, and then decide which module to look up from other (doubling every lookup).
Also, I would point out that the "main" module concept only really makes sense on file systems/directory structures. When a module id is mapped to a plain HTTP URL, there is no way to know if http://site.com/path/to/foo is directory and should be changed to http://site.com/path/to/foo/index.js instead of http://site.com/path/to/foo.js.
Personally this all seems more complicated than worth it for the value it adds (typing "package/index.js" isn't terribly hard), but I wouldn't stand in the way if everyone wants it added.
Sorry for delay on this one:
On Tue, May 11, 2010 at 00:43, Kris Zyp <kri...@gmail.com> wrote:
Maybe, although I don't really know how. They are operated on completely
On 5/10/2010 4:29 PM, Irakli Gozalishvili wrote:
> Maybe I miss something here, but can we:
>
> merge dependencies and mappings ?
different concepts right now. "dependencies" works on named packages vs
and mappings works with URIs. Mappings don't really indicate any
package-wide dependency. If a mapping is not used (no require is made
that matches a particular mapping), there is no reason that the target
of the mapping needs to be available.
I don't think they are that different, since in a current spec "A CommonJS package is a cohesive wrapping of a collection of modules, code and other assets into a single form", in my understanding aliased URI is the same, even though collection might contain just a single asset.
I also don't see any point in declaring mapping if declaring package is not using it (there for depends on it). I also was assuming that package managers will cache mapped url's locally so that it can be aliased by any package to any name.
Mappings explicitly specify how
the target can be located and how it can be required. Mappings don't
necessarily correspond to any package (could be to just a random URL on
the web, a nested folder in a package, etc).
I would interpret it a single module dependency, and it doesn't matters where is it coming from
I'm open to ideas how they
could be merged, but I wouldn't want to complicate mappings too much.
I think I posted example before and it looked like this"dependencies": {"uri": "http://github.com/kriskowal/narwhal-lib/", // explicit mapping
"narwhal-lib": { // alias following same naming convention as module id's except `/`
"version": "0.2" // does verision makes sence with expliciting mapping ?
},Guess version property makes no sense in mapping which is first example. This also makes it easy to switch from mapped dependency used in dev process to a named package in production, even though I think that with a well designed package manager mapping can fully replace named packages, since name will can be url and it's guaranteed to be unique across all platforms, package managers, etc."foo": { // alias
"id": "foo-bar-pack", // package installed in platform with the matching name
"version": ["1.0", "2.0"] //(optional ? platform preference) version
}
}
> can we have relative mappings for nested packages ?Following the standard rules for relative URIs (mapping targets can be
relative URIs and module ids follow the relative paths part), that
should be easy to do right now.
--
Thanks,
Kris
Maybe, although I don't really know how. They are operated on completely
On 5/10/2010 4:29 PM, Irakli Gozalishvili wrote:
> Maybe I miss something here, but can we:
>
> merge dependencies and mappings ?
different concepts right now. "dependencies" works on named packages vs
and mappings works with URIs. Mappings don't really indicate any
package-wide dependency. If a mapping is not used (no require is made
that matches a particular mapping), there is no reason that the target
of the mapping needs to be available.
Mappings explicitly specify how
the target can be located and how it can be required. Mappings don't
necessarily correspond to any package (could be to just a random URL on
the web, a nested folder in a package, etc).
I'm open to ideas how they
could be merged, but I wouldn't want to complicate mappings too much.
> can we have relative mappings for nested packages ?
Following the standard rules for relative URIs (mapping targets can be
relative URIs and module ids follow the relative paths part), that
should be easy to do right now.
--
Thanks,
Kris
+1
> package delimiter is:
> a) /
> b) :
> c) something else
I think we have a log of hand showing for this somewhere,
but I can't find it. In any case:
A +1
> index module name:
> a. index.js
> b. package-name.js
> c. specified as `index` property in package.json
> d. (c) and defaults (a)
> e. (c) and defaults (b)
> f. specified as `main` property in package.json
> g. (f) and defaults to (a)
> h. (f) and defaults to (b)
C. If there's no `index` property in `package.json`, there
is no `index.js`.
> - Is there something I miss and we still need to agree on
> ?
The "jar" URL's remain contentious. I favor plain URL's
to archives, presently in zip format, with the possibility
of supporting tar and tgz eventually.
If we need deep archive paths, I favor using the URL's
anchor/search/hash.
> - Will syntax of requiring dependencies be the same?
> Meaning that if my package depends on foo module bar from
> it can be loaded by require('foo/bar')
It's my understanding that, provided that there is a "foo"
mapping, "foo" would grab the "index.js" of the referenced
package, "foo/bar" would grab the "lib/bar.js" of the
package. In the absence of a "foo" mapping, "foo" would
reference "lib/foo.js" and "foo/bar" would grab
"lib/foo/bar.js". Anything else would be beyond
specification.
Obviously, some implementations, like Narwhal, will still
have a module search path, which will be useful for overlays
(particularly for engine-specific overlays) and the like,
but I don't think we need to agree on that. We might as
well remove and reserve the `dependencies` property of the
`package.json` since it is a vestige of the older,
overlay-based model of package management. I don't object
to repurposing it for `mappings` as you suggested, since it
is likely to be the dominant form of dependency management.
Tom and some Narwhal users might disagree with me about the
above paragraph.
Kris Kowal
On 5/25/2010 3:41 PM, Kris Kowal wrote:
> [snip]
>> - Is there something I miss and we still need to agree on
>> ?
>>
> The "jar" URL's remain contentious. I favor plain URL's
> to archives, presently in zip format, with the possibility
> of supporting tar and tgz eventually.
>
> If we need deep archive paths, I favor using the URL's
> anchor/search/hash.
>
There are some key advantages to using archives, obviously that you can
download packages much faster than individually downloading each module.
Archives are also a great indicator of the root of a package as well
(module loaders face more effort with mappings to plain URLs like
"foo":"http://site.com/some/where/in/here/is/the/root/of/my/package/and/the/rest/is/a/path/to/my/mapping/target").
We could force the use of "mirrors" for indicating the archive that
corresponds to "plain" URLs, but this adds complexity, and as I noted in
the spec, this can lead to some troubling security problems with
substituting alternate versions of code that later gets cached by the
URL rather than the archive source.
Of course I prefer tar/gzip to zip format as well, but is there any URI
scheme for tar/gzip? I didn't really want to get into the business of
inventing URI schemes as well. I am certainly open to other ideas, but
the vast majority use case of creating mapping that indicates a target
folder from an downloadable package archive is a drop dead simple one
line mapping right now, and I would hope that we don't make things more
complicated.
(cc'ed Isaac, since I think this is partly based off a conversation from
#node.js about npm)
--
Thanks,
Kris
On Tue, May 25, 2010 at 7:00 AM, Irakli Gozalishvili <rfo...@gmail.com> wrote:
> index module name:
> a. index.js
> b. package-name.js
> c. specified as `index` property in package.json
> d. (c) and defaults (a)
> e. (c) and defaults (b)
> f. specified as `main` property in package.json
> g. (f) and defaults to (a)
> h. (f) and defaults to (b)
I prefer a. index.js, only to make configuration in the browser
easier. It would be nice if the config in the browser for the packages
it used could be done via a simple collection of mappings (this is
just an example, not sure how it would really look):
{
"packages": {
"foo": "scripts/packages/foo/v1.2",
...
}
}
and the code could assume if there was a require('foo') that it
translated directly to 'scripts/packages/foo/v1.2/index.js',
require('foo/bar') to be 'scripts/packages/foo/v1.2/lib/bar.js'.
Otherwise, it seems like more copy/paste of code from each
package.json into the top level HTML page to get all the paths to work
out:
{
"packages": {
"foo": {
"mapping": "scripts/packages/foo/v1.2",
"index": "random.js"
},
...
}
In summary, I prefer stronger constraints in the package layout to
make it easier to configure a web page to use packages. I believe it
will also help make packages more uniform and therefore easier to
understand and visually inspect. Another example, I would prefer if
there was not "directories" option in the Packages spec either, but
just mandate the names of the directories. I suppose just fixing 'lib'
to hold other .js files is probably enough for avoiding the extra
config for the browser.
Feel free to disregard this feedback particularly if this has already
been beaten to death. I am only now starting to look at supporting
CommonJS-type of packages in a browser.
James
James Burke wrote:
> I care primarily about browser implementations, so weight the
> following feedback accordingly:
>
> On Tue, May 25, 2010 at 7:00 AM, Irakli Gozalishvili <rfo...@gmail.com> wrote:
>> index module name:
>> a. index.js
>> b. package-name.js
>> c. specified as `index` property in package.json
>> d. (c) and defaults (a)
>> e. (c) and defaults (b)
>> f. specified as `main` property in package.json
>> g. (f) and defaults to (a)
>> h. (f) and defaults to (b)
>
> I prefer a. index.js, only to make configuration in the browser
> easier. It would be nice if the config in the browser for the packages
> it used could be done via a simple collection of mappings (this is
> just an example, not sure how it would really look):
>
> {
> "packages": {
> "foo": "scripts/packages/foo/v1.2",
> ...
> }
> }
I still think mappings is the best name for the property.
> and the code could assume if there was a require('foo') that it
> translated directly to 'scripts/packages/foo/v1.2/index.js',
> require('foo/bar') to be 'scripts/packages/foo/v1.2/lib/bar.js'.
> Otherwise, it seems like more copy/paste of code from each
> package.json into the top level HTML page to get all the paths to work
> out:
>
> {
> "packages": {
> "foo": {
> "mapping": "scripts/packages/foo/v1.2",
> "index": "random.js"
> },
> ...
> }
I was under the impression the index.js file is a module in the "lib"
directory.
So given:
package.json ~ {
"mappings": {
"foo": "scripts/packages/foo/v1.2"
}
}
You could do:
require('foo') and get scripts/packages/foo/v1.2/lib/index.js
require('foo/bar') and get scripts/packages/foo/v1.2/lib/bar.js
> In summary, I prefer stronger constraints in the package layout to
> make it easier to configure a web page to use packages. I believe it
> will also help make packages more uniform and therefore easier to
> understand and visually inspect. Another example, I would prefer if
> there was not "directories" option in the Packages spec either, but
> just mandate the names of the directories. I suppose just fixing 'lib'
> to hold other .js files is probably enough for avoiding the extra
> config for the browser.
The "directories" property is optional and defaults to "lib" for modules.
Christoph
+1
>> package delimiter is:
>> a) /
>> b) :
>> c) something else
a) +1
>> index module name:
>> a. index.js
>> b. package-name.js
>> c. specified as `index` property in package.json
>> d. (c) and defaults (a)
>> e. (c) and defaults (b)
>> f. specified as `main` property in package.json
>> g. (f) and defaults to (a)
>> h. (f) and defaults to (b)
c) +1
d) +1
Christoph
"mappings" as the config property name works for me, I was just trying
to demonstrate what some imaginary config object in the HTML page
might look like.
> I was under the impression the index.js file is a module in the "lib"
> directory.
>
> So given:
>
> package.json ~ {
> "mappings": {
> "foo": "scripts/packages/foo/v1.2"
> }
> }
>
> You could do:
>
> require('foo') and get scripts/packages/foo/v1.2/lib/index.js
> require('foo/bar') and get scripts/packages/foo/v1.2/lib/bar.js
Great, if they are all in lib, that makes things simpler.
> The "directories" property is optional and defaults to "lib" for modules.
Thanks for the clarification. I must have glossed over that part in the spec.
James
I think we are more or less aligned on this one now can we move to voting part??
If I got it correctly we have to show hands on:
- mapping is restricted on one term only
- package delimiter is:
a) /
b) :
c) something else
- index module name:
a. index.js
b. package-name.js
c. specified as `index` property in package.json
d. (c) and defaults (a)
e. (c) and defaults (b)
f. specified as `main` property in package.json
g. (f) and defaults to (a)
h. (f) and defaults to (b)
-- Thanks, Kris
-- Thanks, Kris
I think we are more or less aligned on this one now can we move to voting part??
If I got it correctly we have to show hands on:
- mapping is restricted on one term only
- package delimiter is:
a) /
b) :
c) something else
- index module name:
a. index.js
b. package-name.js
c. specified as `index` property in package.json
d. (c) and defaults (a)
e. (c) and defaults (b)
f. specified as `main` property in package.json
g. (f) and defaults to (a)
h. (f) and defaults to (b)
Also if you map a package to a URL how would you handle cases where I want to keep a copy of all my packages in an alternate location - say on a CDN or using an internal server. It would be a maintenance nightmare if I had to go in and modify every package.json that I depend upon to do so.
C
-- Thanks, Kris
I think there was two important things mentioned that should be decided1. Should dependencies and mappings get merged ?
2. What should be the name of mappings / dependenciesa) mappingsb) dependenciesc) packages
On 5/27/2010 9:02 AM, Charles Jolley wrote:
> So do I understand correctly that we are now considering dropping the dependencies property in favor of mappings? If not, what is the purpose of having both? It seems that if you name packages mapped to a URL explicitly you just don't even need package versions anymore.
>
> Also if you map a package to a URL how would you handle cases where I want to keep a copy of all my packages in an alternate location - say on a CDN or using an internal server. It would be a maintenance nightmare if I had to go in and modify every package.json that I depend upon to do so.
>
I think the packages specification includes a "repositories" property
for situations where the target package wants to specify the CDN, and
the mappings doesn't include a "mirrors" property, but I assume that is
what you are trying to avoid using. I don't think there is anything
wrong with other configuration techniques to remap URLs to CDN URLs. But
that would be beyond the scope of the package mappings mechanisms, which
primarily is intended to indicate the canonical URL.
--
Thanks,
Kris
On 5/27/2010 8:59 AM, Irakli Gozalishvili wrote:
> I think there was two important things mentioned that should be decided
>
> 1. Should dependencies and mappings get merged ?
What specifically would this mean for mappings? Hopefully it wouldn't
make mappings more complex.
> 2. What should be the name of mappings / dependencies
>
> a) mappings
> b) dependencies
> c) packages
>
Obviously I prefer "mappings". "packages" doesn't make sense because
targets don't have to be packages. "dependencies" is closer, but we are
indicating more than a dependency, we are also indicating how module ids
are mapped to the dependencies.
--
Thanks,
Kris
On 5/27/2010 9:15 AM, Irakli Gozalishvili wrote:
> I thought we accept mappings with url's which either ends by / or file
> extension. In first case it's package / sub-package mapping in second
> it's a module. if it's a sub-package I believe it should also contain
> lib and index.js but endeed it's getting messy. On the other hand if
> you make nested mapping most likely you dont want to require modules
> by this mapping so extra lib folder is not so bad.
Currently the spec says that if the mapping target ends with a slash,
require'd module ids directly match the mapping source, they can only
match when used in a path. If we did change to matching, what if the
path ends with a slash and is not package?
>
> I think we should choose from:
>
> 1) removing directories as was proposed and always default to `lib`
> and have index.js
> 2) keep directories and add index property to package json
>
> In any case having same index for package and nested package doesn't
> makes much sense in my opinion
I am not sure I understand these options.
This seems like it is getting very complicated. The original spec was
simple string substitution. I like simple.
--
Thanks,
Kris
What specifically would this mean for mappings? Hopefully it wouldn't
On 5/27/2010 8:59 AM, Irakli Gozalishvili wrote:
> I think there was two important things mentioned that should be decided
>
> 1. Should dependencies and mappings get merged ?
make mappings more complex.
> 2. What should be the name of mappings / dependenciesObviously I prefer "mappings". "packages" doesn't make sense because
>
> a) mappings
> b) dependencies
> c) packages
>
targets don't have to be packages. "dependencies" is closer, but we are
indicating more than a dependency, we are also indicating how module ids
are mapped to the dependencies.
I think what I'm describing is simpler and I believe it was preference of others here, but I might be wrong. I'll try to illustrate it in example:
mappings:{'foo': 'http://foo.com/path/foo.js''bar': 'http://foo.com/path/bar/''baz': 'http://foo.com/path/bar/subpath/baz/'}
require('foo') // -> http://foo.com/path/foo.jsrequire('foo/whatever') // -> will throw
require('bar') // -> http://foo.com/path/bar/lib/index.jsrequire('bar/foo') // -> http://foo.com/path/bar/lib/foo.js
require('baz') // -> http://foo.com/path/bar/subpath/baz/lib/index.jsrequire('baz/foo') // -> http://foo.com/path/bar/subpath/baz/lib/index.jsrequire('baz/foo') // -> http://foo.com/path/bar/subpath/baz/lib/foo.js
-- Thanks, Kris
+1. This is indeed a far simpler and more predictable state of
affairs. Simple + predictable = less likely to trip up developers. The
extra flexibility of alternate approaches may save a few characters of
typing here or there, but in the end, for programming in the large
(which is what packages attempt to do, after all), clarity and
predictability beat all, I think.
Ihab
--
Ihab A.B. Awad, Palo Alto, CA
On 5/27/2010 9:54 AM, Charles Jolley wrote:
> Hi I don't think this will work in practice for two reasons:
>
> 1. Many times packages will be hosted as a single file. It may be a
> zipped archive, or in the browser case, you may have a single js file
> which actually contains one or more packages and all of their modules
> to minimize round trips to the server. Simple string substitution
> won't work in either of these cases.
>
> 2. In general you can't download just one module if it belongs to
> another package because you need the package.json for the module's
> package to know how to interpret requires inside the other module.
>
> I think the simplest implementation would be to state that the first
> term maps to a URL which represents the package of the other module.
> The CommonJS runtime would then look up the module within that package.
This doesn't work because not every target is a package.
--
Thanks,
Kris
Thanks,
Kris
-- Thanks, Kris
--
Irakli Gozalishvili
Web: http://www.jeditoolkit.com/
Phone: +31 614 205275
Address: Taksteeg 3 - 4, 1012PB Amsterdam, Netherlands
On Thu, May 27, 2010 at 17:42, Kris Zyp <kri...@gmail.com> wrote:
No it's simple you just don't. Either you map package or module as simple as it sounds. If you will tell me the case wehere mapping directory is actually required / is very beneficial you might convince me that it worse it.
Actually I don't mind throwing index all together, but it looks like a lot of people use it, on the other hand we can omit directory mappings and everyone is happy. In any case if we'll have directory mappings it's not clear where to look for package.json either
-- Thanks, Kris
-- Thanks, Kris
This is getting close to the using packages implementation I am working on:
"packages": { // I think "packages" is better than "using"
"jack": {
"location": "http://github.com/kriszyp/jack/zipball/master/",
"descriptor": {
"directories": {
"lib": "lib/jack"
}
}
}
}
You can override the package.json of the referenced package for the
mapping. IMO this is by far the simplest and cleanest solution.
> However, I still feel that moving to a mapping system that requires a
> more complicated machinery to achieve the same level of functionality
> doesn't seem very compelling to me.
I think we are trying to combine mappings to *modules* with mappings to
*packages* again.
In my view "mappings" deals with mapping a term to a URL where suffixes
are simply appended. I made a mistake in my other email stating that
package.json would be consulted and the directories.lib property spliced
into the URL.
I think "mappings" should strictly deal with referencing modules
*without* consulting package.json. i.e. via a simple path concatenation
In this case you are mapping all modules onto one system namespace. This
is what KrisZ is advocating I believe.
The "packages" property on the other hand can deal with mapping to
packages with the ability to override package.json, more dynamic
versioning etc...
I think this distinction needs to be taken to a vote as it keeps
tripping us up and complicating things. If we can agree on the split
then we can ratify "mappings" and start work on "packages".
Christoph
Its not really my primary intent to avoid consulting package.json, and
while you can load modules without package.json, to execute a module,
you certainly need to consult package.json (to know how the target
modules require'd module ids are mapped). While I am not sure what the
merging of "dependencies" and "mappings" would mean, I do agree with
Irakli that we don't want two mechanisms of specifying how module ids
are mapped to dependencies (we wouldn't to have the "package" way and
the URL way). I actually like your format for packages if we are going
to get into dependent packages specifying information about the
dependency packages.
IMO, the real key premises of mappings are:
* A URL-based location of dependents is the included such that modules
can be downloaded from anywhere and we are not dependent on Isaac's,
Charles', Tom's, TJ's or anybody else's catalog or repository.
* Target modules can be specified even if they do not conform to a
CommonJS package structure (with package.json and a module lib directory).
* Keep it simple to use in the common cases
* Packages own their own namespace of module ids, and are allowed to
dictate how they expect their require statements to be mapped to
dependencies.
If we want to move to a more package-oriented approach, I wouldn't mind
definitions like your example above (and maybe this is kind of Irakli
meant by merging dependencies with mappings) in mappings, but it should
be something that can be applied locally (different packages could
potentially map "jack" to different targets). Version ranges might also
be a good addition with this approach.
--
Thanks,
Kris
It is my understanding that this election is about having a
mapping for "foo" to some package and what module
require("foo") returns.
> I am +1 to an index module in situations where a module
> loader provides a way of "executing" a package in some
> sense.
I'm also +1, although I do not think that is the intent of
this election. However, I do think an executable package
feature could piggy-back on the index module.
> However, I wouldn't choose any of the options above, I
> would vote for lib/index.js (I'd prefer to keep my modules
> in the lib directory).
I've convinced myself to be indifferent about this. It is
my personal preference to not introduce a situation where
"foo" and "foo/index" refer to the same module.
Kris Kowal
My interpretation was that, if package A has a mapping from "foo" to B,
require("foo") in package A would:
I.) map to a file in package B, relative to the package
root, in which case the index property would be a file
name.
II.) map to a module in package B, in which case the index
property would be a module top-level identifier.
Which is orthogonal to the concerns above of how to balance
convention and configuration:
A.) convention (always foo/index.js)
B.) configuration (always refers to foo/package.json's
"index" property, in which case it is possible to *not*
map require("foo") to any module.)
C.) configuration before convention (if a property exists in
package.json, use it, otherwise default to the
conventional module name or package path location.
Which is orthogonal to the concern of what the name the
property and the default file name or module name. It seems
clear that "index" is the general preference, either way.
The choices were:
X.) index
Y.) main
Z.) same name as package's self-described name in its
package.json (although there may have been some
confusion that it would be the name of the mapping)
Kris Kowal
Let's table this. There are proposals that use these names
for clearly different purposes, so let's just reserve them
for the purposes defined in their original proposals and
vote on the proposals rather than the names. That will at
least keep us less confused in discussing the proposals.
* "mappings" is used in Kris Zyp's proposal for mapping
short names to packages
* "dependencies" is used by precedent in Narwhal and NPM for
different purposes.
* In Narhwal/Tusk, it is used to
determine what packages are installed globally, and in
what order their lib directories will appear.
* In NPM it is used to determine top-level short names for
each package in a single lib directory, into which the
packages' lib directories will be linked.
* "packages" is used differently by Christoph Dorn and
Charles Jolley:
* Charles uses a packages mapping to map a short name in
the current package's module name space to a location
and additional metadata about what path to traverse into
for its library path.
* Christoph Dorn uses a packages mapping to map a short
name in the current package's module name space to a
location and to an object that overrides the contents of
that package's package.json "descriptor" object, such as
the library path.
Kris Kowal
Agreed, for the purposes of the mappings or packages proposal, the
dependencies property is not useful and should be removed from the
specification. I do not think we should rename "mappings" or
"packages" to make use of the "dependencies" property name.
Narwhal will continue to support "dependencies" as it has before,
since it is so useful for having engine packages mix modules into the
top level name space and other uses, but I plan to migrate it into a
narwhal.dependencies property in future versions. I am in favor of
dropping the "dependencies" property from the specification and
reserving it for a future specification if it proves possible to mix
the strategies in a way that is beneficial outside the scope of
Narwhal.
> Also if you map a package to a URL how would you handle cases where
> I want to keep a copy of all my packages in an alternate location -
> say on a CDN or using an internal server. It would be a maintenance
> nightmare if I had to go in and modify every package.json that I
> depend upon to do so.
I actually think that it's reasonable to solve the web depolyment
problem with tooling; it's necessary to build "lean" versions of
packages for web deployment anyway. I think that using packages on
the web is relevant in so far as that it should be possible create a
loader that can operate on source packages if they're unarchived at a
particular URL. For production deployment, it is still necessary to
compile packages into bundles or transports, at the very least.
Kris Kowal
It's my opinion that a mapping should always be from a short name to
the root of a package, albeit its archive. That seems simplest to me.
If you need to delve into a package, I think it should be through some
other mechanism as Charles and Christoph have proposed.
I think some of your concerns are in addressing existing Narwhal
packages, which are designed for a different packaging scheme, where
their lib directories are simply overlayed in a global, system
installation of packages. You cite the example of Jack. I think the
right way to grandfather these packages in is as Christoph proposes,
to override the "index" and "directories.lib" properties of the
package.
{
"packages": {
"jack": {
"location": "...zip",
"descriptor": {
"index": "lib/jack.js",
"directories": {
"lib": "lib/jack"
}
}
}
}
}
I think it would be lovely if we could set up a migration path so
packages can advertise package.json metadata for both the old and
busted Narwhal approach and the "mappings" new hawtness, but it might
be better to just use the above technique to assist new packages in
using old packages and just hope that the old style disappears in
time.
Regardless, it will always be useful for the consumer of a package to
be able to override its package.json descriptor in cases where a
package was not designed for use in the JavaScript package ecosystem,
like the Google App Engine standard library archive. In Narwhal, we
provide a descriptor for that package in the catalog and write it out
to gae/package.json after installing it.
Kris Kowal
It looks like there is a lot of overlap between the "mappings", "system"
and "using packages" approaches now.
Maybe we can combine them as follows:
Drop "mappings", "using" and "packages" in favor of "dependencies":
package.json ~ {
"dependencies": {
"foo": { // mapping alias
"as": "mapping", // map onto system namespace
"location": "http://domain.com/packages/package1/"
}
}
}
require("foo/<module>")
-> http://domain.com/packages/package1/[lib]/<module>
package.json ~ {
"dependencies": {
"foo": { // informational only in this case
"as": "system", // dump onto system namespace
"location": "http://domain.com/packages/package1/"
}
}
}
require("<module>")
-> http://domain.com/packages/package1/[lib]/<module>
package.json ~ {
"dependencies": {
"foo": { // package alias
"as": "local", // local to package
"location": "http://domain.com/packages/package1/"
}
}
}
require("<module>", "foo")
-> http://domain.com/packages/package1/[lib]/<module>
The package locator can support the following optional properties among
others:
"foo": {
"as": "mapping",
"location": "http://domain.com/packages/package1/",
"path": "<pathToSubPackage>"
"module": "<module>"
}
require("foo")
-> http://domain.com/packages/package1/<pathToSubPackage>/[lib]/<module>
Possible target specifiers:
// zip archive or base URL
"foo": {
"location": "http://domain.com/packages/package1/"
}
// explicit archive types
"foo": {
"location": "http://domain.com/packages/package1.<ext>"
}
"foo": {
"location": "<type>:http://domain.com/packages/package1/"
}
// catalog based
"foo": {
"catalog": "http://domain.com/packages/catalog.json",
"name": "package1",
"version": <version selector>
}
Overwriting package.json for target package local to the dependency:
package.json ~ {
"dependencies": {
"foo": {
"descriptor": {
"directories": {
"lib": "lib/bar"
}
}
}
}
}
Thoughts?
Christoph
No, let's just focus on getting mappings right, drop
dependencies, and drop require2. Keep it simple.
Kris Kowal
+1
-g.
It is not so much about the naming of the property than the approaches
to requiring dependencies. Originally I thought mappings would only deal
with modules directly. Now they deal with packages as well.
Narwhal's "dependencies" property can be nicely grandfathered:
"dependencies": [
"jack"
]
can be equivalent to
"dependencies": {
"jack": ["1.0", "2.0"]
}
and
"dependencies": {
"group": {
"jack": ["1.0", "2.0"]
}
}
and
"dependencies": {
"jack": {
"as": "system",
"location": "http://..."
}
}
and
"dependencies": {
"jack": {
"as": "system",
"catalog": "http://...",
"name": "jack"
}
}
Now instead of dumping the dependency onto the system namespace you use
"as" to map it:
"dependencies": {
"jack": {
"as": "mapping",
"location": "http://...",
"descriptor": {
"directories": {
"lib": "lib/jack"
}
}
}
}
Having two properties, one for mappings and one for proper packages,
will be more confusing I think than having one property with the "as"
feature.
Christoph
The official "as" values can be limited to:
- mapping
- system
I may be able to drop require2 for my purposes completely if "mappings"
is going to deal with packages and is limited to one term.
Christoph