feat(react): add react fast refresh to webpack (#5612)
This commit is contained in:
parent
4a0dcbab40
commit
b8584a6f18
@ -26,6 +26,14 @@ Type: `string`
|
|||||||
|
|
||||||
Target which builds the application
|
Target which builds the application
|
||||||
|
|
||||||
|
### hmr
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Enable hot module replacement.
|
||||||
|
|
||||||
### host
|
### host
|
||||||
|
|
||||||
Default: `localhost`
|
Default: `localhost`
|
||||||
|
|||||||
@ -34,6 +34,10 @@ The options below are common to the `serve` command used within an Nx workspace.
|
|||||||
|
|
||||||
This option allows you to whitelist services that are allowed to access the dev server.
|
This option allows you to whitelist services that are allowed to access the dev server.
|
||||||
|
|
||||||
|
### hmr
|
||||||
|
|
||||||
|
Enable hot module replacement.
|
||||||
|
|
||||||
### host
|
### host
|
||||||
|
|
||||||
Host to listen on.
|
Host to listen on.
|
||||||
@ -140,10 +144,6 @@ Don't verify connected clients are part of allowed hosts.
|
|||||||
|
|
||||||
Output in-file eval sourcemaps.
|
Output in-file eval sourcemaps.
|
||||||
|
|
||||||
### hmr
|
|
||||||
|
|
||||||
Enable hot module replacement.
|
|
||||||
|
|
||||||
### hmr-warning
|
### hmr-warning
|
||||||
|
|
||||||
Show a warning when the `--hmr` option is enabled.
|
Show a warning when the `--hmr` option is enabled.
|
||||||
|
|||||||
@ -27,6 +27,14 @@ Type: `string`
|
|||||||
|
|
||||||
Target which builds the application
|
Target which builds the application
|
||||||
|
|
||||||
|
### hmr
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Enable hot module replacement.
|
||||||
|
|
||||||
### host
|
### host
|
||||||
|
|
||||||
Default: `localhost`
|
Default: `localhost`
|
||||||
|
|||||||
@ -34,6 +34,10 @@ The options below are common to the `serve` command used within an Nx workspace.
|
|||||||
|
|
||||||
This option allows you to whitelist services that are allowed to access the dev server.
|
This option allows you to whitelist services that are allowed to access the dev server.
|
||||||
|
|
||||||
|
### hmr
|
||||||
|
|
||||||
|
Enable hot module replacement.
|
||||||
|
|
||||||
### host
|
### host
|
||||||
|
|
||||||
Host to listen on.
|
Host to listen on.
|
||||||
@ -140,10 +144,6 @@ Don't verify connected clients are part of allowed hosts.
|
|||||||
|
|
||||||
Output in-file eval sourcemaps.
|
Output in-file eval sourcemaps.
|
||||||
|
|
||||||
### hmr
|
|
||||||
|
|
||||||
Enable hot module replacement.
|
|
||||||
|
|
||||||
### hmr-warning
|
### hmr-warning
|
||||||
|
|
||||||
Show a warning when the `--hmr` option is enabled.
|
Show a warning when the `--hmr` option is enabled.
|
||||||
|
|||||||
@ -27,6 +27,14 @@ Type: `string`
|
|||||||
|
|
||||||
Target which builds the application
|
Target which builds the application
|
||||||
|
|
||||||
|
### hmr
|
||||||
|
|
||||||
|
Default: `false`
|
||||||
|
|
||||||
|
Type: `boolean`
|
||||||
|
|
||||||
|
Enable hot module replacement.
|
||||||
|
|
||||||
### host
|
### host
|
||||||
|
|
||||||
Default: `localhost`
|
Default: `localhost`
|
||||||
|
|||||||
@ -34,6 +34,10 @@ The options below are common to the `serve` command used within an Nx workspace.
|
|||||||
|
|
||||||
This option allows you to whitelist services that are allowed to access the dev server.
|
This option allows you to whitelist services that are allowed to access the dev server.
|
||||||
|
|
||||||
|
### hmr
|
||||||
|
|
||||||
|
Enable hot module replacement.
|
||||||
|
|
||||||
### host
|
### host
|
||||||
|
|
||||||
Host to listen on.
|
Host to listen on.
|
||||||
@ -140,10 +144,6 @@ Don't verify connected clients are part of allowed hosts.
|
|||||||
|
|
||||||
Output in-file eval sourcemaps.
|
Output in-file eval sourcemaps.
|
||||||
|
|
||||||
### hmr
|
|
||||||
|
|
||||||
Enable hot module replacement.
|
|
||||||
|
|
||||||
### hmr-warning
|
### hmr-warning
|
||||||
|
|
||||||
Show a warning when the `--hmr` option is enabled.
|
Show a warning when the `--hmr` option is enabled.
|
||||||
|
|||||||
@ -64,6 +64,7 @@ Options:
|
|||||||
--sslCert SSL certificate to use for serving HTTPS.
|
--sslCert SSL certificate to use for serving HTTPS.
|
||||||
--watch Watches for changes and rebuilds application (default: true)
|
--watch Watches for changes and rebuilds application (default: true)
|
||||||
--liveReload Whether to reload the page on change, using live-reload. (default: true)
|
--liveReload Whether to reload the page on change, using live-reload. (default: true)
|
||||||
|
--hmr Enable hot module replacement.
|
||||||
--publicHost Public URL where the application will be served
|
--publicHost Public URL where the application will be served
|
||||||
--open Open the application in the browser.
|
--open Open the application in the browser.
|
||||||
--allowedHosts This option allows you to whitelist services that are allowed to access the dev server.
|
--allowedHosts This option allows you to whitelist services that are allowed to access the dev server.
|
||||||
|
|||||||
@ -34,6 +34,10 @@ The options below are common to the `serve` command used within an Nx workspace.
|
|||||||
|
|
||||||
This option allows you to whitelist services that are allowed to access the dev server.
|
This option allows you to whitelist services that are allowed to access the dev server.
|
||||||
|
|
||||||
|
### hmr
|
||||||
|
|
||||||
|
Enable hot module replacement.
|
||||||
|
|
||||||
### host
|
### host
|
||||||
|
|
||||||
Host to listen on.
|
Host to listen on.
|
||||||
@ -140,10 +144,6 @@ Don't verify connected clients are part of allowed hosts.
|
|||||||
|
|
||||||
Output in-file eval sourcemaps.
|
Output in-file eval sourcemaps.
|
||||||
|
|
||||||
### hmr
|
|
||||||
|
|
||||||
Enable hot module replacement.
|
|
||||||
|
|
||||||
### hmr-warning
|
### hmr-warning
|
||||||
|
|
||||||
Show a warning when the `--hmr` option is enabled.
|
Show a warning when the `--hmr` option is enabled.
|
||||||
|
|||||||
@ -68,6 +68,7 @@
|
|||||||
"@nrwl/tao": "12.3.0",
|
"@nrwl/tao": "12.3.0",
|
||||||
"@nrwl/web": "12.3.0",
|
"@nrwl/web": "12.3.0",
|
||||||
"@nrwl/workspace": "12.3.0",
|
"@nrwl/workspace": "12.3.0",
|
||||||
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
|
||||||
"@popperjs/core": "^2.9.2",
|
"@popperjs/core": "^2.9.2",
|
||||||
"@reduxjs/toolkit": "1.5.0",
|
"@reduxjs/toolkit": "1.5.0",
|
||||||
"@rollup/plugin-babel": "5.0.2",
|
"@rollup/plugin-babel": "5.0.2",
|
||||||
@ -189,6 +190,7 @@
|
|||||||
"protractor": "5.4.3",
|
"protractor": "5.4.3",
|
||||||
"raw-loader": "3.1.0",
|
"raw-loader": "3.1.0",
|
||||||
"react-redux": "7.2.3",
|
"react-redux": "7.2.3",
|
||||||
|
"react-refresh": "^0.9.0",
|
||||||
"react-router-dom": "5.1.2",
|
"react-router-dom": "5.1.2",
|
||||||
"regenerator-runtime": "0.13.7",
|
"regenerator-runtime": "0.13.7",
|
||||||
"release-it": "^7.4.0",
|
"release-it": "^7.4.0",
|
||||||
|
|||||||
@ -37,11 +37,13 @@
|
|||||||
"@nrwl/storybook": "*",
|
"@nrwl/storybook": "*",
|
||||||
"@nrwl/web": "*",
|
"@nrwl/web": "*",
|
||||||
"@nrwl/workspace": "*",
|
"@nrwl/workspace": "*",
|
||||||
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
|
||||||
"@svgr/webpack": "^5.4.0",
|
"@svgr/webpack": "^5.4.0",
|
||||||
"eslint-plugin-import": "^2.22.1",
|
"eslint-plugin-import": "^2.22.1",
|
||||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||||
"eslint-plugin-react": "^7.23.1",
|
"eslint-plugin-react": "^7.23.1",
|
||||||
"eslint-plugin-react-hooks": "^4.2.0",
|
"eslint-plugin-react-hooks": "^4.2.0",
|
||||||
|
"react-refresh": "^0.9.0",
|
||||||
"url-loader": "^3.0.0"
|
"url-loader": "^3.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { Configuration } from 'webpack';
|
import { Configuration } from 'webpack';
|
||||||
|
import * as ReactRefreshPlugin from '@pmmmwh/react-refresh-webpack-plugin';
|
||||||
|
|
||||||
// Add React-specific configuration
|
// Add React-specific configuration
|
||||||
function getWebpackConfig(config: Configuration) {
|
function getWebpackConfig(config: Configuration) {
|
||||||
@ -54,6 +55,27 @@ function getWebpackConfig(config: Configuration) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (config.mode === 'development' && config['devServer']?.hot) {
|
||||||
|
// add `react-refresh/babel` to babel loader plugin
|
||||||
|
const babelLoader = config.module.rules.find((rule) =>
|
||||||
|
rule.loader.toString().includes('babel-loader')
|
||||||
|
);
|
||||||
|
if (babelLoader) {
|
||||||
|
babelLoader.options['plugins'] = [
|
||||||
|
...(babelLoader.options['plugins'] || []),
|
||||||
|
[
|
||||||
|
require.resolve('react-refresh/babel'),
|
||||||
|
{
|
||||||
|
skipEnvCheck: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// add https://github.com/pmmmwh/react-refresh-webpack-plugin to webpack plugin
|
||||||
|
config.plugins.push(new ReactRefreshPlugin());
|
||||||
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -278,9 +278,11 @@ describe('app', () => {
|
|||||||
expect(targetConfig.serve.executor).toEqual('@nrwl/web:dev-server');
|
expect(targetConfig.serve.executor).toEqual('@nrwl/web:dev-server');
|
||||||
expect(targetConfig.serve.options).toEqual({
|
expect(targetConfig.serve.options).toEqual({
|
||||||
buildTarget: 'my-app:build',
|
buildTarget: 'my-app:build',
|
||||||
|
hmr: true,
|
||||||
});
|
});
|
||||||
expect(targetConfig.serve.configurations.production).toEqual({
|
expect(targetConfig.serve.configurations.production).toEqual({
|
||||||
buildTarget: 'my-app:build:production',
|
buildTarget: 'my-app:build:production',
|
||||||
|
hmr: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -112,10 +112,12 @@ function createServeTarget(options: NormalizedSchema): TargetConfiguration {
|
|||||||
executor: '@nrwl/web:dev-server',
|
executor: '@nrwl/web:dev-server',
|
||||||
options: {
|
options: {
|
||||||
buildTarget: `${options.projectName}:build`,
|
buildTarget: `${options.projectName}:build`,
|
||||||
|
hmr: true,
|
||||||
},
|
},
|
||||||
configurations: {
|
configurations: {
|
||||||
production: {
|
production: {
|
||||||
buildTarget: `${options.projectName}:build:production`,
|
buildTarget: `${options.projectName}:build:production`,
|
||||||
|
hmr: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -35,6 +35,7 @@ export interface WebDevServerOptions {
|
|||||||
buildTarget: string;
|
buildTarget: string;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
liveReload: boolean;
|
liveReload: boolean;
|
||||||
|
hmr: boolean;
|
||||||
watch: boolean;
|
watch: boolean;
|
||||||
allowedHosts: string;
|
allowedHosts: string;
|
||||||
maxWorkers?: number;
|
maxWorkers?: number;
|
||||||
|
|||||||
@ -41,6 +41,11 @@
|
|||||||
"description": "Whether to reload the page on change, using live-reload.",
|
"description": "Whether to reload the page on change, using live-reload.",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
|
"hmr": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Enable hot module replacement.",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"publicHost": {
|
"publicHost": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Public URL where the application will be served"
|
"description": "Public URL where the application will be served"
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { getDevServerConfig } from './devserver.config';
|
|||||||
import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
|
import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
import { HotModuleReplacementPlugin } from 'webpack';
|
||||||
import { WebBuildBuilderOptions } from '../builders/build/build.impl';
|
import { WebBuildBuilderOptions } from '../builders/build/build.impl';
|
||||||
import { WebDevServerOptions } from '../builders/dev-server/dev-server.impl';
|
import { WebDevServerOptions } from '../builders/dev-server/dev-server.impl';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
@ -54,6 +55,7 @@ describe('getDevServerConfig', () => {
|
|||||||
buildTarget: 'webapp:build',
|
buildTarget: 'webapp:build',
|
||||||
ssl: false,
|
ssl: false,
|
||||||
liveReload: true,
|
liveReload: true,
|
||||||
|
hmr: true,
|
||||||
open: false,
|
open: false,
|
||||||
watch: true,
|
watch: true,
|
||||||
allowedHosts: null,
|
allowedHosts: null,
|
||||||
@ -328,7 +330,7 @@ describe('getDevServerConfig', () => {
|
|||||||
root,
|
root,
|
||||||
sourceRoot,
|
sourceRoot,
|
||||||
buildInput,
|
buildInput,
|
||||||
serveInput
|
{ ...serveInput, hmr: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result.liveReload).toEqual(true);
|
expect(result.liveReload).toEqual(true);
|
||||||
@ -339,13 +341,49 @@ describe('getDevServerConfig', () => {
|
|||||||
root,
|
root,
|
||||||
sourceRoot,
|
sourceRoot,
|
||||||
buildInput,
|
buildInput,
|
||||||
{ ...serveInput, liveReload: false }
|
{ ...serveInput, hmr: false, liveReload: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result.liveReload).toEqual(false);
|
expect(result.liveReload).toEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('hmr option', () => {
|
||||||
|
it('should set the correct value', () => {
|
||||||
|
const { devServer: result } = getDevServerConfig(
|
||||||
|
root,
|
||||||
|
sourceRoot,
|
||||||
|
buildInput,
|
||||||
|
{ ...serveInput, hmr: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.hot).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set the correct if true and disable live reload', () => {
|
||||||
|
const { devServer: result } = getDevServerConfig(
|
||||||
|
root,
|
||||||
|
sourceRoot,
|
||||||
|
buildInput,
|
||||||
|
serveInput
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.liveReload).toEqual(false);
|
||||||
|
expect(result.hot).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add hot module replacement plugin', () => {
|
||||||
|
const { plugins } = getDevServerConfig(
|
||||||
|
root,
|
||||||
|
sourceRoot,
|
||||||
|
buildInput,
|
||||||
|
serveInput
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(plugins).toContainEqual(new HotModuleReplacementPlugin());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('ssl option', () => {
|
describe('ssl option', () => {
|
||||||
it('should set https to false if not on', () => {
|
it('should set https to false if not on', () => {
|
||||||
const { devServer: result } = getDevServerConfig(
|
const { devServer: result } = getDevServerConfig(
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { readFileSync } from 'fs';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { getWebConfig } from './web.config';
|
import { getWebConfig } from './web.config';
|
||||||
import { Configuration } from 'webpack';
|
import { Configuration, HotModuleReplacementPlugin } from 'webpack';
|
||||||
import { WebBuildBuilderOptions } from '../builders/build/build.impl';
|
import { WebBuildBuilderOptions } from '../builders/build/build.impl';
|
||||||
import { WebDevServerOptions } from '../builders/dev-server/dev-server.impl';
|
import { WebDevServerOptions } from '../builders/dev-server/dev-server.impl';
|
||||||
import { buildServePath } from './serve-path';
|
import { buildServePath } from './serve-path';
|
||||||
@ -31,6 +31,10 @@ export function getDevServerConfig(
|
|||||||
serveOptions,
|
serveOptions,
|
||||||
buildOptions
|
buildOptions
|
||||||
);
|
);
|
||||||
|
webpackConfig.plugins = [
|
||||||
|
...(webpackConfig.plugins || []),
|
||||||
|
getHmrPlugin(serveOptions),
|
||||||
|
].filter(Boolean);
|
||||||
|
|
||||||
return webpackConfig;
|
return webpackConfig;
|
||||||
}
|
}
|
||||||
@ -85,7 +89,8 @@ function getDevServerPartial(
|
|||||||
publicPath: servePath,
|
publicPath: servePath,
|
||||||
contentBase: false,
|
contentBase: false,
|
||||||
allowedHosts: [],
|
allowedHosts: [],
|
||||||
liveReload: options.liveReload,
|
liveReload: options.hmr ? false : options.liveReload, // disable liveReload if hmr is enabled
|
||||||
|
hot: options.hmr,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.ssl && options.sslKey && options.sslCert) {
|
if (options.ssl && options.sslKey && options.sslCert) {
|
||||||
@ -114,3 +119,7 @@ function getProxyConfig(root: string, options: WebDevServerOptions) {
|
|||||||
const proxyPath = path.resolve(root, options.proxyConfig as string);
|
const proxyPath = path.resolve(root, options.proxyConfig as string);
|
||||||
return require(proxyPath);
|
return require(proxyPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHmrPlugin(options: WebDevServerOptions) {
|
||||||
|
return options.hmr && new HotModuleReplacementPlugin();
|
||||||
|
}
|
||||||
|
|||||||
@ -20519,6 +20519,11 @@ react-refresh@0.8.3, react-refresh@^0.8.3:
|
|||||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
||||||
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
|
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
|
||||||
|
|
||||||
|
react-refresh@^0.9.0:
|
||||||
|
version "0.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf"
|
||||||
|
integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==
|
||||||
|
|
||||||
react-router-dom@5.1.2:
|
react-router-dom@5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18"
|
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.1.2.tgz#06701b834352f44d37fbb6311f870f84c76b9c18"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user