Angular2,Angular-cli,Webpack - 图像资产未在github上加载:prod部署后的页面

rmc*_*rry 6 github-pages webpack angular-cli angular


这不是一个重复的问题:

这个问题解释了这个问题,但是该项目并没有像我一样使用angular-cli构建,因此我没有webpack.config文件.

虽然我在下面描述的问题显然是关于使base_url设置正确,但它与此问题不同,这是关于设置角度以将请求发送到像api这样的base_url.


我的项目在localhost上运行并运行github:pages(甚至css都正确加载).唯一不适用于github的东西:页面是图像,它们全部返回404(即使我可以看到它们,如果我直接在浏览器中导航到assets文件夹).

问题是在localhost上,angular-cli在主机名后面没有子文件夹运行项目.但github:pages确实如此.

比如说项目名称testapp就在github:pages这里部署:

https://<username>.github.io/testapp
Run Code Online (Sandbox Code Playgroud)

图像在

src/assets/images
Run Code Online (Sandbox Code Playgroud)

它们在angular-2组件内的css中使用相对路径引用,如下所示:

background-image: url('../../assets/images/dining-room.png');
Run Code Online (Sandbox Code Playgroud)

那么如何配置angular-2生产部署文件,以便在生产中路径变为:

background-image: url('testapp/assets/dining-room.png');
Run Code Online (Sandbox Code Playgroud)

据我所知,这github:pages是基于Jekyll,我理解这个解释,但我不明白的是你如何配置一个angular-cli项目,以便知道github:pages正在使用文件夹来部署应用程序.


更新1

到目前为止,我已经发现部署的命令行github:pages有一个base_href选项.所以我可以这样做:

ng github-pages:deploy --base-href /testapp/
Run Code Online (Sandbox Code Playgroud)

然后我可以在/ dist文件夹中看到html文件已被更改为包含基本href,如下所示:

<base href="/testapp/">
Run Code Online (Sandbox Code Playgroud)

我本来希望这可以自动解决问题,但图像仍会返回404.这个base_href不会像你期望的那样自动注入到相对路径中.在本地,index.html文件<base href="/">显然有效.


更新2

在试图解决这个问题时,我开始相信这与Angular构建组件的方式有关.可以在这里找到一个非常好的解释.


编辑添加了angular-cli.json

{
  "project": {
    "version": "1.0.0-beta.22-1",
    "name": "floorbook"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "fb",
      "mobile": false,
      "styles": [
        "styles.css"
      ],
      "scripts": [],
      "environments": {
        "source": "environments/environment.ts",
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  "addons": [],
  "packages": [],
  "e2e": {
    "protractor": {
      "config": "./protractor.conf.js"
    }
  },
  "test": {
    "karma": {
      "config": "./karma.conf.js"
    }
  },
  "defaults": {
    "styleExt": "css",
    "prefixInterfaces": false,
    "inline": {
      "style": false,
      "template": false
    },
    "spec": {
      "class": false,
      "component": true,
      "directive": true,
      "module": false,
      "pipe": true,
      "service": true
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

rmc*_*rry 11

理解Angular2中的所有组件都被声明为相对路径是解决这个问题的关键.简单地说这意味着当ng正在构建/编译项目时,一切都与ROOT相关.请参阅问题中的链接更新2.

因此,我的CSS文件是组件的本地文件,以及我的app/src层次结构中的2个文件夹.这就是我引用这样的图像的原因:

../../assets/images/<file>.png
Run Code Online (Sandbox Code Playgroud)

但是当角度构建/assets/images处于ROOT时 - 您可以DIST在构建后(即运行后ng github-pages:deploy)在文件夹中看到

所以我需要做的就是将css更改为直接从root引用(即忽略该css文件是组件中的2个文件夹):

assets/images/<file>.png
Run Code Online (Sandbox Code Playgroud)

然后建立:

ng github-pages:deploy --base-href /testapp/
Run Code Online (Sandbox Code Playgroud)

在生产中,那些图像链接将起作用,因为/testapp/现在是根,它们是相对于root的,因此:

/testapp/assets/images/<file>.png
Run Code Online (Sandbox Code Playgroud)


回答我认为的问题 - 如何从组件内部访问APP_BASE_HREF

为了将来参考,其他人也可能会像我一样思考并且需要base-href直接在组件中进行访问以解决此问题.由于我想出了如何做到这一点,我想我会在这里添加它:

1 - app.module.ts您需要导入并提供它:

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

providers: [{provide: APP_BASE_HREF, useValue : '/your-value/'}]
Run Code Online (Sandbox Code Playgroud)

警告 - 请注意,这现在很难编码您的生产基础-href.这将覆盖您设置的任何内容index.html(因此使用ng build命令行选项将毫无意义,因为这是index.htmlDIST文件夹内部创建该设置的内容).

2 - 在你的组件中添加2个import并APP_BASE_REF在构造函数中注入:

import { APP_BASE_HREF } from '@angular/common';
import { Inject } from '@angular/core';

constructor(@Inject(APP_BASE_HREF) private baseHref:string) { 
  console.log(this.baseHref);
}
Run Code Online (Sandbox Code Playgroud)

重要的提示

如果您在上面的步骤1中将值设置为:

useValue : '/'
Run Code Online (Sandbox Code Playgroud)

然后部署到github:pages ...浏览到你的应用程序后,它将停止使用文件夹名称(它在应用程序加载后只是从地址栏中消失......虽然应用程序将继续运行).

最后

自2016年12月30日起,无法在组件内部显示图像并使用本地相对路径引用它们.看到这个这个.