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