1. const {resolve} = require('path');
    
  2. const Webpack = require('webpack');
    
  3. const WebpackDevServer = require('webpack-dev-server');
    
  4. const fs = require('fs');
    
  5. const {
    
  6.   DARK_MODE_DIMMED_WARNING_COLOR,
    
  7.   DARK_MODE_DIMMED_ERROR_COLOR,
    
  8.   DARK_MODE_DIMMED_LOG_COLOR,
    
  9.   LIGHT_MODE_DIMMED_WARNING_COLOR,
    
  10.   LIGHT_MODE_DIMMED_ERROR_COLOR,
    
  11.   LIGHT_MODE_DIMMED_LOG_COLOR,
    
  12.   GITHUB_URL,
    
  13.   getVersionString,
    
  14. } = require('react-devtools-extensions/utils');
    
  15. const {resolveFeatureFlags} = require('react-devtools-shared/buildUtils');
    
  16. const semver = require('semver');
    
  17. 
    
  18. const {SUCCESSFUL_COMPILATION_MESSAGE} = require('./constants');
    
  19. 
    
  20. const ReactVersionSrc = fs.readFileSync(require.resolve('shared/ReactVersion'));
    
  21. const currentReactVersion = /export default '([^']+)';/.exec(
    
  22.   ReactVersionSrc,
    
  23. )[1];
    
  24. 
    
  25. const NODE_ENV = process.env.NODE_ENV;
    
  26. if (!NODE_ENV) {
    
  27.   console.error('NODE_ENV not set');
    
  28.   process.exit(1);
    
  29. }
    
  30. 
    
  31. const EDITOR_URL = process.env.EDITOR_URL || null;
    
  32. 
    
  33. const builtModulesDir = resolve(
    
  34.   __dirname,
    
  35.   '..',
    
  36.   '..',
    
  37.   'build',
    
  38.   'oss-experimental',
    
  39. );
    
  40. 
    
  41. const __DEV__ = NODE_ENV === 'development';
    
  42. 
    
  43. const DEVTOOLS_VERSION = getVersionString();
    
  44. 
    
  45. // If the React version isn't set, we will use the
    
  46. // current React version instead. Likewise if the
    
  47. // React version isnt' set, we'll use the build folder
    
  48. // for both React DevTools and React
    
  49. const REACT_VERSION = process.env.REACT_VERSION
    
  50.   ? semver.coerce(process.env.REACT_VERSION).version
    
  51.   : currentReactVersion;
    
  52. 
    
  53. const E2E_APP_BUILD_DIR = process.env.REACT_VERSION
    
  54.   ? resolve(__dirname, '..', '..', 'build-regression', 'node_modules')
    
  55.   : builtModulesDir;
    
  56. 
    
  57. const makeConfig = (entry, alias) => ({
    
  58.   mode: __DEV__ ? 'development' : 'production',
    
  59.   devtool: __DEV__ ? 'cheap-source-map' : 'source-map',
    
  60.   stats: 'normal',
    
  61.   entry,
    
  62.   output: {
    
  63.     publicPath: '/dist/',
    
  64.   },
    
  65.   node: {
    
  66.     global: false,
    
  67.   },
    
  68.   resolve: {
    
  69.     alias,
    
  70.   },
    
  71.   optimization: {
    
  72.     minimize: false,
    
  73.   },
    
  74.   plugins: [
    
  75.     new Webpack.ProvidePlugin({
    
  76.       process: 'process/browser',
    
  77.     }),
    
  78.     new Webpack.DefinePlugin({
    
  79.       __DEV__,
    
  80.       __EXPERIMENTAL__: true,
    
  81.       __EXTENSION__: false,
    
  82.       __PROFILE__: false,
    
  83.       __TEST__: NODE_ENV === 'test',
    
  84.       'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
    
  85.       'process.env.EDITOR_URL': EDITOR_URL != null ? `"${EDITOR_URL}"` : null,
    
  86.       'process.env.DEVTOOLS_PACKAGE': `"react-devtools-shell"`,
    
  87.       'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
    
  88.       'process.env.DARK_MODE_DIMMED_WARNING_COLOR': `"${DARK_MODE_DIMMED_WARNING_COLOR}"`,
    
  89.       'process.env.DARK_MODE_DIMMED_ERROR_COLOR': `"${DARK_MODE_DIMMED_ERROR_COLOR}"`,
    
  90.       'process.env.DARK_MODE_DIMMED_LOG_COLOR': `"${DARK_MODE_DIMMED_LOG_COLOR}"`,
    
  91.       'process.env.LIGHT_MODE_DIMMED_WARNING_COLOR': `"${LIGHT_MODE_DIMMED_WARNING_COLOR}"`,
    
  92.       'process.env.LIGHT_MODE_DIMMED_ERROR_COLOR': `"${LIGHT_MODE_DIMMED_ERROR_COLOR}"`,
    
  93.       'process.env.LIGHT_MODE_DIMMED_LOG_COLOR': `"${LIGHT_MODE_DIMMED_LOG_COLOR}"`,
    
  94.       'process.env.E2E_APP_REACT_VERSION': `"${REACT_VERSION}"`,
    
  95.     }),
    
  96.   ],
    
  97.   module: {
    
  98.     rules: [
    
  99.       {
    
  100.         test: /\.js$/,
    
  101.         loader: 'babel-loader',
    
  102.         options: {
    
  103.           configFile: resolve(
    
  104.             __dirname,
    
  105.             '..',
    
  106.             'react-devtools-shared',
    
  107.             'babel.config.js',
    
  108.           ),
    
  109.         },
    
  110.       },
    
  111.       {
    
  112.         test: /\.css$/,
    
  113.         use: [
    
  114.           {
    
  115.             loader: 'style-loader',
    
  116.           },
    
  117.           {
    
  118.             loader: 'css-loader',
    
  119.             options: {
    
  120.               sourceMap: true,
    
  121.               modules: true,
    
  122.               localIdentName: '[local]',
    
  123.             },
    
  124.           },
    
  125.         ],
    
  126.       },
    
  127.     ],
    
  128.   },
    
  129. });
    
  130. 
    
  131. const app = makeConfig(
    
  132.   {
    
  133.     'app-index': './src/app/index.js',
    
  134.     'app-devtools': './src/app/devtools.js',
    
  135.     'e2e-app': './src/e2e/app.js',
    
  136.     'e2e-devtools': './src/e2e/devtools.js',
    
  137.     'e2e-devtools-regression': './src/e2e-regression/devtools.js',
    
  138.     'multi-left': './src/multi/left.js',
    
  139.     'multi-devtools': './src/multi/devtools.js',
    
  140.     'multi-right': './src/multi/right.js',
    
  141.     'e2e-regression': './src/e2e-regression/app.js',
    
  142.     'perf-regression-app': './src/perf-regression/app.js',
    
  143.     'perf-regression-devtools': './src/perf-regression/devtools.js',
    
  144.   },
    
  145.   {
    
  146.     react: resolve(builtModulesDir, 'react'),
    
  147.     'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
    
  148.     'react-devtools-feature-flags': resolveFeatureFlags('shell'),
    
  149.     'react-dom/client': resolve(builtModulesDir, 'react-dom/client'),
    
  150.     'react-dom': resolve(builtModulesDir, 'react-dom/unstable_testing'),
    
  151.     'react-is': resolve(builtModulesDir, 'react-is'),
    
  152.     scheduler: resolve(builtModulesDir, 'scheduler'),
    
  153.   },
    
  154. );
    
  155. 
    
  156. // Prior to React 18, we use ReactDOM.render rather than
    
  157. // createRoot.
    
  158. // We also use a separate build folder to build the React App
    
  159. // so that we can test the current DevTools against older version of React
    
  160. const e2eRegressionApp = semver.lt(REACT_VERSION, '18.0.0')
    
  161.   ? makeConfig(
    
  162.       {
    
  163.         'e2e-app-regression': './src/e2e-regression/app-legacy.js',
    
  164.       },
    
  165.       {
    
  166.         react: resolve(E2E_APP_BUILD_DIR, 'react'),
    
  167.         'react-dom': resolve(E2E_APP_BUILD_DIR, 'react-dom'),
    
  168.         ...(semver.satisfies(REACT_VERSION, '16.5')
    
  169.           ? {schedule: resolve(E2E_APP_BUILD_DIR, 'schedule')}
    
  170.           : {scheduler: resolve(E2E_APP_BUILD_DIR, 'scheduler')}),
    
  171.       },
    
  172.     )
    
  173.   : makeConfig(
    
  174.       {
    
  175.         'e2e-app-regression': './src/e2e-regression/app.js',
    
  176.       },
    
  177.       {
    
  178.         react: resolve(E2E_APP_BUILD_DIR, 'react'),
    
  179.         'react-dom': resolve(E2E_APP_BUILD_DIR, 'react-dom'),
    
  180.         'react-dom/client': resolve(E2E_APP_BUILD_DIR, 'react-dom/client'),
    
  181.         scheduler: resolve(E2E_APP_BUILD_DIR, 'scheduler'),
    
  182.       },
    
  183.     );
    
  184. 
    
  185. const appCompiler = Webpack(app);
    
  186. const appServer = new WebpackDevServer(
    
  187.   {
    
  188.     hot: true,
    
  189.     open: true,
    
  190.     port: 8080,
    
  191.     client: {
    
  192.       logging: 'warn',
    
  193.     },
    
  194.     static: {
    
  195.       directory: __dirname,
    
  196.       publicPath: '/',
    
  197.     },
    
  198.   },
    
  199.   appCompiler,
    
  200. );
    
  201. 
    
  202. const e2eRegressionAppCompiler = Webpack(e2eRegressionApp);
    
  203. const e2eRegressionAppServer = new WebpackDevServer(
    
  204.   {
    
  205.     port: 8181,
    
  206.     client: {
    
  207.       logging: 'warn',
    
  208.     },
    
  209.     static: {
    
  210.       publicPath: '/dist/',
    
  211.     },
    
  212.     headers: {
    
  213.       'Access-Control-Allow-Origin': '*',
    
  214.     },
    
  215.   },
    
  216.   e2eRegressionAppCompiler,
    
  217. );
    
  218. 
    
  219. const runServer = async () => {
    
  220.   console.log('Starting server...');
    
  221. 
    
  222.   appServer.compiler.hooks.done.tap('done', () =>
    
  223.     console.log(SUCCESSFUL_COMPILATION_MESSAGE),
    
  224.   );
    
  225. 
    
  226.   await e2eRegressionAppServer.start();
    
  227.   await appServer.start();
    
  228. };
    
  229. 
    
  230. runServer();