5

I'm trying to deploy my project site on gh-pages, it's angular2 app with webpack, I set the base url to my repo name and everything loads fine except the relative paths in the templates, here is what I mean

import {Component} from '@angular/core';

@Component({
  selector: 'header',
  template: `
      <img class="fb-logo" [src]="fbLogo"/>
      <img class="ang-logo" [src]="angularLogo"/>
  `
})

export class Header{

    angularLogo = '../../assets/img/angular-logo.png';
    fbLogo = '../../assets/img/share/facebook.svg';
}

This works well on local dev, but when I push it to gh-pages branch It gives 404 because it's trying to get it from the root server http://myAcc.github.io/assets/img/fbLogo.svg instead of http://myAcc.github.io/myRepo/assets/img/fbLogo.svg

I couldn't figure out how to fix it so I tried to use it as inline-svg using require

angularLogo = require('../../assets/img/angular-logo.png');
fbLogo = require('../../assets/img/share/facebook.svg');

it works fine on local (with xss warnings) but when I deploy it to gh-pages It refuses to run over https.

How can I fix this issue?

Murhaf Sousli
  • 12,622
  • 20
  • 119
  • 185

2 Answers2

5

For future visitors, github pages deploy has been removed from ng-cli and will be available as different npm, https://github.com/angular/angular-cli/pull/4385

But it looks like deploying an angular app to github pages is now more effortless with https://github.com/angular-buch/angular-cli-ghpages

Usage:

ng build --prod --base-href "https://USERNAME.github.io/REPOSITORY/"
angular-cli-ghpages [OPTIONS]

there is also a shorter ngh command available

ng build --prod --base-href "https://USERNAME.github.io/REPOSITORY/"
ngh [OPTIONS]
Tarun Gupta
  • 6,305
  • 2
  • 42
  • 39
3

The problem is that your dev and your gh-pages have different roots levels, your dev root url must be something like this: http://localhost:port while your gh-page root is http://myAcc.github.io that's why your relative icons are not working.

I guess that you have different webpack configs, change your production config to something like this:

output: {
  path: 'something',
  filename: 'something.bundle.js',
  publicPath: '/myRepo/' // this will add /myRepo/ to all your assets
}

Here's a quick explanation about publicPath:

output.publicPath

The publicPath specifies the public URL address of the output files when referenced in a browser. For loaders that embed <script> or <link> tags or reference assets like images, publicPath is used as the href or url() to the file when it's different than their location on disk (as specified by path). This can be helpful when you want to host some or all output files on a different domain or on a CDN. The Webpack Dev Server also uses this to determine the path where the output files are expected to be served from. As with path you can use the [hash] substitution for a better caching profile.

You can find more info about publicPath here

Update:

The output.publicPathonly works with assets that were already declared since you are specifying your img source dynamically it won't work. You can use file-loader to do that for you, just change your loader to this:

{
  test: /\.(jpg|png|gif)$/,
  loader: 'file?name=/myRepo/[name].[ext]'
},

So whenever you require a jpg|png|gif on your code it adds the string /myRepo/.

Another solution is creating your custom pipe, since you are using the angular2-webpack-starter your building process exports your environment to the varaible ENV so you can use that for your custom pipe, something like this:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'pathResolver'})
export class PathResolverPipe implements PipeTransform {
  transform(path: string): string {

    return ENV === 'production' ? path.replace(/assets/i, 'myRepo/assets') : path;
  }
}

And use it on your component like this:

import {Component} from '@angular/core';
import { PathResolverPipe } from 'path/to/pipe';

@Component({
  selector: 'header',
  pipes: [PathResolverPipe],
  template: `
      <img class="fb-logo" [src]="fbLogo | pathResolver"/>
      <img class="ang-logo" [src]="angularLogo | pathResolver"/>
  `
})

export class Header{

    angularLogo = '../../assets/img/angular-logo.png';
    fbLogo = '../../assets/img/share/facebook.svg';
}
Fabio Antunes
  • 22,251
  • 15
  • 81
  • 96
  • I added `publicPath` but didn't effect, It still requests the url from the root, I'm using https://github.com/AngularClass/angular2-webpack-starter – Murhaf Sousli Aug 20 '16 at 20:41
  • 1
    I have the same issue, but I don't have a webpack.config file, and neither do I want to implement a pipe. Angular-cli created an envrionment.prod.ts file - any idea what I put in that to setup base.url properly? – rmcsharry Dec 29 '16 at 14:47