Angular ESBuild插件构建前生成文件引发Watch模式无限循环的解决方法
解决Angular ESBuild插件watch模式无限循环问题
针对你遇到的watch模式下生成文件触发无限重建的问题,提供以下几种可行的解决方案:
方案一:提前执行脚本+内容判断避免无意义写入
核心思路是把脚本执行时机从构建结束后(onEnd)移到构建开始前(onStart),同时修改生成脚本,仅当内容确实变化时才写入文件,避免触发watch的变更检测。
1. 修改ESBuild插件的触发时机
import { exec } from 'child_process'; const generateFile = { name: 'generate-file', setup(build) { // 构建开始前执行生成脚本 build.onStart(() => { console.log('Launching script scripts/generate-file.js...'); // 用Promise包裹,确保脚本执行完成后再开始构建 return new Promise((resolve, reject) => { exec('node scripts/generate-file.js', (error, stdout, stderr) => { if (error) { console.error('Error:', error.message); reject(error); return; } if (stderr) { console.error('Error:', stderr); reject(new Error(stderr)); return; } console.log(stdout); resolve(); }); }); }); }, }; export default [generateFile];
2. 修改生成脚本(scripts/generate-file.js)
添加内容校验,只有当新内容和现有文件不一致时才写入:
const fs = require('fs'); const path = require('path'); // 目标文件路径,根据你的项目实际位置调整 const targetPath = path.join(__dirname, '../src/generated-file.ts'); // 替换成你的实际生成逻辑 const newContent = `// 动态生成的代码,示例内容 export const GeneratedConfig = { timestamp: ${Date.now()} };`; try { // 读取现有文件内容 const existingContent = fs.readFileSync(targetPath, 'utf8'); if (existingContent === newContent) { console.log('Generated file content unchanged, skip writing.'); process.exit(0); } } catch (err) { // 文件不存在,直接进入写入流程 } // 写入新内容 fs.writeFileSync(targetPath, newContent); console.log('Generated file updated successfully.');
方案二:标记触发源,跳过不必要的脚本执行
通过标记构建的触发源,如果是generated-file.ts变更导致的重建,就跳过脚本执行,打断循环链。
修改ESBuild插件代码:
import { exec } from 'child_process'; // 标记是否是由生成文件触发的构建 let isTriggeredByGeneratedFile = false; const generateFile = { name: 'generate-file', setup(build) { build.onStart(() => { // 如果是生成文件触发的重建,跳过脚本执行 if (isTriggeredByGeneratedFile) { isTriggeredByGeneratedFile = false; return Promise.resolve(); } console.log('Launching script scripts/generate-file.js...'); return new Promise((resolve, reject) => { exec('node scripts/generate-file.js', (error, stdout, stderr) => { if (error) { console.error('Error:', error.message); reject(error); return; } if (stderr) { console.error('Error:', stderr); reject(new Error(stderr)); return; } console.log(stdout); resolve(); }); }); }); // 监听generated-file.ts的加载事件,标记触发源 build.onLoad({ filter: /generated-file\.ts$/ }, () => { isTriggeredByGeneratedFile = true; return null; }); }, }; export default [generateFile];
方案三:将生成文件移出watch监听目录
把生成的文件放到ESBuild默认不监听的目录,比如项目根目录下的generated文件夹,避免watch检测到文件变更。
1. 修改生成脚本的输出路径
const targetPath = path.join(__dirname, '../generated/generated-file.ts');
2. 配置TypeScript识别该目录
在tsconfig.json的include数组中添加该目录:
"include": [ "src/**/*", "generated/**/*" ]
3. 确保ESBuild不监听该目录
检查angular.json中@angular-builders/custom-esbuild的配置,确保watch的include不包含generated目录,或者默认的watch范围仅覆盖src目录即可。
内容的提问来源于stack exchange,提问作者menrodriguez
相关产品推荐
相关产品推荐

