no-multi-comp.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /**
  2. * @fileoverview Prevent multiple component definition per file
  3. * @author Yannick Croissant
  4. */
  5. 'use strict';
  6. const values = require('object.values');
  7. const Components = require('../util/Components');
  8. const docsUrl = require('../util/docsUrl');
  9. const report = require('../util/report');
  10. // ------------------------------------------------------------------------------
  11. // Rule Definition
  12. // ------------------------------------------------------------------------------
  13. const messages = {
  14. onlyOneComponent: 'Declare only one React component per file',
  15. };
  16. module.exports = {
  17. meta: {
  18. docs: {
  19. description: 'Disallow multiple component definition per file',
  20. category: 'Stylistic Issues',
  21. recommended: false,
  22. url: docsUrl('no-multi-comp'),
  23. },
  24. messages,
  25. schema: [{
  26. type: 'object',
  27. properties: {
  28. ignoreStateless: {
  29. default: false,
  30. type: 'boolean',
  31. },
  32. },
  33. additionalProperties: false,
  34. }],
  35. },
  36. create: Components.detect((context, components, utils) => {
  37. const configuration = context.options[0] || {};
  38. const ignoreStateless = configuration.ignoreStateless || false;
  39. /**
  40. * Checks if the component is ignored
  41. * @param {Object} component The component being checked.
  42. * @returns {Boolean} True if the component is ignored, false if not.
  43. */
  44. function isIgnored(component) {
  45. return (
  46. ignoreStateless && (
  47. /Function/.test(component.node.type)
  48. || utils.isPragmaComponentWrapper(component.node)
  49. )
  50. );
  51. }
  52. return {
  53. 'Program:exit'() {
  54. if (components.length() <= 1) {
  55. return;
  56. }
  57. values(components.list())
  58. .filter((component) => !isIgnored(component))
  59. .slice(1)
  60. .forEach((component) => {
  61. report(context, messages.onlyOneComponent, 'onlyOneComponent', {
  62. node: component.node,
  63. });
  64. });
  65. },
  66. };
  67. }),
  68. };