Skip to content

Commit

Permalink
Replace React Hot Loader with Fast Refresh (#2953)
Browse files Browse the repository at this point in the history
  • Loading branch information
taneliang authored Nov 24, 2020
1 parent eb51954 commit 4ba9c9b
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 115 deletions.
7 changes: 4 additions & 3 deletions website/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ module.exports = (api) => {

if (IS_DEV || IS_PROD) {
plugins.push(['@babel/plugin-proposal-object-rest-spread', { useBuiltIns: true }]);
// In production this cleans up hot reload code
// See https://github.com/gaearon/react-hot-loader#what-about-production
plugins.push('react-hot-loader/babel');
}

if (IS_DEV) {
plugins.push('react-refresh/babel');
}

if (IS_PROD) {
Expand Down
5 changes: 2 additions & 3 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"@babel/preset-env": "7.12.7",
"@babel/preset-react": "7.12.7",
"@babel/preset-typescript": "7.12.7",
"@hot-loader/react-dom": "17.0.0",
"@packtracker/webpack-plugin": "2.3.0",
"@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
"@svgr/webpack": "5.5.0",
"@types/classnames": "2.2.11",
"@types/enzyme": "3.10.8",
Expand All @@ -50,7 +50,6 @@
"@types/react-beautiful-dnd": "13.0.0",
"@types/react-dom": "17.0.0",
"@types/react-helmet": "6.1.0",
"@types/react-hot-loader": "4.1.1",
"@types/react-kawaii": "0.11.0",
"@types/react-loadable": "5.5.4",
"@types/react-modal": "3.10.6",
Expand Down Expand Up @@ -106,6 +105,7 @@
"postcss-loader": "4.1.0",
"prettier": "2.2.0",
"react-dev-utils": "11.0.0",
"react-refresh": "0.9.0",
"react-test-renderer": "17.0.1",
"redux-logger": "3.0.6",
"redux-mock-store": "1.5.4",
Expand Down Expand Up @@ -154,7 +154,6 @@
"react-dom": "17.0.1",
"react-feather": "2.0.9",
"react-helmet": "6.1.0",
"react-hot-loader": "4.13.0",
"react-kawaii": "0.16.0",
"react-leaflet": "3.0.2",
"react-loadable": "5.5.0",
Expand Down
3 changes: 1 addition & 2 deletions website/src/entry/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { State } from 'types/state';
import { Persistor } from 'storage/persistReducer';

import * as React from 'react';
import { hot } from 'react-hot-loader/root';
import { BrowserRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
Expand Down Expand Up @@ -44,4 +43,4 @@ const App: React.FC<Props> = ({ store, persistor }) => {
);
};

export default hot(App);
export default App;
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
SearchkitProvider,
} from 'searchkit';
import classnames from 'classnames';
import { hot } from 'react-hot-loader/root';

import { ElasticSearchResult } from 'types/vendor/elastic-search';
import { ModuleInformation } from 'types/modules';
Expand Down Expand Up @@ -108,4 +107,4 @@ const ModuleFinderContainer: React.FC = () => {
);
};

export default hot(ModuleFinderContainer);
export default ModuleFinderContainer;
3 changes: 1 addition & 2 deletions website/src/views/modules/ModulePageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Component } from 'react';
import classnames from 'classnames';
import ScrollSpy from 'react-scrollspy';
import { kebabCase, map, mapValues, values, sortBy } from 'lodash';
import { hot } from 'react-hot-loader/root';

import { Module, NUSModuleAttributes, attributeDescription } from 'types/modules';

Expand Down Expand Up @@ -321,4 +320,4 @@ class ModulePageContent extends Component<Props, State> {
}
}

export default hot(ModulePageContent);
export default ModulePageContent;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { connect } from 'react-redux';
import { flatMap, flatten, sortBy, toPairs, values } from 'lodash';
import { DragDropContext, Droppable, OnDragEndResponder } from 'react-beautiful-dnd';
import classnames from 'classnames';
import { hot } from 'react-hot-loader/root';

import { Module, ModuleCode, Semester } from 'types/modules';
import { PlannerModulesWithInfo, PlannerModuleInfo, AddModuleData } from 'types/planner';
Expand Down Expand Up @@ -307,4 +306,4 @@ const PlannerContainer = connect(mapStateToProps, {
removeModule: removePlannerModule,
})(PlannerContainerComponent);

export default hot(PlannerContainer);
export default PlannerContainer;
3 changes: 1 addition & 2 deletions website/src/views/today/TodayContainer/TodayContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
parseISO,
} from 'date-fns';
import produce from 'immer';
import { hot } from 'react-hot-loader/root';

import { DaysOfWeek } from 'types/modules';
import { Lesson, ColoredLesson, SemTimetableConfigWithLessons } from 'types/timetables';
Expand Down Expand Up @@ -364,4 +363,4 @@ const ConnectedTimetableContainer = connect(mapStateToProps)(TodayContainerCompo
const TodayContainerWithTimer = withTimer(ConnectedTimetableContainer);
const ResponsiveTodayContainer = makeResponsive(TodayContainerWithTimer, breakpointUp('lg'));

export default hot(ResponsiveTodayContainer);
export default ResponsiveTodayContainer;
27 changes: 8 additions & 19 deletions website/webpack/webpack.config.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const { merge } = require('webpack-merge');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

const commonConfig = require('./webpack.config.common');
const parts = require('./webpack.parts');
Expand All @@ -25,20 +26,12 @@ const developmentConfig = merge([
// Use a fast source map for good-enough debugging usage
// https://webpack.js.org/configuration/devtool/#devtool
devtool: 'eval-cheap-module-source-map',
entry: [
'react-hot-loader/patch',
// Modify entry for hot module reload to work
// See: https://survivejs.com/webpack/appendices/hmr/#setting-wds-entry-points-manually
'webpack-dev-server/client',
'webpack/hot/only-dev-server',
'entry/main',
],
resolve: {
alias: {
// Replace React DOM with the hot reload patched version in development
'react-dom': '@hot-loader/react-dom',
},
},
entry: 'entry/main',
// Fixes HMR in Webpack 5
// TODO: Remove once one of these issues are fixed:
// https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/235
// https://github.com/webpack/webpack-dev-server/issues/2758
target: 'web',
plugins: [
new HtmlWebpackPlugin({
template: path.join(parts.PATHS.src, 'index.html'),
Expand All @@ -54,11 +47,7 @@ const developmentConfig = merge([
new webpack.WatchIgnorePlugin({
paths: [parts.PATHS.node, parts.PATHS.build],
}),
// Enable multi-pass compilation for enhanced performance
// in larger projects. Good default.
// Waiting on: https://github.com/jantimon/html-webpack-plugin/issues/533
// { multiStep: true }
new webpack.HotModuleReplacementPlugin(),
new ReactRefreshWebpackPlugin(),
],
},
parts.lintJavaScript({
Expand Down
11 changes: 7 additions & 4 deletions website/webpack/webpack.config.timetable-only.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ const path = require('path');
const { merge } = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

const commonConfig = require('./webpack.config.common');
const parts = require('./webpack.parts');

const isProduction = process.env.NODE_ENV === 'production';
// eslint-disable-next-line no-underscore-dangle
const __DEV__ = process.env.NODE_ENV !== 'production';

const source = (file) => path.join('entry/export', file);

const productionConfig = merge([
{
plugins: [
new webpack.DefinePlugin({
__DEV__: !isProduction,
__DEV__,
DISPLAY_COMMIT_HASH: JSON.stringify(parts.appVersion().commitHash),
VERSION_STR: JSON.stringify(parts.appVersion().versionStr),
DEBUG_SERVICE_WORKER: !!process.env.DEBUG_SERVICE_WORKER,
Expand All @@ -36,7 +38,7 @@ const productionConfig = merge([
output: {
// The build folder.
path: parts.PATHS.buildTimetable,
filename: isProduction ? '[chunkhash].js' : '[contenthash].js',
filename: __DEV__ ? '[contenthash].js' : '[chunkhash].js',
// This is used for require.ensure. The setup
// will work without but this is useful to set.
chunkFilename: '[chunkhash].js',
Expand All @@ -47,7 +49,8 @@ const productionConfig = merge([
inject: true,
}),
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/\.(js|css)$/]),
],
__DEV__ && new ReactRefreshWebpackPlugin(),
].filter(Boolean),
},
parts.loadImages({
include: parts.PATHS.images,
Expand Down
Loading

0 comments on commit 4ba9c9b

Please sign in to comment.