Closed elvisbegovic closed 7 years ago
What is happening here is that <img src="../assets/images/avatar2.jpg" />
tries to go up one directory, but on the server there is no directory above. The server gives you http://localhost:4200
, but you are asking for http://localhost:4200/...
which doesn't exist. That is why your app fails to load the resources at runtime.
The --output-path
options is not related to locale, or assets, or language so it doesn't make sense to add that sort of functionality IMHO.
Since what you really need is to load different things (images etc) at runtime depending on the app locale, my advice is to use the LOCALE_ID
token (https://angular.io/api/core/LOCALE_ID). Then you can use interpolation in <img src="../assets/{{LOCALE_ID}}/images/avatar2.jpg" />
to load your assets from the right folder.
Please apologize, but not sure we are not talking about the same thing.
I'm not talk about --output-path but this
"assets": [
{
"glob": "**/*",
"input": "./assets/",
"output": "./assets/" <---- THIS i mean have something like output-dev and output-dist
},{
"glob": "favicon.ico",
"input": "./",
"output": "./" <---- THIS i mean have something like output-dev and output-dist
}
],
On DEVELOPEMENT mode ng serve
I'm not sure that <img src="../assets/images/avatar2.jpg" />
tries to go up one directory or I don't know HOW but actually with this configuration ABOVE I write in template <img src="../assets/images/avatar2.jpg" />
and it works .
This works on DEV ng serve
but if I want to get it working on ng build
I ned edit in config this "output": "./assets/"
to "output": "../assets/"
That's why I wonder how can we specify for dev to go to ./assets path (which have no directory above) and on production put my /assets outside /fr and /de distribution
Actually I solved this with 2 apps[] and only one character change from . to ..
My assets are about 5mo and don't want duplicate them in /fr and /de dist just because of i18n non-runtime compilation, it's about cache performance too.
@filipesilva
I'm not sure what you want me to apologize for :/
Thanks for the clarification that you're talking about the "output" property in the assets array and not the --output-path
flag in your example. We're not looking at adding per-environment asset output, as environments are arbitrary and we only use them for the environment functionality proper.
In ng serve
, when you use <img src="../assets/images/avatar2.jpg" />
on a template, your browser will try to resolve that path relative to the url. So if you are on http://localhost:4200/
, the full request url will be http://localhost:4200/../assets/images/avatar2.jpg
, which is resolved to http://localhost:4200/assets/images/avatar2.jpg
- notice how the /..
went away because there is no folder up. You can test this on a new project with ng serve
. So essentially the ../
is ignored.
In your production server maybe you are not serving at the root. If you serve at http://myserver.com/mysite/
, and request <img src="../assets/images/avatar2.jpg" />
, the full url will be http://myserver.com/mysite/../assets/images/avatar2.jpg
. This is then resolved to http://myserver.com/assets/images/avatar2.jpg
- notice how the /mysite/..
went away because the there was a folder above to go up to.
If you see something working when you do ng serve
but not when you do ng build
and then deploy it to your server, it likely means that something is different between your server and the ng serve
development server. Pay close attention to your folder structure, base url, public path, and anything else that can affect the browser requests. You can also find more information about deployment in https://angular.io/guide/deployment.
@filipesilva Wanted to say "apologize me" to be confuse because my english's limited and thanks a lot for theses infos but we are still diagree: I'd say thanks for your link about deployment but it's not question about "understand deployment and base url and so" this I understand.
Here's really question about new feature and how this output
is used if we are on ng s
or ng b
, and if you don't see requirement let me try with another way:
As you explain you agree this: on ng serve
if I write in template "../assets/images/avatar2.jpg"
the browser will try to resolve that path relative to the url. So if I'm on http://localhost:4200/
, the full request url will be http://localhost:4200/../assets/images/avatar2.jpg
, which is resolved to http://localhost:4200/assets/images/avatar2.jpg
So essentially the ../ is ignored EXACTLY WHAT YOU SAID AND IT'S COOL.
My question always on ng serve
is to apply EXACTLY same behavior "essentially ../ ignored" in angular-cli.json
So if I write:
"assets": [
{
"glob": "**/*",
"input": "./assets/",
"output": "../assets/"
},{
"glob": "favicon.ico",
"input": "./",
"output": "../"
}
],
On ng serve
the ../ wnt away because there is no folder up, AND for ng build
respect it and put it onle folder UP.
This behavior will really be nice, only one assets on prod (which is exactly same for each language) My /assets is about 5-10mo, theses images will be on cache if we switch language and so on and so on... Hope this time I'm clear.
Ok I understand the please apologize
expression now! Don't worry about the language difference, english isn't the first language for most people (it isn't for me either).
Oh I think I understand better... so the folder structure that you want when you do ng build --output-path=dist/fr/
is this:
dist/
assets/ (made from assets array)
fr/ (made from assets array AND build command)
So your dist/fr
contains all contents from your build AND from src/assets/fr
. That is a more difficult question... And https://github.com/angular/angular-cli/pull/7778 will actually make that setup not work anymore.
It is true that the current setup allowed for assets to be written outside of the output path but that was really not intentional as it is the cause of a lot of silent errors. In your case you were using it consciously to obtain that behaviour due to how your deployment works.
I think that the best alternative for you is to use multiple apps: https://github.com/angular/angular-cli/wiki/stories-multiple-apps
With multiple apps you can set different outDir
and assets
, while leaving all the other properties the same. You'd still have to manually copy favicon though... but this the correct answer because you really are building two different apps, it just so happens that you have your production server serving them from the same parent folder.
I understand that you can feel this could be easier, and it's true that i18n builds are somewhat messing right now (you always have to build multiple times, and deploy multiple times, etc, see more in https://github.com/angular/angular-cli/issues/6789). But improvements are planned for the future (https://github.com/angular/angular-cli/issues/6789#issuecomment-316036805).
@filipesilva yes I think we are nearly my question just little mistake because I don't have src/assets/fr
as you write
Otherwise you are correct I can achieve my behavior with 2 apps in angular-cli
(as I said in my second post).
Here is the actual solution of my requirement. To build different language I run npm run ok
here details:
"scripts": {
...
"fr": "ng build --prod --app=prod --output-path dist/fr --locale fr --bh /fr/ --i18n-format xtb --i18n-file src/locale/fr.xtb",
"de": "ng build --prod --app=prod --output-path dist/de --locale de --bh /de/ --i18n-format xtb --i18n-file src/locale/de.xtb",
"ok": "npm run fr && npm run de && cd dist && 7z a dist -mx9",
"report": "ng build --prod --output-path dist/fr --locale fr --bh ./ --i18n-format xtb --i18n-file src/locale/fr.xtb --stats-json && webpack-bundle-analyzer dist/fr/stats.json"
},
And in my angular-cli.json I have two apps named dev and prod
You can remark that both app are completly same the only thing different is ONE CHARACTER in assets output in app called dev I have "./assets" and in app called prod I have "../assets"
With this configuration I can run my npm run ok
and it gives me:
I have only one /assets
folder, in others words there is not /assets
folder in /fr
or /de
build.
https://github.com/angular/angular-cli/pull/7778 that beats me :) but not sure my question couldn't work with.
Advantage with my actual cli configuration
is I can keep for others developers on my team to use simply ng serve
to run fast dev-mode without sepcifying --app=dev
(I think it takes first apps[] when I simply run ng s
, nice) but for prod I need specify --app=prod
and it still not annoying for me, because ng build is not done every day, what embarassing me is that I need duplicate apps[] for dev and for prod while only 1 more char is added in assets output ./ for dev and ../ for prod, I expect To have same approach as you treat template url if we write ../../../ for a image on ng serve
it will simply went away and stay relativly on same folder (keeping output path).
I dont' realize how go ahead, to resume: treat differenty assets output depending if we are on ng serve or ng build. All assets.output[] you write as "../../../" should be resolved to ./ on ng serve and keeped "../../../" for ng build.
Now I think you see better, if not possible or not interessant sorry to make so much noise
I understand much better now, thank you. We can't make that change because on some setups it would break. You need it for your particular deployment setup but in other setups they need the ../../
etc. So changing it for them would break.
I appreciate you taking the time to explain this so well, I really do. It is very hard to understand the setups that people use sometimes and talking about it is the only way really.
Sorry to make noise one more time here, but after making workaround and have 2 app in my config file to get what I need : angular-cli.json
today I udpate to last version of cli 1.4.7 tried ng build
this get error :
An asset cannot be written to a location outside of the output path. source file common.ts
This is very annoying for me. Because all was working with my workaround. Now I can't have ma requirement. Maybe this need to be Warning instead Error
@filipesilva
why this issue is closed? Does anyone supposed that duplicated assets for each language is the correct way to build multilang app?
@istiti
did you get to fix it?
my project:
/en
/es
/assets
my solution: 1) use Multiple Apps integration 2) my .angular-cli.json:
"name": "dev",
"root": "src",
"outDir": "dist",
"assets": [
"favicon.ico",
{
"glob": "**/*",
"input": "./assets/",
"output": "./assets/"
}
"name": "prod",
"root": "src",
"outDir": "dist",
"assets": [
"favicon.ico",
{
"glob": "**/*",
"input": "./assets/",
"output": "../assets/",
"allowOutsideOutDir": true
}
3) Build:
(production):
"build-i18n:es": "ng build --app=prod --output-path=dist/es --aot -prod --bh /es/ --i18n-file=src/i18n/messages.es.xlf --i18n-format=xlf --locale=es",
"build-i18n:en": "ng build --app=prod --output-path=dist/en --aot -prod --bh /en/ --i18n-file=src/i18n/messages.en.xlf --i18n-format=xlf --locale=en",
"build-i18n": "npm run build-i18n:es && npm run build-i18n:en"
optional: if they had problems with their images in css in el file: /src/styles.css
error:
.buscador_itinerario{
background-image: url('../assets/themes/1/images/bg_full.jpg') !important;
}
solution:
.buscador_itinerario{
background-image: url('/../assets/themes/1/images/bg_full.jpg') !important;
}
add: '/../assets'
It's a shame that issue is closed and there is no real solution for multilang apps. @gamunax thanks for your temporary solution
Is there any official solution from angular team?
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.
Versions.
Repro steps.
I have multi language app, I know I need build for each language and actually output is:
with this configuration in angular-cli
And in all my template component I use ressources from assets like :
<img src="assets/images/avatar2.jpg" />
This ABOVE works for ng serve and ng b !
PROBLEM:
What I want is: have only one /assets folder like
So I simply edit my angular-cli config file to put assets one level higher :
And in all my template I juste specify one level higher like :
<img src="../assets/images/avatar2.jpg" />
PROBLEM: this only works on ng build NOT on ng serve !
The log given by the failure.
Mention any other details that might be useful.
to build I simply use
"ng build --prod --output-path dist/fr --locale fr --bh /fr/ --i18n-format xtb --i18n-file src/locale/fr.xtb
What I expect
Is it possible to considere "output" path of assets in DEVELOPEMENT mode server ? Or how achieve this behavior ?