Skip to content
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

Various Esbuild improvements #25030

Merged
merged 5 commits into from Apr 24, 2023
Merged

Conversation

dgp1130
Copy link
Collaborator

@dgp1130 dgp1130 commented Apr 17, 2023

PR Checklist

Please check to confirm your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Feature

What is the current behavior?

Issue Number: N/A

What is the new behavior?

  • browser-esbuild options are now able to differ slightly from the existing browser builder. This is to support adding additional functionality not currently supported by the browser builder, staying compatible with the existing builder is still a primary goal of the project.
  • browser-esbuild now supports an additional entryPoints option in its InfrastructureSettings.
    • This required an update to builder test harnesses in order to effectively test.
  • main and entryPoints now support absolute file paths. Absolute files paths are always output with the same basename in the root of the output directory.
  • browser-esbuild now allows index to be optional. It already supported index not being set, this just updates the schema.
  • browser-esbuild now supports an outExtension option to configure the output file extension.

Does this PR introduce a breaking change?

  • No

@dgp1130 dgp1130 added action: review The PR is still awaiting reviews from at least one requested reviewer target: rc This PR is targeted for the next release-candidate labels Apr 17, 2023
@dgp1130
Copy link
Collaborator Author

dgp1130 commented Apr 17, 2023

The formatter seems to be conflicting with the linter here? Linter complains that an error message exceeds the line length, but if I break it into two lines, the formatter collapses them back on to one. Not sure how to handle that?

@alan-agius4
Copy link
Collaborator

The formatter seems to be conflicting with the linter here? Linter complains that an error message exceeds the line length, but if I break it into two lines, the formatter collapses them back on to one. Not sure how to handle that?

You'd need to split the message into multiple strings.

@dgp1130 dgp1130 force-pushed the esbuilder-improvements branch 3 times, most recently from 7c241bf to 8692660 Compare April 19, 2023 05:30
As is, the `browser` and `browser-esbuild` schemas needed to be identical to check for unsupported properties. This loosens it slightly by casting the `browser-esbuild` schema into the `browser` schema and looking for invalid properties. This makes the module more flexible as the `browser-esbuild` schema evolves _and_ more closely aligns with the actual mistake of users who incorrectly think of `browser-esbuild` as supporting all the options of `browser`, which it does not yet do so.
@dgp1130
Copy link
Collaborator Author

dgp1130 commented Apr 20, 2023

I also added another commit to support absolute file paths in entry points. Hopefully nothing too objectionable there, can you take another quick look @clydin?

Copy link
Collaborator

@alan-agius4 alan-agius4 left a comment

Choose a reason for hiding this comment

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

It looks like there is a potential breaking change and I left some feedback comments.

@clydin clydin self-requested a review April 20, 2023 14:09
Copy link
Collaborator

@alan-agius4 alan-agius4 left a comment

Choose a reason for hiding this comment

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

LGTM, just a couple of NITs.

This makes the `main` parameter optional and allows multiple entry points instead. `main` is still technically required by the schema, since it should almost always be set when invoked by a user. However, it now supports `null` as a value so it can be explicitly omitted.

Longer term, we may choose to remove `main` and fold it into `entryPoints`, but for now we want to keep compatibility with the existing `browser` builder.

Since `entryPoints` is an internal-only options (cannot be set in `angular.json` and isn't exposed in the schema), I made a new `buildEsbuildBrowserInternal()` function which adds the extra private option. This way direct invocations of the builder can provide this extra information without compromising the public API surface defined in the schema.
This allows `browser-esbuild` to consume absolute file paths and `entryPoints`. Absolute paths will always output in the root of the output directory with the same basename, since they are not within the workspace root and cannot exist at any guaranteed unique relative path. No attempt is made to check if the absolute path is actually within the workspace root, since this would require a call to `fs.realpath()` and make this logic dependent on the actual file system structure which introduces a lot of complexity we'd rather avoid.

Longer term, the ideal approach is probably to leverage virtual files in some capacity, but this should be sufficient for now.

`main` functionality is left alone, and absolute paths like `/main.ts` are treated as relative to the workspace root. This is to preserve existing functionality and discourage public API usage of file paths outside the workspace.
For testing use cases, we don't need an `index.html` file in the same capacity as a typical application. The builder already omits an `index.html` page when not set, this just updates the schema to reflect that.

The parameter could be left optional, rather than required but allowing `false`. However doing it this way prevents users from accidentally forgetting to provide an index while still allowing users to explicitly disable index generation. We use `false` instead of `null` so users can write `--no-index` on the command line and get the same behavior, which would not be possible with `null`.
The `outExtension` option allows users to generate `*.mjs` files, which is useful for forcing ESM execution in Node under certain use cases. The option is limited to `*.js` and `*.mjs` files to constrain it to expected values. `*.cjs` could theoretically be useful in some specific situations, but `browser-esbuild` does not support that output format anyways, so it is not included in the type.

I also updated `index.html` generation, which will correctly insert a `<script />` tag with the `*.mjs` extension. I opted to explicitly ban a "non-module" `*.mjs` file, since that would be very counterintuitive and I can't think of a valid use case for it.
@angular-robot angular-robot bot requested a review from clydin April 24, 2023 21:01
@dgp1130 dgp1130 removed the action: review The PR is still awaiting reviews from at least one requested reviewer label Apr 24, 2023
@dgp1130 dgp1130 added the action: merge The PR is ready for merge by the caretaker label Apr 24, 2023
@angular-robot angular-robot bot merged commit c045c99 into angular:main Apr 24, 2023
21 checks passed
@dgp1130 dgp1130 deleted the esbuilder-improvements branch April 24, 2023 22:44
@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 May 25, 2023
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 target: rc This PR is targeted for the next release-candidate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants