Skip to content

Commit 0c2378c

Browse files
committed
Fix react refresh bug
1 parent d5ea382 commit 0c2378c

File tree

1 file changed

+71
-85
lines changed

1 file changed

+71
-85
lines changed

config/rspack.config.js

Lines changed: 71 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -30,31 +30,23 @@ module.exports = (webpackEnv, argv) => {
3030

3131
const isDevServerOnly = env.dev_server_only?.toLowerCase() === 'true';
3232
const isFastMode = env.fast?.toLowerCase() !== 'false' && isDevServer && !isDevServerOnly;
33-
33+
const isReactRefresh = isDevServer && isEnvDevelopment;
3434
if (isFastMode) {
3535
console.log('Fast mode enabled: disabled sourcemaps, ...');
3636
}
3737

3838
const now = new Date();
39-
// workspace constants
40-
const workspacePath = fs.realpathSync(process.cwd()); // TODO: Add , '../') if you move this file in a subdirectory
39+
const workspacePath = fs.realpathSync(process.cwd());
4140
const appPkg = require(path.join(workspacePath, 'package.json'));
4241
const workspaceBuildInfoFile = path.join(workspacePath, 'package-lock.json');
4342
const workspaceMetaDataFile = path.join(workspacePath, 'metaData.json');
44-
// Always look for the phovea_registry.ts in the src folder for standalone repos, or in the workspace root in workspaces.
43+
// Always look for the phovea_registry.ts in the src folder for standalone repos.
4544
const workspaceRegistryFile = path.join(workspacePath, 'src/phovea_registry.ts');
46-
const workspaceRepos = ['./'];
47-
48-
const libName = appPkg.name;
49-
const libDesc = appPkg.description || '';
5045

5146
if (!appPkg.visyn) {
5247
throw Error(`The package.json of ${appPkg.name} does not contain a 'visyn' entry.`);
5348
}
5449

55-
// Extract workspace proxy configuration from .yo-rc-workspace.json and package.json
56-
const workspaceProxy = appPkg.visyn.devServerProxy || {};
57-
5850
/**
5951
* Configuration of visyn repos. Includes entrypoints, registry configuration, files to copy, ...
6052
*
@@ -84,62 +76,17 @@ module.exports = (webpackEnv, argv) => {
8476

8577
let {
8678
// eslint-disable-next-line prefer-const
87-
entries, copyFiles, historyApiFallback,
79+
devServerProxy, entries, copyFiles, historyApiFallback,
8880
} = appPkg.visyn;
8981

9082
if (isDevServerOnly) {
9183
// If we do yarn start dev_server_only=true, we only want to start the dev server and not build the app (i.e. for proxy support).
9284
entries = {};
9385
}
9486

95-
const copyAppFiles = copyFiles?.map((file) => ({
96-
from: path.join(workspacePath, file),
97-
to: path.join(workspacePath, 'bundles', path.basename(file)),
98-
})) || [];
99-
10087
const prefix = (n) => (n < 10 ? `0${n}` : n.toString());
10188
const buildId = `${now.getUTCFullYear()}${prefix(now.getUTCMonth() + 1)}${prefix(now.getUTCDate())}-${prefix(now.getUTCHours())}${prefix(now.getUTCMinutes())}${prefix(now.getUTCSeconds())}`;
10289

103-
const copyPluginPatterns = copyAppFiles.concat(
104-
[
105-
fs.existsSync(workspaceMetaDataFile) && {
106-
from: workspaceMetaDataFile,
107-
to: path.join(workspacePath, 'bundles', 'phoveaMetaData.json'),
108-
// @ts-ignore TODO: check why https://webpack.js.org/plugins/copy-webpack-plugin/#transform is not in the typing.
109-
transform: () => {
110-
function resolveScreenshot(appDirectory) {
111-
const f = path.join(appDirectory, './media/screenshot.png');
112-
if (!fs.existsSync(f)) {
113-
return null;
114-
}
115-
const buffer = Buffer.from(fs.readFileSync(f)).toString('base64');
116-
return `data:image/png;base64,${buffer}`;
117-
}
118-
119-
return JSON.stringify(
120-
{
121-
name: appPkg.name,
122-
displayName: appPkg.displayName || appPkg.name,
123-
version: appPkg.version,
124-
repository: appPkg.repository?.url,
125-
homepage: appPkg.homepage,
126-
description: appPkg.description,
127-
screenshot: resolveScreenshot(workspacePath),
128-
buildId,
129-
},
130-
null,
131-
2,
132-
);
133-
},
134-
},
135-
// use package-lock json as buildInfo
136-
fs.existsSync(workspaceBuildInfoFile) && {
137-
from: workspaceBuildInfoFile,
138-
to: path.join(workspacePath, 'bundles', 'buildInfo.json'),
139-
},
140-
].filter(Boolean),
141-
);
142-
14390
// Check if Tailwind config exists
14491
const useTailwind = fs.existsSync(path.join(workspacePath, 'tailwind.config.js'));
14592

@@ -148,7 +95,7 @@ module.exports = (webpackEnv, argv) => {
14895
// Logging noise constrained to errors and warnings
14996
stats: 'errors-warnings', // { logging: 'verbose', timings: true, assets: true },
15097
// eslint-disable-next-line no-nested-ternary
151-
devtool: isFastMode ? 'eval' : (isEnvDevelopment ? 'cheap-module-source-map' : 'source-map'),
98+
devtool: isFastMode ? 'eval' : isEnvDevelopment ? 'cheap-module-source-map' : 'source-map',
15299
// These are the "entry points" to our application.
153100
// This means they will be the "root" imports that are included in JS bundle.
154101
entry: Object.fromEntries(
@@ -167,8 +114,8 @@ module.exports = (webpackEnv, argv) => {
167114
// Needs to be enabled to make SPAs work: https://stackoverflow.com/questions/31945763/how-to-tell-webpack-dev-server-to-serve-index-html-for-any-route
168115
historyApiFallback: historyApiFallback == null ? true : historyApiFallback,
169116
proxy: {
170-
// Append on top to allow overriding /api/v1/ for example
171-
...workspaceProxy,
117+
// Append on top to allow overriding /api/v1/ for example
118+
...(devServerProxy || {}),
172119
...{
173120
'/api/*': {
174121
target: 'http://localhost:9000',
@@ -192,11 +139,11 @@ module.exports = (webpackEnv, argv) => {
192139
secure: false,
193140
},
194141
// Append on bottom to allow override of exact key matches like /api/*
195-
...workspaceProxy,
142+
...(devServerProxy || {}),
196143
},
197144
},
198145
client: {
199-
// Do not show the full-page error overlay
146+
// Do not show the full-page error overlay
200147
overlay: false,
201148
},
202149
}
@@ -292,7 +239,7 @@ module.exports = (webpackEnv, argv) => {
292239
react: {
293240
runtime: 'automatic',
294241
development: isEnvDevelopment,
295-
refresh: isEnvDevelopment,
242+
refresh: isReactRefresh,
296243
},
297244
},
298245
},
@@ -317,7 +264,7 @@ module.exports = (webpackEnv, argv) => {
317264
react: {
318265
runtime: 'automatic',
319266
development: isEnvDevelopment,
320-
refresh: isEnvDevelopment,
267+
refresh: isReactRefresh,
321268
},
322269
},
323270
},
@@ -408,7 +355,7 @@ module.exports = (webpackEnv, argv) => {
408355
},
409356
plugins: [
410357
process.env.RSDOCTOR && new RsdoctorRspackPlugin(),
411-
isEnvDevelopment && new ReactRefreshPlugin(),
358+
isReactRefresh && new ReactRefreshPlugin(),
412359
// TODO: Enable, but creates a warning right now
413360
new DotenvPlugin({
414361
path: path.join(workspacePath, '.env'), // load this now instead of the ones in '.env'
@@ -427,40 +374,79 @@ module.exports = (webpackEnv, argv) => {
427374
'process.env.__DEBUG__': JSON.stringify(isEnvDevelopment),
428375
}),
429376
new CopyRspackPlugin({
430-
patterns: copyPluginPatterns,
377+
patterns: [
378+
...(copyFiles?.map((file) => ({
379+
from: path.join(workspacePath, file),
380+
to: path.join(workspacePath, 'bundles', path.basename(file)),
381+
})) || []),
382+
...[
383+
fs.existsSync(workspaceMetaDataFile) && {
384+
from: workspaceMetaDataFile,
385+
to: path.join(workspacePath, 'bundles', 'phoveaMetaData.json'),
386+
// @ts-ignore TODO: check why https://webpack.js.org/plugins/copy-webpack-plugin/#transform is not in the typing.
387+
transform: () => {
388+
function resolveScreenshot(appDirectory) {
389+
const f = path.join(appDirectory, './media/screenshot.png');
390+
if (!fs.existsSync(f)) {
391+
return null;
392+
}
393+
const buffer = Buffer.from(fs.readFileSync(f)).toString('base64');
394+
return `data:image/png;base64,${buffer}`;
395+
}
396+
397+
return JSON.stringify(
398+
{
399+
name: appPkg.name,
400+
displayName: appPkg.displayName || appPkg.name,
401+
version: appPkg.version,
402+
repository: appPkg.repository?.url,
403+
homepage: appPkg.homepage,
404+
description: appPkg.description,
405+
screenshot: resolveScreenshot(workspacePath),
406+
buildId,
407+
},
408+
null,
409+
2,
410+
);
411+
},
412+
},
413+
// use package-lock json as buildInfo
414+
fs.existsSync(workspaceBuildInfoFile) && {
415+
from: workspaceBuildInfoFile,
416+
to: path.join(workspacePath, 'bundles', 'buildInfo.json'),
417+
},
418+
].filter(Boolean),
419+
],
431420
}),
432421
...Object.entries(entries).map(
433422
// TODO: Do not use HtmlRspackPlugin, as it can't handle require calls in ejs templates.
434423
([chunkName, entry]) => new HtmlWebpackPlugin({
435424
template: entry.template ? path.join(workspacePath, entry.template) : 'auto',
436425
filename: entry.html || `${chunkName}.html`,
437-
title: libName,
426+
title: appPkg.name,
438427
chunks: [chunkName],
439428
// By default, exclude all other chunks
440429
excludedChunks: entry.excludeChunks || Object.keys(entries).filter((entryKey) => entryKey !== chunkName),
441430
meta: {
442-
description: libDesc,
431+
description: appPkg.description || '',
443432
},
444433
minify: isEnvProduction,
445434
}),
446435
),
447-
...workspaceRepos.map(
448-
(repo) => isEnvDevelopment
449-
&& new ForkTsCheckerWebpackPlugin({
450-
async: isEnvDevelopment,
451-
typescript: {
452-
diagnosticOptions: {
453-
semantic: true,
454-
syntactic: true,
455-
},
456-
// Build the repo and type-check
457-
build: true,
458-
mode: 'write-references',
459-
// Use the corresponding config file of the repo folder
460-
configFile: path.join(workspacePath, repo, 'tsconfig.json'),
461-
},
462-
}),
463-
),
436+
isEnvDevelopment
437+
&& new ForkTsCheckerWebpackPlugin({
438+
async: isEnvDevelopment,
439+
typescript: {
440+
diagnosticOptions: {
441+
semantic: true,
442+
syntactic: true,
443+
},
444+
// Build the repo and type-check
445+
build: true,
446+
mode: 'write-references',
447+
configFile: path.join(workspacePath, 'tsconfig.json'),
448+
},
449+
}),
464450
].filter(Boolean),
465451
});
466452
};

0 commit comments

Comments
 (0)