Files
AFFiNE-Mirror/blocksuite/playground/scripts/hmr-plugin/fine-tune.ts
2024-12-20 16:48:10 +00:00

66 lines
1.8 KiB
TypeScript

/* eslint-disable import-x/no-extraneous-dependencies */
import path from 'node:path';
import { init, parse } from 'es-module-lexer';
import MagicString from 'magic-string';
import micromatch from 'micromatch';
import type { Plugin } from 'vite';
const isMatch = micromatch.isMatch;
export function fineTuneHmr({
include,
exclude,
}: {
include: string[];
exclude: string[];
}): Plugin {
let root = '';
const plugin: Plugin = {
name: 'add-hot-for-pure-exports',
apply: 'serve',
configResolved(config) {
root = config.root;
},
async configureServer() {
await init;
},
transform: (code, id) => {
// only handle js/ts files
const includeGlob = include.map(i => path.resolve(root, i));
const excludeGlob = exclude.map(i => path.resolve(root, i));
const isInScope = isMatch(id, includeGlob) && !isMatch(id, excludeGlob);
if (!isInScope) return;
if (!(id.endsWith('.js') || id.endsWith('.ts'))) return;
// only handle files which not contains Lit elements
if (code.includes('import.meta.hot')) return;
const [imports, exports] = parse(code, id);
if (exports.length === 0 && imports.length > 0) {
const modules = imports.map(i => i.n);
const modulesEndsWithTs = modules
.filter(Boolean)
.map(m => m!.replace(/\.js$/, '.ts'));
const preamble = `
if (import.meta.hot) {
import.meta.hot.accept(${JSON.stringify(
modulesEndsWithTs
)}, data => {
// some update logic
});
}
`;
const s = new MagicString(code);
s.prepend(preamble + '\n');
return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id, includeContent: true }),
};
}
return;
},
};
return plugin;
}