Our mission at Reactime is to maintain and iterate constantly, but never at the expense of future developers.
We know how hard it is to quickly get up to speed and onboard in a new codebase.
So, here are some helpful pointers to help you hit the ground running. 🏃🏾💨
-
Download React Dev Tools from the Chrome Webstore Here
-
Clone down the Reactime repo onto your machine.
git clone https://github.com/open-source-labs/reactime.git
- Install dependencies and build.
cd reactime
npm install --force
npm run dev
With release of Node v18.12.1 (LTS) on 11/4/22, the script has been updated to 'npm run dev' || 'npm run build' for backwards compatibility.
For version Node v16.16.0, please use script 'npm run devlegacy' || 'npm run buildlegacy'
- Spin up the demo application.
cd demo-app
npm install
npm run dev
Similar approach for Next.js and Remix demo apps
- Add Reactime to your Chrome extensions.
- Navigate to chrome://extensions
- Select “Load Unpacked”
- Choose reactime > src > extension > build
- Navigate to http://localhost:8080/ to inspect the demo application using Reactime!
Can Reactime be integrated with Redux compatibility so applications using Redux can track state in Reactime?
Now you should be able to change Reactime code and see the changes instantly reflected in your browser!
With release of Node v18.12.1 (LTS) on 11/4/22, the script has been updated to 'npm run dev' | 'npm run build' for backwards compatibility.
For version Node v16.16.0, please use script 'npm run devlegacy' | 'npm run buildlegacy'
- Before beginning development, especially on teams, make sure to configure your linter and code formatting to conform to one unified setting (We recommend the Airbnb style guide!) This will make reviewing PRs much more readable and less error-prone.
In the src folder, there are three directories we care about: app, backend, and extension.
src/
├── app/ # Frontend code
│ ├── __tests__/ #
│ ├── actions/ # Redux action creators
│ ├── components/ # React components
│ ├── constants/ #
│ ├── containers/ # More React components
│ ├── reducers/ # Redux mechanism for updating state
│ ├── styles/ #
│ ├── index.tsx # Starting point for root App component
│ ├── module.d.ts #
│ └── store.tsx #
│
├── backend/ # "Backend" code (injected into target app)
│ │ # Focus especially on linkFiber, timeJump, tree, and helpers
│ ├── __tests__/ #
│ ├── controllers/ #
│ ├── createComponentActionsRecord.ts # Update the componentActionsRecord with new bound state-update methods
│ ├── createTree.ts # Construct a tree snapshot from the FiberRoot tree given by ReactFiber.
│ ├── statePropExtractor.ts # Helper functions to extract & format prop, state, and context data
│ ├── throttle.ts #
│ ├── timeJump.ts # Rerenders DOM based on snapshot from background script
│ ├── models/
│ ├── filterConditions.ts #
│ ├── masterState.ts # Component action record interface
│ ├── routes.ts # Interfaces with the browser history stack
│ ├── tree.ts # Custom structure to send to background
│ ├── routers/
│ ├── linkFiber.ts # Check for all requirement to start Reactime and
│ ├── snapShot.ts #
│ ├── types/ # Typescript interfaces
│ ├── index.ts # Starting point for backend functionality
│ ├── index.d.ts # Definitely Type file for Index
│ ├── module.d.ts #
│ ├── package.json #
│ ├── puppeteerServer.js #
│
├── extension/ # Chrome Extension code
│ ├── build/ # Destination for bundles and manifest.json (Chrome config file)
│ │ #
│ ├── background.js # Chrome Background Script
│ └── contentScript.ts # Chrome Content Script
└──
- The app folder is responsible for the Single Page Application that you see when you open the chrome dev tools under the Reactime tab.
- The backend folder contains the set of all scripts that we inject into our "target" application via
background.js
- In Reactime, its main role is to generate data and handle time-jump requests from the background script in our extension folder.
- The extension folder is where the
contentScript.js
andbackground.js
are located.- Like regular web apps, Chrome Extensions are event-based. The background script is where one typically monitors for browser triggers (e.g. events like closing a tab, for example). The content script is what allows us to read or write to our target web application, usually as a result of messages passed from the background script.
- These two files help us handle requests both from the web browser and from the Reactime extension itself
All the diagrams of data flows are avaliable on MIRO
The general flow of data is described in the following steps:
-
When the background bundle is loaded by the browser, it executes a script injection into the dom. (see section on backend). This script uses a technique called throttle to send state data from the app to the content script every specified milliseconds (in our case, this interval is 70ms).
-
The content script always listens for messages being passed from the extension's target application. Upon receiving data from the target app, the content script will immediately forward this data to the background script which then updates an object called
tabsObj
. Each timetabsObj
is updated, its latest version will be passed to Reactime, where it is processed for displaying to the user by the app folder scripts. -
Likewise, when Reactime emits an action due to user interaction -- a "jump" request for example -- a message will be passed from Reactime via the background script to the content script. Then, the content script will pass a message to the target application containing a payload that represents the state the user wants the DOM to reflect or "jump" to.
- One important thing to note here is that this jump action must be dispatched in the target application (i.e. backend land), because only there do we have direct access to the DOM.
See Reacti.me README for instruction of how to update the website
Navigation between different console.log panels can be confusing when running Reactime. We created a short instruction where you can find the results for your console.log
Console.logs from the Extension folder you can find here:
- Chrome Extension (Developer mode)
- Background page
Console.logs from the App folder you can find here:
- Chrome Browser
- Inspect
Console.logs from the App folder you can find here:
- Open the Reactime extension in Chrome
- Click "Inspect" on Reactime
Still unsure about what content scripts and background scripts do for Reactime, or for a chrome extensions in general?
- The implementation details can be found in the source files themselves.
- We also encourage you to dive into the official Chrome Developer Docs.
Some relevant sections are reproduced below:
Content scripts are files that run in the context of web pages.
By using the standard Document Object Model (DOM), they are able to read details of the web pages the browser visits, make changes to them and pass information back to their parent extension. (Source)
- One helpful way to remember a content script's role in the Chrome ecosystem is to think: a content script is used to read and modify a target web page's rendered content.
A background page is loaded when it is needed, and unloaded when it goes idle.
Some examples of events include: The extension is first installed or updated to a new version. The background page was listening for an event, and the event is dispatched. A content script or other extension sends a message. Another view in the extension, such as a popup, calls
runtime.getBackgroundPage
.Once it has been loaded, a background page will stay running as long as it is performing an action, such as calling a Chrome API or issuing a network request.
Additionally, the background page will not unload until all visible views and all message ports are closed. Note that opening a view does not cause the event page to load, but only prevents it from closing once loaded. (Source)
- You can think of background scripts serving a purpose analogous to that of a server in the client/server paradigm. Much like a server, our
background.js
listens constantly for messages (i.e. requests) from two main places:- The content script
- The chrome extension "front-end" (NOT the interface of the browser, this is an important distinction.)
- In other words, a background script works as a sort of middleman, directly maintaining connection with its parent extension, and acting as a proxy enabling communication between it and the content script.