bower/bower — pull request #963 by josh (2013-11-11 11:57:52+00:00)
Title: Clarify main spec

As sparked by https://github.com/bower/bower/issues/935, we need to
properly respecify the `main` property. The original documentation has
mostly been lost.

Firstly, we need to preserve the original intent to some extent since we
are past 1.0 and we should not be removing things from the spec at this
point.

Second, I want to take this an opportunity to enhance `main` to a
degree.

The idea behind `main` is inspired from node.js usage. It is an alias
for “requiring the component by name”. What “requiring” means is up to
the package manager, not bower.

`main` does not have anything to do with being a manifest of the files
needed to use the package. This is an entirely separate concern. I
mostly disagree with the change in the google doc that says “The primary
acting files necessary to use your package."

`main` presence is always entirely optional and is a convenience for
requiring the full component path. Its implicit that an omitted `main`
means `index.*`. This also comes from node.js convention.

## Usage in the wild

**Packages**

The majority of packages are simple single js files. They use the most
basic usage of `main.`

```
"main": "foo.js"
```

There are packages already using the Array format that package different
file types. See [qunit’s
bower.json](https://github.com/jquery/qunit/blob/master/bower.json).

```
"main": ["qunit/qunit.js", "qunit/qunit.css"],
```

Requiring `quint` from a JS build tool would choose
`qunit/qunit/qunit.js`. Requiring from a CSS build tool would choose
`qunit/qunit/qunit.css`.

**Build tools**

Existing build tools already implement both `main`s single value and
Array of values. See
[sprockets](https://github.com/sstephenson/sprockets) and
[yeoman/grunt-bower-requirejs](https://github.com/yeoman/grunt-bower-requirejs).

For RequireJS, `main` can automatically setup a path alias so you don’t
have to type `../bower_components/qunit/qunit/qunit.js`.

``` js
requirejs.config({
paths: {
qunit: “../bower_components/qunit/qunit/qunit.js”
}
})
```

Can be automatically configured by build tools.

## Proposal

1. `main` can be a path to a file in the package that serves as an alias
of the package name.
2. `main` can be an Array of paths in the package. There must only be
one path per file extension. This usage is considered deprecated. Build
tools and package managers should still support the usage. Packages
themselves should migrate to the 3 option as implementation roll out.
3. `main` can be an Object with file extension keys mapping to a single
path. This is preferred over the Array definition as it makes it clear
only one file can exist per extension.

**extensions not types**

I think “extensions” make more sense over “types” (script, style, font).
For one, we’d have to spec all the the types. Bower is about all assets,
not about one specific type and the ones we can think of. Maybe you want
to package to contain text or data files. We shouldn’t stop you because
it doesn’t fit inside a predefined bucket.

Extensions express capabilities to build tools. Some tools can’t handle
files that will processing. Require.js for an example will never know
what to do with a `.coffee` file. It needs `.js` files. It makes sense
for it to just use the file of `package[‘main’][‘js’]`. Other tools like
Sprockets are aware of both `.css`, `.scss`, `.less`, etc and can choose
the based on which preprocessor the user has available.

```
“main”: {
coffee: “foo.coffee”,
js: “foo.js”
}
```

Seems acceptable to me. Coffeescript aware tools can prefer building
from source, while other tools may just pick the compiled version and be
fine. This helps Sprocket’s automatic source map generation.

## Not comprehensive

We will still need **new** properties to cover the concepts of “all
files”. And I would also like to address non-main files with some sort
of directories aliases.

## Spec

So I’m not quite sure where the spec even lives now or where I should be
drafting up changes. Seems like docs have been moved out of the README.
Is the google doc the only thing we have? This diff really doesn't change anything yet.