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

如何构建支持特性单独导入的Angular库?

Got it, let's break down exactly how to implement that Angular Material-style tree-shakable, feature-by-feature import setup for your library. The core idea is to structure your library into secondary entry points (each feature as its own sub-module) and configure ng-packagr to bundle them separately, while still allowing users to import from the root if they want. Here's the step-by-step guide:

1. Restructure Your Library Directory

First, organize each feature into its own subfolder under your library's src/lib directory. Each feature needs its own module, components, and entry files. Here's what the structure should look like:

projects/
  my-lib/
    src/
      lib/
        custom-input-1/          # Feature 1 folder
          custom-input-1.module.ts
          custom-input-1.component.ts
          index.ts               # Feature entry file
          package.json           # Secondary entry point config
        custom-input-2/          # Feature 2 folder
          custom-input-2.module.ts
          custom-input-2.component.ts
          index.ts
          package.json
        index.ts                 # Root entry (aggregates all features)
      public-api.ts              # Root library entry
    ng-package.json              # ng-packagr root config
    package.json                 # Root library package.json

2. Configure Each Feature's package.json

Each secondary entry point needs its own package.json to define its identity and dependencies. For custom-input-1/package.json:

{
  "name": "my-lib/custom-input-1",
  "version": "1.0.0", // Match root library version
  "main": "./custom-input-1.module.js",
  "module": "./esm/custom-input-1.module.js",
  "typings": "./custom-input-1.module.d.ts",
  "peerDependencies": {
    "@angular/core": "^16.0.0", // Match root's peer deps
    "@angular/common": "^16.0.0",
    "my-lib": "^1.0.0" // Depend on the root library
  }
}

Repeat this for custom-input-2 (update the name to my-lib/custom-input-2).

3. Setup Feature Entry Files (index.ts)

Each feature's index.ts should export all public APIs for that feature. For custom-input-1/index.ts:

export * from './custom-input-1.module';
export * from './custom-input-1.component'; // If you want to export components directly

4. Update Root Library Entries

In your root src/lib/index.ts (or public-api.ts), export all features to support root-level imports:

export * from './custom-input-1';
export * from './custom-input-2';

5. Configure ng-packagr for Secondary Entry Points

Update your root ng-package.json to tell ng-packagr to bundle each feature as a separate entry point:

{
  "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
  "dest": "../../dist/my-lib",
  "lib": {
    "entryFile": "src/public-api.ts",
    "secondaryEntryPoints": [
      "src/lib/custom-input-1",
      "src/lib/custom-input-2"
    ]
  }
}

This tells ng-packagr to build each secondary entry point into its own folder in the dist directory.

6. Enable Tree-Shaking

To ensure unused modules aren't bundled, add "sideEffects": false to your root library's package.json. This tells webpack/Rollup that none of your files have side effects, so it can safely tree-shake unused code:

{
  "name": "my-lib",
  "version": "1.0.0",
  "sideEffects": false, // Critical for tree-shaking
  // ... other configs
}

Also, make sure your tsconfig.lib.json has these compiler options to support modern tree-shaking:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ES2020",
    "moduleResolution": "node",
    // ... other options
  }
}

7. Test the Import Flow

Now your users can import features in two ways:

  • Feature-specific import (only bundles this feature):
    import { CustomInputModule1 } from 'my-lib/custom-input-1';
    
  • Root import (tree-shaking will remove unused features if sideEffects: false is set):
    import { CustomInputModule1 } from 'my-lib';
    

Key Notes to Avoid Pitfalls

  • No Cross-Feature Dependencies: Don't import components/modules from custom-input-2 into custom-input-1 (and vice versa). If you have shared code, move it to a separate shared secondary entry point.
  • Version Sync: Keep all secondary entry points' versions identical to the root library to avoid dependency conflicts.
  • Peer Dependencies: Ensure all secondary entry points have the same peer dependencies as the root library to maintain compatibility with users' Angular versions.

That's the exact setup Angular Material uses (they rely heavily on ng-packagr's secondary entry points) — this will eliminate the issue where importing one module pulls in the entire library.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:31:36