refurbish
Version:
rEFui HMR plugin for Rollup/Vite
72 lines (62 loc) • 1.96 kB
JavaScript
import { createFilter } from '@rollup/pluginutils';
const BEGIN = '// ---- BEGIN REFUI HMR INJECT ----';
const END = '// ---- END REFUI HMR INJECT ----';
/**
* @param {object} [options]
* @param {string|string[]} [options.include] - picomatch/glob(s) to include (default: jsx,tsx,mdx)
* @param {string|string[]} [options.exclude] - patterns to exclude
* @param {string} [options.importSource='refui/hmr'] - where to import {setup} from
* @returns {import('rollup').Plugin}
*/
export function refurbish(options = {}) {
const {
include = ['**/*.jsx', '**/*.tsx', '**/*.mdx'],
exclude,
importSource = 'refui/hmr'
} = options;
const filter = createFilter(include, exclude);
// pre–serve only for Vite; for plain Rollup we check `command`
const apply = 'serve'; // Vite hint
let isBuild = false; // Rollup flag
const snippet =
`${BEGIN}
if (import.meta.hot) {
import('${importSource}').then(({ setup }) =>
setup({
url: import.meta.url,
accept: (cb) => import.meta.hot.accept(cb),
invalidate: (reason) => {
if (import.meta.hot.invalidate) {
import.meta.hot.invalidate(reason);
} else {
location.reload();
}
}
})
);
}
${END}
`;
return {
name: 'refui-hmr-inject',
apply,
// Rollup-only: record whether we are running a production build
buildStart(_, inputOptions) {
// inputOptions is undefined in Vite; OK
if (inputOptions) {
// rollup passes `{command: 'build'|'serve'}`
// @ts-expect-error
isBuild = (this.meta.watchMode === false); // equals "rollup -c" build
}
},
transform(code, id) {
if (!filter(id)) return null; // wrong file type
if (isBuild) return null; // production build – skip
if (code.includes(BEGIN)) return null; // already injected
return {
code: `${code}\n${snippet}`,
map: null
};
}
};
}