{"action":"created","issue":{"url":"https://api.github.com/repos/babel/babel/issues/7358","repository_url":"https://api.github.com/repos/babel/babel","labels_url":"https://api.github.com/repos/babel/babel/issues/7358/labels{/name}","comments_url":"https://api.github.com/repos/babel/babel/issues/7358/comments","events_url":"https://api.github.com/repos/babel/babel/issues/7358/events","html_url":"https://github.com/babel/babel/pull/7358","id":295683068,"number":7358,"title":"Allow more flexible file-based configuration while preventing .babelrcs from breaking things","user":{"login":"loganfsmyth","id":132260,"avatar_url":"https://avatars1.githubusercontent.com/u/132260?v=4","gravatar_id":"","url":"https://api.github.com/users/loganfsmyth","html_url":"https://github.com/loganfsmyth","followers_url":"https://api.github.com/users/loganfsmyth/followers","following_url":"https://api.github.com/users/loganfsmyth/following{/other_user}","gists_url":"https://api.github.com/users/loganfsmyth/gists{/gist_id}","starred_url":"https://api.github.com/users/loganfsmyth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/loganfsmyth/subscriptions","organizations_url":"https://api.github.com/users/loganfsmyth/orgs","repos_url":"https://api.github.com/users/loganfsmyth/repos","events_url":"https://api.github.com/users/loganfsmyth/events{/privacy}","received_events_url":"https://api.github.com/users/loganfsmyth/received_events","type":"User","site_admin":false},"labels":[{"id":311566360,"url":"https://api.github.com/repos/babel/babel/labels/PR:%20Breaking%20Change%20:boom:","name":"PR: Breaking Change :boom:","color":"fbca04","default":false},{"id":311566482,"url":"https://api.github.com/repos/babel/babel/labels/PR:%20New%20Feature%20:rocket:","name":"PR: New Feature :rocket:","color":"fbca04","default":false},{"id":438614032,"url":"https://api.github.com/repos/babel/babel/labels/Priority:%20High","name":"Priority: High","color":"b60205","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":37,"created_at":"2018-02-08T22:08:27Z","updated_at":"2018-03-24T10:35:23Z","closed_at":null,"author_association":"OWNER","pull_request":{"url":"https://api.github.com/repos/babel/babel/pulls/7358","html_url":"https://github.com/babel/babel/pull/7358","diff_url":"https://github.com/babel/babel/pull/7358.diff","patch_url":"https://github.com/babel/babel/pull/7358.patch"},"body":"| Q                        | A <!--(Can use an emoji 👍) -->\r\n| ------------------------ | ---\r\n| Fixed Issues?            | Fixes #6766\r\n| Patch: Bug Fix?          |\r\n| Major: Breaking Change?  | Y\r\n| Minor: New Feature?      | Y\r\n| Tests Added + Pass?      |\r\n| Documentation PR         | \r\n| Any Dependency Changes?  |\r\n| License                  | MIT\r\n\r\nAlright! Let's do this. This is my proposal for fixing the issues spelled out in #6766. This PR does the following:\r\n\r\n### When searching for `.babelrc` files for a given file, stop at package.json\r\n\r\nCurrently, Babel will look all the way up the directory hierarchy. This change prevents config files outside of a given package from potentially breaking your project's builds, which has been a problem occasionally. Also potentially frustrating for projects that integrate Babel, because they often allow users can _optionally_ create .babelrc files, and if they haven't created one, but have one in a parent folder, it might find a bad config.\r\n\r\nThe downside here is that monorepos like\r\n\r\n```\r\n.babelrc\r\npackages/\r\n  one/\r\n    package.json\r\n    index.js\r\n  two/\r\n    package.json\r\n    index.js\r\n```\r\nwill fail to find the `.babelrc`. I think that is acceptable because there are alternatives:\r\n\r\n1. Have each module have their own `.babelrc` doing `{ extends: \"../../.babelrc\" }` to explicitly load the config from a parent directory.\r\n2. See the next point.\r\n\r\n\r\n### Adds support for a `babel.config.js` file along the lines of what Webpack does\r\n\r\nThis PR adds a `root` option (that defaults to the working directory), that defines the conceptual \"root\" of your project. This location is used to automatically search for the config file `babel.config.js`. Optionally instead the user can specify `configFile: \"./foo.js\"` or whatever they'd like.\r\n\r\nThe file itself behaves just like a `.babelrc.js` file would, but is not loaded relative to the individual file being compiled, and thus has more flexibility in what files it applies to. For instance, if users are symlinking in `node_modules` or something, it is currently impossible for a `.babelrc` to configure their builds any way other than by hard-coding their config into webpack.config.js, which is not great.\r\n\r\nWith our new support for `overrides` it's now easy for users to have a single `babel.config.js` which could define the full build process for their project, when used alongside `env`.\r\n\r\n\r\n### Only search for a `.babelrc` for files inside the `root` (which defaults to cwd) (unless the user opts out)\r\n\r\nSpecifically excluding `node_modules` folders. Given the path of the file being compiled, if the path relative to the root contains `node_modules`, do not attempt to search for `.babelrc` files. This essentially has the effect of making `.babelrc` files only useful by default in a \"root\" package, which is essentially how most people used them.\r\n\r\nThis (potentially combined with the previous `babel.config.js`) allows users to _safely_ do\r\n```\r\ntest: /\\.js$/,\r\nloader: \"babel-loader\",\r\n```\r\nwithout risking loading a `.babelrc` from a node_modules that was not intented to apply to the current project. There _are_ still other edge cases to compiling `node_modules`, but this was a particularly dangerous edge case, especially for things like `babel-register` that don't have a nice `rules` list like Webpack does.\r\n\r\nTo allow people to opt into `.babelrc` usage, potentially for local development, this PR allows Babel's `babelrc` option to be an array, so users could do\r\n\r\n```\r\ntest: /\\.js$/,\r\nloader: \"babel-loader\",\r\noptions: {\r\n  babelrc: [\r\n    \".\",\r\n    \"../some-linked-package\"\r\n  ]\r\n}\r\n```\r\nwhich would also attempt to load `.babelrc` files for anything within that package. Alternatively\r\n\r\n```\r\noptions: {\r\n  babelrc: [\r\n    \".\",\r\n    \"node_modules/foo\"\r\n  ]\r\n}\r\n```\r\nif there was a specific package you wanted to load a config for, and were confident in its installation location.\r\n\r\n\r\n### What this PR does _not_ do\r\n\r\nPart of the reason I personally had so much back and forth on this issue is because it wasn't necessarily obvious what `root` should actually be responsible for. For instance, if Babel is passed a file that is not in the `root`, should it compile it at all? As is hopefully clear, my answer there was yes.\r\n\r\nOne core thing that this PR does is that it leaves it up to the individual _callers_ of Babel to decide what files should actually be passed to Babel in the first place. Alongside that, if you configure Babel with a custom `root` or `configFile` or `babelrc` array, the user will have to decide if those need to be replicated between Babel callers, because they are top-level Babel options, not ones that can be included inside a config file (for obvious reasons).\r\n\r\n### What is left\r\n\r\nThis PR has no tests, and an unoptimized implementation of a lot of stuff. It will need more work before it can land, but I want to post it now to get a feel for what everyone thinks."},"comment":{"url":"https://api.github.com/repos/babel/babel/issues/comments/375868426","html_url":"https://github.com/babel/babel/pull/7358#issuecomment-375868426","issue_url":"https://api.github.com/repos/babel/babel/issues/7358","id":375868426,"user":{"login":"novemberborn","id":33538,"avatar_url":"https://avatars0.githubusercontent.com/u/33538?v=4","gravatar_id":"","url":"https://api.github.com/users/novemberborn","html_url":"https://github.com/novemberborn","followers_url":"https://api.github.com/users/novemberborn/followers","following_url":"https://api.github.com/users/novemberborn/following{/other_user}","gists_url":"https://api.github.com/users/novemberborn/gists{/gist_id}","starred_url":"https://api.github.com/users/novemberborn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/novemberborn/subscriptions","organizations_url":"https://api.github.com/users/novemberborn/orgs","repos_url":"https://api.github.com/users/novemberborn/repos","events_url":"https://api.github.com/users/novemberborn/events{/privacy}","received_events_url":"https://api.github.com/users/novemberborn/received_events","type":"User","site_admin":false},"created_at":"2018-03-24T10:35:23Z","updated_at":"2018-03-24T10:35:23Z","author_association":"CONTRIBUTOR","body":"@loganfsmyth \r\n\r\n> Essentially what this PR allows is for babelrc to be a string (defaulting to the value of root), or an array. So for your comment\r\n> \r\n>> For files inside the root, but not in any way inside node_modules, hierarchically search for .babelrc until the root is encountered\r\n> \r\n> It is totally accurate, but it would be \"for files inside any of the babelrc values, if it is a single string, or an array of strings.\r\n\r\nAh so Babel will hierarchically search for `.babelrc` files until any of the paths in the `babelrc` option is encountered. So you could segment the search boundaries inside your package on a per-directory basis. Am I getting that right?"}}
{"actor":{"display_login":"novemberborn"}}