JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q16637F
  • License MIT

swc plugin implementation of react-refresh/babel

Package Exports

  • swc-plugin-react-refresh
  • swc-plugin-react-refresh/target/wasm32-wasi/release/swc_plugin_react_refresh.wasm

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (swc-plugin-react-refresh) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

swc-plugin-react-refresh

Swc plugin implementation of react-refresh/babel

npm

[!IMPORTANT] A plugin for developing bundlers

[!WARNING] This plugin is experimental.

  • Explore React components in module
    • Function expressions
    • Arrow function expressions
    • Class declarations
    • Import statements(default, named)
    • Export statements(default, named, named with declare)
  • Get component name from AST
  • Parse hook calls from AST
  • Parse HoC(High Order Component) expressions(React.memo, React.forwardedRef, and Custom HoC)
    • Wrapped components
    • Original components
  • Generate signature key based on the order of hook call expressions Use moduleId options instead

Setup

Requirements: >= @swc/core@1.3.81

npm install swc-plugin-react-refresh
# or yarn
yarn add swc-plugin-react-refresh

Add plugin to your swc options.

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

await transform(code, {
  jsc: {
    experimental: {
      plugins: [
        // Add plugin here
        ['swc-plugin-react-refresh', {
          /**
           * moduleId: string;
           * 
           * Module id (eg. generated id by bundler)
           */
          moduleId: "",
          /**
           * skipEnvCheck?: boolean;
           * 
           * Plugin available on only development environment.
           * If you want to use plugin in production, set `skipEnvCheck` to `true`.
           */
          skipEnvCheck: true,
        }],
      ],
    },
  },
});

Finally, inject runtime code at the top of bundled source.

Runtime Code
const RefreshRuntime = require('react-refresh/runtime');


const ModuleMap = typeof WeakMap === 'function' ? WeakMap : Map;
const modules = new ModuleMap();

const isReactRefreshBoundary = (type) => {
  return RefreshRuntime.isLikelyComponentType(type) && !type.prototype.isReactComponent;
}

const createHmrContext = (type) => {
  if (!isReactRefreshBoundary(type)) {
    return {
      accept: () => undefined,
      dispose: () => undefined,
    };
  }

  const state = {
    timeout: null,
    accepted: false,
    disposed: false,
  };

  const hot = {
    accept: () => {
      if (state.disposed) {
        throw new Error('HMR module was disposed');
      }
  
      if (state.accepted) {
        throw new Error('HMR already accepted');
      }

      state.accepted = true;
      state.timeout = setTimeout(() => {
        state.timeout = null;
        RefreshRuntime.performReactRefresh();
      }, 50);
    },
    dispose: () => {
      state.disposed = true;
    },
  };

  if (modules.has(type)) {
    modules.get(type).dispose();
  }
  modules.set(type) = hot;

  return hot;
};

// `global` is platform dependent.
RefreshRuntime.injectIntoGlobalHook(global);
global.$RefreshReg$ = () => {};
global.$RefreshSig$ = () => (type) => type;
global.$RefreshRuntime$ = {
  getRegisterFunction: () => {
    return (type, id) => {
      if (!isReactRefreshBoundary(type)) return;
      RefreshRuntime.register(type, id);
    };
  },
  getCreateSignatureFunction: () => {
    return () => {
      const signature = RefreshRuntime.createSignatureFunctionForTransform();
      return (type, id, forceReset, getCustomHooks) => {
        if (!isReactRefreshBoundary(type)) return;
        signature(type, id, forceReset, getCustomHooks);
      }
    };
  },
  getContext: (type) => createHmrContext(type),
};

Development

cargo build

# release build
yarn build # target: wasm32-wasi
# or
cargo build-wasi --release # target: wasm32-wasi
cargo build-wasm32 --release # target: wasm32-unknown-unknown

# run unit tests
cargo test

# run on @swc/core
yarn demo

License

MIT