# Angular Build Optimizer Angular Build Optimizer contains Angular optimizations applicable to JavaScript code as a TypeScript transform pipeline. ## Available optimizations Transformations applied depend on file content: - [Class fold](#class-fold), [Scrub file](#scrub-file) and [Prefix functions](#prefix-functions): applied to Angular apps and libraries. - [Import tslib](#import-tslib): applied when TypeScript helpers are found. Some of these optimizations add `/*@__PURE__*/` comments. These are used by JS optimization tools to identify pure functions that can potentially be dropped. ### Class fold Static properties are folded into ES5 classes: ```typescript // input var Clazz = (function () { function Clazz() {} return Clazz; })(); Clazz.prop = 1; // output var Clazz = (function () { function Clazz() {} Clazz.prop = 1; return Clazz; })(); ``` ### Scrub file Angular decorators, property decorators and constructor parameters are removed, while leaving non-Angular ones intact. ```typescript // input import { Injectable, Input, Component } from '@angular/core'; import { NotInjectable, NotComponent, NotInput } from 'another-lib'; var Clazz = (function () { function Clazz() {} return Clazz; })(); Clazz.decorators = [{ type: Injectable }, { type: NotInjectable }]; Clazz.propDecorators = { 'ngIf': [{ type: Input }] }; Clazz.ctorParameters = function () { return [{ type: Injector }]; }; var ComponentClazz = (function () { function ComponentClazz() {} __decorate([Input(), __metadata('design:type', Object)], Clazz.prototype, 'selected', void 0); __decorate( [NotInput(), __metadata('design:type', Object)], Clazz.prototype, 'notSelected', void 0, ); ComponentClazz = __decorate( [ NotComponent(), Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }), ], ComponentClazz, ); return ComponentClazz; })(); // output import { Injectable, Input, Component } from '@angular/core'; import { NotInjectable, NotComponent } from 'another-lib'; var Clazz = (function () { function Clazz() {} return Clazz; })(); Clazz.decorators = [{ type: NotInjectable }]; var ComponentClazz = (function () { function ComponentClazz() {} __decorate( [NotInput(), __metadata('design:type', Object)], Clazz.prototype, 'notSelected', void 0, ); ComponentClazz = __decorate([NotComponent()], ComponentClazz); return ComponentClazz; })(); ``` ### Prefix functions Adds `/*@__PURE__*/` comments to top level downleveled class declarations and instantiation. Warning: this transform assumes the file is a pure module. It should not be used with unpure modules. ```typescript // input var Clazz = (function () { function Clazz() {} return Clazz; })(); var newClazz = new Clazz(); var newClazzTwo = Clazz(); // output var Clazz = /*@__PURE__*/ (function () { function Clazz() {} return Clazz; })(); var newClazz = /*@__PURE__*/ new Clazz(); var newClazzTwo = /*@__PURE__*/ Clazz(); ``` ### Prefix Classes Adds `/*@__PURE__*/` to downleveled TypeScript classes. ```typescript // input var ReplayEvent = (function () { function ReplayEvent(time, value) { this.time = time; this.value = value; } return ReplayEvent; })(); // output var ReplayEvent = /*@__PURE__*/ (function () { function ReplayEvent(time, value) { this.time = time; this.value = value; } return ReplayEvent; })(); ``` ### Import tslib TypeScript helpers (`__extends/__decorate/__metadata/__param`) are replaced with `tslib` imports whenever found. ```typescript // input var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __()); }; // output import { __extends } from 'tslib'; ``` ### Wrap enums Wrap downleveled TypeScript enums in a function, and adds `/*@__PURE__*/` comment. ```typescript // input var ChangeDetectionStrategy; (function (ChangeDetectionStrategy) { ChangeDetectionStrategy[(ChangeDetectionStrategy['OnPush'] = 0)] = 'OnPush'; ChangeDetectionStrategy[(ChangeDetectionStrategy['Default'] = 1)] = 'Default'; })(ChangeDetectionStrategy || (ChangeDetectionStrategy = {})); // output var ChangeDetectionStrategy = /*@__PURE__*/ (function () { var ChangeDetectionStrategy = {}; ChangeDetectionStrategy[(ChangeDetectionStrategy['OnPush'] = 0)] = 'OnPush'; ChangeDetectionStrategy[(ChangeDetectionStrategy['Default'] = 1)] = 'Default'; return ChangeDetectionStrategy; })(); ``` ## Library Usage ```typescript import { buildOptimizer } from '@angular-devkit/build-optimizer'; const transpiledContent = buildOptimizer({ content: input }).content; ``` Available options: ```typescript export interface BuildOptimizerOptions { content?: string; inputFilePath?: string; outputFilePath?: string; emitSourceMap?: boolean; strict?: boolean; isSideEffectFree?: boolean; } ``` ## Webpack loader usage: ```typescript import { BuildOptimizerWebpackPlugin } from '@angular-devkit/build-optimizer'; module.exports = { plugins: [ new BuildOptimizerWebpackPlugin(), ] module: { rules: [ { test: /\.js$/, loader: '@angular-devkit/build-optimizer/webpack-loader', options: { sourceMap: false } } ] } } ``` ## CLI usage ```bash build-optimizer input.js build-optimizer input.js output.js ```