qkhanhpro
qkhanhpro

Reputation: 5220

How to bundle asset for angular application that is loaded elsewhere

For an Angular 7 application that finally build to

- main.js
- assets
  -- assets/img

With an component/html that reference to asset as

src='./assets/img/img1.jpeg'

The application would be given to different teams and can be hosted on different roots

example.com/route/first
example2.com/route/second

If the consumer refer to my build content as <script src=''../some-dir/libs/main.js">

The Angular application will look at the current path to find assets ( example.com/route/first/assets ) which will force them to copy-paste the asset folder that I provided to their root. I imagine It would be much more simple for the customer if my component can look for my asset at the location relative to my build content ( '../some-dir/libs/asset' ), instead of their directory root. However I'm not very sure if what I expect is industry standard or appropriate

How can I correctly build/bundle/reference assets that the consumer can use anywhere by just extracting and referencing/importing my build content ? ( That I don't need to know consumer's project structure and the consumer does not need to alter my/his folder structure )

Upvotes: 5

Views: 9807

Answers (4)

zhimin
zhimin

Reputation: 3050

Just use relative url in app like this:

<img src='./assets/img/img1.jpeg' />

If you know where the root context is, build your app with base-href and deploy-url parameter like this:

ng build --prod --base-href=/route1/ --deploy-url=/route1/

if you need deploy into different root context , change the value of the parameters and build it again.

But if you don't know the deploy root context, the plan B is:

Change useHash to true in the app-routing.module.ts

const routes: Routes = [/* your routes goes here */];

@NgModule({
    imports: [
        RouterModule.forRoot(routes, {
            useHash: true, // change useHash to true
            enableTracing: !environment.production
        })
    ],
    exports: [RouterModule]
})
export class AppRoutingModule { }

and change the base href in index.html to ./,

<head>
  <base href="./">
</head>

don't add base-href and deploy-url parameter with ng build, then you can deploy your app to any web root. but the the url will be end with /{webroot}/#/{client-route}

Upvotes: 5

viren Kalkhudiya
viren Kalkhudiya

Reputation: 792

There is a flag called --deploy-url which can be used with the ng build command. The deploy-url is the URL where files or assets will be stored. If deploy-url is their then the angular app will open the assets and files from this url other wise it used the app url or base-url.

Try the build command

ng build --prod --base-href domainname.com/app/app1/ --deploy-url domainname.com/app/app1/script/

For more details follow the links

Upvotes: 0

user6600549
user6600549

Reputation:

This is what you want 👍

In your angular.json file where is your project name, find your project name there is a property architect

so in the architect.build.assets:['add the path of your assets you want to bundle']

example

"app1": {
      "root": "projects/app1/",
      "sourceRoot": "projects/app1/src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/app1",
            "index": "projects/app1/src/index.html",
            "main": "projects/app1/src/main.ts",
            "polyfills": "projects/app1/src/polyfills.ts",
            "tsConfig": "projects/app1/tsconfig.app.json",
            "assets": [
              "projects/app1/src/favicon.ico",
              "projects/app1/src/assets",
              "../more-assets-folder" <=== add your assets here
            ],
            "styles": [
              "projects/app1/src/styles.css"
            ],
            "scripts": []
          },

Upvotes: 1

waterplea
waterplea

Reputation: 3641

I believe either defining "baseHref" option in angular.json or base tag in your head in index.html should help.

Upvotes: 4

Related Questions