sbt/sbt-rjs — pull request #5 by huntc (2014-05-14 06:51:17+00:00)
Title: configuring the optimizer is not as easy as it should be

To configure the optimizer we can define an `app.build.js` file in our project root directory. This file must define a function returning the configuration options to supply to the requirejs optimizer, as in [the provided template](https://github.com/sbt/sbt-rjs/blob/master/src/main/resources/template.build.js). This function is injected several parameters depending on the current application.

I think there are the following problems with this approach and its current implementation:

- *boilerplate*: the function defined in the file is given several parameters that are just forwarded to the returned object (`appDir`, `baseUrl`, `dir`, `paths`). It would be better if users wouldn’t even have to deal with these parameters at all ;
- *extensibility*: the `paths` parameter is prefilled so that [WebJars dependencies are ignored by the optimizer](https://github.com/sbt/sbt-rjs/blob/892dd41092811d68905a115864b20812ca451f03/src/main/scala/com/typesafe/sbt/rjs/SbtRjs.scala#L133). However, if one wants to add its custom path, it has to extend the object (e.g. `paths['foo'] = 'bar';`) instead of writing the path directly in the returned object (e.g. `paths: { foo: 'bar' }`), which is less idiomatic[¹] ;
- *scattery*: some configuration settings are set from the sbt build configuration (e.g. `RjsKeys.baseUrl = "/foo"`), but if more control is needed users have to write their own `app.build.js` file, it would be better to have everything at the same place ;
- *fragility*: the code supplying the the parameters just performs [text substitution](https://github.com/sbt/sbt-rjs/blob/892dd41092811d68905a115864b20812ca451f03/src/main/scala/com/typesafe/sbt/rjs/SbtRjs.scala#L127-L135), which wouldn’t work if e.g. one added a blank line at the end of its file.

Maybe it would be better to specify the requirejs configuration completely from the sbt configuration:

```scala
RjsKeys.build := Json.obj(
"modules" -> Json.arr(
Json.obj("name" -> "main")
),
// etc. with other settings
)
```

That would make it still possible to supply values based on the current sbt settings:

```scala
"baseUrl" -> (resourcesManaged in rjs).value / "appdir"
```

And, because the control would be inverted, it would be possible to let the user define its settings and to complete them with default settings, when not supplied. So users wouldn’t need to deal with `appDir`, `baseUrl`, `dir` and `paths` if they don’t need to customize them.

[¹] Note that there is a `RjsKeys.paths` key that suggests that it should be possible to override paths right from the sbt configuration, however the value of this key is not passed to the `app.build.js` function. I think it is probably an issue, isn’t it?