Angular库能否嵌套使用public_api.ts?大型库模块化方案咨询
大型Angular库模块化拆分方案(适配ng-packagr)
我完全理解你在开发大型Angular库时想要拆分模块的需求——维护一个臃肿的单文件public_api.ts确实会变成噩梦。针对你遇到的ng-packagr入口文件限制的问题,这里有几个经过验证的优化方案:
方案1:分层public_api导出(单入口多子模块)
这是最直接的方案,不需要改变ng-packagr的核心配置,只需要确保你的子模块public_api.ts正确导出内容,然后根public_api.ts统一聚合这些导出。
步骤:
- 调整目录结构,给每个大模块单独设置子目录和
public_api.ts:
your-library/ ├── lib/ │ ├── lib2-m1/ │ │ ├── components/ │ │ ├── services/ │ │ └── public_api.ts # 导出lib2-m1的所有公共API │ ├── lib2-m2/ │ │ ├── directives/ │ │ ├── pipes/ │ │ └── public_api.ts # 导出lib2-m2的所有公共API │ └── ... ├── public_api.ts # 根入口文件 └── ng-package.json
- 配置子模块的
public_api.ts,比如lib/lib2-m1/public_api.ts:
// 导出模块内的公共组件、服务、指令等 export * from './components/foo.component'; export * from './services/bar.service'; export * from './lib2-m1.module';
- 根
public_api.ts中聚合所有子模块的导出:
// 确保路径正确,相对路径要指向子模块的public_api.ts export * from './lib/lib2-m1/public_api'; export * from './lib/lib2-m2/public_api';
- 保持
ng-package.json的entryFile为根public_api.ts:
{ "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", "dest": "../../dist/your-library", "lib": { "entryFile": "public_api.ts" } }
注意:如果之前导出失败,大概率是路径错误或者子模块的
public_api.ts没有正确导出内部成员——要确保每个子模块的public_api.ts都显式导出了需要对外暴露的内容。
方案2:多包架构(Monorepo风格拆分)
如果你的模块之间相对独立,甚至希望用户可以单独安装某个子模块,那么可以用ng-packagr的多包配置,把整个库拆分为多个独立的npm包。
步骤:
- 调整目录为多包结构:
your-library/ ├── packages/ │ ├── lib2-m1/ │ │ ├── lib/ │ │ ├── public_api.ts │ │ └── ng-package.json │ ├── lib2-m2/ │ │ ├── lib/ │ │ ├── public_api.ts │ │ └── ng-package.json │ └── your-library-core/ # 可选:主包,导出所有子包 │ ├── public_api.ts │ └── ng-package.json └── ng-package.json # 根配置文件
- 根
ng-package.json中配置packages字段,指定所有子包的路径:
{ "$schema": "./node_modules/ng-packagr/ng-package.schema.json", "packages": { "packages/lib2-m1": {}, "packages/lib2-m2": {}, "packages/your-library-core": {} } }
- 每个子包的
ng-package.json独立配置,比如packages/lib2-m1/ng-package.json:
{ "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", "dest": "../../dist/lib2-m1", "lib": { "entryFile": "public_api.ts" } }
- 主包(可选)的
public_api.ts导出所有子包:
export * from '@your-org/lib2-m1'; export * from '@your-org/lib2-m2';
这种方案的优势是用户可以按需安装:npm install @your-org/lib2-m1,同时也可以安装主包获取全部功能。
方案3:基于NgModule的模块化封装
结合Angular自身的NgModule特性,把每个大模块封装为独立的NgModule,然后在根模块中导出这些NgModule,同时在public_api.ts中对外暴露模块和相关API。
步骤:
- 为每个大模块创建独立的NgModule:
// lib/lib2-m1/lib2-m1.module.ts import { NgModule } from '@angular/core'; import { FooComponent } from './components/foo.component'; import { BarService } from './services/bar.service'; @NgModule({ declarations: [FooComponent], exports: [FooComponent], providers: [BarService] }) export class Lib2M1Module {}
- 在子模块的
public_api.ts中导出该NgModule和公共成员:
export * from './lib2-m1.module'; export * from './components/foo.component'; export * from './services/bar.service';
- 根
public_api.ts导出所有模块:
export * from './lib/lib2-m1/public_api'; export * from './lib/lib2-m2/public_api';
这样用户在使用时,可以选择导入整个库,或者单独导入某个模块:
// 导入单个模块 import { Lib2M1Module } from 'your-library'; @NgModule({ imports: [Lib2M1Module] }) export class AppModule {}
内容的提问来源于stack exchange,提问作者Hearen
相关产品推荐
相关产品推荐

