Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat[devtools]: ship source maps for content scripts and ignore list installHook script #28730

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/react-devtools-extensions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"chrome-launch": "^1.1.4",
"crx": "^5.0.0",
"css-loader": "^1.0.1",
"devtools-ignore-webpack-plugin": "^0.1.1",
"file-loader": "^6.1.0",
"filesize": "^6.0.1",
"find": "^0.3.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {readFileSync} from 'fs';
import path from 'path';
import {rimrafSync} from 'rimraf';

describe('x_google_ignoreList source map extension', () => {
describe('ignoreList source map extension', () => {
jest.setTimeout(60 * 1000);

const pathToExtensionsPackage = path.resolve(__dirname, '..', '..');
Expand All @@ -30,26 +30,16 @@ describe('x_google_ignoreList source map extension', () => {
});

describe('for dev builds', () => {
it('should include only sources with /node_modules/ and /webpack/ in path', async () => {
it('should not ignore list anything', async () => {
await exec('yarn build:chrome:local', {
cwd: pathToExtensionsPackage,
});

const sourceMapJSON = readFileSync(pathToSourceMap);
const sourceMap = JSON.parse(sourceMapJSON);

const {sources, x_google_ignoreList} = sourceMap;

const expectedIgnoreList = [];
for (let sourceIndex = 0; sourceIndex < sources.length; ++sourceIndex) {
const source = sources[sourceIndex];

if (source.includes('/node_modules/') || source.includes('/webpack/')) {
expectedIgnoreList.push(sourceIndex);
}
}

expect(x_google_ignoreList).toEqual(expectedIgnoreList);
const {ignoreList} = sourceMap;
expect(ignoreList).toEqual([]);
});
});

Expand All @@ -60,9 +50,9 @@ describe('x_google_ignoreList source map extension', () => {
const sourceMapJSON = readFileSync(pathToSourceMap);
const sourceMap = JSON.parse(sourceMapJSON);

const {sources, x_google_ignoreList} = sourceMap;
const {sources, ignoreList} = sourceMap;

expect(sources.length).toBe(x_google_ignoreList.length);
expect(sources.length).toBe(ignoreList.length);
});
});
});
19 changes: 9 additions & 10 deletions packages/react-devtools-extensions/webpack.backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

const {resolve} = require('path');
const Webpack = require('webpack');
const DevToolsIgnorePlugin = require('devtools-ignore-webpack-plugin');

const {resolveFeatureFlags} = require('react-devtools-shared/buildUtils');
const SourceMapIgnoreListPlugin = require('react-devtools-shared/SourceMapIgnoreListPlugin');

const {
DARK_MODE_DIMMED_WARNING_COLOR,
DARK_MODE_DIMMED_ERROR_COLOR,
Expand Down Expand Up @@ -42,7 +43,7 @@ const featureFlagTarget = process.env.FEATURE_FLAG_TARGET || 'extension-oss';

module.exports = {
mode: __DEV__ ? 'development' : 'production',
devtool: __DEV__ ? 'cheap-module-source-map' : 'nosources-cheap-source-map',
devtool: false,
entry: {
backend: './src/backend.js',
},
Expand Down Expand Up @@ -87,14 +88,12 @@ module.exports = {
'process.env.IS_FIREFOX': IS_FIREFOX,
'process.env.IS_EDGE': IS_EDGE,
}),
new DevToolsIgnorePlugin({
shouldIgnorePath: function (path) {
if (!__DEV__) {
return true;
}

return path.includes('/node_modules/') || path.includes('/webpack/');
},
new Webpack.SourceMapDevToolPlugin({
filename: '[file].map',
noSources: !__DEV__,
}),
new SourceMapIgnoreListPlugin({
shouldIgnoreSource: () => !__DEV__,
}),
],
module: {
Expand Down
24 changes: 23 additions & 1 deletion packages/react-devtools-extensions/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const {
getVersionString,
} = require('./utils');
const {resolveFeatureFlags} = require('react-devtools-shared/buildUtils');
const SourceMapIgnoreListPlugin = require('react-devtools-shared/SourceMapIgnoreListPlugin');

const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
Expand Down Expand Up @@ -54,7 +55,7 @@ const babelOptions = {

module.exports = {
mode: __DEV__ ? 'development' : 'production',
devtool: __DEV__ ? 'cheap-module-source-map' : false,
devtool: false,
entry: {
background: './src/background/index.js',
backendManager: './src/contentScripts/backendManager.js',
Expand Down Expand Up @@ -134,6 +135,27 @@ module.exports = {
'process.env.LIGHT_MODE_DIMMED_ERROR_COLOR': `"${LIGHT_MODE_DIMMED_ERROR_COLOR}"`,
'process.env.LIGHT_MODE_DIMMED_LOG_COLOR': `"${LIGHT_MODE_DIMMED_LOG_COLOR}"`,
}),
new Webpack.SourceMapDevToolPlugin({
filename: '[file].map',
noSources: !__DEV__,
}),
new SourceMapIgnoreListPlugin({
shouldIgnoreSource: (assetName, _source) => {
if (__DEV__) {
// Don't ignore list anything in DEV build for debugging purposes
return false;
}

const contentScriptNamesToIgnoreList = [
// This is where we override console
'installHook',
];

return contentScriptNamesToIgnoreList.some(ignoreListName =>
assetName.startsWith(ignoreListName),
);
},
}),
],
module: {
defaultRules: [
Expand Down
73 changes: 73 additions & 0 deletions packages/react-devtools-shared/SourceMapIgnoreListPlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/**
* The implementation of this plugin is based on similar webpack plugin in Angular CLI
* https://github.com/angular/angular-cli/blob/16d8c552e99bfe65ded9e843e917dbb95eb8ec01/packages/angular_devkit/build_angular/src/tools/webpack/plugins/devtools-ignore-plugin.ts
* and devtools-ignore-webpack-plugin
* https://github.com/mondaychen/devtools-ignore-webpack-plugin/blob/d15274e4d2fdb74f73aa644f14773a5523823999/src/index.ts
* which both are licensed under MIT
*/

const {Compilation} = require('webpack');

const IGNORE_LIST = 'ignoreList';
const PLUGIN_NAME = 'source-map-ignore-list-plugin';

class SourceMapIgnoreListPlugin {
constructor({shouldIgnoreSource}) {
this.shouldIgnoreSource = shouldIgnoreSource;
}

apply(compiler) {
const {RawSource} = compiler.webpack.sources;

compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
compilation.hooks.processAssets.tap(
{
name: PLUGIN_NAME,
stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
additionalAssets: true,
},
assets => {
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
for (const [name, asset] of Object.entries(assets)) {
if (!name.endsWith('.map')) {
continue;
}

const mapContent = asset.source().toString();
if (!mapContent) {
continue;
}

const map = JSON.parse(mapContent);
const ignoreList = [];

const sourcesCount = map.sources.length;
for (
let potentialSourceIndex = 0;
potentialSourceIndex < sourcesCount;
++potentialSourceIndex
) {
const source = map.sources[potentialSourceIndex];

if (this.shouldIgnoreSource(name, source)) {
ignoreList.push(potentialSourceIndex);
}
}

map[IGNORE_LIST] = ignoreList;
compilation.updateAsset(name, new RawSource(JSON.stringify(map)));
}
},
);
});
}
}

module.exports = SourceMapIgnoreListPlugin;
8 changes: 2 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6417,11 +6417,6 @@ detect-node@^2.0.4:
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==

devtools-ignore-webpack-plugin@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/devtools-ignore-webpack-plugin/-/devtools-ignore-webpack-plugin-0.1.1.tgz#8f4fcf83019bc361e8a3cf7b7d466a33693de14e"
integrity sha512-pJ/NGZTQxK1VDoyy8fLm0UV3ugOanostztLKUmzqYnUIKqyUm2ZkIpon6No0gWlpOSMoSpBWTnzrx1cdsbpuyw==

diff-sequences@^27.0.6:
version "27.0.6"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723"
Expand Down Expand Up @@ -6997,6 +6992,7 @@ eslint-plugin-no-unsanitized@3.1.2:

"eslint-plugin-react-internal@link:./scripts/eslint-rules":
version "0.0.0"
uid ""

eslint-plugin-react@^6.7.1:
version "6.10.3"
Expand Down Expand Up @@ -12991,7 +12987,7 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.8:
object-assign "^4.1.1"
scheduler "^0.20.2"

react-is@^16.8.1, react-is@^17.0.1, "react-is@npm:react-is":
react-is@^16.8.1, react-is@^17.0.1, react-is@^18.0.0, react-is@^18.2.0, "react-is@npm:react-is":
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
Expand Down