繁体   English   中英

使用 base-href 和 deploy-url 构建 Angular CLI 以访问 CDN 上的资产

[英]Angular CLI build using base-href and deploy-url to access assets on CDN

背景

我正在使用 Angular CLI 构建一个项目(包含多个应用程序)。 我想在我的域上的单独子路径上发布应用程序,例如example.com/apps/app1/

如果我将--base-href参数设置为/apps/app1/它可以解决有关路由器的任何问题,并且它将加载资产(JS、CSS 和图像等)就好了。

如果我使用Location服务,我可以使用

this.location.prepareExternalUrl('/assets/data/data.json')

解析动态加载的资产(它们将解析为/apps/app1/assets/data/data.json )。

到现在为止还挺好。 但我现在想通过 CDN 提供应用程序资产,例如cdn.example.com ,同时在原始 URL example.com/apps/app1/` 上托管应用程序本身。 所以现在我使用以下方法构建应用程序:

 ng build -prod --app app1 --base-href "/apps/app1/" --deploy-url "http://cdn.example.com/app-assets/apps/app1/"

这一次,我同时应用了--base-href--deploy-url参数。 它工作得很好,因为它使用 base-href 来帮助路由器解析 URL,并从 CDN 加载 js 和 CSS 文件。 它还使用 CDN URL 解析 CSS 文件中的图像 URL 引用。


问题

从资产文件夹动态加载图像或数据时(在服务或模板中),我找不到使用deploy-url配置解析 URL 的好方法。

如果我使用Location服务,它仍然使用base-href来解析 URL,所以

this.location.prepareExternalUrl('/assets/data/data.json')

仍将解析为/apps/app1/assets/data/data.json而不是http://cdn.example.com/app-assets/apps/app1/assets/data/data.json

如果定义了deploy-url值,我本来希望它使用deploy-url值,特别是因为这将是一个通用的解决方案,在同一域上托管文件和在外部域上托管文件时都可以使用。


问题

有没有办法同时考虑base-hrefdeploy-url参数来解析资产 URL?

理想情况下,像Location.prepareExternalUrl这样的官方 Angular 函数,但如果我能以某种方式从 Angular 获取 base-href 和 deploy-url 参数,我就可以为它构建自己的服务。

我不想在环境配置中定义 URL,因为:

  1. 每个应用程序都需要特定的环境配置
  2. 它会与构建应用程序时提供的值产生潜在冲突。

要在应用程序运行时访问--deploy-url值,请使用以下命令创建deploy-url.ts

export const DEPLOY_URL = new InjectionToken<string>('deployUrl');

并在您的 main.ts 文件中使用此代码段:

const deployUrl = (function() {
  const scripts = document.getElementsByTagName('script');
  const index = scripts.length - 1;
  const mainScript = scripts[index];
  return mainScript.src.replace(/main.*?\.js$/, '');
})();

const DEPLOY_URL_PROVIDER = {
  provide: DEPLOY_URL,
  useValue: deployUrl,
};

platformBrowserDynamic([DEPLOY_URL_PROVIDER])
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

这个想法是获取当前执行的 Javascript 文件的 url,它是 main.js(或 main.hash.js,如果启用了outputHashing )并从中剥离文件名。 然后在您的服务中使用@Inject(DEPLOY_URL) deployUrl: string作为构造函数参数注入--deploy-url值。

这是我解决这个“BS”问题的方法。 当您的应用程序用于例如托管在www.domain.de/hehe下时。

  1. angular.json添加"deployUrl": "./",
  2. <head>中的src/index.html添加/更新<base href="./">
  3. 在整个应用程序中,您将使用资产和诸如此类的相对路径: <img src="./assets/img/pictureOfMyCrazyWife.png">
  4. 只需方便地运行ng buildng build --prod

通过这些简单的步骤,您就有了一般设置。 因此,无论是www.domain.de/hehewww.domain.de/hehe2www.domain.de/还是www.domain.de/lol

我遇到了完全相同的情况,正如您在背景中概述的那样,使用base-hrefdeploy-url集进行构建确实有效,因为我们能够在托管另一台服务器上的应用程序。

作为在我们的模板中动态加载资产的解决方案,我们编写了一个 API,为此目的提供环境变量,提供每个部署所需的适当 URL。

这是我为几个项目所做的。

使用服务器设置的动态值设置 APP_BASE_HREF,例如 Cookie,SPA 在初始化时读取它。 getBaseUrl 函数只是读取一个 cookie 值。

{ provide: APP_BASE_HREF, useFactory: () => getBaseUrl() }

将 deployUrl 设置为 CI 过程的一部分。 您需要动态设置 BUILD 和 VERSION。 这可以通过使用一个简单的 shell 脚本来完成。

https://my-cloud.cloudfront.net/my-app/{BUILD}/{VERSION}/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM