You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeError [ERR_INVALID_CALLBACK]报错:Angular Webpack规则添加脚本异常排查

解决Angular Webpack配置脚本的回调错误与执行不稳定问题

我来帮你解决这个问题,你的脚本遇到了两个核心问题:回调函数缺失触发了Node.js的API错误,以及异步与同步操作混用导致脚本有时仅部分执行。下面是详细的分析和修复方案:

错误原因分析

你看到的TypeError [ERR_INVALID_CALLBACK],是因为fs.close()方法必须传入一个回调函数作为参数,但你的代码里直接调用了fs.close(file)没有提供回调,违反了Node.js的fs模块API要求。

除此之外,脚本里同时使用了异步的fs.readFile和同步的fs.openSync,再加上fs.writeFile的使用方式错误(它通常接收文件路径而非文件描述符),这些混合操作会导致代码执行顺序不可控,这就是为什么脚本有时仅部分执行的原因。

修复后的脚本

我重构了脚本,改用同步文件操作(适合这类一次性脚本场景),同时优化了规则匹配和格式,避免出现格式错误:

const fs = require('fs');
const commonCliConfig = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js';
// 调整规则字符串格式,避免多余逗号导致语法错误
const pugRule = `
  { test: /\\.pug$/, loader: ['raw-loader', 'pug-html-loader'] }
`;

try {
  // 同步读取配置文件,避免异步回调嵌套的执行顺序问题
  const configText = fs.readFileSync(commonCliConfig, 'utf8');
  
  // 用正则匹配关键内容,避免空格/换行差异导致的误判
  const hasPugRule = configText.includes(/test: \/\\\.pug\$/.source);
  if (hasPugRule) {
    console.log('Pug规则已存在,无需重复添加');
    process.exit(0);
  }

  // 精准定位rules数组的起始位置
  const rulesStartMarker = 'rules: [';
  const rulesStartIndex = configText.indexOf(rulesStartMarker) + rulesStartMarker.length;
  
  // 匹配原有缩进,保持配置文件格式一致
  const indentMatch = configText.slice(0, rulesStartIndex).match(/(\s*)$/);
  const indent = indentMatch ? indentMatch[1] + '  ' : '  ';
  const formattedPugRule = indent + pugRule.trim();

  // 拼接新的配置内容
  const output = [
    configText.slice(0, rulesStartIndex),
    formattedPugRule + ',',
    configText.slice(rulesStartIndex)
  ].join('');

  // 同步写入文件,自动处理文件的打开与关闭
  fs.writeFileSync(commonCliConfig, output, 'utf8');
  console.log('Pug规则已成功添加到Webpack配置中');
} catch (err) {
  console.error('操作失败:', err.message);
  process.exit(1);
}

关键修复点说明

  • 改用同步文件操作:fs.readFileSync和fs.writeFileSync适合一次性脚本,避免异步回调嵌套带来的执行顺序问题,彻底解决“有时仅部分执行”的情况。
  • 移除手动文件描述符操作:同步写入会自动处理文件的打开和关闭,不需要手动调用fs.openSync和fs.close,从根源上解决回调错误。
  • 鲁棒的规则存在性检查:用正则匹配规则的关键部分,避免因为空格、换行等格式差异导致误判规则已存在。
  • 保持配置格式一致:自动匹配原有缩进,确保添加的规则和配置文件的格式统一,避免Webpack解析报错。

更优的长期解决方案

直接修改node_modules里的文件是不推荐的,因为每次执行npm install或yarn install后,修改的内容都会被覆盖。更好的方式是使用Angular官方支持的自定义Webpack配置方案:

  1. 安装自定义Webpack构建器:
npm install @angular-builders/custom-webpack --save-dev
  1. 在项目根目录创建webpack.custom.js文件:
module.exports = {
  module: {
    rules: [
      { test: /\.pug$/, loader: ['raw-loader', 'pug-html-loader'] }
    ]
  }
};
  1. 修改angular.json中的构建配置:
    将原来的@angular-devkit/build-angular:browser和@angular-devkit/build-angular:dev-server替换为自定义构建器,并指定配置文件路径:
"architect": {
  "build": {
    "builder": "@angular-builders/custom-webpack:browser",
    "options": {
      "customWebpackConfig": {
        "path": "./webpack.custom.js"
      },
      // 保留原有其他配置项...
    }
  },
  "serve": {
    "builder": "@angular-builders/custom-webpack:dev-server",
    // 保留原有其他配置项...
  }
}

这种方式不需要修改node_modules里的文件,配置持久化且符合Angular的最佳实践。

内容的提问来源于stack exchange,提问作者ryuu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:18:16