first commit
Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled

This commit is contained in:
Arian Tron
2026-03-10 19:37:31 +03:30
commit 61f56f997c
27684 changed files with 2784175 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
# `@next/react-refresh-utils`
This is an **experimental** package that provides utilities for React Refresh.
Its API is not stable as that of Next.js, nor does it follow semver rules.
**Use it at your own risk**.
## Usage
All entrypoints below must wired into your build tooling for this to work.
### `@next/react-refresh-utils/dist/loader`
### `@next/react-refresh-utils/dist/ReactRefreshWebpackPlugin`
### `@next/react-refresh-utils/dist/runtime`

View File

@@ -0,0 +1,24 @@
import type { Compiler } from 'webpack'
const PLUGIN_NAME = 'ReactRefreshRspackPlugin'
class ReactRefreshRspackPlugin {
static loader = 'builtin:react-refresh-loader'
apply(compiler: Compiler) {
new compiler.webpack.ProvidePlugin({
$ReactRefreshRuntime$: require.resolve('./internal/RspackReactRefresh'),
}).apply(compiler)
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
compilation.hooks.additionalTreeRuntimeRequirements.tap(
PLUGIN_NAME,
(_, runtimeRequirements) => {
runtimeRequirements.add(compiler.webpack.RuntimeGlobals.moduleCache)
}
)
})
}
}
export default ReactRefreshRspackPlugin

View File

@@ -0,0 +1,195 @@
import type {
Compiler as WebpackCompiler,
Template as WebpackTemplate,
RuntimeModule as WebpackRuntimeModule,
RuntimeGlobals as WebpackRuntimeGlobals,
Compilation as WebpackCompilation,
} from 'webpack'
// Shared between webpack 4 and 5:
function injectRefreshFunctions(
compilation: WebpackCompilation,
Template: typeof WebpackTemplate
) {
const hookVars: any = (compilation.mainTemplate.hooks as any).localVars
hookVars.tap('ReactFreshWebpackPlugin', (source: string) =>
Template.asString([
source,
'',
'// noop fns to prevent runtime errors during initialization',
'if (typeof self !== "undefined") {',
Template.indent('self.$RefreshReg$ = function () {};'),
Template.indent('self.$RefreshSig$ = function () {'),
Template.indent(Template.indent('return function (type) {')),
Template.indent(Template.indent(Template.indent('return type;'))),
Template.indent(Template.indent('};')),
Template.indent('};'),
'}',
])
)
}
function webpack4(this: ReactFreshWebpackPlugin, compiler: WebpackCompiler) {
const { Template } = this
// Webpack 4 does not have a method to handle interception of module
// execution.
// The closest thing we have to emulating this is mimicking the behavior of
// `strictModuleExceptionHandling` in `MainTemplate`:
// https://github.com/webpack/webpack/blob/4c644bf1f7cb067c748a52614500e0e2182b2700/lib/MainTemplate.js#L200
compiler.hooks.compilation.tap('ReactFreshWebpackPlugin', (compilation) => {
injectRefreshFunctions(compilation, Template)
const hookRequire: any = (compilation.mainTemplate.hooks as any).require
// @ts-ignore webpack 5 types compat
hookRequire.tap('ReactFreshWebpackPlugin', (source: string) => {
// Webpack 4 evaluates module code on the following line:
// ```
// modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
// ```
// https://github.com/webpack/webpack/blob/4c644bf1f7cb067c748a52614500e0e2182b2700/lib/MainTemplate.js#L200
const lines = source.split('\n')
// @ts-ignore webpack 5 types compat
const evalIndex = lines.findIndex((l) =>
l.includes('modules[moduleId].call(')
)
// Unable to find the module execution, that's OK:
if (evalIndex === -1) {
return source
}
// Legacy CSS implementations will `eval` browser code in a Node.js
// context to extract CSS. For backwards compatibility, we need to check
// we're in a browser context before continuing.
return Template.asString([
...lines.slice(0, evalIndex),
`
var hasRefresh = typeof self !== "undefined" && !!self.$RefreshInterceptModuleExecution$;
var cleanup = hasRefresh
? self.$RefreshInterceptModuleExecution$(moduleId)
: function() {};
try {
`,
lines[evalIndex],
`
} finally {
cleanup();
}
`,
...lines.slice(evalIndex + 1),
])
})
})
}
function webpack5(this: ReactFreshWebpackPlugin, compiler: WebpackCompiler) {
const { RuntimeGlobals, RuntimeModule, Template } = this
class ReactRefreshRuntimeModule extends RuntimeModule {
constructor() {
super('react refresh', 5)
}
generate() {
const { runtimeTemplate } = this.compilation!
return Template.asString([
`if (${RuntimeGlobals.interceptModuleExecution}) {`,
`${
RuntimeGlobals.interceptModuleExecution
}.push(${runtimeTemplate.basicFunction('options', [
`${
runtimeTemplate.supportsConst() ? 'const' : 'var'
} originalFactory = options.factory;`,
`options.factory = ${runtimeTemplate.basicFunction(
'moduleObject, moduleExports, webpackRequire',
[
// If the original factory is missing, e.g. due to race condition
// when compiling multiple entries concurrently, recover by doing
// a full page reload.
'if (!originalFactory) {',
Template.indent('document.location.reload();'),
Template.indent('return;'),
'}',
// Legacy CSS implementations will `eval` browser code in a Node.js
// context to extract CSS. For backwards compatibility, we need to check
// we're in a browser context before continuing.
`${
runtimeTemplate.supportsConst() ? 'const' : 'var'
} hasRefresh = typeof self !== "undefined" && !!self.$RefreshInterceptModuleExecution$;`,
`${
runtimeTemplate.supportsConst() ? 'const' : 'var'
} cleanup = hasRefresh ? self.$RefreshInterceptModuleExecution$(moduleObject.id) : ${
runtimeTemplate.supportsArrowFunction()
? '() => {}'
: 'function() {}'
};`,
'try {',
Template.indent(
'originalFactory.call(this, moduleObject, moduleExports, webpackRequire);'
),
'} finally {',
Template.indent(`cleanup();`),
'}',
]
)}`,
])})`,
'}',
])
}
}
// @ts-ignore webpack 5 types compat
compiler.hooks.compilation.tap('ReactFreshWebpackPlugin', (compilation) => {
injectRefreshFunctions(compilation, Template)
compilation.hooks.additionalTreeRuntimeRequirements.tap(
'ReactFreshWebpackPlugin',
(chunk: any) => {
compilation.addRuntimeModule(chunk, new ReactRefreshRuntimeModule())
}
)
})
}
class ReactFreshWebpackPlugin {
webpackMajorVersion: number
// @ts-ignore exists in webpack 5
RuntimeGlobals: typeof WebpackRuntimeGlobals
// @ts-ignore exists in webpack 5
RuntimeModule: typeof WebpackRuntimeModule
Template: typeof WebpackTemplate
constructor(
{
version,
RuntimeGlobals,
RuntimeModule,
Template,
} = require('webpack') as typeof import('webpack')
) {
this.webpackMajorVersion = parseInt(version ?? '', 10)
this.RuntimeGlobals = RuntimeGlobals
this.RuntimeModule = RuntimeModule
this.Template = Template
}
apply(compiler: WebpackCompiler) {
switch (this.webpackMajorVersion) {
case 4: {
webpack4.call(this, compiler)
break
}
case 5: {
webpack5.call(this, compiler)
break
}
default: {
throw new Error(
`ReactFreshWebpackPlugin does not support webpack v${this.webpackMajorVersion}.`
)
}
}
}
}
export default ReactFreshWebpackPlugin

View File

@@ -0,0 +1,91 @@
import type { RefreshRuntimeGlobals } from '../runtime'
declare const self: Window & RefreshRuntimeGlobals
type Dictionary = { [key: string]: unknown }
declare const __webpack_module__: {
id: string
exports: unknown
hot: {
accept: () => void
dispose: (onDispose: (data: Dictionary) => void) => void
invalidate: () => void
data?: Dictionary
}
}
// This function gets unwrapped into global scope, which is why we don't invert
// if-blocks. Also, you cannot use `return`.
export default function () {
// Wrapped in an IIFE to avoid polluting the global scope
;(function () {
// Legacy CSS implementations will `eval` browser code in a Node.js context
// to extract CSS. For backwards compatibility, we need to check we're in a
// browser context before continuing.
if (
typeof self !== 'undefined' &&
// No-JS mode does not inject these helpers:
'$RefreshHelpers$' in self
) {
// @ts-ignore __webpack_module__ is global
var currentExports = __webpack_module__.exports
// @ts-ignore __webpack_module__ is global
var prevSignature: unknown[] | null =
__webpack_module__.hot.data?.prevSignature ?? null
// This cannot happen in MainTemplate because the exports mismatch between
// templating and execution.
self.$RefreshHelpers$.registerExportsForReactRefresh(
currentExports,
__webpack_module__.id
)
// A module can be accepted automatically based on its exports, e.g. when
// it is a Refresh Boundary.
if (self.$RefreshHelpers$.isReactRefreshBoundary(currentExports)) {
// Save the previous exports signature on update so we can compare the boundary
// signatures. We avoid saving exports themselves since it causes memory leaks (https://github.com/vercel/next.js/pull/53797)
__webpack_module__.hot.dispose(function (data) {
data.prevSignature =
self.$RefreshHelpers$.getRefreshBoundarySignature(currentExports)
})
// Unconditionally accept an update to this module, we'll check if it's
// still a Refresh Boundary later.
// @ts-ignore importMeta is replaced in the loader
global.importMeta.webpackHot.accept()
// This field is set when the previous version of this module was a
// Refresh Boundary, letting us know we need to check for invalidation or
// enqueue an update.
if (prevSignature !== null) {
// A boundary can become ineligible if its exports are incompatible
// with the previous exports.
//
// For example, if you add/remove/change exports, we'll want to
// re-execute the importing modules, and force those components to
// re-render. Similarly, if you convert a class component to a
// function, we want to invalidate the boundary.
if (
self.$RefreshHelpers$.shouldInvalidateReactRefreshBoundary(
prevSignature,
self.$RefreshHelpers$.getRefreshBoundarySignature(currentExports)
)
) {
__webpack_module__.hot.invalidate()
} else {
self.$RefreshHelpers$.scheduleUpdate()
}
}
} else {
// Since we just executed the code for the module, it's possible that the
// new exports made it ineligible for being a boundary.
// We only care about the case when we were _previously_ a boundary,
// because we already accepted this update (accidental side effect).
var isNoLongerABoundary = prevSignature !== null
if (isNoLongerABoundary) {
__webpack_module__.hot.invalidate()
}
}
}
})()
}

View File

@@ -0,0 +1,96 @@
import RefreshHelpers from './helpers'
declare const __webpack_require__: {
c: Record<string | number, { exports: unknown | (() => Promise<unknown>) }>
}
// Extracts exports from a webpack module object.
function getModuleExports(moduleId: string) {
if (typeof moduleId === 'undefined') {
// `moduleId` is unavailable, which indicates that this module is not in the cache,
// which means we won't be able to capture any exports,
// and thus they cannot be refreshed safely.
// These are likely runtime or dynamically generated modules.
return {}
}
var maybeModule = __webpack_require__.c[moduleId]
if (typeof maybeModule === 'undefined') {
// `moduleId` is available but the module in cache is unavailable,
// which indicates the module is somehow corrupted (e.g. broken Webpack `module` globals).
// We will warn the user (as this is likely a mistake) and assume they cannot be refreshed.
console.warn(
'[React Refresh] Failed to get exports for module: ' + moduleId + '.'
)
return {}
}
var exportsOrPromise = maybeModule.exports
if (typeof Promise !== 'undefined' && exportsOrPromise instanceof Promise) {
return exportsOrPromise.then(function (exports) {
return exports
})
}
return exportsOrPromise
}
function executeRuntime(moduleExports, moduleId, webpackHot) {
RefreshHelpers.registerExportsForReactRefresh(moduleExports, moduleId)
if (webpackHot) {
var isHotUpdate = !!webpackHot.data
var prevSignature: unknown[] | null = webpackHot.data?.prevSignature ?? null
if (RefreshHelpers.isReactRefreshBoundary(moduleExports)) {
webpackHot.dispose(
// Save the previous exports signature on update so we can compare the boundary
// signatures. We avoid saving exports themselves since it causes memory leaks (https://github.com/vercel/next.js/pull/53797)
function hotDisposeCallback(data) {
data.prevSignature =
RefreshHelpers.getRefreshBoundarySignature(moduleExports)
}
)
webpackHot.accept()
// This field is set when the previous version of this module was a
// Refresh Boundary, letting us know we need to check for invalidation or
// enqueue an update.
if (prevSignature !== null) {
if (isHotUpdate) {
if (
RefreshHelpers.shouldInvalidateReactRefreshBoundary(
prevSignature,
RefreshHelpers.getRefreshBoundarySignature(moduleExports)
)
) {
webpackHot.invalidate()
} else {
RefreshHelpers.scheduleUpdate()
}
}
}
} else {
if (isHotUpdate && prevSignature !== null) {
webpackHot.invalidate()
}
}
}
}
// Port from https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/loader/utils/getRefreshModuleRuntime.js#L29
export function refresh(moduleId, webpackHot) {
const currentExports = getModuleExports(moduleId)
const fn = (exports) => {
executeRuntime(exports, moduleId, webpackHot)
}
if (typeof Promise !== 'undefined' && currentExports instanceof Promise) {
currentExports.then(fn)
} else {
fn(currentExports)
}
}
export {
register,
createSignatureFunctionForTransform,
} from 'react-refresh/runtime'

View File

@@ -0,0 +1,204 @@
/**
* MIT License
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
// This file is copied from the Metro JavaScript bundler, with minor tweaks for
// webpack 4 compatibility.
//
// https://github.com/facebook/metro/blob/d6b9685c730d0d63577db40f41369157f28dfa3a/packages/metro/src/lib/polyfills/require.js
import RefreshRuntime from 'react-refresh/runtime'
type ModuleHotStatus =
| 'idle'
| 'check'
| 'prepare'
| 'ready'
| 'dispose'
| 'apply'
| 'abort'
| 'fail'
type ModuleHotStatusHandler = (status: ModuleHotStatus) => void
declare const module: {
hot: {
status: () => ModuleHotStatus
addStatusHandler: (handler: ModuleHotStatusHandler) => void
removeStatusHandler: (handler: ModuleHotStatusHandler) => void
}
}
function isSafeExport(key: string): boolean {
return (
key === '__esModule' ||
key === '__N_SSG' ||
key === '__N_SSP' ||
// TODO: remove this key from page config instead of allow listing it
key === 'config'
)
}
function registerExportsForReactRefresh(
moduleExports: unknown,
moduleID: string
) {
RefreshRuntime.register(moduleExports, moduleID + ' %exports%')
if (moduleExports == null || typeof moduleExports !== 'object') {
// Exit if we can't iterate over exports.
// (This is important for legacy environments.)
return
}
for (var key in moduleExports) {
if (isSafeExport(key)) {
continue
}
try {
var exportValue = moduleExports[key]
} catch {
// This might fail due to circular dependencies
continue
}
var typeID = moduleID + ' %exports% ' + key
RefreshRuntime.register(exportValue, typeID)
}
}
function getRefreshBoundarySignature(moduleExports: unknown): Array<unknown> {
var signature = []
signature.push(RefreshRuntime.getFamilyByType(moduleExports))
if (moduleExports == null || typeof moduleExports !== 'object') {
// Exit if we can't iterate over exports.
// (This is important for legacy environments.)
return signature
}
for (var key in moduleExports) {
if (isSafeExport(key)) {
continue
}
try {
var exportValue = moduleExports[key]
} catch {
// This might fail due to circular dependencies
continue
}
signature.push(key)
signature.push(RefreshRuntime.getFamilyByType(exportValue))
}
return signature
}
function isReactRefreshBoundary(moduleExports: unknown): boolean {
if (RefreshRuntime.isLikelyComponentType(moduleExports)) {
return true
}
if (moduleExports == null || typeof moduleExports !== 'object') {
// Exit if we can't iterate over exports.
return false
}
var hasExports = false
var areAllExportsComponents = true
for (var key in moduleExports) {
hasExports = true
if (isSafeExport(key)) {
continue
}
try {
var exportValue = moduleExports[key]
} catch {
// This might fail due to circular dependencies
return false
}
if (!RefreshRuntime.isLikelyComponentType(exportValue)) {
areAllExportsComponents = false
}
}
return hasExports && areAllExportsComponents
}
function shouldInvalidateReactRefreshBoundary(
prevSignature: unknown[],
nextSignature: unknown[]
): boolean {
if (prevSignature.length !== nextSignature.length) {
return true
}
for (var i = 0; i < nextSignature.length; i++) {
if (prevSignature[i] !== nextSignature[i]) {
return true
}
}
return false
}
var isUpdateScheduled: boolean = false
// This function aggregates updates from multiple modules into a single React Refresh call.
function scheduleUpdate() {
if (isUpdateScheduled) {
return
}
isUpdateScheduled = true
function canApplyUpdate(status: ModuleHotStatus) {
return status === 'idle'
}
function applyUpdate() {
isUpdateScheduled = false
try {
RefreshRuntime.performReactRefresh()
} catch (err) {
console.warn(
'Warning: Failed to re-render. We will retry on the next Fast Refresh event.\n' +
err
)
}
}
if (canApplyUpdate(module.hot.status())) {
// Apply update on the next tick.
Promise.resolve().then(() => {
applyUpdate()
})
return
}
const statusHandler = (status) => {
if (canApplyUpdate(status)) {
module.hot.removeStatusHandler(statusHandler)
applyUpdate()
}
}
// Apply update once the HMR runtime's status is idle.
module.hot.addStatusHandler(statusHandler)
}
// Needs to be compatible with IE11
export default {
registerExportsForReactRefresh: registerExportsForReactRefresh,
isReactRefreshBoundary: isReactRefreshBoundary,
shouldInvalidateReactRefreshBoundary: shouldInvalidateReactRefreshBoundary,
getRefreshBoundarySignature: getRefreshBoundarySignature,
scheduleUpdate: scheduleUpdate,
}

View File

@@ -0,0 +1,34 @@
import type { LoaderDefinition } from 'webpack'
import RefreshModuleRuntime from './internal/ReactRefreshModule.runtime'
let refreshModuleRuntime = RefreshModuleRuntime.toString()
refreshModuleRuntime = refreshModuleRuntime
.slice(
refreshModuleRuntime.indexOf('{') + 1,
refreshModuleRuntime.lastIndexOf('}')
)
// Given that the import above executes the module we need to make sure it does not crash on `import.meta` not being allowed.
.replace('global.importMeta', 'import.meta')
let commonJsrefreshModuleRuntime = refreshModuleRuntime.replace(
'import.meta.webpackHot',
'module.hot'
)
const ReactRefreshLoader: LoaderDefinition = function ReactRefreshLoader(
source,
inputSourceMap
) {
this.callback(
null,
`${source}\n\n;${
// Account for commonjs not supporting `import.meta
this.resourcePath.endsWith('.cjs')
? commonJsrefreshModuleRuntime
: refreshModuleRuntime
}`,
inputSourceMap
)
}
export default ReactRefreshLoader

View File

@@ -0,0 +1,32 @@
{
"name": "@next/react-refresh-utils",
"version": "16.2.0-canary.85",
"description": "An experimental package providing utilities for React Refresh.",
"repository": {
"url": "vercel/next.js",
"directory": "packages/react-refresh-utils"
},
"files": [
"dist"
],
"author": "Joe Haddad <timer@vercel.com>",
"license": "MIT",
"scripts": {
"build": "node ../../scripts/rm.mjs dist && tsc -d -p tsconfig.json",
"prepublishOnly": "cd ../../ && turbo run build",
"dev": "tsc -d -w -p tsconfig.json"
},
"peerDependencies": {
"react-refresh": "0.12.0",
"webpack": "^4 || ^5"
},
"peerDependenciesMeta": {
"webpack": {
"optional": true
}
},
"devDependencies": {
"react-refresh": "0.12.0",
"webpack": "^4 || ^5"
}
}

View File

@@ -0,0 +1,20 @@
import RefreshRuntime from 'react-refresh/runtime'
import type { RefreshRuntimeGlobals } from './runtime'
declare const self: Window & RefreshRuntimeGlobals
if (typeof self !== 'undefined') {
var $RefreshInjected$ = '__reactRefreshInjected'
// Only inject the runtime if it hasn't been injected
if (!self[$RefreshInjected$]) {
RefreshRuntime.injectIntoGlobalHook(self)
// Empty implementation to avoid "ReferenceError: variable is not defined" in module which didn't pass builtin:react-refresh-loader
self.$RefreshSig$ = () => (type) => type
self.$RefreshReg$ = () => {}
// Mark the runtime as injected to prevent double-injection
self[$RefreshInjected$] = true
}
}

View File

@@ -0,0 +1,35 @@
import RefreshRuntime from 'react-refresh/runtime'
import RefreshHelpers from './internal/helpers'
export type RefreshRuntimeGlobals = {
$RefreshReg$: (type: unknown, id: string) => void
$RefreshSig$: () => (type: unknown) => unknown
$RefreshInterceptModuleExecution$: (moduleId: string) => () => void
$RefreshHelpers$: typeof RefreshHelpers
}
declare const self: Window & RefreshRuntimeGlobals
// Hook into ReactDOM initialization
RefreshRuntime.injectIntoGlobalHook(self)
// Register global helpers
self.$RefreshHelpers$ = RefreshHelpers
// Register a helper for module execution interception
self.$RefreshInterceptModuleExecution$ = function (webpackModuleId) {
var prevRefreshReg = self.$RefreshReg$
var prevRefreshSig = self.$RefreshSig$
self.$RefreshReg$ = function (type, id) {
RefreshRuntime.register(type, webpackModuleId + ' ' + id)
}
self.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform
// Modeled after `useEffect` cleanup pattern:
// https://react.dev/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed
return function () {
self.$RefreshReg$ = prevRefreshReg
self.$RefreshSig$ = prevRefreshSig
}
}

View File

@@ -0,0 +1,17 @@
{
"compilerOptions": {
"module": "commonjs",
"sourceMap": true,
"esModuleInterop": true,
"target": "es2015",
"lib": ["dom"],
"downlevelIteration": true,
"preserveWatchOutput": true,
"outDir": "dist",
"paths": {
"webpack": ["../../node_modules/webpack5"]
}
},
"include": ["**/*.ts"],
"exclude": ["node_modules", "dist"]
}