Angular - 资产在库生产构建中返回 404
Angular - Assets returning 404 in library production build
我正在使用 ng serve 在 Angular 中开发组件库。
只要我是 运行 开发服务器,我就能够提供资产,因为我已将它们捆绑在我的项目 angular.json
文件中。项目结构如下:
angular-project
- projects
- component-library
- src
- assets <- contains SVGs consumed by library
- lib <- source code
- src
- app
app.component.ts
app.component.html
app.component.scss
app.module.ts
angular.json <-- bundles projects/component-library/src/assets when running ng serve
我认为这是我把自己搞砸的地方。在我的 angular.json
文件中,我有这个:
"angular-project-name": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/angular-project",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets",
"src/manifest.webmanifest",
{
"glob": "**/*",
"input": "./projects/component-library/src/assets",
"output": "/src/assets/"
} <-- HERE is where I bundle everything
],
...
然后我可以像这样在代码中调用资产:
export class SomeComponent {
public get logoUrl(): string {
switch (this.messageBarType) {
case 'warning':
return './src/assets/img/message-bar/string-icon-info-warn.svg';
case 'severe-warning':
return './src/assets/img/message-bar/string-icon-info-severe-warn.svg';
case 'error':
return './src/assets/img/message-bar/string-icon-info-error.svg';
case 'blocked':
return './src/assets/img/message-bar/string-icon-info-blocked.svg';
case 'success':
return './src/assets/img/message-bar/string-icon-info-success.svg';
case 'info':
return './src/assets/img/message-bar/string-icon-info-warn.svg';
}
}
}
这在开发服务器上运行良好。但是当我创建一个生产构建并将其推送到 NPM 时,任何对资产 returns 404 的调用。资产文件夹肯定包含在生产构建中,正如我在 dist
文件夹中看到的那样,并且据我所知,我的 ng-package.json
文件是正确的:
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/component-library",
"lib": {
"entryFile": "src/public-api.ts"
},
"assets": [
"./src/lib/**/*.scss",
"./src/assets/**"
]
}
我试过移动 assets 文件夹,我试过更改代码中的路径以指向正确的位置,但在生产构建方面我完全没有运气。以前有没有人经历过这样的事情?
我最终创建了自己的自定义图标模块。
因为资产是 SVG,而且很可能永远都是这种情况,所以我在这里创建了这种类型:
export interface INgxFluentDesignIcon {
readonly name: string;
readonly paths: Array<string>;
readonly fill: string;
readonly width: number;
readonly height: number;
}
然后创建了一个采用 INgxFluentDesignIcon 的组件,如下所示:
import { Component, Input } from '@angular/core';
import { INgxFluentDesignIcon } from '../shared/types/ngx-fluent-design-icon.interface';
@Component({
selector: 'ngx-fluent-design-icon',
templateUrl: './icon.component.html',
styleUrls: ['./icon.component.html']
})
export class NgxFluentDesignIconComponent {
@Input() public icon: INgxFluentDesignIcon;
}
<svg *ngIf="icon" [attr.width]="icon.width" [attr.height]="icon.height" [attr.viewBox]="'0 0' + ' ' + icon.width + ' ' + icon.height" fill="none" xmlns="http://www.w3.org/2000/svg">
<path *ngFor="let path of icon.paths" [attr.d]="path" [attr.fill]="icon.fill"></path>
</svg>
现在我的组件上显示了正确的图标。
public get logoUrl(): INgxFluentDesignIcon {
switch (this.messageBarType) {
case 'warning':
return NgxFluentDesignIconInfoWarn;
case 'severe-warning':
return NgxFluentDesignIconInfoSevereWarn;
case 'error':
return NgxFluentDesignIconInfoError;
case 'blocked':
return NgxFluentDesignIconInfoBlocked;
case 'success':
return NgxFluentDesignIconInfoSuccess;
case 'info':
return NgxFluentDesignIconInfoWarn;
}
}
这完全符合我的需要。不过,我仍然不知道如何将资产包含在 Angular 库的生产版本中,所以我会再开放几天。
我正在使用 ng serve 在 Angular 中开发组件库。
只要我是 运行 开发服务器,我就能够提供资产,因为我已将它们捆绑在我的项目 angular.json
文件中。项目结构如下:
angular-project
- projects
- component-library
- src
- assets <- contains SVGs consumed by library
- lib <- source code
- src
- app
app.component.ts
app.component.html
app.component.scss
app.module.ts
angular.json <-- bundles projects/component-library/src/assets when running ng serve
我认为这是我把自己搞砸的地方。在我的 angular.json
文件中,我有这个:
"angular-project-name": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/angular-project",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets",
"src/manifest.webmanifest",
{
"glob": "**/*",
"input": "./projects/component-library/src/assets",
"output": "/src/assets/"
} <-- HERE is where I bundle everything
],
...
然后我可以像这样在代码中调用资产:
export class SomeComponent {
public get logoUrl(): string {
switch (this.messageBarType) {
case 'warning':
return './src/assets/img/message-bar/string-icon-info-warn.svg';
case 'severe-warning':
return './src/assets/img/message-bar/string-icon-info-severe-warn.svg';
case 'error':
return './src/assets/img/message-bar/string-icon-info-error.svg';
case 'blocked':
return './src/assets/img/message-bar/string-icon-info-blocked.svg';
case 'success':
return './src/assets/img/message-bar/string-icon-info-success.svg';
case 'info':
return './src/assets/img/message-bar/string-icon-info-warn.svg';
}
}
}
这在开发服务器上运行良好。但是当我创建一个生产构建并将其推送到 NPM 时,任何对资产 returns 404 的调用。资产文件夹肯定包含在生产构建中,正如我在 dist
文件夹中看到的那样,并且据我所知,我的 ng-package.json
文件是正确的:
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/component-library",
"lib": {
"entryFile": "src/public-api.ts"
},
"assets": [
"./src/lib/**/*.scss",
"./src/assets/**"
]
}
我试过移动 assets 文件夹,我试过更改代码中的路径以指向正确的位置,但在生产构建方面我完全没有运气。以前有没有人经历过这样的事情?
我最终创建了自己的自定义图标模块。
因为资产是 SVG,而且很可能永远都是这种情况,所以我在这里创建了这种类型:
export interface INgxFluentDesignIcon {
readonly name: string;
readonly paths: Array<string>;
readonly fill: string;
readonly width: number;
readonly height: number;
}
然后创建了一个采用 INgxFluentDesignIcon 的组件,如下所示:
import { Component, Input } from '@angular/core';
import { INgxFluentDesignIcon } from '../shared/types/ngx-fluent-design-icon.interface';
@Component({
selector: 'ngx-fluent-design-icon',
templateUrl: './icon.component.html',
styleUrls: ['./icon.component.html']
})
export class NgxFluentDesignIconComponent {
@Input() public icon: INgxFluentDesignIcon;
}
<svg *ngIf="icon" [attr.width]="icon.width" [attr.height]="icon.height" [attr.viewBox]="'0 0' + ' ' + icon.width + ' ' + icon.height" fill="none" xmlns="http://www.w3.org/2000/svg">
<path *ngFor="let path of icon.paths" [attr.d]="path" [attr.fill]="icon.fill"></path>
</svg>
现在我的组件上显示了正确的图标。
public get logoUrl(): INgxFluentDesignIcon {
switch (this.messageBarType) {
case 'warning':
return NgxFluentDesignIconInfoWarn;
case 'severe-warning':
return NgxFluentDesignIconInfoSevereWarn;
case 'error':
return NgxFluentDesignIconInfoError;
case 'blocked':
return NgxFluentDesignIconInfoBlocked;
case 'success':
return NgxFluentDesignIconInfoSuccess;
case 'info':
return NgxFluentDesignIconInfoWarn;
}
}
这完全符合我的需要。不过,我仍然不知道如何将资产包含在 Angular 库的生产版本中,所以我会再开放几天。