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

如何构建输出分离的Angular 2?多应用共享公共库缓存方案

刚好我之前帮团队做过类似的多Angular应用共享公共依赖的方案,既能分离打包业务代码和公共库,又能最大化利用浏览器缓存,给你详细讲讲具体怎么实现:

核心思路

我们要把四个应用共享的依赖(Angular、Angular Material、RxJS这些)单独打包成一个带内容哈希的vendor文件,部署到统一的静态资源地址;然后每个应用构建时排除这些公共依赖,只打包业务代码,最后在应用的入口页面引用这个公共vendor文件。这样浏览器只要加载过一次vendor包,后续访问其他应用就会直接用缓存,不用重复下载。

步骤1:单独构建公共依赖包

首先我们需要生成一个独立的vendor bundle,这里可以用Webpack自定义配置来实现(Angular CLI也支持集成自定义Webpack配置):

  1. 任选一个应用项目(或者单独建个极简的Angular项目),创建webpack.vendor.config.js配置文件:
const path = require('path');
const webpack = require('webpack');
const { AngularCompilerPlugin } = require('@ngtools/webpack');

module.exports = {
  entry: {
    vendor: [
      '@angular/core',
      '@angular/common',
      '@angular/material',
      '@angular/cdk',
      'rxjs',
      'zone.js'
      // 把所有四个应用共享的依赖都列在这里
    ]
  },
  output: {
    path: path.resolve(__dirname, '../shared-vendor'), // 输出到公共目录
    filename: 'vendor.bundle.[contenthash].js', // 用contenthash确保依赖不变时文件名不变
    library: 'vendor_lib' // 暴露全局变量给应用使用
  },
  plugins: [
    new webpack.ContextReplacementPlugin(
      /@angular(\\|\/)core(\\|\/)fesm2015/,
      path.resolve(__dirname, './src')
    ),
    new AngularCompilerPlugin({
      tsConfigPath: './tsconfig.vendor.json',
      entryModule: './src/app/app.module#AppModule', // 随便用一个应用的模块就行,只是为了让Angular编译器正常工作
      skipCodeGeneration: true
    }),
    new webpack.HashedModuleIdsPlugin() // 确保依赖模块ID稳定,哈希不会无故变化
  ],
  mode: 'production'
};
  1. 创建配套的tsconfig.vendor.json,只保留基础编译配置:
{
  "compilerOptions": {
    "target": "es2020",
    "module": "es2020",
    "moduleResolution": "node",
    "declaration": false,
    "noImplicitAny": false,
    "removeComments": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "lib": ["es2020", "dom"],
    "typeRoots": ["node_modules/@types"],
    "types": ["node"]
  },
  "exclude": ["node_modules", "dist"]
}
  1. 在项目的package.json里添加构建脚本:
"scripts": {
  "build:vendor": "webpack --config webpack.vendor.config.js"
}

运行npm run build:vendor,就能在shared-vendor目录下生成带哈希的vendor包,比如vendor.bundle.abc123def.js。这个哈希只有当你更新依赖版本时才会变化,完美适配浏览器缓存策略。

步骤2:配置每个应用排除公共依赖

每个应用构建时要告诉Angular CLI不要打包那些已经在vendor包里的依赖,这里用自定义Webpack的externals配置:

  1. 安装@angular-builders/custom-webpack:
npm install @angular-builders/custom-webpack --save-dev
  1. 修改应用的angular.json,把构建器换成自定义Webpack的版本:
"projects": {
  "your-app-name": {
    "architect": {
      "build": {
        "builder": "@angular-builders/custom-webpack:browser",
        "options": {
          "customWebpackConfig": {
            "path": "./webpack.app.config.js"
          },
          // 保留原来的其他配置(输出路径、assets等)
        }
      }
    }
  }
}
  1. 创建webpack.app.config.js,把公共依赖声明为外部资源:
module.exports = {
  externals: {
    '@angular/core': 'vendor_lib',
    '@angular/common': 'vendor_lib',
    '@angular/material': 'vendor_lib',
    '@angular/cdk': 'vendor_lib',
    'rxjs': 'vendor_lib',
    'zone.js': 'vendor_lib'
    // 所有在vendor包里的依赖都要映射到全局的vendor_lib变量
  }
};

这样构建应用时,Webpack会把这些依赖当成外部资源,不会打包进应用的bundle里,而是直接引用全局的vendor_lib变量。

步骤3:在应用中引入公共vendor包

把生成的vendor包部署到一个统一的静态资源服务地址(比如你的CDN或者服务器的静态资源目录),然后在每个应用的index.html头部添加引用:

<script src="https://your-shared-domain.com/vendor.bundle.abc123def.js"></script>

注意这里的URL要使用带哈希的文件名,当你更新依赖重新构建vendor包后,哈希会变,浏览器会自动加载新的文件;如果依赖没变化,浏览器会直接用缓存的旧文件。

步骤4:配置服务器缓存策略

为了让浏览器的缓存效果最大化,需要在服务器上给vendor包设置合适的响应头:

  • 对于vendor.bundle.[contenthash].js,设置Cache-Control: public, max-age=31536000, immutable,意思是浏览器可以缓存这个文件一年,而且不需要再向服务器验证是否更新(因为哈希变了才会有新的URL)。
  • 对于应用的业务代码bundle(比如main.xyz789.js),可以设置Cache-Control: public, max-age=0, must-revalidate,或者也给业务代码加上contenthash,这样业务更新时URL也会变,同样可以利用缓存。

额外注意事项

  • 版本统一:确保四个应用使用的公共依赖版本完全一致,否则可能出现兼容性问题。可以用npm install --save-exact来固定版本,或者用pnpm workspace、lerna这类工具统一管理依赖。
  • CI/CD自动化:每次更新依赖后,重新构建vendor包,然后可以用脚本自动替换所有应用index.html里的vendor引用URL,避免手动修改出错。
  • 懒加载模块:如果应用有懒加载模块,要确保懒加载模块里用到的公共依赖也已经包含在vendor包里,避免重复打包。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:02:32