chrome-extension anatomy and how its parts communicate
Tags: javascript
Published: 2020-11-21 19:13:27


there are lots of resources out there talking about extensions. here is one chart that contains **every single layer** and the relationships between them. 

![chrome extension anatomy](https://dev-to-uploads.s3.amazonaws.com/i/zn9nnnbp224j687t2s2w.png)

### chrome extension contains 6 important files:

1. `manifest.json:` organises the extension structure ( somehow similar to **package.json**).
 
2. `background script`: this resource is shared between all browser windows and every element inside them (so changing a value in the background will **change it everywhere** on the browser instantly).

3. `popup script:` contains the markup that the extension displays when you click on **its icon**, it is containable in the **single tab**, does not have access to the extension background or page content but it can communicate with them through messages as:
  a. **chrome.runtime API** to communicate with the background.
  b. **chrome.tabs API** to communicate with its tab.

4. `content scripts:` it is containable in the **page window** so it has access to the page **DOM**, it does not have an actual effect on the extension itself unless it starts communicating with the background and popup scripts through messaging events.

5. `options script:` this is a special file that allows you to give the user some options in order to personalise their extension as they want, any piece of option can be saved to the **chrome.storage.local** and can be synchronised between multiple browsers where the user logged in to chrome using **chrome.storage.sync**. 

6. `icons files`: should be in sizes like 16*16 and 32*32px, the **paths** to those files should be specified in the manifest. 

## Communication between different scripts:

### 1. `From everywhere to background scripts and vice versa:`
you can use ** chrome.runtime.sendMessage()** or any other runtime events, you need an **eventListener** in the background, which in turn will handle the request and **dispatch its response everywhere**.    
and in order to receive that message (or response) you need **another eventListener** on the other script listening to the runtime events.

### 2. `From popup to content and vice versa:`
you can't communicate directly between those 2 scripts. since both scripts can communicate with the background we can use it as middleware between them or we can use the tabs API.

#### first: background as middleware
you can use **chrome.runtime API** to exchange messages between the script you are in (popup or content) and the background using the **chrome.runtime.sendMessage()**, the background will send its response to **everywhere**.
in order to receive the message, you need to listen to it on the other script itself.
 so:
 1. you send a message from popup to the background.
 2. background will handle the request and send its response to **everywhere**.
 3. both popup and content scripts are containable in `everywhere` (check the chart).
 4. you can listen to that response either in popup or content or both, so you received the message.
 5. done !!   



#### second: create a connection between popup and content through the tab
you can use **chrome.tabs API** to create a connection between the popup and the content script using the **chrome.tabs.connect()** and then **postMessage** through the tab background.
in order to receive the message, you need to listen to it on the script itself.
 so:
 1. you open a port between popup and content through the tab background.
 2. you send a message through that port to the tab background.
 3. tab background will redirect it to the content script which will handle the request and send it through the same port to the popup.
 4. you can listen to that response either in the popup, so you received the message.
 6. you can close the port, or leave it open to send other messages.
 7. done !!