{"id":13495680,"url":"https://github.com/dominique-mueller/angular-package-builder","last_synced_at":"2025-03-16T17:35:20.770Z","repository":{"id":47037711,"uuid":"101553708","full_name":"dominique-mueller/angular-package-builder","owner":"dominique-mueller","description":"[DEPRECATED] Packages your Angular 4+ library based on the Angular Package Format.","archived":false,"fork":false,"pushed_at":"2025-02-09T03:07:15.000Z","size":2238,"stargazers_count":23,"open_issues_count":12,"forks_count":2,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-03-11T05:19:21.410Z","etag":null,"topics":["angular","build","cli","library","package","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/angular-package-builder","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dominique-mueller.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-27T13:21:35.000Z","updated_at":"2024-06-17T20:46:31.000Z","dependencies_parsed_at":"2024-05-23T01:40:49.536Z","dependency_job_id":"610679ab-dd2e-4f9d-9975-1185ab64f48f","html_url":"https://github.com/dominique-mueller/angular-package-builder","commit_stats":{"total_commits":131,"total_committers":4,"mean_commits":32.75,"dds":0.3435114503816794,"last_synced_commit":"bbe595928d4c82b2647d883e72ba5abd8e217087"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominique-mueller%2Fangular-package-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominique-mueller%2Fangular-package-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominique-mueller%2Fangular-package-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominique-mueller%2Fangular-package-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dominique-mueller","download_url":"https://codeload.github.com/dominique-mueller/angular-package-builder/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243823330,"owners_count":20353651,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","build","cli","library","package","typescript"],"created_at":"2024-07-31T19:01:37.089Z","updated_at":"2025-03-16T17:35:20.038Z","avatar_url":"https://github.com/dominique-mueller.png","language":"TypeScript","readme":"\u003cbr\u003e\n\n---\n\n**DEPRECATION NOTICE**\n\nThis library is now deprecated because the **[Angular CLI](https://cli.angular.io/)** has finally added official support for creating,\nbuilding and publishing Angular libraries.\n\nRead more: **[https://angular.io/guide/creating-libraries](https://angular.io/guide/creating-libraries)**.\n\n---\n\n\u003cbr\u003e\u003cbr\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n# angular-package-builder\n\n**Packages your Angular 4+ library based on the [Angular Package Format](https://docs.google.com/document/d/1CZC2rcpxffTDfRDs6p1cfbmKNLA6x5O-NtkJglDaBVs/preview).**\n\n\u003c/div\u003e\n\n\u003cbr\u003e\u003cbr\u003e\n\n## What it does\n\nThese days, setting up build chains for frontend projects requires lots of knowledge and time. When working with Angular, in particular, there is a fair amount of things to do in order to get an Angular library published just right.\n\nThe **Angular Package Builder** is here to help! Once set up, this NodeJS-based command line tool will build your Angular libraries with a single command, allowing developers to focus on the important things - developing!\n\nFeatures include:\n\n- :pushpin: Support for primary and (multiple) secondary entry points\n- :gift: Support for multiple libraries (e.g. in a monorepo)\n- :page_facing_up: Inlining of external resources, such as templates (HTML) and styles (CSS, SASS)\n- :hammer: Custom configurations (Angular compiler options, TypeScipt compiler options, external dependencies)\n\nThe result is a package, following the official **[Angular Package Format](https://docs.google.com/document/d/1CZC2rcpxffTDfRDs6p1cfbmKNLA6x5O-NtkJglDaBVs/preview)**:\n\n- :green_book: JavaScript build (ES2015, ES5)\n- :orange_book: JavaScript bundles (flat ES2015, flat ES5, UMD)\n- :blue_book: TypeScript type definition files\n- :closed_book: Angular AoT metadata file\n- :notebook_with_decorative_cover: package.json file with references to entry files\n\n![Angular Package Builder Preview](/docs/preview.gif?raw=true)\n\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n\n## How to install\n\nYou can get the **angular-package-builder** via **npm** by adding it as a new _devDependency_ to your `package.json` file and running\n`npm install`. Alternatively, run the following command:\n\n```bash\nnpm install angular-package-builder --save-dev\n```\n\n\u003cbr\u003e\n\n### Angular compatibility\n\nThe following lists the Angular versions supported by the **Angular Package Builder**. The table also mentions the TypeScript and RxJS\nversions which are officially supported by each Angular version. Diverging from this matrix is surely possible yet might lead to\nunexpected issues. The last column defines the minimal required NodeJS version.\n\n| Angular                                 | TypeScript              | RxJS  | NodeJS     |\n| --------------------------------------- | ----------------------- | ----- | ---------- |\n| `4.0.x` `4.1.x` `4.2.x` `4.3.x` `4.4.x` | `2.1.x` `2.2.x` `2.3.x` | `5.x` | `\u003e= 7.6.0` |\n| `5.0.x`                                 | `2.4.x`                 | `5.x` | `\u003e= 7.6.0` |\n| `5.1.x`                                 | `2.4.x` `2.5.x`         | `5.x` | `\u003e= 7.6.0` |\n| `5.2.x`                                 | `2.4.x` `2.5.x` `2.6.x` | `5.x` | `\u003e= 7.6.0` |\n| `6.0.x`                                 | `2.7.x`                 | `6.x` | `\u003e= 8.0.0` |\n| `6.1.x`                                 | `2.7.x` `2.8.x` `2.9.x` | `6.x` | `\u003e= 8.0.0` |\n\n\u003e Angular 2 is not supported. Angular versions newer than `6.1.x` might work, yet have not not been tested.\n\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n\n## How to use\n\nIn most cases, integrating **angular-package-builder** into a project is very straightforward.\n\n\u003e The **Angular Package Builder** only builds libraries from an Angular / JavaScript perspective. It's possible that you might have to setup\n\u003e a few extra build steps, for instance in order to compile global SASS, or copy assets / other files.\n\n\u003cbr\u003e\n\n### Step 1: Create `.angular-package.json` file\n\nNow, every library requires a `.angular-package.json` file to be present, placed directly next to the `package.json` file of that library.\nWithin that `.angular-package.json` file, you can place the build onfiguration for your library.\n\nA minimal configuration looks like the following:\n\n```json\n{\n  \"$schema\": \"./node_modules/angular-package-builder/angular-package.schema.json\",\n  \"entryFile\": \"./index.ts\",\n  \"outDir\": \"./dist\"\n}\n```\n\nThe two options seen above are also the only required ones:\n\n- `entryFile` is the relative path to the primary entry file\n  - Usually, entry files are named `index.ts`\n  - All further files of the library must be within the same folder, or some place deeper in the directory\n- `outDir` is the relative path to the build output folder\n  - Usually, the build output folder is named `dist`\n  - Don't forget to add the `outDir` path to your `.gitignore` file\n\n#### Directory structure\n\nThe following directory structure is recommended:\n\n```typescript\n── dist/                  // Output\n   └── ...\n── src/                   // Source\n   └── ...\n── .angular-package.json  // Build config\n── index.ts               // Entry file\n── package.json           // Package\n```\n\n\u003e Note: The build process will create additional files at the root level (where the entry files is placed). Thus, it's highly recommended\n\u003e to place all other files in a subfolder - usually that's the `src` folder.\n\n#### Secondary entry points\n\nAngular, for instance, has packages with multiple entry points: `@angular/core` as the primary, and `@angular/core/testing` as the (here\nonly) secondary. Within the `.angular-package.json` file, you can define any number of secondary entry points using the `secondaryEntries`\noption. For instance:\n\n```json\n{\n  \"$schema\": \"./node_modules/angular-package-builder/angular-package.schema.json\",\n  \"entryFile\": \"./index.ts\",\n  \"outDir\": \"./dist\",\n  \"secondaryEntries\": [\n    {\n      \"entryFile\": \"./testing/index.ts\"\n    }\n  ]\n}\n```\n\n\u003cbr\u003e\n\n### Step 2: Add build script to `package.json`\n\nNow, run **angular-package-builder** within one of your `package.json` scripts. The command accepts an unordered list of paths to\n`.angular-package.json` files as parameters. For instance:\n\n```json\n{\n  \"scripts\": {\n    \"build\": \"angular-package-builder ./my-library/.angular-package.json\"\n  }\n}\n```\n\n#### Multiple libraries\n\nAngular, again, consists of multiple packages, all united in a single Git repository (called monorepo). The **Angular Package Builder** is\nable to build multiple libraries using a single command. Building more libraries means adding more `.angular-package.json` files to the\ncorresponding npm script. For example:\n\n```json\n{\n  \"scripts\": {\n    \"build\": \"angular-package-builder ./lib-one/.angular-package.json ./lib-two/.angular-package.json\"\n  }\n}\n```\n\n\u003e The order of the parameters does not matter as the **Angular Package Builder** will derive the build order independently.\n\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n\n## Advanced configuration\n\nUsually, configuring the `entryFile` and `outDir` should be sufficient for most libraries. For more advanced use cases or requirements, you\ncan extend the build configuration in your `.angular-package.json` file(s).\n\n\u003cbr\u003e\n\n### TypeScript compiler options\n\nOne of the things you might want to configure specifically for your project is TypeScript. Popular options include `strictNullChecks`,\n`skipLibCheck` and `allowSyntheticDefaultImports`. For instance:\n\n```json\n{\n  \"typescriptCompilerOptions\": {\n    \"strictNullChecks\": true\n  }\n}\n```\n\nSee the **[TypeScript Compiler Options Documentation](https://www.typescriptlang.org/docs/handbook/compiler-options.html)** for the full\nlist of available options.\n\n\u003e The following options cannot be changed:\u003cbr\u003e \u003e `declaration`, `emitDecoratorMetadata`, `experimentalDecorators`, `module`, `moduleResolution`, `newLine`, `outDir`, `rootDir`,\n\u003e `sourceRoot` and `target`\n\n\u003cbr\u003e\n\n### Angular compiler options\n\nFurthermore, you might also decide to configure the Angular compiler differently. Common options are `annotateForClosureCompiler`,\n`preserveWhitespaces` and `strictMetadataEmit`. For instance:\n\n```json\n{\n  \"angularCompilerOptions\": {\n    \"annotateForClosureCompiler\": false\n  }\n}\n```\n\n\u003e The following options cannot be changed:\u003cbr\u003e \u003e `flatModuleId`, `flatModuleOutFile` and `skipTemplateCodegen`\n\n\u003cbr\u003e\n\n### Dependencies\n\nBy default, the **Angular Package Builder** will identify your libraries' dependencies automatically. If, for some reason, a dependency is\nmissing or you want to overwrite a dependency definition, you can declare them in the form of `package -\u003e global constant`. For instance:\n\n```json\n{\n  \"dependencies\": {\n    \"@ngx-translate/core\": \"ngxTranslate.core\"\n  }\n}\n```\n\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\n\n## Known pitfalls with solutions\n\nThere are quite a few pitfalls when packaging an Angular library. Most of them are all but obvious, and the fix is not always clear. The\nfollowing is a collection of known pitfally, plus tips on how to solve them.\n\n\u003e Feel free to extend this list by **[creating an issue](https://github.com/dominique-mueller/angular-package-builder/issues/new)**!\n\n\u003cbr\u003e\n\n### Caution with barrels\n\nUsually, libraries are built in a way that allows us to import them from a single source (normally the module name). This is achieved by\nre-exporting the implementation (spread accross multiple files) with a so-called\n**[Barrel](https://angular.io/guide/glossary#barrel)** (normally `index.ts`).\n\nNow, _issues might occur when - somewhere within the library - two barrels meet each other_. Funnily enough, should such a constellation\nlead to any issues, it won't be appearant right away: Chances are good that the **Angular Package Builder** will succeed, and the\ncompilation output might also look correct. At the latest, when trying to import the library into an Angular application, an error will be\nthrown (something like \"injected dependencies cannot be resolved\").\n\n#### Solution\n\nWe recommend to only use a single barrel / `index.ts` file at the root of you library, re-exporting all public functionality from that\nsingle place.\n\n\u003cbr\u003e\n\n### Forbidden JSDoc tags\n\nThe usage of type-related JSDoc tags / information within JSdoc tags is disallowed, reason being that the TypeScript syntax already exposes\nthis kind of information. Forbidden are (amongst other things):\n\n- type information in parameter tags (e.g. `@param {string} myOption`)\n- type-related tags on variables, functions, classes (e.g. `@type`, `@constructor`, `@function`, `@class`)\n- tags regarding visibility (e.g. `@private`, `@public`)\n- further redundant tags such as `@static`, `@extends`, `@implements`\n\n\u003e The full list of allowed / disallowed JSDoc tags can be found\n\u003e **[in the tsickle source](https://github.com/angular/tsickle/blob/d24b139b71a3f86bf25d6eecf4d4dcdad3b379e4/src/jsdoc.ts#L48)**.\n\nIf any of those tags are being used anyway, the Angular Compiler (`tsickle` to be specific) will complain:\n\n![Angular Package Builder - forbidden JSdoc error](/docs/error-jsdoc.png?raw=true)\n\n#### Solution\n\nPreferably, remove all redundant JSDoc tags until the Angular Compiler is happy. As an alternative, one could also set the\n`annotateForClosureCompiler` option in the `angularCompilerOptions` to `false` - but it's not recommended. Read the **[Angular annotateForClosureCompiler documentation](https://angular.io/guide/aot-compiler#annotateforclosurecompiler)** for further information.\n\n\u003cbr\u003e\n\n### Angular metadata generation errors\n\nEspecially when writing custom factories for `NgModules`, one might run into Angular metadata generation issues, usually resulting in errors\nlike `Lambda not supported` or `Reference to a non-exported function`.\n\n![Angular Package Builder - metadata generation error](/docs/error-lambda.png?raw=true)\n\n#### Solution\n\nThis issue can be solved by extracing the mentioned arrow function into a separate function, and making sure that it's exported.\n\n\u003e Also see **[this Angular issue on GitHub](https://github.com/angular/angular/issues/11262)**.\n\n\u003cbr\u003e\n\n### Angular metadata validation errors\n\nRarely, and only when using arrow functions within static classes and / or methods, an error like `Function call not supported` might occur.\n\n#### Solution\n\nThis issue can be solved in two ways:\n\n- Prefered: Add the `@dynamic`JSdoc tag to the comment describing the static method (or, if this should not work, the class containing the\n  static method). Then, the Angular Compiler will make an exception for this piece of code when validating the generated metadata.\n- Alternative: Set the `strictMetadataEmit` option in the `angularCompilerOptions` object to `false`. Then, however, other metadata\n  validation issues will no longer be visible. Read the\n  **[Angular strictMetadataEmit documentation](https://angular.io/guide/aot-compiler#strictmetadataemit)** for further information.\n\n\u003e Also see **[this Angular issue on GitHub](https://github.com/angular/angular/issues/19698)**.\n\n\u003cbr\u003e\n\n### Synthetic imports\n\nOften, we integrate long-existing libraries into our Angular projects. **[Moment.js](https://momentjs.com/)**, for instance, is one of _the_\nlibraries used when working with dates. Due to its age, however, it's still published as a single-entry ES5 module - which means people\nusually write the following TypeScript code to import the library:\n\n```typescript\nimport * as moment from 'moment';\n```\n\nWhen trying to package an Angular library using the import statement above, an error will be thrown:\n\n![Angular Package Builder - synthetic imports](/docs/error-synthetic.png?raw=true)\n\n#### Solution\n\nThe solution to this problem is called **[synthetic default imports](https://www.typescriptlang.org/docs/handbook/compiler-options.html)**,\na technique which does allow TypeScript to make default import from modules that come without a default export.\n\nFirst, enable synthetic default import support in the TypeScript configuration by adding the following line to the\n`typescriptCompilerOptions` within your `.angular-package.json` file:\n\n```json\n\"typescriptCompilerOptions\": {\n  \"allowSyntheticDefaultImports\": true\n}\n```\n\nThen, change the affected import statements to default import statements. For instance:\n\n```typescript\nimport moment from 'moment';\n```\n\nAlternatively, you could also consider **[Moment ES6](https://github.com/Agamnentzar/moment-es6)** - it wraps around Moment.js and exports\nit in an ES6-compatible (and thus TypeScript-compatible) way.\n\n\u003e Also see **[this Moment.js issue on GitHub](https://github.com/moment/moment/issues/3748)**.\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdominique-mueller%2Fangular-package-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdominique-mueller%2Fangular-package-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdominique-mueller%2Fangular-package-builder/lists"}