Skip to content
This repository was archived by the owner on Feb 23, 2026. It is now read-only.
This repository was archived by the owner on Feb 23, 2026. It is now read-only.

Supports hot reload #38

@leegeunhyeok

Description

@leegeunhyeok

Description

Supports hot reload on development environment.

Tasks

  • Implement custom file watcher instead esbuild.context.watch()
    • On some files change, trigger rebuild() and get the metadata(path, etc..) of the changed module.
    • Implement custom file system watcher using chokidar
  • Transformer
  • Get updated module code from bundle
  • Add experimental config for toggle hot reload

References

Limitations

  • Esbuild isn't supports HMR(Hot Module Replacement).
  • Cannot skip transform(js, ts) loader in Esbuild.

Notes

  • 0.1.0-alpha.42

// before
var __commonJS = (cb, mod) => function __require2() {
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};

// after
global.cachedModule = {};
var __commonJS = (cb, mod) => {
  var name = __getOwnPropNames(cb)[0];
  Object.defineProperty(global.cachedModule, name, {
    get: () => mod
  });
  return function __require2() {
    return mod || (0, cb[name])((mod = { exports: {} }).exports, mod), mod.exports;
  };
};

// when file changes detected -> don't rebuild, just transform target file with swc only.
// `import { a, b, c } from 'module-path';`

try {
  const { a, b, c } = global.cachedModule['module-path'];

  // ...
} catch (error) {
  // hot reload failed. fully reload instead
}
// Esbuild metafile
interface Metafile {
  // `inputs` key is module file path.
  inputs: Record<string, {
    byte: number;
    imports: {
      path: string; // eg. 'node_modules/react/cjs/index.js'
      original: string; // eg. 'react'
      kind: '...',
    }[];
  }>[],
  // ...
}

// {
//   react: 'node_modules/react/cjs/index.js',
//   '../components': 'src/components/index.ts',
// }
const mappedModules = metafile.inputs[changedFilePath]?.imports.reduce((prev, curr) => {
  return { ...prev, [curr.original]: curr.path };
}, {});

// Example usage
import { transform } from '@swc/core';

await transform(code, {
  jsc: {
    experimental: {
      plugins: [
        // https://github.com/leegeunhyeok/swc-plugin-react-native-esbuild-module
        ['react-native-esbuild-module-plugin', {
          alias: mappedModules ?? {},
        }],
      ],
    },
  },
});

Metadata

Metadata

Assignees

Labels

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions