Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 1 | # About //components |
| 2 | |
| 3 | This directory is meant to house features or subsystems that are used in more |
| 4 | than one part of the Chromium codebase. |
| 5 | |
John Abd-El-Malek | b0608b7 | 2022-08-12 19:38:22 | [diff] [blame] | 6 | ## Use cases: |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 7 | |
| 8 | * Features that are shared by Chrome on iOS (`//ios/chrome`) and Chrome on |
| 9 | other platforms (`//chrome`). |
| 10 | * Note: `//ios` doesn't depend on `//chrome`. |
| 11 | * Features that are shared between multiple embedders of content. For example, |
| 12 | `//chrome` and `//android_webview`. |
| 13 | * Features that are shared between Blink and the browser process. |
| 14 | * Note: It is also possible to place code shared between Blink and the |
| 15 | browser process into `//third_party/blink/common`. The distinction comes |
| 16 | down to (a) whether Blink is the owner of the code in question or a |
| 17 | consumer of it and (b) whether the code in question is shared by Chrome |
| 18 | on iOS as well. If the code is conceptually its own cross-process |
| 19 | feature with Blink as a consumer, then `//components` can make sense. If |
| 20 | it's conceptually Blink code, then `//third_party/blink/common` likely |
| 21 | makes more sense. (In the so-far hypothetical case where it's |
| 22 | conceptually Blink code that is shared by iOS, raise the question on |
| 23 | chromium-dev@, where the right folks will see it). |
| 24 | |
John Abd-El-Malek | b0608b7 | 2022-08-12 19:38:22 | [diff] [blame] | 25 | Note that the above list is meant to be exhaustive. A component should not be |
| 26 | added just to separate it from other code in the same layer that is the only |
David Dorwin | 154becc | 2022-10-20 20:55:58 | [diff] [blame] | 27 | consumer; that can be done with strict `DEPS` or GN `visibility` rules. |
John Abd-El-Malek | b0608b7 | 2022-08-12 19:38:22 | [diff] [blame] | 28 | |
Ted Choc | 422440e3 | 2023-04-06 22:48:03 | [diff] [blame] | 29 | ## Before adding a new component |
| 30 | |
| 31 | * Is there an existing component that you can leverage instead of introducing |
| 32 | a new component? |
| 33 | * Can you restructure an existing component to logically encompass the |
| 34 | proposed new code? |
| 35 | * As a general rule, we prefer fewer top level components. So, consider |
| 36 | whether adding sub-features within an existing component is more |
| 37 | appropriate for your use case. |
| 38 | * Historically, dependency issues were simply addressed by adding new |
| 39 | components. But, you can (and it is preferred to) solve that by |
| 40 | restructing an existing component and its dependencies where possible. |
| 41 | |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 42 | ## Guidelines for adding a new component |
| 43 | |
David Dorwin | 154becc | 2022-10-20 20:55:58 | [diff] [blame] | 44 | * You will be added to an `OWNERS` file under `//components/{your component}` |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 45 | and be responsible for maintaining your addition. |
Ted Choc | 422440e3 | 2023-04-06 22:48:03 | [diff] [blame] | 46 | * You must specify at least two OWNERS for any new component. |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 47 | * A `//components/OWNER` must approve of the location of your code. |
Ted Choc | 422440e3 | 2023-04-06 22:48:03 | [diff] [blame] | 48 | * The CL (either commit message or comment) must explicitly specify what [use |
| 49 | case(s)](#use-cases) justify the new component. |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 50 | * Code must be needed in at least 2 places in Chrome that don't have a "higher |
| 51 | layered" directory that could facilitate sharing (e.g. `//content/common`, |
| 52 | `//chrome/utility`, etc.). |
Colin Blundell | 17af29b | 2022-08-31 07:25:33 | [diff] [blame] | 53 | * The CL adding a new component should be substantial enough so that |
| 54 | //components/OWNERS can see its basic intended structure and usage before |
| 55 | approving the addition (e.g., it should not just be an empty shell). |
Ted Choc | 422440e3 | 2023-04-06 22:48:03 | [diff] [blame] | 56 | * You must add a [`DIR_METADATA`](https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md) |
| 57 | file under `//components/{your component}` with an appropriately specified |
| 58 | bug-component. |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 59 | |
| 60 | ## Dependencies of a component |
| 61 | |
| 62 | Components **cannot** depend on the higher layers of the Chromium codebase: |
| 63 | |
| 64 | * `//android_webview` |
| 65 | * `//chrome` |
| 66 | * `//chromecast` |
| 67 | * `//headless` |
| 68 | * `//ios/chrome` |
| 69 | * `//content/shell` |
| 70 | |
| 71 | Components **can** depend on the lower layers of the Chromium codebase: |
| 72 | |
| 73 | * `//base` |
| 74 | * `//gpu` |
| 75 | * `//mojo` |
| 76 | * `//net` |
Alan Screen | 1c738270 | 2020-09-25 00:07:15 | [diff] [blame] | 77 | * `//printing` |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 78 | * `//ui` |
| 79 | |
| 80 | Components **can** depend on each other. This must be made explicit in the |
| 81 | `DEPS` file of the component. |
| 82 | |
Matt Falkenhagen | f28d6d7 | 2021-05-27 13:43:41 | [diff] [blame] | 83 | Components **can** depend on `//content/public`, `//ipc`, and |
| 84 | `//third_party/blink/public`. This must be made explicit in the `DEPS` file of |
| 85 | the component. If such a component is used by Chrome for iOS (which does not |
| 86 | use content or IPC), the component will have to be in the form of a [layered |
Colin Blundell | 20752075 | 2024-01-02 21:21:33 | [diff] [blame] | 87 | component](https://www.chromium.org/developers/design-documents/layered-components-design). |
| 88 | In particular, code that is shared with iOS *cannot* depend on any of the |
| 89 | above modules; those dependencies must be injected into the shared code (either via |
| 90 | a layered component structure or directly from the embedder for simple dependencies |
| 91 | such as booleans that can be passed as constructor parameters). It is not |
| 92 | an acceptable solution to conditionally depend on the above modules in code shared |
| 93 | with iOS. |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 94 | |
| 95 | `//chrome`, `//ios/chrome`, `//content` and `//ios/web` **can** depend on |
| 96 | individual components. The dependency might have to be made explicit in the |
| 97 | `DEPS` file of the higher layer (e.g. in `//content/browser/DEPS`). Circular |
| 98 | dependencies are not allowed: if `//content` depends on a component, then that |
| 99 | component cannot depend on `//content/public`, directly or indirectly. |
| 100 | |
| 101 | ## Structure of a component |
| 102 | |
Matt Falkenhagen | f28d6d7 | 2021-05-27 13:43:41 | [diff] [blame] | 103 | As mentioned above, components that depend on `//content/public`, `//ipc`, or |
| 104 | `third_party/blink/public` might have to be in the form of a [layered |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 105 | component](http://www.chromium.org/developers/design-documents/layered-components-design). |
| 106 | |
| 107 | Components that have bits of code that need to live in different processes (e.g. |
| 108 | some code in the browser process, some in the renderer process, etc.) should |
| 109 | separate the code into different subdirectories. Hence for a component named |
| 110 | 'foo' you might end up with a structure like the following (assuming that foo is |
| 111 | not used by iOS and thus does not need to be a layered component): |
| 112 | |
David Dorwin | 154becc | 2022-10-20 20:55:58 | [diff] [blame] | 113 | * `components/foo` - `BUILD.gn`, `DEPS`, `DIR_METADATA`, `OWNERS`, `README.md` |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 114 | * `components/foo/browser` - code that needs the browser process |
| 115 | * `components/foo/common` - for e.g. Mojo interfaces and such |
| 116 | * `components/foo/renderer` - code that needs renderer process |
| 117 | |
David Dorwin | 154becc | 2022-10-20 20:55:58 | [diff] [blame] | 118 | These subdirectories should have `DEPS` files with the relevant restrictions in |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 119 | place, i.e. only `components/foo/browser` should be allowed to #include from |
Matt Falkenhagen | f28d6d7 | 2021-05-27 13:43:41 | [diff] [blame] | 120 | `content/public/browser`. Note that `third_party/blink/public` is a |
| 121 | renderer process directory except for `third_party/blink/public/common` which |
| 122 | can be used by all processes. |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 123 | |
| 124 | Note that there may also be an `android` subdir, with a Java source code |
| 125 | structure underneath it where the package name is org.chromium.components.foo, |
| 126 | and with subdirs after 'foo' to illustrate process, e.g. 'browser' or |
| 127 | 'renderer': |
| 128 | |
David Dorwin | 154becc | 2022-10-20 20:55:58 | [diff] [blame] | 129 | * `components/foo/android/`{`OWNERS`, `DEPS`} |
Francois Doray | f7d34072 | 2019-04-05 20:28:50 | [diff] [blame] | 130 | * `components/foo/android/java/src/org/chromium/components/foo/browser/` |
| 131 | * `components/foo/android/javatests/src/org/chromium/components/foo/browser/` |
| 132 | |
| 133 | Code in a component should be placed in a namespace corresponding to the name of |
| 134 | the component; e.g. for a component living in `//components/foo`, code in that |
| 135 | component should be in the `foo::` namespace. |