diff --git a/.gitignore b/.gitignore index 66028cb2..206be3ab 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ # distribution *dist +*umd # misc .DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md index 36be6840..270569d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ It was necessary to support WDS below `4.8.0` (published in April 2022), but is no-longer needed as a direct integration with WDS is now possible. +### Features + +- Added helper script to better support use cases where React and/or React-DOM are externalized (#852) + ## 0.5.15 (3 Jun 2024) ### Fixes diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index c4882566..e2295a0f 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -268,9 +268,21 @@ but do note that React DevTools does not inject hooks over a frame boundary (`if **Externalise React Refresh** If all solutions above are not applicable, you can also externalise `react-refresh/runtime` together with React. +We provide an entrypoint to easily achieve this - `@pmmmwh/react-refresh-webpack-plugin/umd/client.min.js`. -Using this, however, would require you to ensure the injected entry from this plugin is executed before React. -You can check out [this sandbox](https://codesandbox.io/s/react-refresh-externals-14fpn) for an example on how this could be done. +If you would like to use the provided script, ensure that it is loaded before React and/or React-DOM. +You can load this script via any CDN for `npm`, such as `jsDelivr` and `unpkg`: + +```html + + + + + +``` + +If you don't want to use the provided script, +you can check out [this sandbox](https://codesandbox.io/s/react-refresh-externals-14fpn) for an example on how this could be done manually. ## Running multiple instances of React Refresh simultaneously diff --git a/package.json b/package.json index b4584f66..c3c21a06 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "options", "overlay", "sockets", - "types" + "types", + "umd" ], "packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610", "scripts": { @@ -54,8 +55,9 @@ "types:clean": "rimraf types", "types:compile": "tsc -p tsconfig.json", "types:prune-private": "del \"types/*/*\" \"!types/{lib,loader,options}/{index,types}.d.ts\"", - "generate-types": "run-s types:clean types:compile types:prune-private \"format --loglevel silent\"", - "prepublishOnly": "yarn generate-types" + "generate:client-external": "webpack", + "generate:types": "run-s types:clean types:compile types:prune-private \"format --log-level silent\"", + "prepublishOnly": "run-p generate:*" }, "dependencies": { "ansi-html": "^0.0.9", @@ -97,6 +99,7 @@ "puppeteer": "^22.10.0", "react-refresh": "^0.14.2", "sourcemap-validator": "^2.1.0", + "terser-webpack-plugin": "^5.3.10", "type-fest": "^4.18.3", "typescript": "~5.4.5", "webpack": "^5.91.0", diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 00000000..f685ac78 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,25 @@ +const path = require('node:path'); +const TerserPlugin = require('terser-webpack-plugin'); + +module.exports = { + mode: 'production', + entry: { + client: './client/ReactRefreshEntry.js', + }, + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + extractComments: false, + terserOptions: { + format: { comments: false }, + }, + }), + ], + nodeEnv: 'development', + }, + output: { + filename: '[name].min.js', + path: path.resolve(__dirname, 'umd'), + }, +};