diff --git a/packages/plugin-react-refresh/README.md b/packages/plugin-react-refresh/README.md index 49f51a5cd77048..498d2d7f3126bc 100644 --- a/packages/plugin-react-refresh/README.md +++ b/packages/plugin-react-refresh/README.md @@ -27,6 +27,25 @@ export default { [Full list of Babel parser plugins](https://babeljs.io/docs/en/babel-parser#ecmascript-proposalshttpsgithubcombabelproposals). +## Specifying files to include or exclude from refreshing + +By default, @vite/plugin-react-refresh will process files ending with `.js`, `.jsx`, `.ts`, and `.tsx`, and excludes all files in `node_modules`. + +In some situations you may not want a file to act as an HMR boundary, instead preferring that the changes propagate higher in the stack before being handled. In these cases, you can provide an `include` and/or `exclude` option, which can be regex or a [picomatch](https://github.com/micromatch/picomatch#globbing-features) pattern, or array of either. Files must match include and not exclude to be processed. Note, when using either `include`, or `exclude`, the defaults will not be merged in, so re-apply them if necessary. + +```js +export default { + plugins: [ + reactRefresh({ + // Exclude storybook stories and node_modules + exclude: [/\.stories\.(t|j)sx?$/, /node_modules/], + // Only .tsx files + include: '**/*.tsx' + }) + ] +} +``` + ### Notes - If using TSX, any TS-supported syntax will already be transpiled away so you won't need to specify them here. diff --git a/packages/plugin-react-refresh/index.d.ts b/packages/plugin-react-refresh/index.d.ts index f5197c9089f7b5..20fd573b44beae 100644 --- a/packages/plugin-react-refresh/index.d.ts +++ b/packages/plugin-react-refresh/index.d.ts @@ -6,7 +6,9 @@ type PluginFactory = (options?: Options) => Plugin declare const createPlugin: PluginFactory & { preambleCode: string } export interface Options { - parserPlugins: ParserOptions['plugins'] + parserPlugins?: ParserOptions['plugins'] + include?: string | RegExp | Array + exclude?: string | RegExp | Array } export default createPlugin diff --git a/packages/plugin-react-refresh/index.js b/packages/plugin-react-refresh/index.js index 0a1a415da17d7f..f72a12fa065a51 100644 --- a/packages/plugin-react-refresh/index.js +++ b/packages/plugin-react-refresh/index.js @@ -1,7 +1,7 @@ // @ts-check const fs = require('fs') const { transformSync, ParserOptions } = require('@babel/core') - +const { createFilter } = require('@rollup/pluginutils') const runtimePublicPath = '/@react-refresh' const runtimeFilePath = require.resolve( 'react-refresh/cjs/react-refresh-runtime.development.js' @@ -37,6 +37,10 @@ window.__vite_plugin_react_preamble_installed__ = true function reactRefreshPlugin(opts) { let shouldSkip = false let base = '/' + const filter = createFilter( + (opts && opts.include) || /\.(t|j)sx?$/, + (opts && opts.exclude) || /node_modules/ + ) return { name: 'react-refresh', @@ -65,7 +69,7 @@ function reactRefreshPlugin(opts) { return } - if (!/\.(t|j)sx?$/.test(id) || id.includes('node_modules')) { + if (!filter(id)) { return } diff --git a/packages/plugin-react-refresh/package.json b/packages/plugin-react-refresh/package.json index 5cf65b440f95ec..085cb156c83aca 100644 --- a/packages/plugin-react-refresh/package.json +++ b/packages/plugin-react-refresh/package.json @@ -29,6 +29,7 @@ "@babel/core": "^7.14.6", "@babel/plugin-transform-react-jsx-self": "^7.14.5", "@babel/plugin-transform-react-jsx-source": "^7.14.5", + "@rollup/pluginutils": "^4.1.0", "react-refresh": "^0.9.0" } }