使用ng build从环境变量设置基础href

38

有人知道如何使用angular-cli完成这个任务吗?我希望能够将 baseHref 路径存储在/ src / environments / environment.x.ts 中的环境变量中,并根据构建期间选择的环境,设置baseHref路径。

像这样的东西:

environment.ts

export const environment = {
  production: false,
  baseHref: '/'
};

environment.prod.ts

export const environment = {
  production: true,
  baseHref: '/my-app/'
};

然后呼叫...

ng build --prod

我希望能够通过在/dist/index.html文件中添加<base href="/my-app/">来显示内容。

我曾尝试将我的环境变量命名为构建命令中使用的--base-href选项,希望cli可以识别它,但是并没有成功。

是否有一种方法可以从命令行中引用环境变量?例如ng build --base-href environment.baseHref


1
你为什么想在环境文件中设置基础 href?index.html 中的基础 href 可以通过 --base-href your-url 进行配置。 - shusson
9
因为我需要在一个有多个不同部署位置的构建服务器上运行此程序,最好利用 Angular 提供的内置功能(如果可能的话)。 - ryanulit
4个回答

25

你需要使用APP_BASE_HREF

@NgModule({
  providers: [{provide: APP_BASE_HREF, useValue: environment.baseHref }]
})
class AppModule {}

请参见Angular文档

编辑

由于CSS / JS不适用于APP_BASE_HREF,因此您可以执行以下操作:

app.component.ts中通过import { DOCUMENT } from "@angular/platform-browser";注入DOCUMENT。

constructor(@Inject(DOCUMENT) private document) {
}

然后在你的ngOnInit()函数中

ngOnInit(): void {
    let bases = this.document.getElementsByTagName('base');

    if (bases.length > 0) {
      bases[0].setAttribute('href', environment.baseHref);

    }
  }

1
是的,我在谈论全局CSS/JS。我将任何第三方引用添加到angular-cli.json文件中的apps[0].styles和apps[0].scripts数组中。具体而言,我正在谈论内联、供应商、主要等捆绑文件,这些文件是angular-cli json编译和压缩项目代码的结果。它们试图从<base />标签路径解析,而不是我为APP_BASE_HREF提供的路径。 - ryanulit
@12秒,您能否更新您的答案并包含导入部分。我尝试使用这段代码,在app.module.ts文件中它会抛出一个环境变量错误。它是从哪里来的?它如何在app.component.ts文件中可用? - AndrasCsanyi
1
@SayusiAndo 环境变量是从生成于 angular-cli 的 environment.ts 文件中获取的。如果您没有使用 angular-cli,可以创建自己的 environment.ts 文件并导出环境变量的 const 变量。(请参阅原问题以了解变量的定义) - penleychan
2
DOCUMENT现在已经移动到@angular/common包中。 - ratatosk
5
在访问任何JavaScript代码(从app.ts获取)之前,服务器必须提供实际包含该代码的文件(例如main.bundle.js)。如果我将其发布在Web应用程序中,而该应用程序不位于Web站点的根目录(IIS)内,则所有初始资源都会被提供,而不考虑环境的baseHref。例如,http://localhost/Angular5Starter将提供localhost/somefile.js而不是localhost/Angular5Starter。这个问题能解决吗?还是我仍然需要使用--base-href - Alexei - check Codidact
显示剩余5条评论

9
你需要编辑 angular.json 文件来适应生产环境。将 __BASE_HREF____DEPLOY_URL__ 这两个常量替换为你想要的路径,然后就可以愉快地使用了。
  "configurations": {
    "production": {
      "baseHref": "__BASE_HREF__",
      "deployUrl": "__DEPLOY_URL__",
      "fileReplacements": [
        {
          "replace": "src/environments/environment.ts",
          "with": "src/environments/environment.prod.ts"
        }
      ],

https://angular.io/cli/serve中阅读关于baseHrefdeployUrl的内容。


1
你可以编辑你的angular.json文件,并设置构建配置为指向不同的tsconfing文件来进行生产环境的构建。

angular.json

"targets": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
      "options": {
        "tsConfig": "src/tsconfig.app.dev.json"
      },
      "configurations": {
        "production": {
         ...
         "tsConfig": "src/tsconfig.app.prod.json"
        }
      }
    }
...
}

tsconfig.app.prod.json

{
    "compilerOptions" : {
        "baseUrl" : "/my-app/",
        ......
    }
}

tsconfig.app.dev.json

{
    "compilerOptions" : {
        "baseUrl" : "/",
        ......
    }
}

0

这种方法对我很有效:

 <body>
    <app-root></app-root>
    <script>
       this.document.getElementsByTagName('base')[0]
        .setAttribute('href', window.location.pathname);
    </script>
 </body>

为什么它有效:当浏览器加载index.html时,base href属性会设置为当前相对路径。这就是你需要从正确的路径加载以下运行时、主要和polyfill javascript文件所需的全部内容。这也适用于资产。

这种方法适用于本地开发环境和生产环境。

而且,你不需要设置环境变量来设置index.html的当前相对路径,这应该是显而易见的。

附加说明: 也许HashLocationStrategy对于这种解决方案是必需的:

{ provide: LocationStrategy, useClass: HashLocationStrategy }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接