Angular2,Angular-cli,Webpack - 产品部署后 github:pages 上未加载图像资产

Angular2, Angular-cli, Webpack - image assets not loading on github:pages after prod deploy


这不是一个重复的问题:

解释了问题,但该项目不是用 angular-cli 构建的,就像我的一样,因此我没有 webpack.config 文件。

虽然我在下面描述的问题显然是关于正确设置 base_url,但它与 this issue 不同,后者是关于设置 angular 以将请求发送到一个 base_url 就像一个 api.


我的项目在 localhost 和 github:pages 上构建和运行(甚至 css 都正确加载)。唯一在 github:pages 上不起作用的是图像,它们都是 return 404(尽管如果我直接在浏览器中导航到资产文件夹,我可以看到它们)。

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

例如,项目名称是 testapp 然后在 github:pages 上它部署在这里:

https://<username>.github.io/testapp

图片在

src/assets/images

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

background-image: url('../../assets/images/dining-room.png');

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

background-image: url('testapp/assets/dining-room.png');

我知道 github:pages 是基于 Jekyll 的,我知道 this explanation,但我不明白的是你如何配置一个 angular-cli 项目来了解github:pages 正在使用文件夹部署应用程序。


更新 1

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

ng github-pages:deploy --base-href /testapp/

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

<base href="/testapp/">

我本以为这会自动解决问题,但图像仍然是 return 404。这个 base_href 并没有像您期望的那样自动注入到相对路径中。 index.html 文件在本地具有 <base href="/"> 并且显然有效。


更新 2

在尝试解决这个问题时,我开始相信这与 Angular 构建组件的方式有关。 here.

对此有一个很好的解释


编辑已添加 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
    }
  }
}

了解 Angular2 中的所有组件都声明为相对路径是解决此问题的关键。简单地说,这意味着当 ng 是 building/compiling 你的项目时,一切都与 ROOT 相关。请参阅问题中的 link 更新 2。

因此,我的 CSS 文件是组件的本地文件,在我的 app/src 层次结构中有 2 个文件夹。这就是为什么我像这样引用图像的原因:

../../assets/images/<file>.png

但是当 angular 构建时 /assets/images 位于 ROOT - 你可以在构建后的 DIST 文件夹中看到它(即在 运行 ng github-pages:deploy 之后)

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

assets/images/<file>.png

然后构建:

ng github-pages:deploy --base-href /testapp/

在生产中,这些图像 links 将工作,因为 /testapp/ 现在是根,并且它们是相对于根的,因此:

/testapp/assets/images/<file>.png


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

为了将来参考,其他人可能会和我一样思考这个问题,需要直接在组件中访问 base-href 来解决这个问题。因为我想出了如何做到这一点,我想我会在这里添加它:

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

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

providers: [{provide: APP_BASE_HREF, useValue : '/your-value/'}]

警告 - 请注意,这现在正在对您的生产基地 href 进行硬编码。这将覆盖您在 index.html 中设置的任何内容(因此使用 ng build 命令行选项将毫无意义,因为这是在 DIST 文件夹内的 index.html 中创建该设置的原因).

2 - 在您的组件中添加 2 个导入并在构造函数中注入 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);
}

重要提示

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

useValue : '/'

然后部署到 github:pages...在您浏览到您的应用程序后,它将停止使用文件夹名称(它会在应用程序加载后从地址栏中消失...尽管应用程序会继续运作)。

最后

截至 2016 年 12 月 30 日,无法在组件内包含图像并使用本地相对路径引用它们。参见 this and this

我在开发模式下的本地主机上遇到了类似的问题。每当我更新 SCSS 文件时,我的背景图像都不会显示在浏览器中。我的背景图片都引用了相对路径,例如: background: url(../../assets/heros/contact-hero-mbl@2x.jpg);。我将图像路径更新为: background: url(/assets/heros/contact-hero-mbl@2x.jpg); 一切似乎都按预期进行。希望这对某人有所帮助。