如何创建可像Angular Material那样导入模块的Angular库NPM包
实现Angular库的分路径导入(类似Angular Material风格)
问题背景
Angular Material支持从子路径单独导入模块,比如:
import { MatButtonModule } from '@angular/material/button';
当前自己开发的Angular库构建后,所有模块都通过根目录的index.ts导出,只能从根路径导入:
import { MyModule1 } from 'my-lib'import { MyModule2 } from 'my-lib'
需要改成支持子路径导入的形式:
import { MyModule1 } from 'my-lib/my-module-1'import { MyModule2 } from 'my-lib/my-module-2'
实现步骤
1. 调整库的目录结构
给每个模块单独创建子目录,并添加专属的public-api.ts:
my-lib/ ├── projects/ │ ├── my-lib/ │ │ ├── src/ │ │ │ ├── lib/ │ │ │ │ ├── my-module-1/ │ │ │ │ │ ├── my-module-1.module.ts │ │ │ │ │ ├── public-api.ts │ │ │ │ ├── my-module-2/ │ │ │ │ │ ├── my-module-2.module.ts │ │ │ │ │ ├── public-api.ts │ │ │ ├── public-api.ts (根级可选,用于批量导出所有模块)
每个子模块的public-api.ts仅导出自身内容,比如my-module-1/public-api.ts:
export * from './my-module-1.module';
2. 配置根目录的package.json
核心是通过exports字段定义子路径的映射,匹配构建后的产物位置:
{ "name": "my-lib", "version": "1.0.0", "exports": { ".": { "types": "./index.d.ts", "esm2020": "./esm2020/my-lib.mjs", "esm": "./esm/my-lib.mjs", "main": "./my-lib.umd.js" }, "./my-module-1": { "types": "./my-module-1/index.d.ts", "esm2020": "./esm2020/my-lib/my-module-1.mjs", "esm": "./esm/my-lib/my-module-1.mjs", "main": "./my-module-1/my-lib-my-module-1.umd.js" }, "./my-module-2": { "types": "./my-module-2/index.d.ts", "esm2020": "./esm2020/my-lib/my-module-2.mjs", "esm": "./esm/my-lib/my-module-2.mjs", "main": "./my-module-2/my-lib-my-module-2.umd.js" } }, "types": "index.d.ts", "type": "module" }
注意路径要和Angular CLI构建后的输出目录对应,默认构建产物会按模块结构生成对应文件。
3. 调整tsconfig.lib.json
确保开启类型声明生成,同时配置模块解析规则:
{ "compilerOptions": { "declaration": true, "baseUrl": "./src", "paths": { "my-lib/my-module-1": ["lib/my-module-1/public-api.ts"], "my-lib/my-module-2": ["lib/my-module-2/public-api.ts"] } } }
4. 构建并验证
执行ng build my-lib完成构建后,在测试应用中尝试子路径导入:
import { MyModule1 } from 'my-lib/my-module-1';
确认模块能正常导入、编译及运行。
核心原理
Angular Material的实现本质是利用Node.js的条件导出机制(package.json的exports字段),配合Angular CLI的模块化构建能力,将每个子模块打包为独立的代码单元,同时维护类型文件的正确映射,从而支持从子路径单独导入模块。
内容的提问来源于stack exchange,提问作者mimo
相关产品推荐
相关产品推荐

