I'm not sure how viable this is currently due to the way pkg-conf is walking up until it finds a package.json file, but it would be nice to be able to set ava config in an .avarc file in the root of the project.
I'm not a huge fan of keeping config in my package.json or of overly verbose cli commands in scripts config. This is also pretty common practice with other tooling frameworks so I don't think it's too crazy of an idea.
I think an initial approach could be to check the current working directory for a .avarc file and if not found fall back to pkgConf.sync.
I would be more than willing to put together a PR if this seems like something you find appealing.
We're intentionally only using package.json for simplicity and consistency.
I'm not a huge fan of keeping config in my package.json
Why? _We_ are not big fans of having an endless amount of meta files in our repos. It's IMHO nice to have one place for all config. This is becoming more and more common, with both AVA, ESLint, XO, nyc, standard, etc, tools doing it.
This is also pretty common practice with other tooling frameworks
Common practice doesn't necessarily mean it's a good one.
okay, thanks for the response
Why? We are not big fans of having an endless amount of meta files in our repos
I am. I prefer separation over concentration, and it's handy to just ctrl-c ctrl-v a dotfile. That said, I think no one is really wrong or right and is just a matter of taste.
From what I can see, to add support for a dotfile there are just a handful of lines to edit in cli.js, profile.js and test/cli.js.
My naive implementation would just grab the config object from .avarc instead of package.json. A one-liner. I'd be really happy to make a PR for this (also because I love this project and I'd like to contribute). The only thing to decide is precedence, and I'll leave package.json first for legacy reasons.
Are there any complications I'm overlooking?
@mattecapu Sorry, we're not interested in having multiple ways to define config.
Bump. For all my projects, my babel configuration is in a dot file, my eslint config is in a dot file, my editor config is in a dotfile, but my ava config has to be in my package.json.
This doesn't seem like a hard feature to implement and pretty much every other major tool in the JS ecosystem allows this style.
This is not going to get implemented until someone can demonstrate an _actual need_.
There are plenty of tools that just use package.json (browserify, nyc, xo, etc.). Adding multiple ways to do something "just because" is a quick road to project bloat. Users then have to ponder which method is "the better fit for their project", instead of just getting on with making things.
You could conceivably use global installs of eslint and babel on projects that don't have a package.json because they aren't Node based (that is less true of babel@6 than it was of babel@5, but whatever). You could make the argument that a package.json requirement for those was restrictive / confusing (it's a weak argument, but it's an argument). Some people have hundreds of rules in their eslint config - another decent argument. Putting an editorconfig in package.json would be nonsensical - it's a separate standard that has nothing to do with Node / npm.
My point here, is demonstrate some _actual need_. "Because I want" is not sufficient. Neither is "because project X does it that way". If not having the option is legitimately preventing you from getting things done, and you demonstrate why, we will happily change our minds.
There're some annoying things on putting the configuration in package.json instead of dot files. Besides which was already said here, every time I npm install --save something my babel config will become from this:
{
"presets": ["es2015", "react", "stage-0"],
"plugins": [
["resolver", {"resolveDirs": ["app"]}]
],
"env": {
"development": {
"plugins": ["react-hot-loader/babel"]
}
}
}
to something like this due to package.json auto re-indent:
{
"presets": [
"es2015",
"react",
"stage-0"
],
"plugins": [
[
"resolver", {
"resolveDirs": [
"app"
]
}
]
],
"env": {
"development": {
"plugins": [
"react-hot-loader/babel"
]
}
}
}
Also, eslintConfig rules are terribly indented in package.json.
Because of this I do prefer to keep it on dotfiles, but I can't do this with ava. š
Here's a concrete use-case. I run a bunch of my integration tests using ava inside a docker container orchestrated via docker-compose. My docker image takes significantly longer (~100x) to rebuild when i modify package.json (since it has to re-run npm install). because i have to define ava defaults in this file, any change to those forces a pretty long and usually unnecessary rebuild. this is a relatively minor inconvenience but i definitely feel the pain when i'm setting up a new project, debugging test timeouts, trying to find an optimal concurrency limit, etc. i can of course specify other defaults on the command line or in custom scripts, but at that point i'm being forced to break from the concept of consolidating these defaults in one place anyways so it seems like having a file like .avarc would just be a better alternative.
i'm not gonna be all torn up inside if this never happens, but given that this project places a high value on developer workflow, productivity, and speed it seemed like a reasonable use-case to share.
Neither is "because project X does it that way".
There are a bunch of "project X" out there that _does_ have a dotfile for config. It was mentioned that nyc did not, and that was true until not so long ago.. I'd say that _"because project X does it that way"_ is a valid argument if there are more than just a few cases.
I don't see how adding support for dotfiles will ruin the experience for those who prefer package.json.
@sindresorhus you are opening the door for every meta tool to now store info in package.json, just think about what that might mean :) It probably won't mean much, except small chance of namespace conflicts, and very large package.json files :)
I was a large proponent of package.json based configs for the exact reasons you've offered here. Once I built a large project with that mentality and had numerous tools and environments to account for it became completely unruly and I quickly changed my tune. Also this is just imposing your thoughts on what is the right way to configure a project rather than allowing a developer to make that choice.
If this is implemented Iād recommend looking at cosmiconfig.
I submitted PR #1627 resolving this issue. It's seriously trivial to implement. Hopefully the maintainers will consider adopting it. I have no interest in maintaining a separate fork for 7 lines of code difference, but find it strange that there has been such a strong pushback against something that has no effect on the library's performance.
I am cross-posting this from #1627 so it stays with the mainline of discussion.
@novemberborn there is a perfectly valid argument from @jtag05. The package.json file has become a dumping ground for configuration. In large projects it makes it huge and unwieldy. Digging through a giant JSON file is not a pleasant experience and is reminiscent of the Java world's XML configs. My team prefers the dotfiles as it neatly separates each tool's configuration that is easily explorable. It is not just because "we are used to it". Every other tool we use manages to support this trivial feature that we value but AVA. It seems absurd that even in the face of community outcry and the presence of a perfectly fine PR the maintainers here ignore the need.
It's been nearly two years since this issue was first raised, and yes alternative configuration files have seen more adoption since then, as have monorepo projects. I'm not ignoring the need. We're trying hard not to overcomplicate what AVA does and this has also applied to how it's configured. There's some effort involved in revisiting this decision that goes beyond the number of lines of code an implementation takes. To that end:
We'd need to consider where AVA would find these alternative files. Currently it finds the closest package.json file from where AVA is invoked. This also determines the working directory for the test processes. Presumably these configuration files can only live next to package.json files? Or do folks here have use cases where alternative configuration files should determine the working directory?
The current trend seems to be for JS-based configuration files. Would folks be upset if AVA supported ava.config.js files but not .avarc files?
Do monorepo folks expect .avarc files to support inheritance?
I can only speak for myself, but I tend to expect my .rc files to live in the project root and would expect the applications to respond based on current working directory.
In regards to the current trend of config.js files I tend to associate that with projects like webpack where the config itself can perform operations. Seeing as AVA currently doesn't operate that way it's hard for me to think of a use case where that would be particularly beneficial, but I also can't say for certain it wouldn't be.
I think that if you were to take the ava.config.js route, being able to define where that lives becomes more of a conversation. It's easy to parse .rc files as configuration whereas a .js file could have implications for regex based tooling. Perhaps adding a --config option to the cli would be in order to allow developers to define whatever .js file they like as well as where it is stored relative to the working directory.
As far as .avarc inheritance, I again can only speak for myself, but I would think that testing configurations are unique enough to not make this a pressing concern.
My use cases follow the same logic that @jtag05 has presented. There isn't much of a use case for a js config file and if there is ever a need for it AVA can implement that at a later date. The current conversation here is to just provide an alternative location with the same implications as the current package.json setup. The MVP implementation requested here is for there to be an option for a co-located rc file that lives next to the package configs. It doesn't need to be more complicated than that as far as inheritance goes. It is a starting point that future changes can build upon if more complicated use cases present themselves. I also like the idea of supporting a --config flag that would allow further customization but it isn't necessary to implement up front.
Why not just use a standard tool like cosmiconfig which handles all these decisions and behavior for you?
@jtag05 @pho3nixf1re, @danawoodman, thanks, I'm just trying to get a fuller picture.
A --config flag might be interesting in monorepo projects. Any thoughts on that?
I'm hesitant in supporting it just so folks can pick different names for the configuration files. And ironically you may want to configure that flag in say the package.json so you don't need to add it into the build tooling š
What would be the expected priority order between these various files? E.g. Babel 6 loads .babelrc before checking package.json. Babel 7 also checks .babelrc.js (and soon babel.config.js I believe), but throws an exception when it finds multiple configurations. How would you expect AVA to behave?
āconfig has highest priority. Then it would be whatever config file is present. I donāt know where package.json fits but Cosmiconfig probably documents which is highest priority. The project Prettier just adopted cosmiconfig after a long discussion and it worked out great. Iām using it too on my own projects and itās very easy to integrate.
Using a prexisting tool that many projects use is much preferable than a āroll your ownā approach in my opinion. Convention is good!
@sindresorhus are you sure youāre not willing to reconsider your stance on this? As outlined, there are a lot of good reasons to make this change and the only reason not to is āwe donāt want multiple ways to configure thingsā. If you use a tool like cosmiconfig you donāt have to make any decisions as the tool does it for you. This means AVA stays simple because it just says āuse cosmiconfig to handle configā. Nearly every major project has a dot file/config file (Babel, Prettier, Mocha, Lerna, nvm, etc.) and I believe it is because there are legitimate reasons to do this. Please reconsider so that users of AVA have options that work for them. Thanks!
@danawoodman I'm also on the core team. We'll be taking all of this into account and go from there.
Meanwhile, please keep the feedback coming!
@novemberborn, good to know! Would be very excited to see this change. Being able to copy a config file from one project to another sure beats manually editing package.json šŗ Also, I really do think having the config file would improve AVAs marketing because I know, at least for myself, that Iāve discovered lots of great tools by looking at a projects config files! Thanks!
After 2 yrs if you still need this that bad I recommend move to a framework that supports your needs. I opened this issue and have long since left Ava for Jest.
I've been thinking about this a bit. I can definitely see some interesting use cases for an ava.config.js configuration file. For instance certain behaviors can be changed dynamically during CI, or when Babel 7 support lands you could inline a Babel plugin.
I see less need for an .avarc file. If you want to write JSON you can do that in package.json. If you want to use a separate file there's ava.config.js. @danawoodman, looking at cosmicconfig it also ships with support for YAML files and config discovery, neither of which are needed with AVA.
I propose the following behavior:
package.json fileava.config.js file existspackage.json file contains an "ava" configuration, and ava.config.js exists, AVA will exit with a warning about ambiguous configurationpackage.json configuration takes precedence over ava.config.jsava.config.js is loaded through esm so can be either a CJS or ESM file. The loader should support ESM transpilation by looking for a thruthy __esModule property: if set then the value of the default property is usedthen property.babelrc.js files in Babel 7)Down the line I'd be interested in exploring a --config argument. It would take precedence over both package.json and ava.config.js files, without ambiguity warnings. Multiple projects in a monorepo could use the same configuration through this argument (this is where passing the project directory to the factory function comes in). Perhaps we'd also support a string value for the "ava" key in package.json to point at a separate configuration file.
Eventually it'd also be good to support ESM for the configuration files, and allow asynchronous values. It'd also be good to have logic that can validate the configuration objects. In the meantime we could ship TS and Flow definitions (though we won't support ava.config.ts configuration files yet).
Thank you @jtag05, @pho3nixf1re and @danawoodman for pushing us on this issue. Please let me know if you're interested in implementing this before I get round to it.
@novemberborn Although I disagree about the JSON format in an 'rc' file I am fine with the proposal. It solves the need and allows for a lot of future flexibility. Thank you for discussing this with us and coming up with a good compromise on the solution.
I know this issue is re-opened, but I'd like to add some points
demonstrate an actual need.
I decided to try Ava today for the first time, because it looks awesome. However, without so much as a --config option I can't use it. My use case: I store my build procedures and dependencies in a single package that is shared with all my projects, so I need to tell each tool where to read configuration from.
Despite how awesome Ava looks, I simply can't use it unless I can tell it where to look for configuration (in the shared package), and I want to avoid unwieldy command line arguments.
Furthermore, when configurations are stored in separate files (particularly in JSON form, or they export a JS object), it makes it easier for projects that use the shared config to be able to extend certain configs for their own needs.
Freedom of choice is the key here, it allows developer flexibility.
In my case, I'm making a setup that allows me to build many JS packages without having to configure each one ever again. Al I have to write in my packages is source with latest language features, and test files. The rest is all abstracted away and shared among all my JS packages. It is only possible (in a clean way) with tools that have configurable config location.
@novemberborn thanks for re-opening!
By the way, hoping this makes it into v1.0.0 so I can come back to try it out later! Mostly everything about Ava seems really awesome, just that the config option is holding me back for now.
@trusktr while less convenient than a --config flag, an initial implementation without it would still let you write an ava.config.js file which re-exports the config from your shared package.
That's true, but means the project has to know about Ava. In my case, projects don't know about the tools, and no configs (even re-export types) need to exist in the project. It's completely decoupled. There's only, at maximum, a few package.json scripts that call generic prod, dev, and test commands on my Builder archetype.
But, true, that could be "good enough" for the time being!
I'm not sure if this bloated thread needs another +1 comment, but my use cases are:
src/__tests__ and dist/__tests__ with different configurations. I'd like to test the dist directory without using babel.ava.config.js from one project to another would be ideal.@good-idea well the feature is approved as of https://github.com/avajs/ava/issues/520#issuecomment-358030492 āĀ it's ready for somebody to pick up š
@novemberborn I'm looking into it right now. I'm a little confused by this line in your comment:
- When invoked, AVA walks the file hierarchy looking for a
package.jsonfile- AVA checks whether a sibling
ava.config.jsfile exists- ---> If this file contains an "ava" configuration, and
ava.config.jsexists, AVA will exit with a warning about ambiguous configuration- Otherwise the
package.jsonconfiguration takes precedence overava.config.js
When you say "this file" are you referring to package.json or ava.config.js? Or, to clarify:
package.json contains an "ava" config property and ava.config.js exports a configuration, warn about ambiguous configuration.ava.config.js exists and does not export a configuration, use package.json.Is that what you're thinking?
@good-idea good catch. I meant to give the ambiguity warning if package.json contains an "ava" config property. I've updated my above comment.
I've also updated the comment to reflect that we should use esm to load the ava.config.js file. That way we can support export default syntax.
Most helpful comment
Here's a concrete use-case. I run a bunch of my integration tests using ava inside a docker container orchestrated via docker-compose. My docker image takes significantly longer (~100x) to rebuild when i modify package.json (since it has to re-run npm install). because i have to define ava defaults in this file, any change to those forces a pretty long and usually unnecessary rebuild. this is a relatively minor inconvenience but i definitely feel the pain when i'm setting up a new project, debugging test timeouts, trying to find an optimal concurrency limit, etc. i can of course specify other defaults on the command line or in custom scripts, but at that point i'm being forced to break from the concept of consolidating these defaults in one place anyways so it seems like having a file like .avarc would just be a better alternative.
i'm not gonna be all torn up inside if this never happens, but given that this project places a high value on developer workflow, productivity, and speed it seemed like a reasonable use-case to share.