/** * 构建前扫描 `demos/gen_attribute/*.json`,写入 `ts/demos/genAttributeBundledDemoManifest.generated.ts`,供 bundle 内联 slug 列表。 * 并为该目录注册 contextDependencies,便于 watch 下增减 demo JSON 时触发重编。 */ const path = require('path'); const fs = require('fs'); const REL_DIR = 'demos/gen_attribute'; const GENERATED_BASENAME = 'genAttributeBundledDemoManifest.generated.ts'; function collectSlugs(srcDir) { if (!fs.existsSync(srcDir)) return []; const files = fs.readdirSync(srcDir).filter((f) => f.endsWith('.json')); const slugs = files .map((f) => f.replace(/\.json$/i, '')) .filter((s) => s.length > 0); // UTF-16 码元序,与 locale 无关,避免不同构建机生成顺序不一致 slugs.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)); return slugs; } function writeGeneratedModule(srcDir, outPath) { const slugs = collectSlugs(srcDir); const content = '/**\n' + ' * Generated by GenAttributeDemoManifestPlugin — do not edit.\n' + ' */\n' + `export const GEN_ATTRIBUTE_BUNDLED_DEMO_SLUGS: readonly string[] = ${JSON.stringify(slugs)};\n`; if (fs.existsSync(outPath) && fs.readFileSync(outPath, 'utf8') === content) return; fs.mkdirSync(path.dirname(outPath), { recursive: true }); fs.writeFileSync(outPath, content, 'utf8'); } class GenAttributeDemoManifestPlugin { apply(compiler) { const srcDir = path.join(__dirname, '..', REL_DIR); const outPath = path.join(__dirname, '..', 'ts', 'demos', GENERATED_BASENAME); compiler.hooks.beforeCompile.tapAsync('GenAttributeDemoManifestPlugin', (_params, callback) => { try { writeGeneratedModule(srcDir, outPath); callback(); } catch (e) { callback(e); } }); compiler.hooks.thisCompilation.tap('GenAttributeDemoManifestPlugin', (compilation) => { compilation.contextDependencies.add(srcDir); }); } } module.exports = { GenAttributeDemoManifestPlugin };