next.js/packages/next/src/build/webpack/plugins/nextjs-require-cache-hot-reloader.ts
nextjs-require-cache-hot-reloader.ts46 lines1.6 KB
import type { webpack } from 'next/dist/compiled/webpack/webpack'
import { deleteCache } from '../../../server/dev/require-cache'
import { clearModuleContext } from '../../../server/web/sandbox'
import path from 'path'

type Compiler = webpack.Compiler
type WebpackPluginInstance = webpack.WebpackPluginInstance

const RUNTIME_NAMES = ['webpack-runtime', 'webpack-api-runtime']
const PLUGIN_NAME = 'NextJsRequireCacheHotReloader'

// This plugin flushes require.cache after emitting the files. Providing 'hot reloading' of server files.
export class NextJsRequireCacheHotReloader implements WebpackPluginInstance {
  prevAssets: any = null
  serverComponents: boolean

  constructor(opts: { serverComponents: boolean }) {
    this.serverComponents = opts.serverComponents
  }

  apply(compiler: Compiler) {
    compiler.hooks.assetEmitted.tap(PLUGIN_NAME, (_file, { targetPath }) => {
      // Clear module context in this process
      clearModuleContext(targetPath)
      deleteCache([targetPath])
    })

    compiler.hooks.afterEmit.tapPromise(PLUGIN_NAME, async (compilation) => {
      // we need to make sure to clear all server entries from cache
      // since they can have a stale webpack-runtime cache
      // which needs to always be in-sync
      const outputPath = compilation.outputOptions.path!
      const allPaths = RUNTIME_NAMES.map((name) =>
        path.join(outputPath, `${name}.js`)
      )
      for (const entry of compilation.entrypoints.keys()) {
        if (entry.startsWith('pages/') || entry.startsWith('app/')) {
          allPaths.push(path.join(outputPath, `${entry}.js`))
        }
      }

      deleteCache(allPaths)
    })
  }
}
Quest for Codev2.0.0
/
SIGN IN