Skip to content

Provide Angular build context to external tool configuration files #20253

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

Open
1 task done
dgp1130 opened this issue Mar 11, 2021 · 6 comments
Open
1 task done

Provide Angular build context to external tool configuration files #20253

dgp1130 opened this issue Mar 11, 2021 · 6 comments
Labels
area: @angular-devkit/build-angular devkit/build-angular:browser feature: insufficient votes Label to add when the not a sufficient number of votes or comments from unique authors feature Issue that requests a new feature
Milestone

Comments

@dgp1130
Copy link
Collaborator

dgp1130 commented Mar 11, 2021

🚀 Feature request

Command (mark with an x)

  • build

Description

Spin off from PurgeCSS discussion in #20015.

It would be nice for external tool configuration files (like Tailwind) to have some knowledge about the Angular build context in order to conditionalize their configurations. This could allow ng build --configuration production to change the config used by other tools and affect their builds as well. This allows other tools in a project to be more intelligent about the intent of a build and do what the user expects.

Describe the solution you'd like

There are a couple possible implementations of this.

  1. Set an environment variable like NG_BUILD_CONFIGS="foo,bar,baz". Then config files could do something like:
const enableOptimizations = process.env['NG_BUILD_CONFIGS'].split(',').includes('production');

This would decouple the Angular CLI from any specific tools and allow the individual tool configs to define the semantics for each configuration. Similarly, the semantics for each configuration are also defined directly in the tool's config file rather than angular.json. That seems weird to me, but arguably it's a benefit so 🤷‍♂️. It also means that the config needs some knowledge of Angular, which isn't too bad considering its in the config, not the tool library, but this can still be undesirable.

  1. Add an env option in angular.json. Each configuration in the angular.json file could include an env map that looks like:
{
  "projects": {
    "my-project": {
      "architect": {
        "build": {
          "options": {
            "env": {
              "MY_BUILD_ENV": "development",
            },
          },
        },
        "configurations": {
          "production": {
            "env": {
              "MY_BUILD_ENV": "production",
            },
          },
        },
      },
    },
  },
}

The Angular CLI would parse and set the relevant environment variables during a build. Then tool configs could look for the project-specific environment variables like so:

const enableOptimizations = process.env['MY_BUILD_ENV'] === 'production';

This would still give users full control over the semantics of any given environment variable and they can choose its value on a per-configuration basis. The challenges here include merging multiple configuration environment variables which might conflict and that this environment would apply to all tools used by the Angular CLI. Users might also break something by setting a variable they probably shouldn't (such as PATH or other system variables) and breaking the CLI.

  1. Just have users set the environment variable on the command line:
MY_BUILD_ENV="production" ng build --configuration production

Then use that variable in the tool config just like previously:

const enableOptimizations = process.env['MY_BUILD_ENV'] === 'production';

This requires no effort on the Angular CLI side and users can do this today. The downside here is that it requires special knowledge of how to build a particular app. A new developer would reasonably expect ng build --configuration production to do everything it needs to, and then be surprised something didn't optimize because they didn't set MY_BUILD_ENV="production". Projects could wrap such a command into an npm run build:prod which sets the variable, but not everyone will use it. This is also a cross platform issue, as I don't think there is a Unix and Windows compatible way of doing this (see this question), so supporting both environment for build is more hassle for the user.

There are likely other possible implementations that have their own trade offs. We'll need to discuss this more and come to a decision on how to move forward here.

@dgp1130 dgp1130 added feature Issue that requests a new feature needs: discussion On the agenda for team meeting to determine next steps devkit/build-angular:browser labels Mar 11, 2021
@ngbot ngbot bot added this to the Backlog milestone Mar 11, 2021
@ahasall
Copy link
Contributor

ahasall commented Mar 11, 2021

Users might also break something by setting a variable they probably shouldn't (such as PATH or other system variables) and breaking the CLI.

We could mitigate this concern by requiring all environment variables to begin with NG_.

@nartc
Copy link

nartc commented Mar 15, 2021

https://github.com/tailwindlabs/tailwindcss-jit Just want to bring this to you guys' attention that is Tailwind JIT is in the work. As soon as this is stable, the need for Purging is obsolete. Although, there will be option from the Tailwind side to go back to AOT mode which, again, requires Purge functionality. So I guess this issue is still relevant

@dgp1130
Copy link
Collaborator Author

dgp1130 commented Mar 18, 2021

Had some more discussion on this today. While this build context issue is generic to any executable config file for any tool, the main motivation is for Tailwind. We do have a couple other executable configs (Karma for instance), but these have more direct integration where we pass in specific, known data about the build. So there isn't much need for this particular feature right now outside of Tailwind and we'd like to move away from the executable config format as much as possible due to its security and maintainability implications. For that reason we probably won't add this kind of support unless we have a specific need for it.

JIT mode seems like an easy answer to the Tailwind purging issue, avoids this issue entirely, and seems to be on track in a reasonable time frame. We'll need to do a bit of testing to confirm that Tailwind JIT works well with Angular, and if so, that seems like a better solution than inventing a scheme to pass build context to external config files. We'll keep an eye on Tailwind JIT for now, and hopefully we can use that to avoid this build context issue entirely.

@dgp1130 dgp1130 removed the needs: discussion On the agenda for team meeting to determine next steps label Mar 18, 2021
@nartc
Copy link

nartc commented Mar 26, 2021

@dgp1130 Thanks for sharing that insight. Can we get some update regarding Tailwind JIT testing as it goes along or as you guys make any decision for TailwindJIT? As of right now, Tailwind JIT needs to be included in postcss.config and that's not very straightforward to have a custom postcss.config to work with Angular, is it?

@angular-robot angular-robot bot added the feature: votes required Feature request which is currently still in the voting phase label Feb 1, 2022
@angular-robot
Copy link
Contributor

angular-robot bot commented Feb 1, 2022

Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.

Find more details about Angular's feature request process in our documentation.

@ngbot ngbot bot modified the milestones: Backlog, needsTriage Feb 1, 2022
@angular-robot
Copy link
Contributor

angular-robot bot commented Feb 21, 2022

Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.

We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.

You can find more details about the feature request process in our documentation.

@angular-robot angular-robot bot added feature: insufficient votes Label to add when the not a sufficient number of votes or comments from unique authors and removed feature: votes required Feature request which is currently still in the voting phase labels Feb 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: @angular-devkit/build-angular devkit/build-angular:browser feature: insufficient votes Label to add when the not a sufficient number of votes or comments from unique authors feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests

4 participants