Skip to content

feat(@angular-devkit/build-angular): add define build option to application builder #27047

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 7, 2024

Conversation

clydin
Copy link
Member

@clydin clydin commented Feb 7, 2024

The application builder now supports a new option named define. This option allows global identifiers present in the code to be replaced with another value at build time. This is similar to the behavior of Webpack's DefinePlugin which was previously used with some custom Webpack configurations that used third-party builders. The option has similar capabilities to the esbuild option of the same name. The documentation for that option can be found here: https://esbuild.github.io/api/#define
The command line capabilities of the Angular CLI option are not yet implemented and will added in a future change.

The option within the angular.json configuration file is of the form of an object. The keys of the object represent the global identifier to replace and the values of the object represent the corresponding replacement value for the identifier. An example is as follows:

"define": {
    "SOME_CONSTANT": "5",
    "ANOTHER": "'this is a string literal'"
}

All replacement values are defined as strings within the configuration file. If the replacement is intended to be an actual string literal, it should be enclosed in single quote marks. This allows the flexibility of using any valid JSON type as well as a different identifier as a replacement.

Additionally, TypeScript needs to be aware of the types to prevent type-checking
errors during the build. This can be accomplished with an additional type definition file within the
application source code (src/types.d.ts, for example) with the following or similar content:

declare const SOME_CONSTANT: number;
declare const ANOTHER: string;

The default project configuration is already setup to use any type definition files present in the
project source directories. If the TypeScript configuration for the project has been altered, the
tsconfig may need to be adjusted to reference this newly added type definition file.

An important caveat to the option is that it does not function when used with values contained within Angular metadata such as a Component or Directive decorator. This limitation was present with previous third-party builder usage as well.

@clydin clydin added the target: minor This PR is targeted for the next minor release label Feb 7, 2024
@angular-robot angular-robot bot added the detected: feature PR contains a feature commit label Feb 7, 2024
@clydin clydin force-pushed the esbuild/define-option branch from 001df4d to 5f5dd29 Compare February 7, 2024 03:11
…cation builder

The `application` builder now supports a new option named `define`. This option allows
global identifiers present in the code to be replaced with another value at build time.
This is similar to the behavior of Webpack's `DefinePlugin` which was previously used with
some custom Webpack configurations that used third-party builders. The option has similar
capabilities to the `esbuild` option of the same name. The documentation for that option
can be found here: https://esbuild.github.io/api/#define
The command line capabilities of the Angular CLI option are not yet implemented and will added
in a future change.

The option within the `angular.json` configuration file is of the form of an object. The keys
of the object represent the global identifier to replace and the values of the object represent
the corresponding replacement value for the identifier. An example is as follows:

```
"define": {
    "SOME_CONSTANT": "5",
    "ANOTHER": "'this is a string literal'"
}
```

All replacement values are defined as strings within the configuration file. If the replacement
is intended to be an actual string literal, it should be enclosed in single quote marks. This
allows the flexibility of using any valid JSON type as well as a different identifier as a replacement.

Additionally, TypeScript needs to be aware of the module type for the import to prevent type-checking
errors during the build. This can be accomplished with an additional type definition file within the
application source code (`src/types.d.ts`, for example) with the following or similar content:
```
declare const SOME_CONSTANT: number;
declare const ANOTHER: string;
```
The default project configuration is already setup to use any type definition files present in the
project source directories. If the TypeScript configuration for the project has been altered, the
tsconfig may need to be adjusted to reference this newly added type definition file.

An important caveat to the option is that it does not function when used with values
contained within Angular metadata such as a Component or Directive decorator. This
limitation was present with previous third-party builder usage as well.
@clydin clydin force-pushed the esbuild/define-option branch from 5f5dd29 to 20decfe Compare February 7, 2024 16:54
@clydin clydin marked this pull request as ready for review February 7, 2024 16:54
@clydin clydin requested a review from alan-agius4 February 7, 2024 16:54
@clydin clydin added the action: review The PR is still awaiting reviews from at least one requested reviewer label Feb 7, 2024
@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Feb 7, 2024
@clydin clydin merged commit 7f57123 into angular:main Feb 7, 2024
@clydin clydin deleted the esbuild/define-option branch February 7, 2024 18:40
Comment on lines +35 to +37
define?: {
[key: string]: string;
};
Copy link

@sod sod Feb 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome. Thanks a lot. A real usecase is e.g. if you use sentry, you can omit parts of the library with this like __SENTRY_DEBUG__: false

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Mar 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker detected: feature PR contains a feature commit target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants