Commit Graph

32 Commits

Author SHA1 Message Date
MU AOHUA
dc9b74647e [DevTools] Add fb local build command (#32644)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary
1. Having a development build for FB will be convenient for fb internal
feature development
2. Add a new checkbox to toggle new internal features added to React
Devtools.

## How did you test this change?
1. yarn test
2. set extra env variables in bash profile and build an internal version
with the new script.
3. toggle on/off the new checkbox, the value is stored in local storage
correctly.

---------

Co-authored-by: Aohua Mu <muaohua@fb.com>
2025-03-25 13:45:48 +00:00
Sebastian Markbåge
43dac1ee8d [DevTools] Implement Owner Stacks (#30417)
Stacked on #30410.

Use "owner stacks" as the appended component stack if it is available on
the Fiber. This will only be available if the enableOwnerStacks flag is
on. Otherwise it fallback to parent stacks. In prod, there's no owner so
it's never added there.

I was going back and forth on whether to inject essentially
`captureOwnerStack` as part of the DevTools hooks or replicate the
implementation but decided to replicate the implementation.

The DevTools needs all the same information from internals to implement
owner views elsewhere in the UI anyway so we're not saving anything in
terms of the scope of internals. Additionally, we really need this
information for non-current components as well like "rendered by" views
of the currently selected component.

It can also be useful if we need to change the format after the fact
like we did for parent stacks in:
https://github.com/facebook/react/pull/30289

Injecting the implementation would lock us into specifics both in terms
of what the core needs to provide and what the DevTools can use.

The implementation depends on the technique used in #30369 which tags
frames to strip out with `react-stack-bottom-frame`. That's how the
implementation knows how to materialize the error if it hasn't already.

Firefox:

<img width="487" alt="Screenshot 2024-07-21 at 11 33 37 PM"
src="https://github.com/user-attachments/assets/d3539b53-4578-4fdd-af25-25698b2bcc7d">

Follow up: One thing about this view is that it doesn't include the
current actual synchronous stack. When I used to append these I would
include both the real current stack and the owner stack. That's because
the owner stack doesn't include the name of the currently executing
component. I'll probably inject the current stack too in addition to the
owner stack. This is similar to how native Async Stacks are basically
just appended onto the current stack rather than its own.
2024-07-22 18:49:44 -04:00
Ruslan Lesiutin
6de7733e73 feat[devtools]: ship source maps for content scripts and ignore list installHook script (#28730)
## Summary

1. RDT browser extension's content scripts will now ship source maps
(without source in prod, to save some bundle size).
2. `installHook` content script will be ignore listed via `ignoreList`
field in the corresponding source map.
3. Previously, source map for backend file used `x_google_ignoreList`
naming, now `ignoreList`.

## How did you test this change?

1. `ignoreList-test.js`
2. Tested manually that I don't see `installHook` in stack traces when
`console.error` is called.
2024-04-08 18:10:09 +01:00
Ruslan Lesiutin
e3fb7c1de1 feat[devtools]: support x_google_ignoreList source maps extension (#26951)
## Summary
This was originally implemented by Mengdi @mondaychen in
https://github.com/facebook/react/pull/26506.

Because we patch console methods (to append components stack and some
other features), errors in console will include
`react_devtools_backend-....js` in its stack traces. Example:
<img width="763" alt="Screenshot 2023-06-15 at 13 31 49"
src="https://github.com/facebook/react/assets/28902667/fa9c3d26-b6c5-4965-af71-62d100cd806d">

Using https://github.com/mondaychen/devtools-ignore-webpack-plugin to
support [x_google_ignoreList source maps
extension](https://developer.chrome.com/blog/devtools-better-angular-debugging/#the-x_google_ignorelist-source-map-extension).

@mondaychen created a react app, which throws an error via
`console.error`, when user click on the button -
https://3owqsn.csb.app/.

Stack trace with these changes: 
<img width="759" alt="Screenshot 2023-06-14 at 14 26 38"
src="https://github.com/facebook/react/assets/28902667/b118b168-3200-4a47-9718-39fc455ea993">
2023-06-21 12:36:48 +01:00
Ruslan Lesiutin
4ddc019aca chore[devtools]: upgrade to webpack v5 (#26887)
## Summary
- Updated `webpack` (and all related packages) to v5 in
`react-devtools-*` packages.
- I haven't touched any `TODO (Webpack 5)`. Tried to poke it, but each
my attempt failed and parsing hook names feature stopped working. I will
work on this in a separate PR.
- This work is one of prerequisites for updating Firefox extension to
manifests v3

related PRs:
https://github.com/facebook/react/pull/22267
https://github.com/facebook/react/pull/26506

## How did you test this change?
Tested on all surfaces, explicitly checked that parsing hook names
feature still works.
2023-06-14 13:15:52 +01:00
Mark Erikson
909c6dacfd Update Rollup to 3.x (#26442)
<!--
  Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.

Before submitting a pull request, please make sure the following is
done:

1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
  2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
  9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
  10. If you haven't already, complete the CLA.

Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->

## Summary

This PR:

- Updates Rollup from 2.x to latest 3.x, and updates associated plugins
- Updates deprecated / altered config settings in the Rollup plugin
pipeline
- Fixes some file extension and import issues related to use of ESM in
`react-dom-webpack-server`
- Removes a now-obsolete `strip-unused-imports` Rollup plugin
- <s>Fixes an _existing_ bug with the Rollup 2.x plugin pipeline on
`main` that was causing parts of `DOMProperty.js` to get left out of the
`react-dom-webpack-server` JS bundles, by adding a new plugin to tell
Rollup to treat that file as if it as side effects</s>

This PR should be functionally identical to the other existing "Rollup 3
upgrade" PR at #26078 . I'm filing this as a near-duplicate because I'm
ready to push this change through ASAP so that I can follow it up with a
PR that adds sourcemap support, that PR's artifact diffing seems like
it's possibly stuck and I want to compare the build results, and I've
got this set up against latest `main`.

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

This gets React's build setup updated to the latest Rollup version,
which is generally a good practice, but also ensures that any further
Rollup config tweaks can be done using the current Rollup docs as a
reference.

## How did you test this change?

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->

- Made builds from the latest `main`
- Updated Rollup package versions and cross-compared the changes I
needed to make locally to get successful builds vs #26078
- Diffed the output folders between `main` and this PR, and confirmed
that the bundle contents are identical (with the exception of version
strings and the `react-dom-webpack-server` bundle fix re-adding missing
`DOMProperty.js` content)
2023-03-24 18:08:41 +00:00
Glenn 'devalias' Grant
6b6d0617ef Update Rollup and related plugins to their most recent versions (#24916)
Update Rollup and related plugins to their most recent versions +
resolve any breaking changes/deprecations/etc along the way. I made each
change piece by piece, so the commit history tells a pretty good story
of what was changed where/how/why.

fixes https://github.com/facebook/react/issues/24894

For the full deepdive/context, see:

- https://github.com/facebook/react/issues/24894

The inspiration for this came from @jasonwilliams 's PR for attempting
to add sourcemap output support to React's builds:

- https://github.com/facebook/react/issues/20186
  - https://github.com/facebook/react/pull/21946

But I figured that it would be useful to minimise the scope of changes
in that PR, and to modernise the build tooling along the way.

If any of these updates rely on a node version later than `10.x`, then
the following PR may have to land first, otherwise things might break on
AppVeyor:

- https://github.com/facebook/react/issues/24891
  - https://github.com/facebook/react/pull/24892

Co-authored-by: Sebastian Markbage <sebastian@calyptus.eu>
2023-02-20 01:35:56 -05:00
Juan
545d4c2de7 Prevent errors/crashing when multiple installs of DevTools are present (#22517)
## Summary

This commit is a proposal for handling duplicate installation of DevTools, in particular scoped to duplicates such as a dev build or the internal versions of DevTools installed alongside the Chrome Web Store extension.

Specifically, this commit makes it so when another instance of the DevTools extension is installed alongside the extension installed from the Chrome Web Store, we don't produce a stream of errors or crash Chrome, which is what would usually happen in this case. 


### Detecting Duplicate Installations

- First, we check what type of installation the extension is: from the Chrome Web Store, the internal build of the extension, or a local development build.
- If the extension is from the **Chrome Web Store**:
  - During initialization, we first check if the internal or local builds of the extension have already been installed and are enabled. To do this, we send a [cross-extension message](https://developer.chrome.com/docs/extensions/mv3/messaging/#external) to the internal and local builds of the extension using their extension IDs.  
    - We can do this because the extension ID for the internal build (and for the Chrome Web Store) is a stable ID.
    - For the local build, at build time we hardcode a [`key` in the `manifest.json`](https://developer.chrome.com/docs/extensions/mv2/manifest/key/) which allows us to have a stable ID even for local builds.
  - If we detect that the internal or local extensions are already installed, then we skip initializing the current extension altogether so as to not conflict with the other versions. This means we don't initialize the frontend or the backend at all.
- If the extension is the **Internal Build**:
  - During initialization, we first check if the local builds of the extension has already been installed and is enabled. To do this, we send a [cross-extension message](https://developer.chrome.com/docs/extensions/mv3/messaging/#external) to the local build of the extension using its extension ID.  
    - We can do this for the local build because at build time we hardcode a [`key` in the `manifest.json`](https://developer.chrome.com/docs/extensions/mv2/manifest/key/) which allows us to have a stable ID even for local builds.
  - If we detect that the local extension is already installed, then we skip initializing the current extension altogether so as to not conflict with the that  version. This means we don't initialize the frontend or the backend at all.
- If the extension is a **Local Dev Build**:
  - Since other extensions check for the existence of this extension and disable themselves if they detect it, we don't need any special handling during initialization and assume that there are no duplicate extensions. This means that we will generally prefer keeping this extension enabled.

This behavior means that the order of priority for keeping an extension enabled is the following:

1. Local build
2. Internal build
3. Public build


### Preventing duplicate backend initialization

Note that the backend is injected and initialized by the content script listening to a message posted to the inspected window (via `postMessage`). Since the content script will be injected twice, once each by each instance of the extension, even if we initialize the extension once, both content scripts would still receive the single message posted from the single frontend, and it would then still inject and initialize the backend twice. 

In order to prevent this, we also add the extension ID to the message for injecting the backend. That way each content script can check if the message comes from its own extension, and if not it can ignore the message and avoid double injecting the backend.
  
### Other approaches

- I considered using the [`chrome.management`](https://developer.chrome.com/docs/extensions/reference/management/) API generally to detect other installations, but that requires adding additional permissions to our production extension, which didn't seem ideal.
- I also considered a few options of writing a special flag to the inspected window and checking for it before initializing the extension. However, it's hard to avoid race conditions in that case, and it seemed more reliable to check specifically for the WebStore extension, which is realistically where we would encounter the overlap.
  
### Rollout

- This commit needs to be published and rolled out to the Chrome Web Store first.
- After this commit is published to the Chrome Web Store, any duplicate instances of the extension that are built and installed after this commit will no longer conflict with the Chrome Web Store version.
  
### Next Steps

- In a subsequent PR, I will extend this code to show a warning when duplicate extensions have been detected.

Part of #22486

## How did you test this change?

### Basic Testing

- yarn flow
- yarn test
- yarn test-build-devtools

### Double installation testing

Testing double-installed extensions for this commit is tricky because we are relying on the extension ID of the internal and Chrome Web Store extensions, but we obviously can't actually test the Web Store version (since we can't modify the already published version).

In order to simulate duplicate extensions installed, I did the following process:

- Built separate extensions where I hardcoded a constant for whether the extension is internal or public (e.g. `EXTENSION_INSTALLATION_TYPE = 'internal'`). Then I installed these built extensions corresponding to the "internal" and "Web Store" builds.
- Build and run the regular development extension (with `yarn build:chrome:dev && yarn test:chrome`), using the extension IDs of the previously built extensions as the "internal" and "public" extension IDs.

With this set up in place, I tested the following on pages both with and without React:

- When only the local extension enabled, DevTools works normally.
- When only the "internal" extension enabled, DevTools works normally.
- When only the "public" extension enabled, DevTools works normally.
- When "internal" and "public" extensions are installed, "public" extension is disabled and "internal" extension works normally.
- When the local extension runs alongside the other extensions, other extensions disable themselves and local build works normally.
- When we can't recognize what type of build the extension corresponds to, we show an error.
- When all 3 extensions are installed and enabled in all different combinations, DevTools no longer produces errors or crashes Chrome, and works normally.
2021-10-14 17:15:31 -04:00
Juan
95ecd4a2c3 [DevTools] Commands for internal builds all follow :fb convention (#22463) 2021-09-29 17:46:34 -04:00
Brian Vaughn
e07039bb61 Moved named hooks code (and tests) from react-devtools-extensions to react-devtools-shared (#22260) 2021-09-07 11:44:49 -04:00
Brian Vaughn
64f83a6fd2 Replace "source-map" library with "source-map-js" (#22126) 2021-08-19 11:25:38 -04:00
Juan
88d121899a [DevTools] Support extended source maps with named hooks information (#22010)
## Summary

Adds support for statically extracting names for hook calls from source code, and extending source maps with that information so that DevTools does not have to directly parse source code at runtime, which will speed up the Named Hooks feature and allow it to be enabled by default.

Specifically, this PR includes the following parts:

- [x] Adding logic to statically extract relevant hook names from the parsed source code (i.e. the babel ast). Note that this logic differs slightly from the existing logic in that the existing logic also uses runtime information from DevTools (such as whether given hooks are a custom hook) to extract names for hooks, whereas this code is meant to run entirely at build time, so it does not rely on that information.
- [x] Generating an encoded "hook map", which encodes the information about a hooks *original* source location, and it's corresponding name. This "hook map" will be used to generate extended source maps, included tentatively under an extra `x_react_hook_map` field. The map itself is formatted and encoded in a very similar way as how the `names` and `mappings` fields of a standard source map are encoded ( = Base64 VLQ delta coding representing offsets into a string array), and how the "function map" in Metro is encoded, as suggested in #21782. Note that this initial version uses a very basic format, and we are not implementing our own custom encoding, but reusing the `encode` function from `sourcemap-codec`.
- [x] Updating the logic in `parseHookNames` to check if the source maps have been extended with the hook map information, and if so use that information to extract the hook names without loading the original source code. In this PR we are manually generating extended source maps in our tests in order to test that this functionality works as expected, even though we are not actually generating the extended source maps in production.

The second stage of this work, which will likely need to occur outside this repo, is to update bundlers such as Metro to use these new primitives to actually generate source maps that DevTools can use.

### Follow-ups

- Enable named hooks by default when extended source maps are present
- Support looking up hook names when column numbers are not present in source map.
- Measure performance improvement of using extended source maps (manual testing suggests ~4 to 5x faster)
- Update relevant bundlers to generate extended source maps.

## Test Plan

- yarn flow
- Tests still pass
  - yarn test
  - yarn test-build-devtools
- Named hooks still work on manual test of browser extension on a few different apps (code sandbox, create-react-app, facebook).
- For new functionality:
  - New tests for statically extracting hook names.
  - New tests for using extended source maps to look up hook names at runtime.
2021-08-11 10:46:19 -04:00
Ilham Syahid S
dfd9d62636 [DevTools] Optimize Images yarn command (part 2) (#21968) 2021-08-02 09:32:17 -04:00
Brian Vaughn
f4161c3ec7 [DRAFT] Import scheduling profiler into DevTools Profiler (#21897) 2021-07-22 13:58:57 -04:00
Lucas Correia
25f09e3e4e DevTools: Parse named source AST in a worker (#21902)
Resolves #21855

Ended up using workerize in order to setup the worker once it allows easy imports (for babel's parse function) and exports.
2021-07-21 12:16:08 -04:00
Brian Vaughn
87b3ada89d DevTools: Named hooks supports "cheap-module-source-map" (#21874)
"cheap-module-source-map" is the default source-map generation mode used in created-react-dev mode because of speed. The major trade-off is that the source maps generated don't contain column numbers, so DevTools needs to be more lenient when matching AST nodes in this mode.

In this case, it can ignore column numbers and match nodes using line numbers only– so long as only a single node matches. If more than one match is found, treat it the same as if none were found, and fall back to no name.
2021-07-14 14:37:27 -04:00
Moti Zilberman
9c7f29ebe7 [WIP] DevTools: Support named hooks for >1 module in a bundle (#21790)
* Add named hooks test case built with Rollup

* Fix prepareStackTrace unpatching, remove sourceURL

* Prettier

* Resolve source map URL/path relative to the script

* Add failing tests for multi-module bundle

* Parse hook names from multiple modules in a bundle

* Create a HookSourceData per location key (file, line, column).
* Cache the source map per runtime URL ( = file part of location key).
* Don't store sourceMapContents - only store a consumer instance.
* Look up original source URLs in the source map correctly.
* Cache the code + AST per original URL.
* Fix off-by-one column number lookup.
* Some naming and typing tweaks related to the above.
* Stop storing the consumer outside the with() callback, which is a bug.

* Lint fix for 8d8dd25

* Added devDependencies to react-devtools-extensions package.json

* Added some debug logging and TODO comments

* Added additional DEBUG logging to hook names cache

Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2021-07-07 13:07:58 -04:00
Brian Vaughn
c5cfa71948 DevTools: Show hook names based on variable usage (#21641)
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
Co-authored-by: Saphal Patro <saphal1998@gmail.com>
Co-authored-by: VibhorCodecianGupta <vibhordelgupta@gmail.com>
2021-07-01 14:39:18 -04:00
Brian Vaughn
119736b1c2 [FB-only] Show which hooks (indices) changed when profiling (#20998) 2021-03-17 12:28:21 -04:00
E-Liang Tan
c641b611c4 Upgrade all @babel/* packages to fix DevTools builds on newer Node versions (#19647) 2020-08-20 11:47:16 -04:00
Brian Vaughn
08b8e6e1dc DevTools 4.7.0 -> 4.8.0 (#19297) 2020-07-09 10:49:44 -04:00
Brian Vaughn
fb3f0acad9 Disable Webpack setImmediate polyfill for DevTools (#18860)
* Upgrade Webpack deps to latet

* Disable Webpack setImmediate polyfill
2020-05-07 13:13:47 -07:00
Brian Vaughn
c5c25d35a3 Fixed DevTools extension build:dev command (#18648) 2020-04-16 17:39:16 -07:00
Haseeb Furkhan Mohammed
0e49074f7a Cross platform support to run yarn test:edge for Microsoft Edge dev tools extension (#18108)
* Test automation for edge dev tools extension

* Linter changes

* Load extension automatically.

* Fixed path in `test` command

Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
2020-02-24 18:17:01 -08:00
Haseeb Furkhan Mohammed
d5ddc16a33 React developer tools extension for Microsoft Edge (#18041)
* Port Chrome extension to Microsoft Edge
2020-02-18 09:40:30 -08:00
Brian Vaughn
5fc97420b9 Remove dependency on local git checkout from build process (#17475)
* Remove dependency on local git checkout from build process

* Updated Webpack dependencies to account for recent changes to deps for Flight
2019-11-27 07:48:09 -08:00
Simen Bekkhus
e09097a75d chore: upgrade to jest 24 (#15778)
* chore: upgrade to jest 24

* download react-is from npm manually
2019-10-03 22:44:18 +05:30
Brian Vaughn
996acf9036 Updated DevTools extension build script to work when run remotely (#16603) 2019-08-28 17:01:26 -07:00
Brian Vaughn
30b8ef3756 Iterated on Webpack configs until I got the inline and shell packages seemingly working 2019-08-14 09:24:35 -07:00
Brian Vaughn
441d014cef Cleaned up some extnesions build script stuff 2019-08-13 22:15:38 -07:00
Brian Vaughn
08743b1a8e Reorganized folders into packages/* 2019-08-13 15:59:43 -07:00
Brian Vaughn
ec7ef50e8b Reorganized things again into packages 2019-08-13 11:37:25 -07:00