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

webpack4.44构建时webpack-manifest-plugin未包含全部manifest条目问题

Angular 11非watch构建webpack-manifest-plugin丢失静态资源解决方案

问题根因

@angular-devkit/build-angular 0.1001+版本升级webpack 4.44后,生产非watch模式下会将未被js/ts直接引用的静态资源标记为「额外资源」,走Angular自研的复制逻辑,不会被webpack默认的asset管道捕获,因此webpack-manifest-plugin无法扫描到这部分资源;watch模式下为了支持增量构建,静态资源仍然走webpack标准loader流程,所以可以正常生成。

可落地解决方案

方案1:自定义webpack-manifest-plugin生成逻辑

无需调整依赖版本,直接修改webpack配置中manifest插件的生成规则,手动扫描补充静态资源:

const fs = require('fs');
const path = require('path');
const ManifestPlugin = require('webpack-manifest-plugin');

// 对应项目src/assets目录路径
const ASSETS_ROOT = path.resolve(__dirname, 'src/assets');
// 静态资源输出的public前缀
const ASSETS_PUBLIC_PREFIX = 'hybrid/assets/';

// 递归扫描assets目录下所有文件
function scanAssets(dir, prefix = '') {
  const assetMap = {};
  const items = fs.readdirSync(dir);
  items.forEach(item => {
    const fullPath = path.join(dir, item);
    const stat = fs.statSync(fullPath);
    if (stat.isDirectory()) {
      Object.assign(assetMap, scanAssets(fullPath, `${prefix}${item}/`));
    } else {
      const assetKey = `assets/${prefix}${item}`;
      assetMap[assetKey] = `${ASSETS_PUBLIC_PREFIX}${prefix}${item}`;
    }
  });
  return assetMap;
}

module.exports = {
  plugins: [
    new ManifestPlugin({
      fileName: 'manifest.json',
      publicPath: 'hybrid/',
      // 自定义生成逻辑,合并webpack生成的资源和手动扫描的静态资源
      generate: (seed, files) => {
        const baseManifest = files.reduce((manifest, file) => {
          manifest[file.name] = file.path;
          return manifest;
        }, seed);
        const extraAssets = scanAssets(ASSETS_ROOT);
        return { ...baseManifest, ...extraAssets };
      }
    })
  ]
}

方案2:锁定兼容版本依赖

Angular 11可兼容未引入问题变更的@angular-devkit/build-angular@0.1100.0版本,直接在package.json中固定版本即可:

{
  "dependencies": {
    "@angular-devkit/build-angular": "0.1100.0"
  },
  "resolutions": {
    "@angular-devkit/build-angular": "0.1100.0",
    "webpack": "4.43.0"
  }
}

修改后删除node_modules和lock文件,重新执行安装即可,该版本完全兼容Angular 11核心包和angular-hybrid依赖。

方案3:后置脚本补全manifest

如果不想修改构建配置和依赖,可新增postbuild脚本,构建完成后自动扫描dist目录所有资源生成完整manifest:

  1. 新建build-manifest.js脚本:
const fs = require('fs');
const path = require('path');
// 构建产物输出目录
const DIST_DIR = path.resolve(__dirname, 'dist/hybrid');
const PUBLIC_PREFIX = 'hybrid/';

function walkDistDir(dir, prefix = '') {
  const manifest = {};
  fs.readdirSync(dir).forEach(file => {
    const fullPath = path.join(dir, file);
    if (fs.statSync(fullPath).isDirectory()) {
      Object.assign(manifest, walkDistDir(fullPath, `${prefix}${file}/`));
    } else {
      const key = prefix ? `${prefix}${file}` : file;
      // 过滤掉manifest.json自身
      if (key !== 'manifest.json') {
        manifest[key] = `${PUBLIC_PREFIX}${key}`;
      }
    }
  });
  return manifest;
}

const fullManifest = walkDistDir(DIST_DIR);
fs.writeFileSync(path.join(DIST_DIR, 'manifest.json'), JSON.stringify(fullManifest, null, 2));
  1. 修改package.json的构建脚本:
{
  "scripts": {
    "build": "ng build --prod && node build-manifest.js"
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:24:05