Dynamic Asset Layout in Angular

My application will be used on several machines, and it can be located in a different place each time. For example, a home route can be in any of the following locations:

local: 9000 / house

local: 9000 / a / house

local: 2000 / yet / other / location / house

Therefore, I want to make sure that my application will work no matter where it needs to find its assets. All my paths are relative, so I hope that a step in the right direction, for example:

<link rel="stylesheet" href="assets/global-styles.css"> 

and in my component templates, for example:

 <img src="assets/components/dashboard/images/foo.png" /> 

Here is what I have tried so far:

I changed my <base> attribute to manually capture part of the URL after the port and to the "home" as follows:

 <html> <head> <script> // manually sets the <base> tag href attribute so the app can be located in places other than root var split = location.pathname.split('/'); var base = ""; for (var i = 0; i < split.length - 1; i++) { base += split[i]; if (i < split.length - 2) { base += "/"; } } window['_app_base'] = base; document.write("<base href='" + base + "' />"); </script> .... 

So far an example, if a user loaded the home page on localhost: 9000 / hello / home, the <base> tag would look like this:

 <base href='/hello' /> 

This code also sets the variable to the same value, which I then use in my app.module.ts to also indicate the new base value:

import {APP_BASE_HREF} of '@ angular / common';

 @NgModule({ declarations: [...], imports: [...], providers: [ ..., { provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' } ] }); 

However, despite all this, the application is still looking for assets in the resource folder, which, in its opinion, are still in the root directory.

 GET http://localhost:9000/assets/ionic-styles.css net::ERR_ABORTED GET http://localhost:9000/inline.bundle.js net::ERR_ABORTED GET http://localhost:9000/assets/font-awesome-4.6.3/css/font-awesome.min.css net::ERR_ABORTED GET http://localhost:9000/assets/bootstrap.min.css net::ERR_ABORTED GET http://localhost:9000/assets/global-styles.css net::ERR_ABORTED GET http://localhost:9000/polyfills.bundle.js net::ERR_ABORTED GET http://localhost:9000/styles.bundle.js net::ERR_ABORTED GET http://localhost:9000/vendor.bundle.js net::ERR_ABORTED 

What am I missing? I also saw people take the approach when they indicate the path in their ng build team ... is this necessary for all of the above? I would really like you to not have a separate assembly for everyone, but if necessary, let me know.

Thanks.

UPDATE: After several days of disappointment, my application works using the code indicated in the question above. Turns out I needed to have <script> in my <head> in order to change <base> . There was no need to add APP_BASE_HREF to ngModule providers. However, adding APP_BASE_HREF will not break either ...

This is one of those problems when she β€œjust worked” after she dropped the problem for a week and returned to it. Maybe there was some kind of cache problem? In the end, I tried updating <base> last week, but he was still looking for the wrong place for assets. Although last week I cleared the browser cache several times trying to debug this problem, so I'm not sure if the cache problem really is.

I am sorry that this answer will not be useful to people who will face this problem in the future. I really don't know what to fix the problem. I think one of the answers below is likely to point you in the right direction. It seems that no matter what I tried, it did not work for some unknown reason.

If you encounter this problem and have a specific question, feel free to inform me or leave a comment, and I will tell you how I configured the settings.

+5
source share
2 answers

You just need to do the following base href in index.html

 <base href="./"> 

which you can do manually or when creating, for example,

 ng build --base-href ./ 

You do not need to do anything else on the angular side, except copying your contents from the dist directory to your server directory /whatever/is/your/root/ .

Now you can access your angular app with url

 localhost:port/whatever/is/your/root/index.html 

UPDATE

You might want to do a couple more things on your server. But how you do this will depend entirely on the technology you use on your server.

  • Make localhost:port/whatever/is/your/root/index.html as your default homepage.

  • To your localhost route urls: port / whatever / is / your / root / ** to localhost:port/whatever/is/your/root/index.html . Please note that you must forward the request and not send the redirect.

+1
source

This is how URLs work in browsers. You can change them with a pipe. Given that your injection value works as intended, this should work. It should also be in lines of type 'APP_BASE_HREF' in the module.

  @Pipe({ name: 'assetspipe' }) export class AssetspipePipe implements PipeTransform { baseUrl: string; constructor(@Inject('APP_BASE_HREF') baseHref: string) { this.baseUrl = baseHref; } transform(value: string) { const newval = this.baseUrl + value; return newval; } } 

then in your component:

 <img src="{{'assets/components/dashboard/images/foo.png' | assetspipe}}"/> 

the pipe should add baseurl as a prefix.

Also check this thread. Your implementation may have a problem downloading packages.

0
source

Source: https://habr.com/ru/post/1274821/


All Articles