Explore Angular CLI’s Define Option: Effortless Global Identifier Replacement

Netanel Basal
Netanel Basal
Published in
2 min readFeb 10, 2024

--

In the ever-evolving landscape of web development, Angular CLI continues to empower developers with new features and enhancements. One such addition is the define option introduced in v17.2.0-rc.0 within the angular.json configuration file, offering a powerful tool for global identifier replacement during build time. Let's explore how this functionality can enhance your Angular projects.

Introducing the define Option

The define option in Angular CLI allows developers to replace global identifiers within their codebase with alternative values at build time. This functionality mirrors Webpack's DefinePlugin, providing a seamless transition for those familiar with custom Webpack configurations. Moreover, it shares similarities with the esbuild option of the same name, extending its capabilities to the Angular ecosystem.

Configuration Syntax

Within the angular.json configuration file, the define option is structured as an object. Each key-value pair represents a global identifier and its corresponding replacement value, respectively. For instance:

{
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"configurations": {
"production": {
"define": {
"DEBUG": "false" <===
}
},
"development": {
"define": {
"DEBUG": "true" <===
}
}
},
"defaultConfiguration": "production"
}
}
}

All replacement values are specified as strings in the configuration file. To denote a string literal, enclose the value in single quotes. This flexibility allows for a wide range of replacements, including different identifiers or any valid JSON type.

TypeScript Integration

To ensure seamless integration with TypeScript, developers need to specify the module type for imports. This prevents type-checking errors during the build process. By including a type definition file (e.g., src/types.d.ts) within the application source code, developers can declare the replaced identifiers and their respective types:

declare const DEBUG: boolean;

Angular CLI’s default project configuration automatically includes any type definition files present in the project source directories. However, if the TypeScript configuration has been customized, adjustments may be necessary to reference the newly added type definition file.

@Component({
selector: 'app-foo',
standalone: true,
})
export class FooComponent {
constructor() {
// tree shakeable when it's false
if (DEBUG) {
console.log('Debug mode enabled');
}
}
}

Limitations and Considerations

It’s essential to note that the define option doesn’t apply to values within Angular metadata, such as Component or Directive decorators. This limitation persists from previous third-party builder integrations. Developers should be mindful of this when planning their project architecture and avoid relying on define for such scenarios.

🙏 Support ngneat & Netanel Basal: Get Featured!

Are you passionate about the ngneat open source libraries for Angular or find Netanel Basal’s blog posts invaluable for your learning journey? Show your support by sponsoring my work!

Follow me on Medium or Twitter to read more about Angular and JS!

--

--

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.