{"action":"created","issue":{"url":"https://api.github.com/repos/eslint/eslint/issues/2555","labels_url":"https://api.github.com/repos/eslint/eslint/issues/2555/labels{/name}","comments_url":"https://api.github.com/repos/eslint/eslint/issues/2555/comments","events_url":"https://api.github.com/repos/eslint/eslint/issues/2555/events","html_url":"https://github.com/eslint/eslint/issues/2555","id":77401581,"number":2555,"title":"New rule suggestion: require-style","user":{"login":"denis-sokolov","id":113721,"avatar_url":"https://avatars.githubusercontent.com/u/113721?v=3","gravatar_id":"","url":"https://api.github.com/users/denis-sokolov","html_url":"https://github.com/denis-sokolov","followers_url":"https://api.github.com/users/denis-sokolov/followers","following_url":"https://api.github.com/users/denis-sokolov/following{/other_user}","gists_url":"https://api.github.com/users/denis-sokolov/gists{/gist_id}","starred_url":"https://api.github.com/users/denis-sokolov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/denis-sokolov/subscriptions","organizations_url":"https://api.github.com/users/denis-sokolov/orgs","repos_url":"https://api.github.com/users/denis-sokolov/repos","events_url":"https://api.github.com/users/denis-sokolov/events{/privacy}","received_events_url":"https://api.github.com/users/denis-sokolov/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/eslint/eslint/labels/question","name":"question","color":"cc317c"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":10,"created_at":"2015-05-17T21:20:51Z","updated_at":"2015-05-29T18:48:10Z","closed_at":null,"body":"_Combining ideas of #2539, #2541, #2542 into one rule. If this looks good, we shall close the other proposals._\r\n\r\nI would like to add a new rule to eslint - `require-style`.\r\nIt would allow enforcing a particular module structure by validating local file `require` calls against multiple possible options.\r\n\r\nThe rule is very specific to a particular workflow, and definitely should be off by default (this choice is irrelevant with 1.0.0 using `--reset`).\r\n\r\n# Options\r\n\r\n## Extension\r\n\r\nWhether to require, forbid, or ignore file extension in `require` calls. Perhaps a configurable list of extensions that need to be left out.\r\n\r\nThe following would be invalid when the option is enabled:\r\n```javascript\r\nrequire('./foo.js');\r\nrequire('./foo/bar.js');\r\nrequire('../foo.js');\r\nrequire('foo/bar.js');\r\n```\r\n\r\nThe following would still be valid when the rule is enabled:\r\n```javascript\r\nrequire('./foo');\r\nrequire('./foo/bar');\r\nrequire('../foo');\r\nrequire('foo/bar');\r\n```\r\n\r\nThe use case for requiring the extension is - there is a common programming pattern where you start with small and simple implementations and you can later grow them as needed. What started as `foo.js` can grow too long and need its own subdirectory to be split off into many files. This transition is smooth if everybody who depends on `foo` only used `require('./foo')`, but if dependents used `require('./foo.js')`, then either dependents need to be modified, or a stub `foo.js` needs to remain.\r\n\r\nThe error thus would prevent a maintainability error by a developer.\r\n\r\n## Up\r\n\r\nWhether to forbid requiring up (`../`) entirely, or more than some amount of levels up.\r\n\r\n\r\nThe following would be invalid when the rule is enabled:\r\n```javascript\r\nrequire('../foo');\r\nrequire('./../bar');\r\nrequire('../../bar');\r\n```\r\n\r\nThe use case is - it is sometimes customary to mirror the project module dependency tree using the filesystem. That makes the project structure considerably easier to understand, it almost guarantees a lack of an intricate web of dependencies inside a project.\r\n\r\nThe option thus would prevent a semantic error by a developer. It would also prevent developers from the temptation of using the up selector \"just this once\".\r\n\r\n## Down\r\n\r\nWhether to forbid requiring into subdirectories (`./foo/bar`), or more than some amount of levels deep.\r\n\r\nThe following would be invalid when the option is enabled:\r\n```javascript\r\nrequire('./foo/bar'); // 1 level deep\r\nrequire('./foo/bar.js');\r\nrequire('./foo/bar/quux'); // 2 levels deep\r\nrequire('../foo/bar');\r\n```\r\n\r\nIf the allowed number of levels is, say, 1, only the following among the previous would be invalid:\r\n```javascript\r\nrequire('./foo/bar/quux'); // 2 levels deep\r\n```\r\n\r\nThe following would still be valid when the option is enabled:\r\n```javascript\r\nrequire('./foo'); // Current (0-th) level\r\nrequire('../foo'); // Up\r\n```\r\n\r\nThe option intent, module structure, has no effect on 3rd party modules, thus this would be valid regardless of the option setting:\r\n```javascript\r\n require('unicode-7.0.0/categories/Lu/symbols');\r\n```"},"comment":{"url":"https://api.github.com/repos/eslint/eslint/issues/comments/106901571","html_url":"https://github.com/eslint/eslint/issues/2555#issuecomment-106901571","issue_url":"https://api.github.com/repos/eslint/eslint/issues/2555","id":106901571,"user":{"login":"mathieumg","id":1624812,"avatar_url":"https://avatars.githubusercontent.com/u/1624812?v=3","gravatar_id":"","url":"https://api.github.com/users/mathieumg","html_url":"https://github.com/mathieumg","followers_url":"https://api.github.com/users/mathieumg/followers","following_url":"https://api.github.com/users/mathieumg/following{/other_user}","gists_url":"https://api.github.com/users/mathieumg/gists{/gist_id}","starred_url":"https://api.github.com/users/mathieumg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mathieumg/subscriptions","organizations_url":"https://api.github.com/users/mathieumg/orgs","repos_url":"https://api.github.com/users/mathieumg/repos","events_url":"https://api.github.com/users/mathieumg/events{/privacy}","received_events_url":"https://api.github.com/users/mathieumg/received_events","type":"User","site_admin":false},"created_at":"2015-05-29T18:48:10Z","updated_at":"2015-05-29T18:48:10Z","body":"> I don't know that we want to cover both with one rule\r\n\r\nWhy not? It only applies to the \"path\" part for both, so the distinction wouldn't serve any purpose:\r\n\r\n```js\r\nrequire(\"PATH\");\r\nimport a from \"PATH\";\r\nimport {a} from \"PATH\";\r\nimport a, {b} from \"PATH\";\r\nimport a, {b as c} from \"PATH\";\r\n// etc.\r\n```"}}