Closed ssougnez closed 10 months ago
This is by design.
The application builder will output publicly accessible files in the browser
directory, ssr files in the server
directory and other files such as statistics and licenses information in the root outputPath.
In .NET Core you can configure and change the wwwroot
by using .UseWebRoot
.
Edit: If this change in outputPath
semantics is a major obstacle, consider using browser-esbuild
which leverages esbuild/Vite to provide the same build-time improvements as application
builder but with identical options to the existing browser
builder, meaning outputPath
is unchanged.
Thanks for the tip.
However, I still find it a bit weird (but maybe I'm alone). If I configure an output path, I expect angular to scrupulously respect it. Especially if I don't use SSR.
What would make more sense to me would be to have a SSR section in the angular.json where I could override the default output path.
This way, people could use the regular outputPath setting to have the same behaviour than with webpack and use a combination of the two if they want to use SSR.
With this approach, everyone would be able to configure his application the way he wants.
Just a suggestion...
The main reasons behind this change of having a standardise output are;
/browser
and /server
users don’t need to modify their setup when they opt-in or out of SSR.Whilst this change does remove some flexibility, we believe that the pros outweigh the cons in the long run.
I run in same issue. I am using Firebase for hosting and after moving to application
builder when I deploy to hosting, I see that both browser
and server
folders are deployed, so when I navigate to hosted website I have "not found" as index.html
is in browser/index.html
I prefer to use SSR.
It is application
builder issue or angularfire
? Should I reconfigure Angularfire to deploy only browser
folder or server
folder or application
builder can build into single folder that could be deployed to firebase hosting?
Thnx
@olostan, if you are using AngulsrFire ng deploy
functionality it should determine the right thing out of the box.
Although it does look like they are still working on supporting the new builder https://github.com/firebase/firebase-tools/pull/6480
@alan-agius4 Thnx! Looks like it is exactly what I am missing.
Trying to use esbuild has being absolute hell. I don't use ssr (can't even install node in server) but having this browser directory has introduced so many unnecessary problems.
I am having problem with the browser folder too. I build and output to ../webapp folder in spring boot application. The 'browser' inside ../webapp ruin everything. Developers use Angular to build for many types of applications, not necessarily must use /browser or /server. 'browser' should not be here or at least should have the option not to have it.
Big problem for me too. :( Please consider adding an option as a parameter in angular.json. If the parameter is set to an empty string, the output should be directed to just /dist. If the parameter is set to 'browser', then the output should go to the /dist/browser subfolder.
+1
maybe it's more friendly and a better experience for the developers to make it configurable in addition to the default behavior
As a current hack I currently use this. It is strange but works:
Change angular.json:
"options": { "outputPath": "dist",
Add in angular.json:
"architect": { "build": { "configurations": { "production": { "deleteOutputPath": true,
Add in package.json - scripts
"postbuild": "node .\\post-build.js",
Add post-build.js file in root:
const fs = require('fs-extra');
fs.move('dist/browser', 'dist', (err) => { if(err) { return console.error(err); } });
+1
Problem here too, I also deploy Angular with a Spring Boot application and all of our pipelines are setup so that Angular builds as part of CI/CD and the output path is set to ../application/src/main/resources/public
so that Spring may automatically resolve the view. This change has broken that so we cannot upgrade to Angular 17 without recalibrating all our CI/CD pipelines.
I don't think I even saw this change mentioned in any of the notes, but I may have missed it. If the behaviour isn't going to be looked at/changed/made configurable then maybe it's worth mentioning this more clearly so people upgrading don't blindly cause headaches for themselves.
I agree that there should perhaps be an option for client-side rendering to output in the previous directory structure.
I am having problem with the browser folder too. I build and output to ../webapp folder in spring boot application. The 'browser' inside ../webapp ruin everything. Developers use Angular to build for many types of applications, not necessarily must use /browser or /server. 'browser' should not be here or at least should have the option not to have it.
Same here, everything in pipeline is breaking because of forced "BROWSER" folder which does kill of all middleware proxy and base-href stuff set up (eg. relative to ./api json fetch logic) . Please give an option like before to be able to customize the real dist outputPath without forcing devs. Fine with me to have "browser" as default, but give some extra parameter for real outPath of the browser dist... now we need to hack around like @Crefelder
why not in angular.json:
"outputPath": {
browser: "../backend/wwwroot/admin",
ssr: "../backend/not-public-server-side-rendering",
whatever: "\\server\share\whatever"
}
it's not so easy if you pipe in 5 SPA apps/uis into one wwwroot with the .UseWebRoot .NET change - which also kills of default in C# backend mapping.
If the change in output path is a major obstacle for adopting esbuild/Vite, we recommend using the browser-esbuild
builder. This leverages esbuild and Vite for improved build times but keeps the same options as the existing browser
builder, meaning outputPath
is used directly and no browser
sub-directory is created. You can read more on our docs.
To be clear, the motivation behind this change for application
builder was to align client and server rendering output which makes it much more intuitive when adding SSR to an existing application in particular. This alignment should make deployments easier and more consistent going forward given the stable paths between CSR and SSR builds. That said, we do recognize the churn to get there, which is why we have browser-esbuild
as a compatibility layer to solve this problem so everyone can still see the build performance benefits without having to touch your deployment pipeline.
Building with browser-esbuild show a warning:
The 'browser-esbuild' builder is a compatibility builder which will be removed in a future major version in favor of the 'application' builder.
Will it get removed in the future?
browser-esbuild
is stable in v17 and subject to our standard deprecation policy.
@clydin, I wonder we should remove/rephrase that warning? We should definitely prefer application
builder, but I'm not sure a warning in a stable builder is the best way of communicating that preference. We could maybe drop "will be removed in a future major version" at minimum just to make it less scary?
browser-esbuild
keeps throwing errors in Angular 17, it used to work in 16.
10:50:42 [vite] Internal server error: Failed to resolve import "src/environments/environment" from ".angular\vite-root\YourApp\chunk-SHHAMBP3.js". Does the file exist?
it just won't work with tsconfig.json "baseUrl": "./",
Upgrading to Angular 17 is now breaking all the spring boot apps. Forcing devs to accommodate a change like this(using the browser folder) rather than making it as an option provides more headaches than solutions. As @Crefelder suggested, now we have to 'hack' our way for a work around. This isn't an ideal solution. Please find a fix to this problem, or at the very least, provide it as an option so it can be configured.
I am running into the same issue when upgrading to Angular 17. This forced “BROWSER” directory has introduced a lot of unnecessary problems. Please consider giving an option to be able to customize/configure the dist outputPath.
+1
As a temporary solution I have to modify node_modules\@angular-devkit\build-angular\src\tools\esbuild\utils.js
file, since it's the only way to output files directly to outputPath specified in angular.json.
Please consider adding an option in angular.json.
I'm seeing a lot of feedback in this thread asking Angular CLI to support an option to drop browser/
from the output path and I want to be very clear: This option already exists!
The browser-esbuild
builder is that option. It is designed to be fully backwards-compatible with the existing browser
builder and does not create a browser/
subdirectory. It includes all the esbuild/Vite performance benefits of application
builder. The only thing browser-esbuild
can't do is server-side rendering, however I believe SSR builds have always had the browser/
directory, so if you're having trouble with deployments here, you're probably not using SSR.
If your deployment pipeline is giving you trouble with application
builder due to the browser/
directory, then please try browser-esbuild
instead. See our docs for more info.
The browser-esbuild builder is that option
It is deprecated, it's just a temporary solution, not an "option".
ng build says:
The 'browser-esbuild' builder is a compatibility builder which will be removed in a future major version in favor of the 'application' builder.
That log statement was an artifact of prerelease builds. It's already been removed in https://github.com/angular/angular-cli/pull/26402 and should be published today in 17.0.2.
Angular docs state this the best I think:
For existing projects, you can opt-in to use the new builder on a per-application basis with two different options. Both options are considered stable and fully supported by the Angular team. The choice of which option to use is a factor of how many changes you will need to make to migrate and what new features you would like to use in the project.
The
application
builder is generally preferred as it improves server-side rendered (SSR) builds, and makes it easier for client-side rendered projects to adopt SSR in the future. However it requires a little more migration effort, particularly for existing SSR applications. If theapplication
builder is difficult for your project to adopt,browser-esbuild
can be an easier solution which gives most of the build performance benefits with fewer breaking changes.
outputPath
is one potential place where application
builder can be a little tricky for existing apps, and browser-esbuild
is the recommended solution for that right now.
thank you for the clarification, @dgp1130 !
I also encountered the same situation as you, which forced me to make some changes to my project
+1
As a temporary solution I have to modify
node_modules\@angular-devkit\build-angular\src\tools\esbuild\utils.js
file, since it's the only way to output files directly to outputPath specified in angular.json.Please consider adding an option in angular.json.
helpful to me
For anyone using Asp.Net 8.0 where you have .client and .server subdirectories in your Solution - go to the {solution}.client.esproj
file and add add \browser to the
<PublishAssetsDirectory>$(MSBuildProjectDirectory)\dist\{project}\browser</PublishAssetsDirectory>
Then re-deploy and it should fix it
You can add the following to your application.yml file in a Spring Boot application to accommodate the new output path:
spring:
web:
resources:
static-locations: classpath:/static/browser
This is annoying. If I configure an output path, I expect the output path to be what I configured.
Is there any new news on this issue?
Is there any news? i think an option to prevent the browser folder if ssr is not active would be very helpful and easy to do in my opinion
A configuration option should definitely be added to define the path in which the browser application should be generated - some of the existing projects are already old (they are a few years old). It is a considerable problem to externally change the path (since not always there is direct access to server configuration), from which the files are served.
as quick fix just move the content under browser one level up, remove the browser directory ... should work
I'm not sure why you are still asking for news or solutions - @dgp1130 gave an answer, and it works great. Just use browser-esbuild, that’s it, problem solved.
@e-oz maybe it is not the desired solution?
@curlywu it is exactly the same as "application", but the "server" part will not be created. And it is exactly what you need if you don't use SSR. And if you do, then you do need browser
and server
folders.
This issue is closed, so if you need some other feature, I think it is better to create a new issue and explain to Angular devs why the current one can not be used.
the solution is not sufficiently explained for someone who only has to deal with angular from time to time I now have to sit down again for hours to get it working again
@e-oz updating inside of angular.json
manually is not an ideal solution. This workaround will eventually be forgotten and not supported.
If using angular cli to generate an application with --ssr=false
flag, then angular cli can (and should) honor the --output-path
value. It should not be something difficult.
Or, Angular team can add another flag in the angular cli and angular.json
so that the --output-path
does really mean the output path.
My suggestion is that: make this change more visible, also allow customization using the official Angular CLI (instead of manual editing).
@changhuixu
This workaround will eventually be forgotten and not supported.
No, see this comment.
I don't understand your position here. Are you going to support this workaround? In my opinion, the best way to maintain it is to add a flag in Angular CLI or make Angular CLI smarter.
I believe that you are super smart and able to edit angular.json
. But I don't trust myself that I could remember it next year after updating Angular to a newer version.
@e-oz , you won't lose anything if Angular CLI becomes better and be able to honor the --output-path
value.
@changhuixu right now there is no such option as --output-path
in ng new
. outputPath
, mentioned by the author of this issue, is part of the angular.json
file.
There is one issue with ng new
, though. Right now it creates angular.json
with @angular-devkit/build-angular:application
in the builder
field, even if SSR was not selected (or --ssr=false was applied). It is, indeed, a wrong behavior. It should set @angular-devkit/build-angular:browser-esbuild
there and generate fields, related to this builder (right now it creates field browser
).
Because this issue is already closed, I've created another issue to report this problem.
I've created a feature request, you might want to track it: https://github.com/angular/angular-cli/issues/26632
And it's implemented: #26675 🎉 Thank you, @alan-agius4 !
There are already differences between browser-esbuild and application. For example the new "loader" builder option was added to the application builder but not to the browser-esbuild builder. https://github.com/angular/angular-cli/pull/26371
You can add the following to your application.yml file in a Spring Boot application to accommodate the new output path:
spring: web: resources: static-locations: classpath:/static/browser
Depending on your IDE, this can be an issue. For example, Eclipse will not pick up changes from VSCode, so you will have to manually refresh the Java project to update the web app every time you build or watch your Angular projects. However, if you build to the "webapp" folder, Eclipse will detect the changes automatically.
Fixed in angular >=17.1.x
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": {
"base": "dist/project-name",
"browser": ""
},
...}}}
Keep the "browser" : "" value empty if you don't need the default folder browser being added.
https://angular.io/guide/workspace-config#output-path-configuration
Fixed in angular >=17.1.x
"architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": { "base": "dist/project-name", "browser": "" }, ...}}}
Keep the "browser" : "" value empty if you don't need the default folder name browser being added.
https://angular.io/guide/workspace-config#output-path-configuration
This doesn't seem to work for me on 17.1.1. 'browser' is still flagged as required when building
Error: Schema validation failed with the following errors:
Data path "" must have required property 'browser'.
and also can't be an empty string.
An unhandled exception occurred: `browser` option cannot be an empty string.
See "/tmp/ng-PUeaq4/angular-errors.log" for further details.
Fixed in angular >=17.1.x
"architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": { "base": "dist/project-name", "browser": "" }, ...}}}
Keep the "browser" : "" value empty if you don't need the default folder name browser being added. https://angular.io/guide/workspace-config#output-path-configuration
This doesn't seem to work for me on 17.1.1. 'browser' is still flagged as required when building
Error: Schema validation failed with the following errors: Data path "" must have required property 'browser'.
and also can't be an empty string.
An unhandled exception occurred: `browser` option cannot be an empty string. See "/tmp/ng-PUeaq4/angular-errors.log" for further details.
Can you share the angular.json or configuration
Fixed in angular >=17.1.x
"architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": { "base": "dist/project-name", "browser": "" }, ...}}}
Keep the "browser" : "" value empty if you don't need the default folder name browser being added. https://angular.io/guide/workspace-config#output-path-configuration
This doesn't seem to work for me on 17.1.1. 'browser' is still flagged as required when building
Error: Schema validation failed with the following errors: Data path "" must have required property 'browser'.
and also can't be an empty string.
An unhandled exception occurred: `browser` option cannot be an empty string. See "/tmp/ng-PUeaq4/angular-errors.log" for further details.
Can you share the angular.json or configuration
Using @angular-devkit/build-angular:browser-esbuild
fixes the issue so I hope this isn't in fact a temporary solution.
But for reference I was using exactly the same options for outputPath
you provided.
With
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": {
"base": "dist/project-name",
"browser": ""
},
...}}}
I get
Error: Schema validation failed with the following errors:
Data path "" must have required property 'browser'.
And with
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": {
"base": "dist/project-name",
"browser": ""
},
"browser":"",
...}}}
I get
An unhandled exception occurred: `browser` option cannot be an empty string.
See "/tmp/ng-PUeaq4/angular-errors.log" for further details.
If I don't provide "browser":""
outside of outputPath
I see the first error I mentioned.
Data path "" must have required property 'browser'.
Like I mentioned though @angular-devkit/build-angular:browser-esbuild
works fine for me so no issues there. Just overall a strange decision by the angular team to force @angular-devkit/build-angular:application
onto new projects.
Command
build
Is this a regression?
The previous version in which this bug was not present was
No response
Description
I have an Angular application configure as below:
"outputPath": "../MyNetApplication/wwwroot",
When using webpack build, the compiled files of the Angular application went directly in wwwroot so I could publish my .NET application and it worked directly.
I tried to switch to es-build, however, after the build, the compiled files of the Angular application end up into "../MyNetApplication/wwwroot/browser" which prevents me from publishing the .NET application as this would not work.
It seems weird to me that the outputPath settings of angular.json is only partially honored. According to me, this settings should be used and not altered during the compilation.
Minimal Reproduction
Just create a new Angular application using angular/cli 17 and run ng build. The files will be located under dist/ng17/browser.
Exception or Error
No response
Your Environment
Anything else relevant?
No response