-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: 'configurator' field in package.json #215
Comments
One thing I know about npm is it has a Maybe extend this, to check if I do like the idea of this though. |
Yeah, it serves a different purpose though (we could probably use it for stuff like choosing ports in the future). What I suggest here is a way to “redirect” tool-specific configuration. You can use |
I really like the idea though, I use |
There's already a thousand ways that all those tools can figure out where to find the configuration, it's really unclear to me that adding yet another one is the right solution. Also, adding a hardcoded path to the config that the tools can read means that anybody can also read it and it's not a blackbox anymore. Proposal instead: Have the IDEs read package.json and if there's a script called eslint, then use it instead of the global eslint. Then, we would add an opaque script that calls eslint with --config=opaquepath/eslintrc |
@vjeux I don't think that solves the problem of the proliferation of information in the package.json that the user shouldn't need to worry about. They will at a minimum end up seeing a script for |
I like the simplicity of this. I agree with @ForbesLindesay this doesn’t solve the config proliferation problem though so I‘m not sure it’s much better than the status quo. This is more or less what we’re doing anyway with Also, this doesn’t solve the Flow issue, does it? |
I think the idea would be that you would run |
I'm not sure I understand the issue with flow being a server. If the IDE uses it as a server it is going to call it once with the options. If it uses it as a standalone tool it's going to call it multiple times. Having a wrapper that sets the config flag shouldn't change anything? The goal here is to tell the IDE/CI... how to invoke the tools properly configured without letting them introspect the actual configuration. This way they don't end up relying on specifics. |
The downside with #215 (comment) is that every IDE/plugin would need to implement this. So, for each of N tools (ESLint, Flow), there would be M plugins (Atom, Sublime), and NxM integrations that would need to do it this way (ESLint for Atom, ESLint for Sublime, Flow for Atom, ...). Whereas if we do this on the tool level as suggested in #215 (comment), we only need the N tools to integrate this. IDEs already call the tools with no arguments and rely on the tools to know how to discover configuration. |
Would it? Don't those tools just effectively run ESLint? If the |
Sorry, I meant @vjeux’s proposal. Edited the message. |
A different approach is used in Python packaging with a file in the package root named 'setup.cfg' into which tools can have have a section (or not) with their configurations: https://docs.python.org/3/distutils/configfile.html When the tool is invoked it reads it's config from the setup.cfg. |
@saschwarz This is very similar to how |
@vjeux The issue is that flow is way more complicated than just "run it once" or "run it many times". There is |
@gaearon Sorry I wasn't being clear. I meant it as an additional file just for tool configs; the |
I really dig the concept of abstracting away the build configurations. Copy/pasting scripts to handle bundling or workflow management has been plaguing us since the days of grunt and gulp tasks. Would it make sense to allow This may be unnecessary complexity, as default configs can still be used, but wanted to see what you guys thought. Something like - {
"name": "my-app",
"version": "0.0.1",
"private": true,
"devDependencies": {
"react-scripts": "0.1.0",
"other-scripts": "0.1.0"
},
"dependencies": {...},
"scripts": {...},
"configurator": { // 😀
"flow": "react-scripts",
"eslint": "other-scripts"
}
} |
@gaearon why not use {
"name": "x",
"version": "y",
"config": {
"eslint": "react-scripts",
"flow": "react-scripts"
}
} |
This feels like an oversimplification of the complexity of how tools interact with one another. There is a place for extending configuration in just about every tool in existence, and the way those need to work vary between tool to tool. If you are to avoid wrapping every tool in one of those |
I agree with @thejameskyle there. This seems like a potentially dangerous attempt to generalize from n = 1. It's worth at least waiting to see how things pan out before promulgating a new standard that multiple tooling vendors would be expected to follow. |
Good points. I think the problem is still worth exploring but I'd like to hear more alternative solutions for delegating configuration. |
tl;dr
Add a field to
package.json
that tells ESLint, Flow, other tools, where to look for configs.Useful for zero-conf opinionated packages like
create-react-app
andstandard
.As a community, we’ve mostly solved the problem of nested, extendable configuration. ESLint does this really well, Babel also does this.
However, I think that this project gaining 4k stars in 4 days proves that there is a market for non-configurable opinionated tools hiding dependencies from the user. I’d like to give props to standard for being one of the first tools demonstrating this is a viable model (it doesn’t matter whether I agree with its choices).
The problem I‘m starting to see is that many amazing tools, like ESLint and Flow, don’t currently play very well with this approach out of the box.
Problem
ESLint
ESLint is very flexible but if you want IDE integration, you need to tell it where your config is.
This is why our otherwise zeroconf
package.json
now has to look like this:Yes, one extra field is not a high price, but it is already a bit frustrating that we have to hardcode ESLint there. We would like to treat it as an implementation detail, to the extent that it is reasonable. (e.g.
eslint-ignore
comments are fine, but putting paths to configs into user’spackage.json
is annoying)Also, it doesn’t even solve the problem completely because ESLint will look for plugins relative to the project root, so any transitive plugin dependencies won’t be discovered with npm 2 (or in some cases, admittedly not likely with our tool, with npm 3). You can find the discussion about this in eslint/eslint#3458.
Flow
Flow poses a similar problem for us, although in a more unfortunate way. We can’t even tell Flow to look at a different config. When you run
flow init
, it creates.flowconfig
in the project root, and that’s it. This is reasonable if the user plans to change it (which seems necessary for lib integrations), but we can’t even influence the default generated config in any way. And unfortunately, for a number of reasons, the default generated config won’t work forcreate-react-app
.If you want Flow to work, you need to replace the config generated by
flow init
with this one:And we don’t want to do this automatically because:
react-scripts
, so if we generate Flow config before the person actually starts using Flow, by the time they start using it, their checks might fail because something changed on our side.Solution?
I don’t know if there is a nice solution to this, but here is my proposal. This is how I want
package.json
to look:ESLint would then use
react-scripts/config
as the base directory for its regular config/plugin search mechanism. So it would look for.eslintrc
,package.json
, etc, in that directory, and resolve plugin modules relative to it. Since ESLint wants to stay configurable, it will also look for overrides in the current folder (and use its regular override mechanism), but this would just addconfigurator
as a first-class citizen for providing configuration.Similarly, Flow would look into that project when running
flow init
, and if it finds.flowconfig
inreact-scripts/config
, it would use that instead of its default config. This gives us a way to own the default configuration even if the user is on their own. In the future, Flow could support merging${configurator}/config/.flowconfig
with local.flowconfig
—similar to how ESLint would work if it implemented this feature.This would benefit an ecosystem by fostering development of opinionated presets of preconfigured tools. If you’re a tool, honor
configurator
inpackage.json
and try reading configuration from${configurator}/config
in addition to your normal lookup paths. If you’re a preset author, you can forkreact-scripts
or any other configurator, make some changes to it, and keep it simple to adopt your preset: just swappingconfigurator
is all end users need to do.What do you think? Am I missing something?
The text was updated successfully, but these errors were encountered: